【发布时间】:2019-12-25 10:24:45
【问题描述】:
我正在尝试使用 Haskell 制作我认为称为 Ulam 螺旋的东西。 它需要顺时针向外旋转:
6 - 7 - 8 - 9
| |
5 0 - 1 10
| | |
4 - 3 - 2 11
|
..15- 14- 13- 12
对于我尝试创建坐标的每一步,都会给函数一个数字并将螺旋坐标返回到输入数字的长度,例如:
mkSpiral 9
> [(0,0),(1,0),(1,-1),(0,-1),(-1,-1),(-1,0),(-1,1),(0,1),(1,1)]
(-1, 1) - (0, 1) - (1, 1)
|
(-1, 0) (0, 0) - (1, 0)
| |
(-1,-1) - (0,-1) - (1,-1)
我见过Looping in a spiral 解决方案,但是这是逆时针方向的,它的输入需要矩阵的大小。
我还发现this 代码可以满足我的需要,但它似乎是逆时针方向的,向上而不是顺时针向右步进 :(
type Spiral = Int
type Coordinate = (Int, Int)
-- number of squares on each side of the spiral
sideSquares :: Spiral -> Int
sideSquares sp = (sp * 2) - 1
-- the coordinates for all squares in the given spiral
coordinatesForSpiral :: Spiral -> [Coordinate]
coordinatesForSpiral 1 = [(0, 0)]
coordinatesForSpiral sp = [(0, 0)] ++ right ++ top ++ left ++ bottom
where fixed = sp - 1
sides = sideSquares sp - 1
right = [(x, y) | x <- [fixed], y <- take sides [-1*(fixed-1)..]]
top = [(x, y) | x <- reverse (take sides [-1*fixed..]), y <- [fixed]]
left = [(x, y) | x <- [-1*fixed], y <- reverse(take sides [-1*fixed..])]
bottom = [(x, y) | x <- take sides [-1*fixed+1..], y <- [-1*fixed]]
-- an endless list of coordinates (the complete spiral)
mkSpiral :: Int -> [Coordinate]
mkSpiral x = take x endlessSpiral
endlessSpiral :: [Coordinate]
endlessSpiral = endlessSpiral' 1
endlessSpiral' start = coordinatesForSpiral start ++ endlessSpiral' (start + 1)
经过大量实验后,我似乎无法更改旋转或开始步进方向,有人可以指出我正确的方式或不使用列表理解的解决方案,因为我发现它们很难解码?
【问题讨论】:
-
提示:如何将螺旋从逆时针变为顺时针?
-
首先我会尝试用英语和/或数学写下坐标序列应该是什么或如何产生它。一旦你有了这些,你就可以将一些东西翻译成代码。
-
顺时针方向,我刚刚在 FP slack 频道上获得了一个很好的解决方案,所以如果 OP 没有时间,我可以在这里发布 :)
-
旁注:乌拉姆螺旋特指a spiral highlighting the primes,无论是顺时针还是逆时针。不过维基百科上的例子似乎都是逆时针的。