Объединение списка чисел в одно целое число в haskell - PullRequest
2 голосов
/ 06 октября 2009

Я занимаюсь еще одной проблемой Project Euler - Задача 38 . У меня есть эта функция, которая возвращает список чисел, но мне нужно, чтобы список чисел был одним числом. Он вычисляет составное произведение целого числа.

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] ]

например:

conProInt 192 3

возвращает: [192384576]

мне нужно вернуть: 192384576

Я искал вокруг и не могу найти функцию или подумать о функции, которую я мог бы создать, которая бы доставила то, что мне нужно. Как бы я пошел по этому поводу?

EDIT:

Я обновил скрипт, чтобы включить более быструю конкатенацию, но он не возвращает правильный результат:

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] ]

Я почти уверен, что тест на пандигитальный

(sort $ nub $ (decToList $ (conProInt x n) )) == (sort $ (decToList $ (conProInt x n) )), (sort $ nub $ (decToList $ (conProInt x n))) == [1..9]

не подведет. Я пытался сделать поиск максимально большим, но максимальный 9-pandigital, который я получил, был 986315724. Есть предложения? Диапазон значений для n очень большой?

Ответы [ 3 ]

7 голосов
/ 06 октября 2009

Пройти через String s, вероятно, проще всего:

read $ concat $ map (show) [192,384,576]

Хотя вам, вероятно, потребуется добавить сигнатуру типа:

Prelude> (read $ concat $ map (show) [192,384,576]) :: Int
192384576
5 голосов
/ 06 октября 2009

Вы можете использовать эту функцию для объединения списка чисел:

concatNumbers :: [Int] -> String
concatNumbers = concat . map show

Если вы хотите, чтобы функция возвращала объединение как число, вы можете использовать read.

2 голосов
/ 07 октября 2009

Вот пример того, как объединить цифры без преобразования в и из символьных строк.

-- 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

пример выполнения:

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>
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...