naiの日記

ソフトウェアエンジニアから放射線科診断医にジョブチェンジしました。趣味のことを書きます。

328. base convert

サークルの合宿やら試験やらでずっと更新できない状態が続いていましたが、漸く暇が出来ました。

328. base convert

一位のnnさんの解は凄いですね。無駄がありません。
再帰関数を作り逆順で出力する方法しか考えていなかったので、これには参りました。
自分はどうにかscanfの引数を削り81Bまで縮めましたが、それまででした。

330. Sort by Length for OCaml Golf Competition

かるたの合宿等と被ってまったく参加できず。
とりあえず問題文を読んで方法を考えていましたが、コンパレータを定義してqsortに突っ込む方法しか考えていなかったので、inaniwaさんの解のようにstrcmpでソートしてから全部なめて短い順に出力するのはまったく想定外でした。これも凄いですね。



その他の問題はまだ思考がまとまっていません。
タイミング良くActive Problemsがたくさんあるので、一つずつ考えていこうと思います。


ちなみに、かるたの職域で大学OBの凄腕Golferの方とお会いしました(あなごるで非常に高い成績を出している方です)。
大学の先輩に何人か素晴らしいGolferの方々がいらっしゃるのは知っていましたが、かるたの先輩にいらっしゃるとは。世界は意外と狭いものですね。

322. Substract from a Googol

私生活でいろいろあってしばらくゴルフから離れていましたが、とりあえず再開です。

322. Substract from a Googol

締め切り直前のSubmitすみません。なぜかいつも締め切りギリギリでのSubmitになってしまう……
今回は途中寝落ちしてしまったこともあり、縮めている間に終了という初めての事態に。

sprintfの書式指定によりスペース(32)が左に入るので、15との論理積を取ると0になり、leading zeroと同じ効果が得られるというわけです。

324. Googol division

こちらも終了しました。
最初は左端に0を出力してしまうのをどうにかしなければと悩んでいましたが、単純にr=10000から始めて解決。ついでにforの条件式も1バイト減りますね。

321. add_sub_brainfuck_code

ちょっと遅くなってしまいましたが。
nuさんmskさんの解のように、readの第一引数に変数を入れることで条件分岐するというのは全く思いつきませんでした。凄いですね。

314. Roman numeral

終了しました。


トップのinaniwaさんの解はなんと93B。
減算則のチェックに、直前の値を保存せず、合計値を表す変数sが現在の値aで割り切れるかどうかで判定しています。
なるほど、確かにaの値は通常は広義単調減少で、しかも過去の値はすべて現在の値の倍数なので、これでチェックできますね。まったく思いつきませんでした。


他の人のコードも見ていて面白いです。
nnさんは、「500と1000が一発で表せない」という一番の問題をワイド文字で解決していて衝撃的でした。
nuさんは、-10と負数の論理和を取ることで-1と-10を作れているうえに、一つ答えを表示したときにprintfの返り値をs,p両方に代入することでs=0にする手間を省いています。
与えられた入力は、2行目以降で1バイト目に"I"が出てくるデータがないため次のループでs-=pされて消えるのですが、これは思いつかなかったです。
ちなみに私は、printfの書式"%d\n"の2,3,4バイト目の文字コードがそれぞれ100,10,0であることを利用しているのですが、3桁バイトの壁を越えることは出来ませんでした。


みなさん、お疲れ様でした。

317. Multiplication Table

終了しました。
deadlineギリギリでの投稿、失礼しました。
(一応言っておきますと、隠し玉として温存していたわけでは決してありません)

終了直前までは

i;main(){for(;i-144;)printf("%3d%c",~(i++/12)*~(i%12),~i%12?32:10);}

この68Bだったのですが、printf第三引数で行っていた改行判定を第一引数にも持ってくることが出来ることに気づき、そこから変数を1つ増やして63Bを通すことが出来ました。

ちなみに、終了後の62Bはinaniwaさんのコードを見て思いつきました。


この問題も、単純な割に幾通りものアプローチがあって面白い問題だと思うのですが、惜しむらくは、(Another Tableの出汁にされたためか)deadlineが非常に早かった点です。
もう少しゆっくり解きたい問題でした。

314. Roman numeral

実は今日は大学で英語一列の試験だったので、昨日いっぱいはGolfしないつもり……だったのですが、やはり次々と縮んでいく記録や自分のコードを見ているとGolfが止まらなくなってしまいました。まあ、いつも通りです。
(試験の出来がどうだったかは皆さんのご想像にお任せします)


で、記念すべき第314回、Roman numeralですよ。今こそ落ち着いていますが、昨日から今日にかけて、抜いたり抜かれたりの争いが凄まじかったです。nuさんに113Bで追いついたら3分後に離されていた、なんてこともありました。
その間私のコードはまったく想像もしない方向に転がり続け、今では最初のコードとはまったく似ても似つかないコードになってしまいました(一応言っておきますと、ローマ数字のライブラリ等ではなく、正攻法で解いています)。この問題も良問だと思います。最近は良問が多いですね。
現在私が100Bきっかりでなんとかトップですが、ほぼ同着でお二人がつけていてまったく予断を許さない状況です。誰が最初に二ケタに突入するのか、あるいはこのまま終了するのか、今後の展開が注目されます。


ちなみに、nuさんとは先日お会いしたのですが、あなごる参加はCount diamonds level 3以来9ヶ月ぶりのようです。私があなごるを始めたのが確かbox worldあたりなので、deadline付き問題で競うのはこれが初めてということになります。あなごる上でnuさんと競うことが出来て光栄です。

【7/15追記
ついにnuさんが100Bを切りました。凄まじいですね……。

ICPC・UTPC

ICPC予選とUTPCに参加しました。


全体的にはブランクがあった割にはまずまずの成績となりましたが、問題文をよく読まないために解けなかったり解くのに時間がかかったりした問題が多かったです。
自分の落ち着きの無さを反映していますね……。
UTPCはどれだけ時間がかかろうと自分の成績が下がるだけなのですが、ICPCはチーム戦なのでチームメイトに迷惑をかけてしまい申し訳なかったです。

なお、ICPCは予選突破ならず。ううむ、残念。
というか上位層が鉄板過ぎてどうしようもありませんでした。これはかなり精進しないと。
やはりPKUやTopCoderなどで場数を踏みまくる必要があるのでしょうかね。


ちなみに去年のPracticeのにゃーという問題が面白かったので載せておきます。是非自力で解いてみてください。にゃー。

309. Not Random

まず、終了後にPerlで同じコードを二回Submitしてしまい申し訳ございません。


擬似乱数の生成規則に基づいて文字列を出力させる問題です。
私は数字をいじくり回している間に偶然気付きましたが、やはり参加者は少なかったようです。
言語によってはそもそも擬似乱数を生成せずembedによって出力しているコードもありました。

C

残念ながら、参加者は私一人でした。

main(n,i){for(scanf("%d,%d,%s",&n,&i,i);i--;printf("%*.s%s\n",n=n*8%13));}

printfの引数が二つほど少ないのですが、足りない分はscanfに渡した引数が用いられます。なので第四引数にはちゃんと元々のiの値が渡され、入力した文字列を出力するという寸法。
第三引数にはiへのポインタが渡るのでそのままだとゴミを出力してしまうのですが、printfの書式に"."をつけて精度を0にすることでこれを回避しています。

ちなみに、

main(_,n,i){for(scanf("%d,%d,%s",&n,&i);i--;printf("%*.s%s\n",n=n*8%13));}

これは通りますが、

main(n,i){for(scanf("%d,%d,%s",&n,&i);i--;printf("%*.s%s\n",n=n*8%13));}

これは通りません。scanfで文字列をmainの第一引数へのポインタに入力しているようです。

Perl

コマンドラインオプションを4つもつけて相当縮めたと思ったら、コマンドラインオプションを使わない方が短くなるとは完全に予想外でした。
例の「トップになるとあまり考えなくなる症」が発動してしまったようです。やはりもう少し考えなくては。
冒頭でも書きましたが、同じコードを誤って違う名前で送ってしまいすみませんでした。