新しくプログラミング言語を覚えたいときに行うべき10の練習問題をなでしこでやってみた

計算機学などまるで学ばず、PerlRubyもCもほとんど書けない久樹が独学で学んだ日本語プログラミング言語なでしこにて挑戦。なほ、なでしこの開発環境を持ってゐる人が実証可能であるように、GUIベースで定義した(コピー&ペーストして実行すれば良い)

ちなみに、久樹はいつもなでしこを関数的表現で書いてゐる。その理由は後述。

1.なんらかのカウントアップメッセージを1から100まで出すけど、3のときだけアホになる!

100回
 もし(回数 = 3)ならば
  表示("しゃ〜ん万円!")
 違えば
  表示("{回数}万円!")

そのまんま。なでしこはインデントで制禦構文の範囲とレベルを指定する。また、ループ回数は特殊変数『回数』に代入される。
ちゃんと100回実行されたか確認したい人は『言う(表示ログ)』でどうぞ。

2.現在時刻にあわせてやる気のでるメッセージを出力

表示メッセージ	= `ニコ動の時報うぜー。でも頑張れ。
夜食でも食べて頑張れ。
やっぱり時報がうざかったが頑張れ。
死ぬ気で頑張れ。
そろそろサンテレビの天気予報が始まるが頑張れ。
そろそろ日の出だが頑張れ。
そろそろラジオ体操が始まるが頑張れ。
そろそろ会社に出る支度を始めないといけないが頑張れ。
今日は遅出なのか? まあ頑張れ。
今日は休みなのか? まあ頑張れ。
休日ならこんな時間に起きてるわけないわな。まあ頑張れ。
そろそろお腹も空いてきたが頑張れ。
もうすぐ昼ご飯だ。頑張れ。
午後からも頑張れ。
眠いが頑張れ
間食とって頑張れ
もうすぐ定時だ頑張れ。
やっと定時だ。でも頑張れ。
残業頑張れ。
珍しく残業頑張ってるな。もっと頑張れ。
さすがに帰宅したか? 頑張れ。
今日のNスペは確認したか? 頑張れ。
野球で放送がずれていないか確認したか? 頑張れ。
まだ眠くないか? 頑張れ`

整数変換(文字右部分(今,2))
表示("時刻は{今}だ。{表示メッセージ[_]}")

『今』は現在日時をhh:mm:ss形式で返す関数。右端から2文字分取得し、これを整数に変換して、その値で配列の要素を呼び出してゐる(整数変換は別にしなくても良いのだが、文字列をそのまま流し込むのは流石に気持ち悪いので)
『_』はPerlと同じ。
といふか、やり方よりも言葉を考へる方がむづかしかった(苦笑)

3.複数の数値を入力させ、昇順に並び替え、最大値と最小値を出す(例:同僚の体重を入力して計算)

体重リストとは配列
区切る(`レナ,魅音,圭一,梨花,沙都子,詩音`,`,`)を反復
 尋ねる("{対象}の体重は?")
 配列追加(体重リスト,"{対象}{~}{_}")
表数値ソート(体重リスト,1)
表示("一番体重が軽いのは{体重リスト[0,0]}さんで{体重リスト[0,1]}kgです。")
_	= 配列要素数(体重リスト) - 1
表示("一番体重が重いのは{体重リスト[_,0]}さんで{体重リスト[_,1]}kgです。")

なでしこは変数宣言を必須としてゐないが、変数であることを表す記号(Perlで言ふ『$』とか)がなく、無宣言の『体重リスト』は『体重リスト』といふ文字列が代入された変数と解釈される。そのため、変数を変数として利用する際にはその値を上書きするか、初期化しなければならない。
久樹は変数管理を厳密にする上でも、一行目に『!変数宣言が必要』を宣言して敢えて宣言を必須化させてゐる。

なほ、名前を出さず単純に数値だけで良いのなら配列最大値/配列最小値といふ命令で十分(ソートさせる意味がないが)

4.簡易電卓。0で割ったときの処理を自分なりに作りこむ。

あー、面倒なので今日はパス。

5.キーワードを入れてYahoo!の検索結果を出力。

表示ブラウザとはブラウザ
表示ブラウザのレイアウト = 全体
尋ねる(`検索したいキーワードは?`)
表示ブラウザのURL        = "http://search.yahoo.co.jp/search?p={URLエンコード(_)}&ei=Shift_JIS"

URLクエリについてはYahoo!デベロッパーネットワーク - 検索パラメータ仕様を参照*1
なでしこにはIEコンポーネントGUIとして実装されてゐるため、そのまま表示させればよい。データが取得したい場合は『HTTPデータ取得()』を使ふ。

6.テキストを入れると語尾が赤ちゃん言葉に(例:ですよ→でちゅよ)。

テスト文章とは文字列
テスト文章 = `僕は赤ちゃんですよ。`
表示(置換(テスト文章,`ですよ`,`でちゅよ`))

まあ、これは単純に置換した例だが、文脈を考慮してより赤ちゃん言葉にするとなると大変ややこしくなる。

7.メールアドレスを入れるとあらかじめ用意されたテンプレートファイルにそのメアドを埋め込んだ上でメール送信

なでしこのマニュアルメールの送受信についてにそのまんま載ってゐるので省略。

8.「(名前)が、(場所)で、(アクション)した」がランダムに組み合わされて出てくるプログラム

名前リスト	= 配列シャッフル("レナ{~}魅音{~}圭一{~}梨花{~}沙都子{~}詩音")
場所リスト	= 配列シャッフル("古手神社{~}園崎本家{~}前原邸{~}エンジェルモート{~}裏山")
行動リスト	= 配列シャッフル("推理ゲーム{~}水鉄砲合戦{~}爺抜き{~}散策{~}ゾンビ鬼ごっこ")

表示("{名前リスト[0]}たちが{場所リスト[0]}で{行動リスト[0]}をした")

配列関係の関数を通すと、文字列であっても勝手に配列に変換してくれる。配列の区切りは改行なので、改行を表す特殊変数『〜』を噛ませてゐる。({}は内部の式を評價するためのエスケープシーケンス) 配列関係の関数を通さない時は『区切る()』などで代入した方が安全。
なほ、何回も表示させるのであれば配列シャッフルは変数に代入してからの方がコストパフォーマンスに優れてゐる(と思ふ)

9.URLを入れるとそのページのはてなブックマーク数が出てくるプログラム。

公開ユーザ数とは文字列
非公開ユーザ数とは文字列

尋ねる(`ブックマーク数を調べるURLは?`)
SJIS変換(HTTPデータ取得("http://b.hatena.ne.jp/entry/{_}"))
タグ切り出し(_,`h2`)して反復
 タグ切り出し(対象,`span`)して反復
  もし(空白除去(タグ属性取得(対象,`span`,`class`)) = `public-count`)ならば
   公開ユーザ数   = タグ削除(対象)
  もし(空白除去(タグ属性取得(対象,`span`,`class`)) = `private-count`)ならば
   非公開ユーザ数 = 置換(タグ削除(対象),`+`,空)
   抜ける
言う("公開ユーザは{公開ユーザ数}人。非公開ユーザは{非公開ユーザ数}人です。")

なでしこはHTML関係の処理が非常に貧弱なので、かなり遠回りな処理をしなければならない。タグ属性取得の値に空白除去を噛まさないときちんと式が評價されない点に注意(改行が混じる模様)
『対象』はループ内の代入変数。

本来はAPIをきちんと利用するのが筋なのだらうが、へぼ日曜プログラマにはいまいちよく理解できなかったのでスルーした。

10.ある名前とある名前を入れると相性診断を10段階で出してくれるプログラム。診断結果は適当でもいいけど、同じ組み合わせだったら同じ数値が必ずでないといけないように。

自分 = 尋ねる(`自分の名前`)
相手 = 尋ねる(`相手の名前`)
結果とは整数

文字列分解(自分&相手)を反復
 結果 = 仮箱 + ASC(対象)

結果 = 文字右部分(配列合計(文字列分解(結果)),1)

結果で条件分岐
 0ならば表示(`最も悪し。`)
 1ならば表示(`極めて悪し。`)
 2ならば表示(`悪し。`)
 3ならば表示(`やや悪し。`)
 4ならば表示(`並み。`)
 5ならば表示(`増し。`)
 6ならば表示(`やや良し。`
 7ならば表示(`良し。`)
 8ならば表示(`極めて良し。`)
 9ならば表示(`最も良し。`)

どういふアルゴリズムにするか考へたけど、相手と自分の文字列を足して、1文字づつ分解。その文字コードを数値として合計し、1桁目を見て判断。といふものにしてみた。
もちろん、自分と相手の名前をひっくり返してもちゃんと同じ結果が出力される。

なでしこの命令を関数的に書く利点

なでしこの構文は、自然言語的記法と関数的記法の二種類がある。例へば、次のコードはプログラム的に等価である。

1に1を足して3を引いて言う
言う(引く(足す(1,1),3))
#又は
言う(1 + 1 - 3)

なでしこの周辺の解説では前者の書き方が大半であるが、後者の方が、『何をしてゐるのか』が行の頭の方に来るのと、文字数が少なくて済むので、コードの見通しがよくなるといふ利点がある。他の言語も関数的書き方の方が一般的(?)なので、それとの差違が少ないといふのも挙げられる。

本格的にプログラムを扱へる人間に馬鹿にされがちななでしこだが、そもそもなでしこは、システム開発といふよりは、普段の日常定型業務を自動化するツール開発が主軸であると思ふ。
プログラミングで処理を自動化なんて今まで考へたこともないような人に、手軽に使って貰ふといふ点に関すれば、なでしこはどの言語よりも非常に優れてゐる。
ただ、マニュアルや実例が力不足なので、これを機会に高天原でも解説ページを設けようかと考へてゐるところである。

*1:ただ、フォーム設置用に指定されてゐた『fr=yssw』は何?