我正在尝试解决Haskell中项目Euler(here)的“方形字谜词对”问题,但我被困了......
问题如下(我缩短了它):
- 取一个字,说“CARE”和其中一个字谜,例如“RACE”。
- 用一个唯一的数字替换“CARE”的每个字母,例如C = 1,A = 2,R = 9和E = 6.它恰好是1296并且是一个正方形数字。
- 按照相同的替换政策替换anagram的字母(“RACE”),它生成9216,这也是一个正方形数字!
给出一个单词列表,是什么形成的最大方数 这样一对的成员?
我设法从文件中提取所有的字谜对,我将它们以[(字符串,字符串)]形式存在,即[(“CARE”,“RACE”)...]。
在下一步(映射anasquare)中,对于每对单词,我想链接可以生成的最大方数,使其看起来像[(9216,“CARE”,“RACE”)。 ]。
嗯,有一个技巧(必须有!)以避免蛮力的方法,但到目前为止我没有找到它...实际上问题不在这里,让我们说我想采取蛮力接近并检查每个字母 - >数字转换。我只是不知道如何在Haskell中做到这一点。也许我累了,但我只是在这面前傻了。必须有一个简短但优雅但不太模糊的方式来写它,有人有想法吗?
这就是我的工作,我为您节省了字谜搜索和文件解析功能:
-- Read the file -> store the content into a list -> work on that list -> print the output
result98 = do contents <- readFile ".\\resources\\98.txt"
putStrLn $ (process.words.format) contents
-- Find anagram pairs -> Find corresponding square number -> get the biggest one
process::[String]->String
process = toString . maximum . map anasquare . anagrams
where toString (a,b,c) = "Yay ! the result is " ++ show a
-- Generate the maximum square number possible, 0 when none exist
anasquare::(String,String)->(Integer,String,String)
anasquare (x,y) = (anasquareValue,x,y)
where anasquareValue = 0 -- TODO
答案 0 :(得分:2)
数学见解是
确定哪个数字可以是正方形数字的最后一位(其中有六个)是Haskell的一行。在您的示例中,您因此知道 E 必须是这六个数字中的一个而不是任何数字。这减少了40%的暴力时间。
类似地,它也是Haskell的一行来确定哪些数字对可以是正方形数字的最后两位数。您会注意到十位数的可能性取决于个位数:例如如果最后一个数字被选为 6 ,则倒数第二个数字可能只是 1 ,倒数第二个数字可能只是 4 >如果最后一位是 1 , 4 或 9 。
考虑一下代码如何生成此查找表。什么是适当的数据结构来存储它?你需要预先指定你的方格可以有多少位数,或者你可以利用懒惰来获得优势吗?
答案 1 :(得分:0)
虽然数学洞察力很有用(特别是在项目欧拉上),但由于我遗漏了一些关于“如何”部分的知识,因此对我没有多大帮助。
如果不深入细节,一个解决方案路径就是将anagram字("CARE","RACE")
转换为(1234,4213)
对。直截了当的东西。如果在平方数对中检测到类似的模式,则匹配。