FizzBuzz Lambda 只返回最后一个整数
FizzBuzz Lambda Only Returning Last Integer
我是 Scheme 的新手,正在尝试编写示例 FizzBuzz 函数。规则如下:
- 如果一个数字可以被 3 和 5 整除,则说 "fizzbuzz"
- 否则,如果一个数可以被 3 整除,则说 "fizz"
- 否则,如果一个数可以被 5 整除,则说 "buzz"
- 否则说出数字。
这是我的代码:
(define (fizzbuzz n)
(print (fizzbuzz1 1 n)))
;; Helper function for fizzbuzz
(define (fizzbuzz1 i n)
(cond [(and (= 0 (modulo i 3)) (= 0 (modulo i 5)))
" fizzbuzz "]
[(= 0 (modulo i 3))
" fizz "]
[(= 0 (modulo i 5))
" buzz "]
(i))
(cond [(< i n) (fizzbuzz1 (+ 1 i) n)]))
(fizzbuzz 21)
但它显示的只是“21”(来自测试用例)。有人可以帮我吗?
编辑:稍微修正了我的代码并更新了它,但现在我得到的是 #<void>
打印出来。
你的函数实际上计算了从 1 到 21 的所有数字的正确结果,只是你没有做任何事情来在输出中显示它们,或者以某种方式收集它们,以便它们在被“丢失”之后在fizzbuzz1
里面计算(最初的print
只打印fizzbuzz1
的结果,也就是#<void>
)。如果你想显示它们(通过使用 display
而不是 print
,以获得更美观的结果),你可以在 cond
的每个分支中放置一个 display
,因为像这样的例子(请注意,如果你想学习这些语言,你绝对应该开始以干净的方式缩进你的函数!):
(define (fizzbuzz n)
(fizzbuzz1 1 n))
(define (fizzbuzz1 i n)
(cond [(and (= 0 (modulo i 3) ) (= 0 (modulo i 5) ))
(display " fizzbuzz ")]
[(= 0 (modulo i 3))
(display " fizz ")]
[(= 0 (modulo i 5))
(display " buzz ")]
[else (display i) (display " ")]
)
(cond [(< i n) (fizzbuzz1 (+ 1 i) n)])
)
还请注意,最后的 #void
是由于 fizzbuzz
初始定义中打印函数的值,如果删除它,它将消失。
另一个,更优雅,可能是在计算所有字符串时收集它们,例如通过使用string-append
,就像在这个函数中:
(define (fizzbuzz n)
(fizzbuzz1 1 n))
(define (fizzbuzz1 i n)
(if (> i n)
""
(string-append
(cond [(and (= 0 (modulo i 3) ) (= 0 (modulo i 5) ))
" fizzbuzz "]
[(= 0 (modulo i 3))
" fizz "]
[(= 0 (modulo i 5))
" buzz "]
[else (~a " " i " ")]
)
(fizzbuzz1 (+ 1 i) n))))
请注意,如果您的程序在交互式环境(如 DrRacket)中使用,在这种情况下也没有必要“打印”结果。
编辑
此解决方案的效率低于第一个解决方案,但如果您需要以某种结构收集所有结果以将它们用于其他任务,应该可以让您了解程序应具有何种结构。作为另一个示例,您可以使用 cons
来收集它们,例如,生成一个字符串列表而不是单个字符串(只需将 '()
替换为 ""
和 cons
string-append
).
此外,如果您使用球拍(因为您使用了球拍标签),您可能会发现球拍的 for
结构在这里很有用。
使用 for
(如 Renzo 所说,使用 display
)你可以这样写 fizzbuzz:
#lang racket
(define (fizzbuzz n)
(for ([i (in-range n)])
(cond [(and (= 0 (modulo i 3)) (= 0 (modulo i 5)))
(displayln "fizzbuzz")]
[(= 0 (modulo i 3))
(displayln "fizz")]
[(= 0 (modulo i 5))
(displayln "buzz")]
[else (displayln i)])))
(fizzbuzz 21)
另一种选择是使用for/list
,类似于for
,但将结果累加到列表中:
#lang racket
(define (fizzbuzz n)
(for/list ([i (in-range n)])
(cond [(and (= 0 (modulo i 3)) (= 0 (modulo i 5)))
"fizzbuzz"]
[(= 0 (modulo i 3))
"fizz"]
[(= 0 (modulo i 5))
"buzz"]
[else i])))
(fizzbuzz 21)
(apply string-append (fizzbuzz 21))
我是 Scheme 的新手,正在尝试编写示例 FizzBuzz 函数。规则如下:
- 如果一个数字可以被 3 和 5 整除,则说 "fizzbuzz"
- 否则,如果一个数可以被 3 整除,则说 "fizz"
- 否则,如果一个数可以被 5 整除,则说 "buzz"
- 否则说出数字。
这是我的代码:
(define (fizzbuzz n)
(print (fizzbuzz1 1 n)))
;; Helper function for fizzbuzz
(define (fizzbuzz1 i n)
(cond [(and (= 0 (modulo i 3)) (= 0 (modulo i 5)))
" fizzbuzz "]
[(= 0 (modulo i 3))
" fizz "]
[(= 0 (modulo i 5))
" buzz "]
(i))
(cond [(< i n) (fizzbuzz1 (+ 1 i) n)]))
(fizzbuzz 21)
但它显示的只是“21”(来自测试用例)。有人可以帮我吗?
编辑:稍微修正了我的代码并更新了它,但现在我得到的是 #<void>
打印出来。
你的函数实际上计算了从 1 到 21 的所有数字的正确结果,只是你没有做任何事情来在输出中显示它们,或者以某种方式收集它们,以便它们在被“丢失”之后在fizzbuzz1
里面计算(最初的print
只打印fizzbuzz1
的结果,也就是#<void>
)。如果你想显示它们(通过使用 display
而不是 print
,以获得更美观的结果),你可以在 cond
的每个分支中放置一个 display
,因为像这样的例子(请注意,如果你想学习这些语言,你绝对应该开始以干净的方式缩进你的函数!):
(define (fizzbuzz n)
(fizzbuzz1 1 n))
(define (fizzbuzz1 i n)
(cond [(and (= 0 (modulo i 3) ) (= 0 (modulo i 5) ))
(display " fizzbuzz ")]
[(= 0 (modulo i 3))
(display " fizz ")]
[(= 0 (modulo i 5))
(display " buzz ")]
[else (display i) (display " ")]
)
(cond [(< i n) (fizzbuzz1 (+ 1 i) n)])
)
还请注意,最后的 #void
是由于 fizzbuzz
初始定义中打印函数的值,如果删除它,它将消失。
另一个,更优雅,可能是在计算所有字符串时收集它们,例如通过使用string-append
,就像在这个函数中:
(define (fizzbuzz n)
(fizzbuzz1 1 n))
(define (fizzbuzz1 i n)
(if (> i n)
""
(string-append
(cond [(and (= 0 (modulo i 3) ) (= 0 (modulo i 5) ))
" fizzbuzz "]
[(= 0 (modulo i 3))
" fizz "]
[(= 0 (modulo i 5))
" buzz "]
[else (~a " " i " ")]
)
(fizzbuzz1 (+ 1 i) n))))
请注意,如果您的程序在交互式环境(如 DrRacket)中使用,在这种情况下也没有必要“打印”结果。
编辑
此解决方案的效率低于第一个解决方案,但如果您需要以某种结构收集所有结果以将它们用于其他任务,应该可以让您了解程序应具有何种结构。作为另一个示例,您可以使用 cons
来收集它们,例如,生成一个字符串列表而不是单个字符串(只需将 '()
替换为 ""
和 cons
string-append
).
此外,如果您使用球拍(因为您使用了球拍标签),您可能会发现球拍的 for
结构在这里很有用。
使用 for
(如 Renzo 所说,使用 display
)你可以这样写 fizzbuzz:
#lang racket
(define (fizzbuzz n)
(for ([i (in-range n)])
(cond [(and (= 0 (modulo i 3)) (= 0 (modulo i 5)))
(displayln "fizzbuzz")]
[(= 0 (modulo i 3))
(displayln "fizz")]
[(= 0 (modulo i 5))
(displayln "buzz")]
[else (displayln i)])))
(fizzbuzz 21)
另一种选择是使用for/list
,类似于for
,但将结果累加到列表中:
#lang racket
(define (fizzbuzz n)
(for/list ([i (in-range n)])
(cond [(and (= 0 (modulo i 3)) (= 0 (modulo i 5)))
"fizzbuzz"]
[(= 0 (modulo i 3))
"fizz"]
[(= 0 (modulo i 5))
"buzz"]
[else i])))
(fizzbuzz 21)
(apply string-append (fizzbuzz 21))