昨年の今頃は空前の湯婆婆ブームで、私も湯婆婆 Advent Calendarに2件も書かせて頂きました。(実は今年もあるんですが、さすがにもうニーズは無いようです)
12月を目前に、今年も何かその手のネタが投下されないかとソワソワしていたところ、同じ匂いのする記事を見付け、嬉しくなって便乗させて頂くことにしました。(特にブームにはなっていませんが)
以下、Tclを使って「これはペンです」という文章に、心を込めるプログラムを作成してみました。
1. 素直な実装
仕様
文字数分だけループを回します。
Python
元記事では
a = "これはペンです"
for i in range(len(a)):
print(a[i] + "心", end='')
の出力結果が
こ心れ心は心ペ心ン心で心す心
になるとされています。
私はPythonを使えませんので、Tclに書き替える第一歩として、まずはCygwinに入っていたPython 2.7.18で動作確認してみることにしました。
print(a[i] + "心", end='')
^
SyntaxError: invalid syntax
エラーになってしまいました。う~ん、なぜ?
とは言え、今回はPythonのお勉強ではないので、
- 変数aは文字の配列っぽい
- for文では配列の添字を列挙しておいてループしてるっぽい
- print関数の第2引数は改行抑制っぽい
とテキトーに解釈して話を進めます。
Tcl
最初に思い浮んだ記述は以下の通りで、
set a これはペンです
foreach ai [split $a ""] {
puts -nonewline ${ai}心
}
出力結果もちゃんと
こ心れ心は心ペ心ン心で心す心
になります。(元記事の脚注1の簡潔バージョンには近いかも)
しかし仕様は「文字数分だけループを回す」となっていますし、無理やり元記事と同じ様な記述にする方が面白そうだったので、以下のように修正しました。
proc range length {
for {set i 0} {$i < $length} {incr i} {
lappend ret $i
}
return $ret
}
proc array_set_str {varname str} {
upvar $varname var
set i -1
foreach c [split $str ""] {
set var([incr i]) $c
}
}
array_set_str a これはペンです
foreach i [range [array size a]] {
puts -nonewline $a($i)心
}
無理やりaを配列にしたり、rangeを自作したりして似せてみました。
2. joinメソッドを用いた方法
仕様
joinメソッドを使う。
Python
a = "これはペンです"
print("心".join(a))
と記述すると、
こ心れ心は心ペ心ン心で心す
と出力されるとのことですが、Cygwinに入っていたPython 2.7.18で動作確認してみたところ、
�心�心�心�心�心�心�心�心�心�心�心�心�心�心�心�心�心�心�心�心�
となりました。う~む。
Tcl
set a これはペンです
puts [join [split $a ""] 心]
と記述すると、元記事と同じく
こ心れ心は心ペ心ン心で心す
と出力されました。
たぶんニュアンスは合っているのではないでしょうか。
おわりに
い心か心が心だ心っ心た心で心し心ょ心う心か心。心T心c心l心で心も心心心が心込心も心っ心た心文心章心に心な心り心ま心し心た心で心し心ょ心う心か心?