讓我們從你所擁有的開始。
something n = [[ 2 * x + 1 | x <- xs]|xs <- [3..n],i <- [1..],j <-[1..] ,xs == i+j+2*i*j,i<=j,i>=1]
這裏的基本問題是,你不需要嵌套的列表理解。
something n = [ 2 * x + 1 | x <- [3..n], i <- [1..], j <- [1..], x == i+j+2*i*j, i<=j, i>=1]
這會編譯。但是,正如你懷疑的那樣,這段代碼有更多的錯誤。
讓我們從條件開始。考慮到i <- [1..]
,測試i>=1
是多餘的。
something n = [ 2 * x + 1 | x <- [3..n], i <- [1..], j <- [1..], x == i+j+2*i*j, i<=j]
同樣,如果我們在i
而不是在1
開始j
關閉,我們可以擺脫i<=j
條件。
something n = [ 2 * x + 1 | x <- [3..n], i <- [1..], j <- [i..], x == i+j+2*i*j]
應該清楚的是,超過(n - i) `div` (1 + 2 * i)
更大的j
值不可能導致x
≤n
。
something n = [ 2 * x + 1 | x <- [3..n], i <- [1..], j <- [i .. (n - i) `div` (1 + 2 * i)], x == i+j+2*i*j]
同樣,的n `div` 3
i
或上述的值不可能導致x
≤n
。
something n = [ 2 * x + 1 | x <- [3..n], i <- [1 .. (n `div` 3) - 1], j <- [i .. (n - i) `div` (1 + 2 * i)],
x == i+j+2*i*j]
在這一點上,我們已經做了足夠的something
來實際生成結果。但是有重複的值(例如,當(i,j)是(1,7)或(2,4)時,你得到x = 22),我假設你不想要。
我們使用nub
從Data.List
中篩選出來。
something n = nub [ 2 * x + 1 | x <- [3..n], i <- [1 .. (n `div` 3) - 1],
j <- [i .. (n - i) `div` (1 + 2 * i)], x == i+j+2*i*j]
有沒有必要檢查x
滿足時,我們可以構建x
滿足擺在首位的是條件的條件。 (你會想自己滿足3≤x≤n仍然)。這樣更有效率。
something n = nub [ 2 * x + 1 | i <- [1 .. (n `div` 3) - 1], j <- [1 .. (n - i) `div` (1 + 2 * i)],
let x = i+j+2*i*j]
結果不再按照升序排列,所以讓我們確保他們這樣做。
something n = sort $ nub [ 2 * x + 1 | i <- [1 .. (n `div` 3) - 1], j <- [1 .. (n - i) `div` (1 + 2 * i)],
let x = i+j+2*i*j]
在一個風格點,倍增和添加一個是從確保X單獨計算可以被表示爲I + J + 2 * I *∫,因此讓我們分裂起來。
something n = sort $ map f $ nub [ x | i <- [1 .. (n `div` 3) - 1], j <- [1 .. (n - i) `div` (1 + 2 * i)],
let x = i+j+2*i*j]
where f x = 2 * x + 1
這使我們能夠從列表理解中擺脫x。
something n = sort $ map f $ nub [ i+j+2*i*j | i <- [1 .. (n `div` 3) - 1],
j <- [1 .. (n - i) `div` (1 + 2 * i)]]
where f x = 2 * x + 1
完成。
正如我所懷疑的,我正在以不止一種方式解決這個問題。我最終確實需要[Int]。所以我想我需要做一些超越理解的事情。我也看到xs是一個數字的問題。請參閱編輯。 – atlantis