Concatenating a list of numbers into one integer in haskell
I'm doing another Project Euler issue - Issue 38 . I have this function that returns a list of numbers, but I need the list of numbers to be one number. It calculates the concatenated product of an integer.
f (a,b) = a*b
conProInt x n = map f (zip (replicate n x) ([1..n]))
prob38 = maximum [ (conProInt (x) (n)) | x <- [100..500], n <- [1..9], (sort $ nub $ (decToList $ (conProInt x n) )) == (sort $ (decToList $ (conProInt x n) )), (sort $ nub $ (decToList $ (conProInt x n))) == [1..9] ]
eg:
conProInt 192 3
returns: [192384576]
i need to return: 192384576
I have searched around and cannot find a function or think of any function I could build that will provide what I need. How can i do this?
EDIT:
I updated the script to include faster concatenation, but it doesn't return the correct result:
f (a,b) = a*b
conProInt x n =( combine (map f (zip (replicate n x) ([1..n]))))
prob38 = maximum [ (conProInt (x) (n)) | x <- [1..50000], n <- [2..40], (sort $ nub $ (decToList $ (conProInt x n) )) == (sort $ (decToList $ (conProInt x n) )), (sort $ nub $ (decToList $ (conProInt x n))) == [1..9] ]
I'm pretty sure pandigital testing
(sort $ nub $ (decToList $ (conProInt x n) )) == (sort $ (decToList $ (conProInt x n) )), (sort $ nub $ (decToList $ (conProInt x n))) == [1..9]
will not let you down. I tried to make the search as large as possible, but the 9-pandigital max size I had was 986315724. Any suggestions? Is the range of values for n very large?
source to share
Here is an example of how to concatenate numbers without converting to and from character strings.
-- foldl1' is a strict fold. "foldl1" would also work...
import Data.List (foldl1')
-- Combine two numbers such that their digits are concatenated.
-- op 1 23 = 123, op 0 12 = 12, op 12345 67 = 1234567
op :: Int -> Int -> Int
op a b = a * power 10 (numDigits b) + b
-- How many digits does a positive number have?
numDigits :: Int -> Int
numDigits x = length . takeWhile (>= 1) . iterate (`div` 10) $ x
-- Take a positive number and raise it to a positive power.
-- power 5 2 = 25, power 10 3 = 1000
power :: Int -> Int -> Int
power x y = foldl1' (*) . take y $ repeat x
-- Take a list of numbers, and concatenate all their digits.
combine :: [Int] -> Int
combine xs = foldl1' op xs
example run:
Prelude> :m +Data.List
Prelude Data.List> let power x y = foldl1' (*) . take y $ repeat x
Prelude Data.List> let numDigits = length . takeWhile (>=1) . iterate (`div` 10)
Prelude Data.List> let op a b = a * power 10 (numDigits b) + b
Prelude Data.List> let combine xs = foldl1' op xs
Prelude Data.List> combine [192, 384, 576]
192384576
Prelude Data.List>
source to share