Created
February 12, 2014 22:50
-
-
Save msysyamamoto/8966169 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| import Control.Applicative ((<$>)) | |
| import Data.List (nub, delete, subsequences, group, sort) | |
| import System.Environment (getArgs) | |
| import Test.HUnit | |
| type Gem = Char | |
| main :: IO () | |
| main = do | |
| princessPath <- (!! 0) <$> getArgs | |
| gemPath <- (!! 1) <$> getArgs | |
| (princess, _) <- break (== '\r') <$> readFile princessPath | |
| (gems, _) <- break (== '\r') <$> readFile gemPath | |
| putStrLn . show $ solve princess gems | |
| -- 宝石の一覧は、宝石の組合せを辞書順に並べたもの。 | |
| -- | |
| -- 探したい宝石パターンの先頭のGemを見て、それより小さくなる(先に現れる) | |
| -- 宝石パターンの個数を求める。 | |
| -- それが終わったら次は二つ目のGemを見て、それよりも... | |
| -- それが終わったら次は三つ目のGemを見て... | |
| -- で、だんだん絞り込んで行く感じ | |
| solve :: [Gem] -- 探したい宝石パターン | |
| -> [Gem] -- 使用できる宝石の一覧 | |
| -> Int | |
| solve _ [] = 0 | |
| solve [] _ = 0 | |
| solve (e0:es) gems = preNum + (solve es (delete e0 gems') + 1) | |
| where | |
| gems' = sort gems | |
| preGems = takeWhile (e0 >) $ nub gems' | |
| preNum = sum . map pernums $ map (flip delete gems') preGems | |
| -- xs の重複を除いた部分列に対して順列の数を求め、その和を求める | |
| pernums :: [Gem] -> Int | |
| pernums xs = (1+) . sum $ map pernum subs | |
| where | |
| -- tail は "" を除外するため | |
| subs = nub . map sort . tail $ subsequences xs | |
| -- 同じものを含む順列の数を求める | |
| pernum :: [Gem] -> Int | |
| pernum xs = factorial (sum gnums) `div` product (map factorial gnums) | |
| where | |
| gnums = map length $ group xs | |
| factorial :: Int -> Int | |
| factorial n = product [1..n] | |
| -- | |
| -- Test | |
| -- | |
| runTests :: IO Counts | |
| runTests = runTestTT $ TestList tests | |
| tests :: [Test] | |
| tests = map TestCase | |
| [ assertEqual "1:a" 1 (solve "a" "aaabcc") | |
| , assertEqual "2:aa" 2 (solve "aa" "aaabcc") | |
| , assertEqual "3:aaa" 3 (solve "aaa" "aaabcc") | |
| , assertEqual "4:aaab" 4 (solve "aaab" "aaabcc") | |
| , assertEqual "5:aaabc" 5 (solve "aaabc" "aaabcc") | |
| , assertEqual "6:aaabcc" 6 (solve "aaabcc" "aaabcc") | |
| , assertEqual "7:aaac" 7 (solve "aaac" "aaabcc") | |
| , assertEqual "8:aaacb" 8 (solve "aaacb" "aaabcc") | |
| , assertEqual "9:aaacbc" 9 (solve "aaacbc" "aaabcc") | |
| , assertEqual "10:aaacc" 10 (solve "aaacc" "aaabcc") | |
| , assertEqual "11:aaaccb" 11 (solve "aaaccb" "aaabcc") | |
| , assertEqual "12:aab" 12 (solve "aab" "aaabcc") | |
| , assertEqual "13:aaba" 13 (solve "aaba" "aaabcc") | |
| , assertEqual "14:aabac" 14 (solve "aabac" "aaabcc") | |
| , assertEqual "15:aabacc" 15 (solve "aabacc" "aaabcc") | |
| , assertEqual "16:aabc" 16 (solve "aabc" "aaabcc") | |
| , assertEqual "17:aabca" 17 (solve "aabca" "aaabcc") | |
| , assertEqual "18:aabcac" 18 (solve "aabcac" "aaabcc") | |
| , assertEqual "19:aabcc" 19 (solve "aabcc" "aaabcc") | |
| , assertEqual "20:aabcca" 20 (solve "aabcca" "aaabcc") | |
| , assertEqual "21:aac" 21 (solve "aac" "aaabcc") | |
| , assertEqual "22:aaca" 22 (solve "aaca" "aaabcc") | |
| , assertEqual "23:aacab" 23 (solve "aacab" "aaabcc") | |
| , assertEqual "24:aacabc" 24 (solve "aacabc" "aaabcc") | |
| , assertEqual "25:aacac" 25 (solve "aacac" "aaabcc") | |
| , assertEqual "26:aacacb" 26 (solve "aacacb" "aaabcc") | |
| , assertEqual "27:aacb" 27 (solve "aacb" "aaabcc") | |
| , assertEqual "28:aacba" 28 (solve "aacba" "aaabcc") | |
| , assertEqual "29:aacbac" 29 (solve "aacbac" "aaabcc") | |
| , assertEqual "30:aacbc" 30 (solve "aacbc" "aaabcc") | |
| , assertEqual "31:aacbca" 31 (solve "aacbca" "aaabcc") | |
| , assertEqual "32:aacc" 32 (solve "aacc" "aaabcc") | |
| , assertEqual "33:aacca" 33 (solve "aacca" "aaabcc") | |
| , assertEqual "34:aaccab" 34 (solve "aaccab" "aaabcc") | |
| , assertEqual "35:aaccb" 35 (solve "aaccb" "aaabcc") | |
| , assertEqual "36:aaccba" 36 (solve "aaccba" "aaabcc") | |
| , assertEqual "37:ab" 37 (solve "ab" "aaabcc") | |
| , assertEqual "38:aba" 38 (solve "aba" "aaabcc") | |
| , assertEqual "39:abaa" 39 (solve "abaa" "aaabcc") | |
| , assertEqual "40:abaac" 40 (solve "abaac" "aaabcc") | |
| , assertEqual "41:abaacc" 41 (solve "abaacc" "aaabcc") | |
| , assertEqual "42:abac" 42 (solve "abac" "aaabcc") | |
| , assertEqual "43:abaca" 43 (solve "abaca" "aaabcc") | |
| , assertEqual "44:abacac" 44 (solve "abacac" "aaabcc") | |
| , assertEqual "45:abacc" 45 (solve "abacc" "aaabcc") | |
| , assertEqual "46:abacca" 46 (solve "abacca" "aaabcc") | |
| , assertEqual "47:abc" 47 (solve "abc" "aaabcc") | |
| , assertEqual "48:abca" 48 (solve "abca" "aaabcc") | |
| , assertEqual "49:abcaa" 49 (solve "abcaa" "aaabcc") | |
| , assertEqual "50:abcaac" 50 (solve "abcaac" "aaabcc") | |
| , assertEqual "51:abcac" 51 (solve "abcac" "aaabcc") | |
| , assertEqual "52:abcaca" 52 (solve "abcaca" "aaabcc") | |
| , assertEqual "53:abcc" 53 (solve "abcc" "aaabcc") | |
| , assertEqual "54:abcca" 54 (solve "abcca" "aaabcc") | |
| , assertEqual "55:abccaa" 55 (solve "abccaa" "aaabcc") | |
| , assertEqual "56:ac" 56 (solve "ac" "aaabcc") | |
| , assertEqual "57:aca" 57 (solve "aca" "aaabcc") | |
| , assertEqual "58:acaa" 58 (solve "acaa" "aaabcc") | |
| , assertEqual "59:acaab" 59 (solve "acaab" "aaabcc") | |
| , assertEqual "60:acaabc" 60 (solve "acaabc" "aaabcc") | |
| , assertEqual "61:acaac" 61 (solve "acaac" "aaabcc") | |
| , assertEqual "62:acaacb" 62 (solve "acaacb" "aaabcc") | |
| , assertEqual "63:acab" 63 (solve "acab" "aaabcc") | |
| , assertEqual "64:acaba" 64 (solve "acaba" "aaabcc") | |
| , assertEqual "65:acabac" 65 (solve "acabac" "aaabcc") | |
| , assertEqual "66:acabc" 66 (solve "acabc" "aaabcc") | |
| , assertEqual "67:acabca" 67 (solve "acabca" "aaabcc") | |
| , assertEqual "68:acac" 68 (solve "acac" "aaabcc") | |
| , assertEqual "69:acaca" 69 (solve "acaca" "aaabcc") | |
| , assertEqual "70:acacab" 70 (solve "acacab" "aaabcc") | |
| , assertEqual "71:acacb" 71 (solve "acacb" "aaabcc") | |
| , assertEqual "72:acacba" 72 (solve "acacba" "aaabcc") | |
| , assertEqual "73:acb" 73 (solve "acb" "aaabcc") | |
| , assertEqual "74:acba" 74 (solve "acba" "aaabcc") | |
| , assertEqual "75:acbaa" 75 (solve "acbaa" "aaabcc") | |
| , assertEqual "76:acbaac" 76 (solve "acbaac" "aaabcc") | |
| , assertEqual "77:acbac" 77 (solve "acbac" "aaabcc") | |
| , assertEqual "78:acbaca" 78 (solve "acbaca" "aaabcc") | |
| , assertEqual "79:acbc" 79 (solve "acbc" "aaabcc") | |
| , assertEqual "80:acbca" 80 (solve "acbca" "aaabcc") | |
| , assertEqual "81:acbcaa" 81 (solve "acbcaa" "aaabcc") | |
| , assertEqual "82:acc" 82 (solve "acc" "aaabcc") | |
| , assertEqual "83:acca" 83 (solve "acca" "aaabcc") | |
| , assertEqual "84:accaa" 84 (solve "accaa" "aaabcc") | |
| , assertEqual "85:accaab" 85 (solve "accaab" "aaabcc") | |
| , assertEqual "86:accab" 86 (solve "accab" "aaabcc") | |
| , assertEqual "87:accaba" 87 (solve "accaba" "aaabcc") | |
| , assertEqual "88:accb" 88 (solve "accb" "aaabcc") | |
| , assertEqual "89:accba" 89 (solve "accba" "aaabcc") | |
| , assertEqual "90:accbaa" 90 (solve "accbaa" "aaabcc") | |
| , assertEqual "91:b" 91 (solve "b" "aaabcc") | |
| , assertEqual "92:ba" 92 (solve "ba" "aaabcc") | |
| , assertEqual "93:baa" 93 (solve "baa" "aaabcc") | |
| , assertEqual "94:baaa" 94 (solve "baaa" "aaabcc") | |
| , assertEqual "95:baaac" 95 (solve "baaac" "aaabcc") | |
| , assertEqual "96:baaacc" 96 (solve "baaacc" "aaabcc") | |
| , assertEqual "97:baac" 97 (solve "baac" "aaabcc") | |
| , assertEqual "98:baaca" 98 (solve "baaca" "aaabcc") | |
| , assertEqual "99:baacac" 99 (solve "baacac" "aaabcc") | |
| , assertEqual "100:baacc" 100 (solve "baacc" "aaabcc") | |
| , assertEqual "101:baacca" 101 (solve "baacca" "aaabcc") | |
| , assertEqual "102:bac" 102 (solve "bac" "aaabcc") | |
| , assertEqual "103:baca" 103 (solve "baca" "aaabcc") | |
| , assertEqual "104:bacaa" 104 (solve "bacaa" "aaabcc") | |
| , assertEqual "105:bacaac" 105 (solve "bacaac" "aaabcc") | |
| , assertEqual "106:bacac" 106 (solve "bacac" "aaabcc") | |
| , assertEqual "107:bacaca" 107 (solve "bacaca" "aaabcc") | |
| , assertEqual "108:bacc" 108 (solve "bacc" "aaabcc") | |
| , assertEqual "109:bacca" 109 (solve "bacca" "aaabcc") | |
| , assertEqual "110:baccaa" 110 (solve "baccaa" "aaabcc") | |
| , assertEqual "111:bc" 111 (solve "bc" "aaabcc") | |
| , assertEqual "112:bca" 112 (solve "bca" "aaabcc") | |
| , assertEqual "113:bcaa" 113 (solve "bcaa" "aaabcc") | |
| , assertEqual "114:bcaaa" 114 (solve "bcaaa" "aaabcc") | |
| , assertEqual "115:bcaaac" 115 (solve "bcaaac" "aaabcc") | |
| , assertEqual "116:bcaac" 116 (solve "bcaac" "aaabcc") | |
| , assertEqual "117:bcaaca" 117 (solve "bcaaca" "aaabcc") | |
| , assertEqual "118:bcac" 118 (solve "bcac" "aaabcc") | |
| , assertEqual "119:bcaca" 119 (solve "bcaca" "aaabcc") | |
| , assertEqual "120:bcacaa" 120 (solve "bcacaa" "aaabcc") | |
| , assertEqual "121:bcc" 121 (solve "bcc" "aaabcc") | |
| , assertEqual "122:bcca" 122 (solve "bcca" "aaabcc") | |
| , assertEqual "123:bccaa" 123 (solve "bccaa" "aaabcc") | |
| , assertEqual "124:bccaaa" 124 (solve "bccaaa" "aaabcc") | |
| , assertEqual "125:c" 125 (solve "c" "aaabcc") | |
| , assertEqual "126:ca" 126 (solve "ca" "aaabcc") | |
| , assertEqual "127:caa" 127 (solve "caa" "aaabcc") | |
| , assertEqual "128:caaa" 128 (solve "caaa" "aaabcc") | |
| , assertEqual "129:caaab" 129 (solve "caaab" "aaabcc") | |
| , assertEqual "130:caaabc" 130 (solve "caaabc" "aaabcc") | |
| , assertEqual "131:caaac" 131 (solve "caaac" "aaabcc") | |
| , assertEqual "132:caaacb" 132 (solve "caaacb" "aaabcc") | |
| , assertEqual "133:caab" 133 (solve "caab" "aaabcc") | |
| , assertEqual "134:caaba" 134 (solve "caaba" "aaabcc") | |
| , assertEqual "135:caabac" 135 (solve "caabac" "aaabcc") | |
| , assertEqual "136:caabc" 136 (solve "caabc" "aaabcc") | |
| , assertEqual "137:caabca" 137 (solve "caabca" "aaabcc") | |
| , assertEqual "138:caac" 138 (solve "caac" "aaabcc") | |
| , assertEqual "139:caaca" 139 (solve "caaca" "aaabcc") | |
| , assertEqual "140:caacab" 140 (solve "caacab" "aaabcc") | |
| , assertEqual "141:caacb" 141 (solve "caacb" "aaabcc") | |
| , assertEqual "142:caacba" 142 (solve "caacba" "aaabcc") | |
| , assertEqual "143:cab" 143 (solve "cab" "aaabcc") | |
| , assertEqual "144:caba" 144 (solve "caba" "aaabcc") | |
| , assertEqual "145:cabaa" 145 (solve "cabaa" "aaabcc") | |
| , assertEqual "146:cabaac" 146 (solve "cabaac" "aaabcc") | |
| , assertEqual "147:cabac" 147 (solve "cabac" "aaabcc") | |
| , assertEqual "148:cabaca" 148 (solve "cabaca" "aaabcc") | |
| , assertEqual "149:cabc" 149 (solve "cabc" "aaabcc") | |
| , assertEqual "150:cabca" 150 (solve "cabca" "aaabcc") | |
| , assertEqual "151:cabcaa" 151 (solve "cabcaa" "aaabcc") | |
| , assertEqual "152:cac" 152 (solve "cac" "aaabcc") | |
| , assertEqual "153:caca" 153 (solve "caca" "aaabcc") | |
| , assertEqual "154:cacaa" 154 (solve "cacaa" "aaabcc") | |
| , assertEqual "155:cacaab" 155 (solve "cacaab" "aaabcc") | |
| , assertEqual "156:cacab" 156 (solve "cacab" "aaabcc") | |
| , assertEqual "157:cacaba" 157 (solve "cacaba" "aaabcc") | |
| , assertEqual "158:cacb" 158 (solve "cacb" "aaabcc") | |
| , assertEqual "159:cacba" 159 (solve "cacba" "aaabcc") | |
| , assertEqual "160:cacbaa" 160 (solve "cacbaa" "aaabcc") | |
| , assertEqual "161:cb" 161 (solve "cb" "aaabcc") | |
| , assertEqual "162:cba" 162 (solve "cba" "aaabcc") | |
| , assertEqual "163:cbaa" 163 (solve "cbaa" "aaabcc") | |
| , assertEqual "164:cbaaa" 164 (solve "cbaaa" "aaabcc") | |
| , assertEqual "165:cbaaac" 165 (solve "cbaaac" "aaabcc") | |
| , assertEqual "166:cbaac" 166 (solve "cbaac" "aaabcc") | |
| , assertEqual "167:cbaaca" 167 (solve "cbaaca" "aaabcc") | |
| , assertEqual "168:cbac" 168 (solve "cbac" "aaabcc") | |
| , assertEqual "169:cbaca" 169 (solve "cbaca" "aaabcc") | |
| , assertEqual "170:cbacaa" 170 (solve "cbacaa" "aaabcc") | |
| , assertEqual "171:cbc" 171 (solve "cbc" "aaabcc") | |
| , assertEqual "172:cbca" 172 (solve "cbca" "aaabcc") | |
| , assertEqual "173:cbcaa" 173 (solve "cbcaa" "aaabcc") | |
| , assertEqual "174:cbcaaa" 174 (solve "cbcaaa" "aaabcc") | |
| , assertEqual "175:cc" 175 (solve "cc" "aaabcc") | |
| , assertEqual "176:cca" 176 (solve "cca" "aaabcc") | |
| , assertEqual "177:ccaa" 177 (solve "ccaa" "aaabcc") | |
| , assertEqual "178:ccaaa" 178 (solve "ccaaa" "aaabcc") | |
| , assertEqual "179:ccaaab" 179 (solve "ccaaab" "aaabcc") | |
| , assertEqual "180:ccaab" 180 (solve "ccaab" "aaabcc") | |
| , assertEqual "181:ccaaba" 181 (solve "ccaaba" "aaabcc") | |
| , assertEqual "182:ccab" 182 (solve "ccab" "aaabcc") | |
| , assertEqual "183:ccaba" 183 (solve "ccaba" "aaabcc") | |
| , assertEqual "184:ccabaa" 184 (solve "ccabaa" "aaabcc") | |
| , assertEqual "185:ccb" 185 (solve "ccb" "aaabcc") | |
| , assertEqual "186:ccba" 186 (solve "ccba" "aaabcc") | |
| , assertEqual "187:ccbaa" 187 (solve "ccbaa" "aaabcc") | |
| , assertEqual "188:ccbaaa" 188 (solve "ccbaaa" "aaabcc") | |
| ] |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment