99 Bottles of Beer/Lisp: Difference between revisions
Content added Content deleted
GordonBGood (talk | contribs) (→{{header|newLISP}}: make language name consistent with website...) |
m (Fixed syntax highlighting and duplicate headers.) |
||
Line 4: | Line 4: | ||
{{collection|99 Bottles of Beer}} |
{{collection|99 Bottles of Beer}} |
||
[[99 Bottles of Beer]] done in Lisp-languages |
[[99 Bottles of Beer]] done in Lisp-languages |
||
<!-- |
|||
See [[99 Bottles of Beer/Lisp]] |
|||
--> |
|||
<!-- still missing: |
<!-- still missing: |
||
Line 15: | Line 11: | ||
__toc__ |
__toc__ |
||
== |
===ACL2=== |
||
< |
<syntaxhighlight lang="lisp">(defun bottles-of-beer (n) |
||
(if (zp n) |
(if (zp n) |
||
nil |
nil |
||
Line 29: | Line 25: | ||
(1- n) |
(1- n) |
||
(if (= n 2) 0 1)) |
(if (= n 2) 0 1)) |
||
(bottles-of-beer (- n 1)))))</ |
(bottles-of-beer (- n 1)))))</syntaxhighlight> |
||
== |
===Common Lisp=== |
||
===Sensible solution=== |
====Sensible solution==== |
||
< |
<syntaxhighlight lang="lisp">(defun bottles (x) |
||
(loop for bottles from x downto 1 |
(loop for bottles from x downto 1 |
||
do (format t "~a bottle~:p of beer on the wall~@ |
do (format t "~a bottle~:p of beer on the wall~@ |
||
Line 40: | Line 36: | ||
~V[No more~:;~:*~a bottle~:p of~] beer on the wall~2%" |
~V[No more~:;~:*~a bottle~:p of~] beer on the wall~2%" |
||
bottles (1- bottles)))) |
bottles (1- bottles)))) |
||
</syntaxhighlight> |
|||
</lang> |
|||
and then just call |
and then just call |
||
<lang |
<syntaxhighlight lang="lisp">(bottles 99)</syntaxhighlight> |
||
===Ridiculous=== |
====Ridiculous==== |
||
< |
<syntaxhighlight lang="lisp">(format t "~{~[~^~]~:*~D bottle~:P of beer on the wall~%~:*~D bottle~:P of beer~%Take one down, pass it around~%~D bottle~:P~:* of beer on the wall~2%~}" |
||
(loop :for n :from 99 :downto 0 :collect n))</ |
(loop :for n :from 99 :downto 0 :collect n))</syntaxhighlight> |
||
The [http://www.lispworks.com/documentation/HyperSpec/Body/22_c.htm FORMAT function] is probably the most baroque (i.e. featureful almost to a fault) function in Common Lisp. |
The [http://www.lispworks.com/documentation/HyperSpec/Body/22_c.htm FORMAT function] is probably the most baroque (i.e. featureful almost to a fault) function in Common Lisp. |
||
To really drive this point home, try replacing each instance of <tt>~D</tt> |
To really drive this point home, try replacing each instance of <tt>~D</tt> |
||
Line 60: | Line 56: | ||
* <tt>~:P</tt> is for English plurals: it prints <tt>s</tt> if the last argument wasn't 1; it prints nothing otherwise. There's also <tt>~@P</tt> for <tt>y</tt>/<tt>ies</tt>, in case you were worried about that. |
* <tt>~:P</tt> is for English plurals: it prints <tt>s</tt> if the last argument wasn't 1; it prints nothing otherwise. There's also <tt>~@P</tt> for <tt>y</tt>/<tt>ies</tt>, in case you were worried about that. |
||
Note, by the way, how the emoticons <tt>:*~D</tt> and <tt>:P</tt> have shown up in the format string. FORMAT is so powerful, it's even self-aware about how silly it is. |
Note, by the way, how the emoticons <tt>:*~D</tt> and <tt>:P</tt> have shown up in the format string. FORMAT is so powerful, it's even self-aware about how silly it is. |
||
===Alternate solution=== |
====Alternate solution==== |
||
Bit of a beginner in Lisp, but this seems to work: |
Bit of a beginner in Lisp, but this seems to work: |
||
< |
<syntaxhighlight lang="lisp"> |
||
(defun beer-verse (count) |
(defun beer-verse (count) |
||
"Recurses the verses" |
"Recurses the verses" |
||
Line 78: | Line 74: | ||
(beer-verse (- count 1)))) |
(beer-verse (- count 1)))) |
||
(beer-verse 99) |
(beer-verse 99) |
||
</syntaxhighlight> |
|||
</lang> |
|||
<!-- missing here: |
<!-- missing here: |
||
== |
===Emacs Lisp=== |
||
--> |
--> |
||
== |
===newLISP=== |
||
< |
<syntaxhighlight lang="newlisp">(for (n 99 1) |
||
(println n " bottles of beer on the wall," n " bottles of beer. Take one down, pass it around. ") |
(println n " bottles of beer on the wall," n " bottles of beer. Take one down, pass it around. ") |
||
(println (- n 1) "bottles of beer on the wall!")) |
(println (- n 1) "bottles of beer on the wall!")) |
||
Line 95: | Line 92: | ||
" bottles of beer on the wall" (rec ( - bottles 1))))(list bottles)) |
" bottles of beer on the wall" (rec ( - bottles 1))))(list bottles)) |
||
(rec 99)</ |
(rec 99)</syntaxhighlight> |
||
== |
===Ol=== |
||
< |
<syntaxhighlight lang="scheme"> |
||
(define nn 99) |
(define nn 99) |
||
Line 116: | Line 113: | ||
"Go to the store and buy some more, " |
"Go to the store and buy some more, " |
||
nn " bottles of beer on the wall.") |
nn " bottles of beer on the wall.") |
||
</syntaxhighlight> |
|||
</lang> |
|||
== |
===PicoLisp=== |
||
< |
<syntaxhighlight lang="picolisp">(de bottles (N) |
||
(case N |
(case N |
||
(0 "No more beer") |
(0 "No more beer") |
||
Line 130: | Line 127: | ||
(prinl "Take one down, pass it around,") |
(prinl "Take one down, pass it around,") |
||
(prinl (bottles (dec 'N)) " on the wall.") |
(prinl (bottles (dec 'N)) " on the wall.") |
||
(prinl) )</ |
(prinl) )</syntaxhighlight> |
||
== |
===Shen=== |
||
< |
<syntaxhighlight lang="shen">(define bottles-h |
||
{ number --> string } |
{ number --> string } |
||
0 -> "No more beer" |
0 -> "No more beer" |
||
Line 144: | Line 141: | ||
X -> (let Msg (bottles-h X) |
X -> (let Msg (bottles-h X) |
||
(do (output "~A on the wall~%~A~%Take one down, pass it around~%~A on the wall~%~%" Msg Msg (bottles-h (- X 1))) |
(do (output "~A on the wall~%~A~%Take one down, pass it around~%~A on the wall~%~%" Msg Msg (bottles-h (- X 1))) |
||
(bottles (- X 1)))))</ |
(bottles (- X 1)))))</syntaxhighlight> |
||
== |
===Wart=== |
||
< |
<syntaxhighlight lang="python">def (beer n) |
||
when (n > 0) |
when (n > 0) |
||
prn n " bottles of beer on the wall" |
prn n " bottles of beer on the wall" |
||
Line 154: | Line 151: | ||
prn n-1 " bottles of beer on the wall" |
prn n-1 " bottles of beer on the wall" |
||
prn "" |
prn "" |
||
beer n-1</ |
beer n-1</syntaxhighlight> |
Revision as of 19:34, 1 September 2022
99 Bottles of Beer/Lisp is part of 99 Bottles of Beer. You may find other members of 99 Bottles of Beer at Category:99 Bottles of Beer.
99 Bottles of Beer done in Lisp-languages
ACL2
(defun bottles-of-beer (n)
(if (zp n)
nil
(prog2$ (cw (concatenate 'string
"~%"
"~N0 bottle~#1~[~/s~] of beer on the wall,~%"
"~n0 bottle~#1~[~/s~] of beer.~%"
"Take one down, pass it around,~%"
"~n2 bottle~#3~[~/s~] of beer on the wall.~%")
n
(if (= n 1) 0 1)
(1- n)
(if (= n 2) 0 1))
(bottles-of-beer (- n 1)))))
Common Lisp
Sensible solution
(defun bottles (x)
(loop for bottles from x downto 1
do (format t "~a bottle~:p of beer on the wall~@
~:*~a bottle~:p of beer~@
Take one down, pass it around~@
~V[No more~:;~:*~a bottle~:p of~] beer on the wall~2%"
bottles (1- bottles))))
and then just call
(bottles 99)
Ridiculous
(format t "~{~[~^~]~:*~D bottle~:P of beer on the wall~%~:*~D bottle~:P of beer~%Take one down, pass it around~%~D bottle~:P~:* of beer on the wall~2%~}"
(loop :for n :from 99 :downto 0 :collect n))
The FORMAT function is probably the most baroque (i.e. featureful almost to a fault) function in Common Lisp. To really drive this point home, try replacing each instance of ~D with ~R, and then with ~@R. Yes, this is all standard and dependable (dys?)functionality.
Explanation of the format string for the uninitiated:
- ~{fmt~} expects the next argument to be a list (which is of the integers from 99 down to 0), and executes the format string fmt on each element. It is essentially a map or foreach.
- ~[...~] is a case/switch. It executes the nth clause, where n is taken from the next argument. Since there is only one clause here, it will be executed only when the argument is 0.
- ~^ will terminate formatting.
- ~:* will back-up to the most-recently used argument.
- ~D prints the next argument as a decimal number.
- ~:P is for English plurals: it prints s if the last argument wasn't 1; it prints nothing otherwise. There's also ~@P for y/ies, in case you were worried about that.
Note, by the way, how the emoticons :*~D and :P have shown up in the format string. FORMAT is so powerful, it's even self-aware about how silly it is.
Alternate solution
Bit of a beginner in Lisp, but this seems to work:
(defun beer-verse (count)
"Recurses the verses"
(format t "~A bottle~:P of beer on the wall~%" count)
(format t "~A bottle~:P of beer~%" count)
(format t "Take one down, pass it round~%")
(format t "~A bottle~A of beer on the wall~%~%"
(if (= count 1)
"No"
(- count 1))
(if (/= count 2)
"s"
""))
(if (> count 1)
(beer-verse (- count 1))))
(beer-verse 99)
newLISP
(for (n 99 1)
(println n " bottles of beer on the wall," n " bottles of beer. Take one down, pass it around. ")
(println (- n 1) "bottles of beer on the wall!"))
;;recursive
;;also shows list afterword
(define (rec bottles)
(if (!= 0 bottles) (print "/n" bottles " bottles of beer on the wall" bottles " bottles of beer.
\nTake one down, pass it around, " (- bottles 1)
" bottles of beer on the wall" (rec ( - bottles 1))))(list bottles))
(rec 99)
Ol
(define nn 99)
(for-each (lambda (n)
(let ((bottle (lambda (n) (if (eq? n 1) " bottle" " bottles")))
(m (- n 1)))
(print
n (bottle n) " of beer on the wall, "
n (bottle n) " of beer." "\n"
"Take one down and pass it around, "
(if (eq? m 0) "no more" m)
(bottle m) " of beer on the wall.\n")))
(reverse (iota nn 1)))
(print
"No more bottles of beer on the wall, "
"no more bottles of beer." "\n"
"Go to the store and buy some more, "
nn " bottles of beer on the wall.")
PicoLisp
(de bottles (N)
(case N
(0 "No more beer")
(1 "One bottle of beer")
(T (cons N " bottles of beer")) ) )
(for (N 99 (gt0 N))
(prinl (bottles N) " on the wall,")
(prinl (bottles N) ".")
(prinl "Take one down, pass it around,")
(prinl (bottles (dec 'N)) " on the wall.")
(prinl) )
Shen
(define bottles-h
{ number --> string }
0 -> "No more beer"
1 -> "One bottle of beer"
N -> (make-string "~A bottles of beer" N))
(define bottles
{ number --> number }
0 -> 0
X -> (let Msg (bottles-h X)
(do (output "~A on the wall~%~A~%Take one down, pass it around~%~A on the wall~%~%" Msg Msg (bottles-h (- X 1)))
(bottles (- X 1)))))
Wart
def (beer n)
when (n > 0)
prn n " bottles of beer on the wall"
prn n " bottles of beer"
prn "take one down, pass it around"
prn n-1 " bottles of beer on the wall"
prn ""
beer n-1