【发布时间】:2019-12-24 15:11:20
【问题描述】:
考虑以下程序。
chars = [" "] ++ ["A"] ++ ["B"] ++ (repeat "ABCD")
f :: Int -> [(Char,Int)]
f n = (,) <$> (chars !! n) <*> [1..3]
g :: Int -> [[(Char,Int)]]
g 1 = (\a -> [a ]) <$> (f 1)
g 2 = (\a b -> [a,b ]) <$> (f 1) <*> (f 2)
g 3 = (\a b c -> [a,b,c]) <$> (f 1) <*> (f 2) <*> (f 3)
-- g n = (\x1 x2 ... xn -> [x1,x2,...,xn]) <$> (f 1) <*> (f 2) <*> ... (f n)
我们怎样才能写出g n,一般对于所有n > 0,而不像上面那样显式地输入展开式,理想情况下只使用Prelude(和Control.Applicative,如果需要的话)?请注意,对于所有 n>3,f n = f (n-1),因此可以递归地定义 g。
输出是这样的(忽略漂亮的打印):
> g 1
[ [ ( 'A' , 1 ) ] , [ ( 'A' , 2 ) ] , [ ( 'A' , 3 ) ] ]
> g 2
[ [ ( 'A' , 1 ) , ( 'B' , 1 ) ]
, [ ( 'A' , 1 ) , ( 'B' , 2 ) ]
, [ ( 'A' , 1 ) , ( 'B' , 3 ) ]
, [ ( 'A' , 2 ) , ( 'B' , 1 ) ]
, [ ( 'A' , 2 ) , ( 'B' , 2 ) ]
, [ ( 'A' , 2 ) , ( 'B' , 3 ) ]
, [ ( 'A' , 3 ) , ( 'B' , 1 ) ]
, [ ( 'A' , 3 ) , ( 'B' , 2 ) ]
, [ ( 'A' , 3 ) , ( 'B' , 3 ) ]
]
> g 3
[ [ ( 'A' , 1 ) , ( 'B' , 1 ) , ( 'A' , 1 ) ]
, [ ( 'A' , 1 ) , ( 'B' , 1 ) , ( 'A' , 2 ) ]
...
, [ ( 'A' , 3 ) , ( 'B' , 3 ) , ( 'D' , 3 ) ]
]
【问题讨论】:
-
我不知道这是否可能,但实际上,您真的需要 处理所有
n > 0吗?在n = 10,该列表中将有近 40 亿个元素。在n = 15,将有将近 1E+15 个元素。 -
如所写,
f i为所有i >= 3返回相同的值。 -
我正在用这个为 2D“魔方”立方体游戏编写求解器。应该可以解决它/使用群论策略性地简化解决过程。在这里,我强制一个将 1 与 2 交换的组。希望它不需要超过
n>8。游戏在这里:chiark.greenend.org.uk/~sgtatham/puzzles/js/twiddle.html.
标签: list haskell list-comprehension monads functor