Skip to content

Instantly share code, notes, and snippets.

@rhaseven7h
Created July 26, 2016 22:00
Show Gist options
  • Save rhaseven7h/ff9e0548aa7ce0fd4d389482f22ca257 to your computer and use it in GitHub Desktop.
Save rhaseven7h/ff9e0548aa7ce0fd4d389482f22ca257 to your computer and use it in GitHub Desktop.
HackerRank.com - Functional Programming - Haskell - Captain Prime

Captain Prime

Captain Prime is going on a trip to Primeland and needs support of his troops to make this voyage successful. To prevent the wrath of evil spirits, he has to throw out some people from his troop into the sea. This decision will depend on the identification number of the troop member.

His ship is divided into three parts: Left, right, and central. Every person on the ship is assigned an identification number (referred as id), and according to their id they get to work in one part of the ship, or end up getting thrown out of the ship.


A person's fate depends on the following conditions:

  • CENTRAL: He will be working in central part if (a) his id is a prime number, (b) it doesn't contain 0 as one of the digits, and (c) when the left digits are successively taken off, then all the resulting numbers are also prime. (d) And same goes for the digits on the right side. For example person with id 3137 will work in central part, as 3137, {313, 31, 3}, {137, 37, and 7} are all prime numbers.

  • LEFT: He will be working in left part if (a) his id is a prime number, (b) and doesn't contain 0 as one of the digits. (c) Also when the left digits are successively taken off, then all the resulting numbers are prime, but this doesn't hold true for the right digits. For example, person with id 1367 will work here, since 1367, 367, 67 and 7 are all prime numbers. While 136 is not a prime number, which we get after removing one digit on the right.

  • RIGHT: He will be working on right part if (a) his id is a prime number, (b) and doesn't contain 0 digit as one of the digits. (c) Also on successively stripping right digits, all the resulting numbers are prime, but this does not hold true for the left digits. For example, person with id 2333 belongs to this category, as 2333, 233, 23 and 2 are all prime numbers, while 333 is not a prime number.

DEAD: If a person is not eligible to work anywhere on the ship, then he will be thrown out of the ship. Sad!

import Data.List (unfoldr)
import Data.Maybe (listToMaybe)
pfactors prs n = unfoldr (\(ds,n) -> listToMaybe [(x, (dropWhile (< x) ds, div n x)) | x <- takeWhile ((<=n).(^2)) ds ++ [ n | n > 1 ], mod n x == 0 ]) (prs,n)
primes :: [Int]
primes = 2 : 3 : [x | x <- [5,7..], head (pfactors (tail primes) x) == x]
isPrime n = n > 1 && foldr (\p r -> p*p > n || ((n `rem` p) /= 0 && r)) True primes
solve n
| isPrimeN && hasNoZeroes && isPrimeLefts && isPrimeRights = "CENTRAL"
| isPrimeN && hasNoZeroes && (not isPrimeLefts) && isPrimeRights = "LEFT"
| isPrimeN && hasNoZeroes && isPrimeLefts && (not isPrimeRights) = "RIGHT"
| otherwise = "DEAD"
where ns = show n
isPrimeN = isPrime(n)
digitsLeft = tail $ map (\v -> read v :: Int) [ take x ns | x <- reverse [ 1 .. (length ns) ] ]
digitsRight = tail $ map (\v -> read (reverse v) :: Int) [ take x $ reverse ns | x <- reverse [ 1 .. (length ns) ] ]
primalityLeftDigits = map isPrime digitsLeft
primalityRightDigits = map isPrime digitsRight
isPrimeLefts = foldl (\i j -> i && j) True primalityLeftDigits
isPrimeRights = foldl (\i j -> i && j) True primalityRightDigits
hasNoZeroes = not $ elem '0' ns
main = do
raw <- getContents -- readFile "input.txt"
let lns = map (\s -> read s :: Int) $ tail $ lines raw
mapM_ putStrLn $ map solve lns
5
3137
1367
2333
101
12
CENTRAL
LEFT
RIGHT
DEAD
DEAD
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment