我试图打印一个Pascal's三角终端使用欺骗方案。
下面是脚本:
#!/usr/local/bin/guile \
-e main -s
!#
(define (fact-iter product counter max-count)
(if (> counter max-count)
product
(fact-iter (* counter product) (+ counter 1) max-count)))
(define (factorial n)
(fact-iter 1 1 n))
(define (n-C-r n r)
(/ (factorial n) (* (factorial (- n r)) (factorial r))
)
)
(define (row-iter r l n)
(cond ((= r 0) ((display 1) (row-iter (+ r 1) l n)))
((and (> r 0) (< r l)) ((display (n-C-r l r)) (display " ") (row-iter (+ r 1) l n)))
((= r l) (display 1))
)
)
(define (line-iter l n)
(cond ((<= l n) ( (row-iter 0 l n)
(line-iter (+ l 1) n) ) )
)
)
(define (pascal-triangle n)
(line-iter 0 n) )
(define (main args)
(pascal-triangle (string->number (car (cdr args)) 10))
)文件名为pascalTriangle.scm
顶部的舍邦符号有正确的欺骗路径。
我已经给出了chmod +x pascalTriangle.scm的权限
使用命令./pascalTriangle.scm 5运行程序
当运行上述脚本时,会观察到以下输出/错误:
1回溯:ice 9/boot-9 ice: 15:5捕获#t #. 在未知文件中: .=‘2’>4应用-烟雾/1# 冰-9/启动-9 ice: 电话提示prompt0 63: 3. 冰-9/val.scm: 分值432: 2 eval ## 在/home/tarunmaganti//./pascalTriangle.scm中: .=‘2’> 27: 1线-iter 0 4 在未知文件中: ?:0#错误:在过程#: 错误:应用错误类型:#
注意,输出的第一个字符是1,这意味着在过程行-iter的第一部分之前执行的代码-iter,即(显示1),之后可能会出现错误。
但是输出显示错误在程序行-iter中。我什么都不了解。
如果程序中的任何错误被指出并纠正以使其打印一个帕斯卡三角,我将不胜感激。
Edit1:我编辑了错误/输出文本,用HTML实体替换了'<‘和'>’‘.角括号内的文字以前是看不见的。
发布于 2016-06-24 10:28:54
问题是,您在cond中的结果表达式周围添加了多余的括号。由于cond有显式的begin,所以现在的代码如下所示:
(define (row-iter r l n)
(cond ((= r 0)
;; you see the double (( ?
((display 1)
(row-iter (+ r 1) l n)))
((and (> r 0) (< r l))
;; you see the double (( ?
((display (n-C-r l r))
(display " ")
(row-iter (+ r 1) l n)))
((= r l)
;; without double (( and thus ok
(display 1))))需要将其多余的括号移除如下:
(define (row-iter r l n)
(cond ((= r 0)
(display 1)
(row-iter (+ r 1) l n))
((and (> r 0) (< r l))
(display (n-C-r l r))
(display " ")
(row-iter (+ r 1) l n))
((= r l)
(display 1))))如果要使用if,则必须使用begin
(define (row-iter r l n)
(if (= r 0)
(begin
(display 1)
(row-iter (+ r 1) l n))
(if (and (> r 0) (< r l))
(begin
(display (n-C-r l r))
(display " ")
(row-iter (+ r 1) l n))
(display 1))))仅仅修复这个过程不会解决问题,因为您在line-iter中也有相同的错误。在每个((术语的开头,您可能会看到双cond,但是除非您正在做一些花哨的事情,否则您不应该期望它出现在其他任何地方。
当添加多余的括号时,((display "something") #t)会被解释为(display "something")将返回一个过程,并且您希望用参数#t检查该过程的结果。当对所有部分进行评估时,它就会失败,因为它会发现未定义的值不是一个过程。在某些情况下,这种办法是有效的:
((if (< x 0) - +) x 1) ; absolute increment value without changing sign在这里,您可以看到,当-小于零时,第一部分将被计算为计算x的结果。如果是-10,结果将是-11,如果是10,则应用的过程将是+与结果11的求值。
稍后,它将发现值3不是一个过程,您将得到eerror。要获得结果,方案应该做(应用3 '(#t))and it detects that 3 (in your case whatdesiplayreturns which is an unspecified value) Scheme interprets this by evaluating(display ( excess )‘,它打印一些东西和返回的值,由规范i未定义,从而自由选择的实施者,然后应用作为一个过程,因为过多的括号。
在Guile中,规范中未定义的值的结果变成一个显示#<unspecified>的单例,被REPL忽略。您可能会发现一个Scheme实现,其中未指定的值是一个不带参数的过程,在该过程中,您的实现将完美无缺地工作,但不能移植。
发布于 2016-06-24 17:18:39
西尔维斯特在他的回答中指出的错误是在((display (n-C-r l r)) (display " ") (row-iter (+ r 1) l n)))表达式中。该语句实际上是通过计算((display (n-C-r l r))来解释这一点的,它打印某些内容并返回未定义的值,并将其作为一个过程应用,将((display (n-C-r l r))视为括号过大的过程。
我用测序法解决了这个问题。begin特殊表单用于组合多个语句并返回最后一条语句的值。麻省理工学院的排序-计划。这也适用于诡计。
begin特殊形式的语法:(begin <e1> <e2> <e3>....<en>)
它返回<en>表达式的返回值。
以下是修改后的代码:
(define (row-iter n r)
(cond ((= r 0) (begin (display 1) (display " ") (row-iter n (+ r 1))))
((and (> r 0) (< r n)) (begin (display (n-C-r n r)) (display " ") (row-iter n (+ r 1))))
((= r n) (display 1))
)
)虽然输出没有正确地格式化为“三角形”,但是在更改代码后,我们可以得到左缩进的pascal三角形。
通过运行./pascalTriangle 5,我们获得的输出如下
1
1 1
1 2 1
1 3 3 1
1 4 6 4 1
1 5 10 10 5 1https://stackoverflow.com/questions/38010809
复制相似问题