Skip to content

Commit 9a6ea82

Browse files
committed
Solve 'Pure odd digits primes' kata
1 parent 4d1f384 commit 9a6ea82

File tree

2 files changed

+58
-0
lines changed

2 files changed

+58
-0
lines changed

src/Codewars/G964/Pureoddprime.hs

+37
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
module Codewars.G964.Pureoddprime (onlyOddDigPrime) where
2+
3+
-- https://www.codewars.com/kata/55e0a2af50adf50699000126/train/haskell
4+
5+
import Data.List (genericLength)
6+
7+
onlyOddDigPrime :: (Integral a) => a -> [a]
8+
onlyOddDigPrime n = [genericLength lowerSeq, last lowerSeq, head greaterSeq]
9+
where
10+
greaterSeq = dropWhile (<= n) oddDigPrimeSeq
11+
lowerSeq = takeWhile (<= n) oddDigPrimeSeq
12+
13+
oddDigPrimeSeq :: (Integral a) => [a]
14+
oddDigPrimeSeq = filter hasOddDigits primeSeq
15+
16+
primeSeq :: (Integral a) => [a]
17+
primeSeq = 2 : filter isPrime [3, 5 ..]
18+
19+
isPrime :: (Integral a) => a -> Bool
20+
isPrime n
21+
| n <= 1 = False
22+
| n <= 3 = True
23+
| even n || n `mod` 3 == 0 = False
24+
| otherwise = not (any divides [5, 7 .. limit])
25+
where
26+
limit = sqrtInt n
27+
divides i = n `mod` i == 0 || n `mod` (i + 2) == 0
28+
29+
sqrtInt :: (Integral a) => a -> a
30+
sqrtInt n = round $ sqrt . fromIntegral $ n
31+
32+
hasOddDigits :: (Integral a) => a -> Bool
33+
hasOddDigits = all (odd . (`mod` 2)) . digits
34+
35+
digits :: (Integral a) => a -> [a]
36+
digits 0 = []
37+
digits n = digits (n `div` 10) ++ [n `mod` 10]
+21
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
module Codewars.G964.PureoddprimeSpec where
2+
3+
import Codewars.G964.Pureoddprime (onlyOddDigPrime)
4+
import Test.Hspec
5+
import Test.QuickCheck
6+
import Text.Printf (printf)
7+
8+
testOPS :: Integer -> [Integer] -> Spec
9+
testOPS n s =
10+
it (printf "should return onlyOddDigPrime for n result : %d --> %s \n" n (show s)) $
11+
onlyOddDigPrime n `shouldBe` s
12+
13+
spec :: Spec
14+
spec = do
15+
describe "Basic tests onlyOddDigPrime" $ do
16+
testOPS 20 [7, 19, 31]
17+
testOPS 40 [9, 37, 53]
18+
testOPS 55 [10, 53, 59]
19+
testOPS 60 [11, 59, 71]
20+
testOPS 100 [15, 97, 113]
21+
testOPS 5333 [120, 5333, 5351]

0 commit comments

Comments
 (0)