Вот способ решить проблему Эйлера 43 (пожалуйста, дайте мне знать, если это не даст правильный ответ). Есть ли монада или какой-нибудь другой синтетический сахар, который может помочь в отслеживании условий notElem
?
toNum xs = foldl (\s d -> s*10+d) 0 xs
numTest xs m = (toNum xs) `mod` m == 0
pandigitals = [ [d0,d1,d2,d3,d4,d5,d6,d7,d8,d9] |
d7 <- [0..9],
d8 <- [0..9], d8 `notElem` [d7],
d9 <- [0..9], d9 `notElem` [d8,d7],
numTest [d7,d8,d9] 17,
d5 <- [0,5], d5 `notElem` [d9,d8,d7],
d3 <- [0,2,4,6,8], d3 `notElem` [d5,d9,d8,d7],
d6 <- [0..9], d6 `notElem` [d3,d5,d9,d8,d7],
numTest [d6,d7,d8] 13,
numTest [d5,d6,d7] 11,
d4 <- [0..9], d4 `notElem` [d6,d3,d5,d9,d8,d7],
numTest [d4,d5,d6] 7,
d2 <- [0..9], d2 `notElem` [d4,d6,d3,d5,d9,d8,d7],
numTest [d2,d3,d4] 3,
d1 <- [0..9], d1 `notElem` [d2,d4,d6,d3,d5,d9,d8,d7],
d0 <- [1..9], d0 `notElem` [d1,d2,d4,d6,d3,d5,d9,d8,d7]
]
main = do
let nums = map toNum pandigitals
print $ nums
putStrLn ""
print $ sum nums
Например, в этом случае присвоение d3
не является оптимальным - его действительно следует перенести непосредственно перед тестом numTest [d2,d3,d4] 3
. Однако это будет означать изменение некоторых тестов notElem
для удаления d3
из проверяемого списка. Поскольку последовательные списки notElem
получаются только путем добавления последнего выбранного значения к предыдущему списку, кажется, что это должно быть выполнимо - каким-то образом.
ОБНОВЛЕНИЕ: Вот вышеупомянутая программа, переписанная с монадой Луи UniqueSel
ниже:
toNum xs = foldl (\s d -> s*10+d) 0 xs
numTest xs m = (toNum xs) `mod` m == 0
pandigitalUS =
do d7 <- choose
d8 <- choose
d9 <- choose
guard $ numTest [d7,d8,d9] 17
d6 <- choose
guard $ numTest [d6,d7,d8] 13
d5 <- choose
guard $ d5 == 0 || d5 == 5
guard $ numTest [d5,d6,d7] 11
d4 <- choose
guard $ numTest [d4,d5,d6] 7
d3 <- choose
d2 <- choose
guard $ numTest [d2,d3,d4] 3
d1 <- choose
guard $ numTest [d1,d2,d3] 2
d0 <- choose
guard $ d0 /= 0
return [d0,d1,d2,d3,d4,d5,d6,d7,d8,d9]
pandigitals = map snd $ runUS pandigitalUS [0..9]
main = do print $ pandigitals