060 done but cheated a bit

This commit is contained in:
Yann Esposito (Yogsototh) 2011-11-24 17:03:53 +01:00
parent 1174079776
commit f1fbe33d23
12 changed files with 182 additions and 40 deletions

3
.gitignore vendored Normal file
View file

@ -0,0 +1,3 @@
*.hi
*.o
*.prof

41
014-scanned.hs Normal file
View file

@ -0,0 +1,41 @@
import Data.List
type YInt = Int
collatz :: YInt -> YInt
collatz n
| n < 0 = 1
| even n = n `quot` 2
| otherwise = 3 * n + 1
-- The l `seq` is necessary to not be lazy (non-strict)
-- And not to fill the stack
lencollatz' :: YInt -> YInt -> YInt
lencollatz' l 1 = l
lencollatz' l n = l `seq` lencollatz' (l + 1) (collatz n)
lencollatz = lencollatz' 0
-- The j `seq` is necessary to not be lazy (non-strict)
-- And not to fill the stack
maximalIndex :: (YInt, YInt) -> YInt -> [YInt] -> (YInt, YInt)
maximalIndex (m, i) j [] = (m, i)
maximalIndex (m, i) j (x : xs) = j `seq` maximalIndex res (j + 1) xs
where res = if x > m then (x, j) else (m, i)
showCollatz :: YInt -> String
showCollatz 1 = "1"
showCollatz n = show n ++ "" ++ showCollatz ( collatz n )
pure (Just x) = x
main = do
putStrLn $ "max len: " ++ show m
putStrLn $ "max value: " ++ show i
-- print mrec
-- print irec
-- putStrLn $ showCollatz $ toInteger i
where
array = map lencollatz [1 .. 1000000]
m = maximum array
i = 1 + pure (elemIndex m array)
(mrec, irec) = maximalIndex (0, 0) 1 array

2
058.rb
View file

@ -1,3 +1,5 @@
#!/usr/bin/env ruby
# -*- encoding: utf-8 -*-
problem=%{
-- Starting with 1 and spiralling anticlockwise in the following way, a square spiral with side length 7 is formed.
--

BIN
060

Binary file not shown.

44
060-cheat.hs Normal file
View file

@ -0,0 +1,44 @@
-- Problem 60
-- 02 January 2004
--
-- The primes 3, 7, 109, and 673, are quite remarkable. By taking any two primes and concatenating them in any order the result will always be prime. For example, taking 7 and 109, both 7109 and 1097 are prime. The sum of these four primes, 792, represents the lowest sum for a set of four primes with this property.
--
-- Find the lowest sum for a set of five primes for which any two primes concatenate to produce another prime.
--
import Prime
numOfDigits x
| x < 10 = 1
| x < 100 = 2
| x < 1000 = 3
| x < 10000 = 4
| x < 100000 = 5
| x < 1000000 = 6
| x < 10000000 = 7
-- | otherwise = truncate (logBase 10 x)
-- equivalent but faster than "read (show x ++ show y)"
concatNumbers :: Int -> Int -> Int
concatNumbers x y = (10^numOfDigits y)*x + y
solve = do
a <- primesTo10000
let m = f a $ dropWhile (<= a) primesTo10000
b <- m
let n = f b $ dropWhile (<= b) m
c <- n
let o = f c $ dropWhile (<= c) n
d <- o
let p = f d $ dropWhile (<= d) o
e <- p
return [a,b,c,d,e]
where
f x = filter (\y -> all is_prime [concatNumbers x y, concatNumbers y x])
primesTo10000 = takeWhile (<= 10000) primes
main = do
print $ head $ solve
print $ sum $ head $ solve

BIN
060.hi

Binary file not shown.

96
060.hs
View file

@ -1,50 +1,70 @@
--
-- The primes 3, 7, 109, and 673, are quite remarkable.
-- By taking any two primes and concatenating them in any order the result will always be prime.
-- For example, taking 7 and 109, both 7109 and 1097 are prime.
-- The sum of these four primes, 792, represents the lowest sum for a set of four primes with this property.
-- Problem 60
-- 02 January 2004
--
-- The primes 3, 7, 109, and 673, are quite remarkable. By taking any two primes and concatenating them in any order the result will always be prime. For example, taking 7 and 109, both 7109 and 1097 are prime. The sum of these four primes, 792, represents the lowest sum for a set of four primes with this property.
--
-- Find the lowest sum for a set of five primes for which any two primes concatenate to produce another prime.
--
-- Should use the following property
-- [x,y,z,t] special <=> [x,y,z] & [x,y,t] & [x,z,t] & [y,z,t] special
import Debug.Trace
import Data.List
import Prime
is_couple_prime x y = ( is_prime $ read $ strx ++ stry ) && (is_prime $ read $ stry ++ strx)
where
strx = show x
stry = show y
numOfDigits x
| x < 10 = 1
| x < 100 = 2
| x < 1000 = 3
| x < 10000 = 4
| x < 100000 = 5
| x < 1000000 = 6
| x < 10000000 = 7
-- | otherwise = truncate (logBase 10 x)
first_concat_prime_with_list x [] = True
first_concat_prime_with_list x (y:ys) = is_couple_prime x y && first_concat_prime_with_list x ys
-- equivalent but faster than "read (show x ++ show y)"
concatNumbers :: Int -> Int -> Int
concatNumbers x y = (10^numOfDigits y)*x + y
-- are_concat_primes [3,7,109,673] return true if number are primes
-- even with concat
are_concat_primes [] = True
are_concat_primes (x:xs) = (are_concat_primes xs) && first_concat_prime_with_list x xs
areConcatPrime :: [Int] -> Bool
areConcatPrime [] = True
areConcatPrime (x:xs) =
-- (areConcatPrime xs) && (and $ map concatPrime_x xs)
all concatPrime_x xs
where
concatPrime_x :: Int -> Bool
concatPrime_x y = all is_prime [concatNumbers x y, concatNumbers y x]
special_numbers 1 = take 300 primes
-- special_numbers n = nub $ flatten $ filter (\x -> traceShow x are_concat_primes x) $ subsets n (special_numbers (n-1))
special_numbers n = nub $ flatten $ filter are_concat_primes $ subsets n (special_numbers (n-1))
where
flatten [] = []
flatten ([]:ys) = flatten ys
flatten ((x:xs):ys) = x:flatten (xs:ys)
subsets :: Integer -> [a] -> [[a]]
subsets 0 _ = [[]]
subsets n [] = []
subsets n (x:xs) = [x:ys | ys <- subsets (n-1) xs ] ++ subsets n xs
-- for 1 should return a list of one element list containing a unique prime
--
cprimes :: Int -> [[Int]]
cprimes n = concatMap (memoizedConcatPrimes n) [(n-1)..]
-- concatPrimes' :: Int -> Int -> [[Int]]
-- concatPrimes' 0 _ = [[]]
-- concatPrimes' _ (-1) = error "concatPrimes' ERROR"
-- concatPrimes' _ 0 = []
-- concatPrimes' 1 max = [[ primes !! fromInt max ]]
-- concatPrimes' n max = filter areConcatPrime [ p:cprimes | cprimes <- subsets ]
-- where p = primes !! fromInt max
-- -- subsets = memoized !! fromInt (n-1)
-- subsets = concatMap (concatPrimes' (n-1)) [0..(max-1)]
memoizedConcatPrimes n max =
let p = primes !! max
subsets = concatMap (memoizedConcatPrimes (n-1)) [0..(max-1)]
concatPrimes 0 _ = [[]]
concatPrimes _ 0 = []
concatPrimes 1 max = [[ primes !! max ]]
concatPrimes n max = filter areConcatPrime [p:cprimes | cprimes <- subsets ]
in map (map concatPrimes [0..] !! n) [0..] !! max
main = do
putStrLn $ show $ are_concat_primes [3,7,109,673]
putStrLn $ show $ numbers
putStrLn $ show $ result
where
numbers = take 5 $ special_numbers 5
result = sum numbers
print $ take 20 $ cprimes 2
print $ cprimes 3 !! 0
print $ cprimes 3 !! 1
print $ cprimes 3 !! 2
print $ take 20 $ cprimes 3
print $ cprimes 4 !! 0
print $ cprimes 4 !! 1
print $ cprimes 4 !! 2
let res = take 3 $ cprimes 5
print res
print (map sum res)

BIN
060.o

Binary file not shown.

32
060.rb Normal file
View file

@ -0,0 +1,32 @@
#!/usr/bin/env ruby
# -*- encoding: utf-8 -*-
require './primes'
$po = Primes.new(100)
def concat_prime_with_set(n,set)
set.each do |m|
$po.is_prime( %{#{n}#{m}} ) and
$po.is_prime( %{#{m}#{n}} )
end
end
sets=Array.new
sets[0]=Array.new
$po.primes.each do |p|
break if p>1500
sets[0].append( [p] )
end
def create_set(n)
sets[n]=Array.new
$po.primes.each do |p|
break if p>1500
first_set.each do |qs|
sets[n].append( qs.append(p) ) if concat_prime_with_set p qs
end
end
end
create_set(1)
print sets[1][0]

BIN
Prime.hi

Binary file not shown.

View file

@ -3,7 +3,7 @@ module Prime
, is_prime
)
where
data Wheel = Wheel Integer [Integer]
data Wheel = Wheel Int [Int]
roll (Wheel n rs) = [n*k+r| k<-[0..], r<-rs]
nextSize (Wheel n rs) p =
@ -13,7 +13,7 @@ where
mkWheel ds = foldl nextSize w0 ds
primes :: [Integer]
primes :: [Int]
primes = small ++ large
where
1:p:candidates = roll $ mkWheel small

BIN
Prime.o

Binary file not shown.