99 Bottles of Beer/Tcl: Difference between revisions
m
Fixed syntax highlighting.
m (Add SMW link) |
m (Fixed syntax highlighting.) |
||
(3 intermediate revisions by one other user not shown) | |||
Line 1:
{{collection|99 Bottles of Beer}} [[implementation of task::99 Bottles of Beer| ]]
===using variable traces===
Here's a version that uses Tcl's variable traces
to set a global "bottle string" whenever the counter variable is set.
upvar #0 $varName n▼
set ::bottles [format "%d bottle%s" $n [expr {$n == 1 ? "" : "s"}]]▼
}▼
trace add variable i write setBottles▼
for {set i 99} {$i > 0} {} {▼
puts "$bottles of beer on the wall"▼
puts "$bottles of beer"▼
puts "take one down, pass it around"▼
incr i -1▼
puts "$bottles of beer on the wall\n"▼
}</syntaxhighlight>
===Wordy version===
<syntaxhighlight lang="tcl">set s "s"; set ob "of beer"; set otw "on the wall"; set more "Take one down and pass it around"
for {set n 100} {$n ne "No more"} {} {
switch -- [incr n -1] {
1 {set s ""}
0 {set s "s"; set n "No more"; set more "Go to the store and buy some more"}
}
lappend verse ". $n bottle$s $ob $otw.\n"
lappend verse "\n$n bottle$s $ob $otw, [string tolower $n] bottle$s $ob.\n$more"
}
puts -nonewline [join [lreplace $verse 0 0] ""][lindex $verse 0]</syntaxhighlight>
Version which converts numbers to words, optimized for script length while retaining readability:
<syntaxhighlight lang="tcl">proc 0-19 {n} {
lindex {"no more" one two three four five six seven eight nine ten eleven
twelve thirteen fourteen fifteen sixteen seventeen eighteen nineteen} $n
}
proc TENS {n} {
lindex {twenty thirty fourty fifty sixty seventy eighty ninety} [expr {$n - 2}]
}
proc num2words {n} {
if {$n < 20} {return [0-19 $n]}
set tens [expr {$n / 10}]
set ones [expr {$n % 10}]
if {$ones == 0} {return [TENS $tens]}
return "[TENS $tens]-[0-19 $ones]"
}
proc get_words {n} {
return "[num2words $n] bottle[expr {$n != 1 ? "s" : ""}] of beer"
}
for {set i 99} {$i > 0} {incr i -1} {
puts [string totitle "[get_words $i] on the wall, [get_words $i]."]
puts "Take one down and pass it around, [get_words [expr {$i - 1}]] on the wall.\n"
}
puts "No more bottles of beer on the wall, no more bottles of beer."
puts "Go to the store and buy some more, 99 bottles of beer on the wall."</syntaxhighlight>
===99-bottles-of-beer.net===
from http://99-bottles-of-beer.net/language-tcl-439.html
<
return "$i bottle[expr {$i!=1?{s}:{}}] of beer"
}
Line 20 ⟶ 83:
incr i -1
line4 $i
}</
▲Here's a version that uses Tcl's variable traces to set a global "bottle string" whenever the counter variable is set.
▲<lang tcl>proc setBottles {varName args} {
▲ upvar #0 $varName n
▲ set ::bottles [format "%d bottle%s" $n [expr {$n == 1 ? "" : "s"}]]
▲}
▲trace add variable i write setBottles
▲for {set i 99} {$i > 0} {} {
▲ puts "$bottles of beer on the wall"
▲ puts "$bottles of beer"
▲ puts "take one down, pass it around"
▲ incr i -1
▲ puts "$bottles of beer on the wall\n"
===The Boozy Version===
A [http://99-bottles-of-beer.net/language-expect-249.html
particularly entertaining version] is [[wp:Don Libes|Don Libes]]’s coding
from the mid-'90s in [[Expect]],
which "... SIMULATES a human typing the beer song."
This is a version of that code, adapted to use modern coding styles,
and not require any extensions.<br>
{{works with|Tcl|8.4}}
<
# Author: Don Libes <libes@nist.gov>
### Adapted by: Donal K. Fellows <donal.k.fellows@manchester.ac.uk>
Line 183 ⟶ 231:
set i [expr {6+int(3*rand())}]
}
}</
|