查找带可变轮的机械里程表的所有可能读数

时间:2013-10-05 20:17:17

标签: haskell

问题可以描述为找到机械里程表的所有可能读数,但需要注意的是它的车轮可能有不同的位数。

odometer = [["a1","a2","a3"],["b1","b2"],["c1","c2","c3","c4"]]

到目前为止我得到了什么:

read_heads :: [[[Char]]] -> [[Char]]
read_heads [[[]]] = [[]]
read_heads x = map head x

-- pushes the first element of a list to the end
rotate :: [a] -> [a]
rotate [] = []
rotate (x:xs) = xs ++ [x]

http://www.cartell.ie/car_check/wp-content/uploads/2010/02/Odometer-1.jpg

编辑:澄清问题。鉴于上面的里程表,创建一个包含所有可能读数的列表。

["a1","b1","c1"]
["a1","b1","c2"]
["a1","b1","c3"]
["a1","b1","c4"]
["a1","b2","c1"]
["a1","b2","c2"]
["a1","b2","c3"]
["a1","b2","c4"]
etc.

1 个答案:

答案 0 :(得分:7)

这可能是最简单的一个:

Prelude> let odometer a = sequence a
Prelude> odometer [["a1","a2","a3"],["b1","b2"],["c1","c2","c3","c4"]]
[["a1","b1","c1"],["a1","b1","c2"],["a1","b1","c3"],["a1","b1","c4"],["a1","b2","c1"],
["a1","b2","c2"],["a1","b2","c3"],["a1","b2","c4"],["a2","b1","c1"],["a2","b1","c2"],
["a2","b1","c3"],["a2","b1","c4"],["a2","b2","c1"],["a2","b2","c2"],["a2","b2","c3"],
["a2","b2","c4"],["a3","b1","c1"],["a3","b1","c2"],["a3","b1","c3"],["a3","b1","c4"],
["a3","b2","c1"],["a3","b2","c2"],["a3","b2","c3"],["a3","b2","c4"]]
Prelude>

sequence是一个处理monad的函数。如果你想使用Haskell,你需要了解monad,所以也可以从现在开始。

如果你还没有准备好让强大的monad进入你的生活,那么这是一个更平凡的版本:

Prelude> :{
Prelude| let odometer (xs:yys) = [x:ys | x<-xs, ys<-odometer yys]
Prelude|     odometer [] = [[]]
Prelude| :}
Prelude> odometer [["a1","a2","a3"],["b1","b2"],["c1","c2","c3","c4"]]
[["a1","b1","c1"],["a1","b1","c2"],["a1","b1","c3"],["a1","b1","c4"],["a1","b2","c1"],
["a1","b2","c2"],["a1","b2","c3"],["a1","b2","c4"],["a2","b1","c1"],["a2","b1","c2"],
["a2","b1","c3"],["a2","b1","c4"],["a2","b2","c1"],["a2","b2","c2"],["a2","b2","c3"],
["a2","b2","c4"],["a3","b1","c1"],["a3","b1","c2"],["a3","b1","c3"],["a3","b1","c4"],
["a3","b2","c1"],["a3","b2","c2"],["a3","b2","c3"],["a3","b2","c4"]]
Prelude>

它完全符合它所说的:

  • 给出一个里程表轮(xs:yys)
  • 列表
  • 所有可能读数的列表是 x ys = [ x:ys
  • 的所有可能组合的列表
  • 这样|
  • x 取自第一轮x<-xs的所有可能位置列表
  • ,
  • ys 取自从其余车轮构建的里程表的所有可能读数列表(即除了第一个之外的所有车轮)ys<-odometer yys]
  • 如果里程表没有轮子[]
  • 只有一个可能的读数,即空= [[]]