Function 如何创建Prouhet–;图埃–;哈斯克尔的莫尔斯序列?
我是Haskell的noob,但对ActionScript3.0面向对象有一些经验。因此,我们正在进行一次重大的编程转换。我读过哈斯克尔的基本知识,比如算术。我可以编写简单的函数 作为一项实际作业,我必须在哈斯克尔用计算机生成所谓的tms1。所以它应该是这样的:Function 如何创建Prouhet–;图埃–;哈斯克尔的莫尔斯序列?,function,haskell,recursion,Function,Haskell,Recursion,我是Haskell的noob,但对ActionScript3.0面向对象有一些经验。因此,我们正在进行一次重大的编程转换。我读过哈斯克尔的基本知识,比如算术。我可以编写简单的函数 作为一项实际作业,我必须在哈斯克尔用计算机生成所谓的tms1。所以它应该是这样的: >tms1 0 0 >tms1 1 1 >tms1 2 10 >tms1 3 1001 >tms1 4 10010110 等等。。。根据维基百科,我应该使用这个公式 t0 = 0 t2n = tn t2n
>tms1 0
0
>tms1 1
1
>tms1 2
10
>tms1 3
1001
>tms1 4
10010110
等等。。。根据维基百科,我应该使用这个公式
t0 = 0
t2n = tn
t2n + 1 = 1 − tn
我不知道如何在Haskell中实现这个公式。你能指导我创建一个吗?
到目前为止,我得到的是:
module ThueMorse where
tms1 :: Int -> Int
tms1 0 = 0
tms1 1 = 1
tms1 2 = 10
tms1 3 = 1001
tms1 x = tms1 ((x-1)) --if x = 4 the output will be 1001, i don't know how to make this in a recursion function
我在互联网上做了一些研究,发现了这个代码
资料来源:
代码:
但是这段代码没有给出期望的结果。非常感谢您的帮助。我建议您在代码中使用布尔值列表;然后,不需要显式地转换数字。我使用如下定义的序列:
0
01
0110
01101001
0110100110010110
01101001100101101001011001101001
...
>concatMap show $ lookupMorseAlternate 4
"10010110"
>map (concatMap show) $ take 5 morseAlternate
["0", "1", "10", "1001", "10010110"]
invertList :: [Integer] -> [Integer]
invertList [] = []
invertList (h:t)
|h == 1 = 0:invertList t
|h == 0 = 1:invertList t
|otherwise = error "Wrong Parameters: Should be 0 or 1"
thueMorse :: Integer -> [Integer]
thueMorse 1 = [0]
thueMorse n = thueMorse (n - 1) ++ invertList (thueMorse (n - 1))
请注意,前导零非常重要
递归定义现在很容易:
morse = [False] : map step morse where step a = a ++ map not a
这是因为我们从不访问尚未定义的元素。打印列表留给读者作为练习
下面是另一个定义,使用这样一个事实,即可以通过将1
替换为10
,将0
替换为01
,来实现下一步:
morse = [False] : map (concatMap step) morse where step x = [x,not x]
编辑
以下是sdcvvc使用函数iterate
进行的更简单的定义iterate f x
返回重复应用程序列表,从无应用程序开始,将f
返回到x
:
iterate f x = [x,f x,f (f x),f (f (f x)),...]
以下是定义:
morse = iterate (\a -> a ++ map not a) [False]
morse = iterate (>>= \x -> [x,not x]) [False]
您对序列的定义似乎是位序列的序列:
0 1 10 1001 10010110 ... etc.
t0 t1 t2 t3 t4
但维基百科页面将其定义为一个单位序列:
0 1 1 0 1 ... etc
t0 t1 t2 t3 t4
lookupMorse :: Int -> Int
lookupMorse 0 = 0;
lookupMorse n | even n = lookupMorse (div n 2)
| otherwise = 1 - lookupMorse (div (n-1) 2)
>concatMap show $ take 10 morse
"0110100110"
这是维基百科中的定义所指的公式。有了这些知识,您提到的递归关系的定义更容易理解:
t0 = 0
t2n = tn
t2n + 1 = 1 − tn
在英语中,这可以表述为:
- 第0位为零
- 对于偶数非零索引,该位与索引一半处的位相同
- 对于奇数索引,位是1减去索引一半处的位(减1)
0 1 1 0 1 ... etc
t0 t1 t2 t3 t4
lookupMorse :: Int -> Int
lookupMorse 0 = 0;
lookupMorse n | even n = lookupMorse (div n 2)
| otherwise = 1 - lookupMorse (div (n-1) 2)
>concatMap show $ take 10 morse
"0110100110"
如果需要整个序列,请将lookupMorse映射到非负整数上:
morse :: [Int]
morse = map lookupMorse [0..]
这是无限的Thue-Morse序列。要显示它,获取其中的一些,将它们转换为字符串,并连接生成的序列:
0 1 1 0 1 ... etc
t0 t1 t2 t3 t4
lookupMorse :: Int -> Int
lookupMorse 0 = 0;
lookupMorse n | even n = lookupMorse (div n 2)
| otherwise = 1 - lookupMorse (div (n-1) 2)
>concatMap show $ take 10 morse
"0110100110"
最后,如果要使用“位序列序列序列”定义,首先需要从序列中删除一些位,然后再获取一些位。除零索引情况外,要删除的数字与要获取的数字相同:
lookupMorseAlternate :: Int -> [Int]
lookupMorseAlternate 0 = take 1 morse
lookupMorseAlternate n = take len $ drop len morse
where
len = 2 ^ (n-1)
这就产生了替代序列定义:
morseAlternate :: [[Int]]
morseAlternate = map lookupMorseAlternate [0..]
您可以这样使用:
0
01
0110
01101001
0110100110010110
01101001100101101001011001101001
...
>concatMap show $ lookupMorseAlternate 4
"10010110"
>map (concatMap show) $ take 5 morseAlternate
["0", "1", "10", "1001", "10010110"]
invertList :: [Integer] -> [Integer]
invertList [] = []
invertList (h:t)
|h == 1 = 0:invertList t
|h == 0 = 1:invertList t
|otherwise = error "Wrong Parameters: Should be 0 or 1"
thueMorse :: Integer -> [Integer]
thueMorse 1 = [0]
thueMorse n = thueMorse (n - 1) ++ invertList (thueMorse (n - 1))
像这样简单:
0
01
0110
01101001
0110100110010110
01101001100101101001011001101001
...
>concatMap show $ lookupMorseAlternate 4
"10010110"
>map (concatMap show) $ take 5 morseAlternate
["0", "1", "10", "1001", "10010110"]
invertList :: [Integer] -> [Integer]
invertList [] = []
invertList (h:t)
|h == 1 = 0:invertList t
|h == 0 = 1:invertList t
|otherwise = error "Wrong Parameters: Should be 0 or 1"
thueMorse :: Integer -> [Integer]
thueMorse 1 = [0]
thueMorse n = thueMorse (n - 1) ++ invertList (thueMorse (n - 1))
问题似乎是,您丢弃了前导零。使用列表而不是数字也可以避免反复转换数字。我总是想:如果我用大量代码解决一个小问题,我就做错了。你可以这样写:a`rem`2==0
/1
作为偶数a
和奇数a
custinv x
可以定义map(\a->1-a)x
,甚至custinv=map(1-
)amountTrue x=sum(fromnum x)
或amountTrue x=length(filter id x)
。使用迭代:第一个定义:morse=iterate(\a->a++map not a)[False]
第二个定义:morse=iterate(>=\x->[x,not x])[False]
我认为这里的所有结果都是一步一步得出的。如果将thueMorse 1=[0]更改为thueMorse 0=[0],则此操作有效。