2011年2月22日火曜日

CodeForces Unknown Language Round #1

出場してきました。CodeForces Unknown Language Round #1
言語が分からず、マイナーな言語が使われるとのことだったので、何かなと妄想しつつ待っていると、「Active Tcl」とかいうわけの分からん言語が登場した。

これ、実は開始5分前にアナウンスがあって、標準入力ストリームからどうやって拾ってくるか、どうやって変数に値をセットするか、どうやって出力するかというサンプルコードが挙がってたんだけども、僕はそんなことに一切気付かず、グーグル先生を頼ってひたすらリファレンスを探し回って徒にタイムロスを重ねていた。



今回は言語自体が難しいということで、問題がクソ簡単だった。

!!!---Warning---!!!
下記は糞コードです。参考にしないで下さい。

問 1
指定された数字の階乗を求めよ。

コード







gets stdin number
set sum $number
for {set i 1} {$i < $number} {incr i} { set sum [expr $sum*$i] } puts stdout $number flush

特筆すべき点なし

問 2
5-4とか4-9みたいな文字列がインプットされるので、式を評価せよ
各数字は0以上9以下という縛り
演算子は+か-のみ。

コード







gets stdin number
scan $number "%d%c%d" n f m
if {$f == 42} {
    set result [expr $n + $m]
} else {
    set result [expr $n - $m]
}
puts stdin $result
flush


問 3
n行m列のテーブルがあり、行の左から右へ、上から下へ、1,2,3、、、と数字が書き込まれている。
例えば、3行4列のテーブルの場合、1行目は 1、2、3、4。2行目は5,6,7,8と書き込まれる。
今、1 <= k <= nmとなるkが与えられる。 kは、列を上から下へ、左から右へと遷移していった場合のk番目のセルを指し示している。 k番目のセルに書き込まれた数字を出力せよ。 コード






gets stdin number
scan $number "%d %d %d" n f m
set gyo [expr $m % $n]
set kara [expr $m / $n]
if {$gyo == 0} {
    set gyou [expr $n - 1]
} else {
    set gyou [expr $gyo - 1]
    set kara [expr $kara + 1]
}
set mae [expr $gyou * $f]
set sum [expr $mae + $kara]
puts stdout $sum
flush stdout


解き方
Kを行数+1で割った余りが何行目かを表し、商+1が何列目かを表す。
n行m列目の数値を算出するには { (n-1) * 行数 } + m とすればよい。

問 4
3人姉妹にプレゼントを上げなければならない。
長女には一番高いものを、次女には次に高いものを、三女には一番安いものをあげたい。
3つの数字が与えられ、それぞれ商品の値段を示している。どの商品を姉妹のいずれにあげればよいのか、「1 3 2」のような形式で示せ。








gets stdin number
scan $number "%d %d %d" n f m
if { $n > $f } {
if {$n > $m} {
if {$f > $m} {
set l 1
set me 2
set s 3
} else {
set l 1
set me 3
set s 2
}
} else {
set l 2
set me 3
set s 1
}
} else {
if {$n > $m} {
set l 2
set me 1
set s 3
} else {
if {$f > $m} {
set l 3
set me 1
set s 2
} else {
set l 3
set me 2
set s 1
}
}
}
set kekka [format {%d %d %d} $l $me $s]
puts stdout $kekka
flush stdout


もうちょっと綺麗なコードにも出来たが、問題が単純なのでナイーヴに進めた。
Active Tclはささいなスペースにも厳しいので、うっかり変なことをして怒られないか怖かったというのもある。

問 5
与えられた数字に一番近い素数を、数字より大きいものと小さいものを一つずつ、「小 大」のような形式で示せ。

解き方
エラトステネスの篩で終了。

コードは書いたのだが、配列に入れた数値にアクセスする方法が今一つ分からず、時間切れ。


ということで、4問解いて終了でした。
始めのロスが無ければもうちょっといけたかもしれませんが、後の祭り。
上でも述べた通り、検索しても簡単にリファレンスが見つからないような超マイナーな言語とあってか、問題は非常に簡単でした。
C++を使っていれば、解くのに一時間もかからなかったでしょう。(今回のコンテストは二時間半あった)

とはいえ、未知の言語を使って手探り状態でプログラムを組むというのも中々面白いもの。
次回があるのかどうかは分からないけれども、機会があれば参加してみるのもいいかもしれませんね。

0 件のコメント:

コメントを投稿

注: コメントを投稿できるのは、このブログのメンバーだけです。