Drkcore

15 01 2010 Haskell Tweet

Haskellで覆面算を解く

どう書くは知ってる言語で解くのは楽しいけど、習い始めの言語はつらい。というわけで、mixiの課題丸投げあたりをチョイスすることが多い。

覆面算を解くというのがあったのでやってみた。XYZ + WXYZ + WXYZ + VWXYZ + VWXYZ = UVWXYZを満たす文字をそれぞれ求める。

題意からU=1は自明なんだけどあえて力技で。

-- XYZ + WXYZ + WXYZ + VWXYZ + VWXYZ = UVWXYZ
-- 4*Z + 4*10*Y + 4*100*X + 3*1000*W + 10000*V = 100000*U

check :: [Int] -> Bool
check (u:v:w:x:y:z:_) = 10000*v + 3000*w + 400*x + 40*y + 4*z == 100000*u

notDup :: [Int] -> Bool
notDup (x:xs)= notDup' x xs
    where notDup' _ [] = True
          notDup' x yy@(y:ys) | x `elem` yy = False
                              | otherwise   = notDup' y ys

sol :: [[Int]]
sol = filter check $ filter notDup
      [[u,v,w,x,y,z]|u <- [0..9], v <- [0..9], w <- [0..9], x <- [0..9], y <- [0..9], z <- [0..9]]

全通りの組み合わせを作ってから数字がダブっている組み合わせを除いた。

結局、組み合わせを最初から使えばいいので、0から9の数字の中から6つを選んで、それらの入れ替えをしながらチェックをするのもやってみた。

import List


check :: [Int] -> Bool
check (u:v:w:x:y:z:_) = 10000*v + 3000*w + 400*x + 40*y + 4*z == 100000*u

comb :: [Int] -> Int -> [[Int]]
comb _ 0     = [[]]
comb [] _     = []
comb (x:xs) n = map (x:) (comb xs (n-1)) ++ comb xs n

permutation [] = [[]]
permutation xs = concat [map (x:) $ permutation (delete x xs) | x <- xs]

sol = filter check $ concatMap permutation (comb [0..9] 6)

combとpermutationはProgramming:玉手箱:組合せを参考にした

About

  • もう5年目(wishlistありマス♡)
  • 最近はPythonとDeepLearning
  • 日本酒自粛中
  • ドラムンベースからミニマルまで
  • ポケモンGOゆるめ

Tag

Python Deep Learning javascript chemoinformatics Emacs sake and more...

Ad

© kzfm 2003-2021