Haskell中的出租车编号

时间:2015-08-28 16:25:08

标签: haskell

出租车编号被定义为一个正整数,可以用至少两种不同的方式表示为两个立方体的总和。

1729=1^3+12^3=9^3+10^3

我写了这段代码来制作一个出租车编号,在跑步时会给出第n个最小的出租车编号:

taxicab :: Int -> Int
taxicab n = [(cube a + cube b)
            | a <- [1..100],
              b <- [(a+1)..100],
              c <- [(a+1)..100],
              d <- [(c+1)..100],
              (cube a + cube b) == (cube c + cube d)]!!(n-1)

cube x = x * x * x

但是我得到的输出并不是我所期望的。对于数字1到3,代码产生正确的输出但是taxicab 4产生39312而不是20683。另一个奇怪的是39312最初是第六小的出租车编号 - 不是第四名!

那为什么会这样呢?我的代码中的缺陷在哪里?

1 个答案:

答案 0 :(得分:5)

我认为您错误地认为您的列表包含越来越多的出租车编号。这是您列表的实际内容:

[1729,4104,13832,39312,704977,46683,216027,32832,110656,314496,
 216125,439101,110808,373464,593047,149389,262656,885248,40033,
 195841,20683,513000,805688,65728,134379,886464,515375,64232,171288,
 443889,320264,165464,920673,842751,525824,955016,994688,327763,
 558441,513856,984067,402597,1016496,1009736,684019]

回想一下,[(a,b) | a<-[1..100],b<-[1..100]]之类的列表理解将按如下方式生成其对:

[(1,1),...,(1,100),(2,1),...,(2,100),...,...,(100,100)]

请注意,当a到达下一个值时,b会从1重新启动。在您的代码中,假设您刚刚找到a^3+b^3形式的出租车编号,然后没有更大的b为您提供出租车。在这种情况下,尝试下一个a值。我们可能会找到(a+1)^3+b'^3形式的出租车,但无法保证此数字会更大,因为b'[a+2..100]中的任意数字,并且可能小于b }。 a值较大时也会发生这种情况:当a增加时,无法保证其相关的出租车比我们之前发现的要大。

另请注意,出于同样的原因,101^3+b^3形式的hypotetical出租车可能比您列表中的出租车小,但在那里不会出现。

最后,请注意,您的功能效率非常低,因为每次拨打taxicab n时,都会重新计算所有首个n出租车价值。