2019/02/17に行われた全国統一プログラミング王決定戦決勝に参加してきました。日帰りです。
・決勝前
朝は目覚ましが鳴る前に起きました。 東京駅に着いたのは10時半あたりで、一瞬だけゲームセンターに行きました。
・決勝
意識がない
・決勝後
エキシビションマッチでは速解きコンテストが行われました。 速解きコンテストではコードゴルフをしろと蟻本にも書いてあります。 幸いエキシビションマッチ終了直後からコンテストページがオープンになったので、懇親会の最中に縮めてしまうことにします。
コードゴルフをしていたと思ったらいつのまにか懇親会が終わっていた
新幹線の終電に乗ることにして、%20さんとうらさんと店に入ってコードゴルフの続きをしたりしました。
エキシビションマッチのA-F問題で僕が提出したコードを載せます。(家に帰ってから提出したものも含む)
A問題
1..length(S)
を出力します。
Perl6 16B
put 1..get.chars
length(S)=get.chars
です。これは改行区切りではなく空白区切りになりますが通ります。
Bash 16B
read s;seq ${#s}
length(S)=${#s}
です。
最短はRuby 15Bでした。負け
B問題
floor(sqrt(N))
を出力します。
Awk 13B
$0=int($0^.5)
まあ……
Perl 13B
print<>**.5|0
bit演算をすると非負整数型にキャストされます。
C問題
N mod 11
を出力します。
Awk 6B
$0%=11
N mod 11=0
のときこのコードは出力を行わずWAになりますが、そのようなケースは存在しないので通ります。
D問題
10^(N-1)
を出力します。
Perl 15B
print+1,0 x~-<>
1
の後に続けて0
をN-1
回繰り返した文字列を出力します。
Perl6で10^(N-1)
をするとTLEしました。
E問題
FizzBuzzっぽいことをします。詳しくは問題文を見てください。
Perl6 46B
(.++;say chrs(95 X+grep $_%%*,2..6)||$_)xx get
.++;say chrs(95 X+grep $_%%*,2..6)||$_
をget
回繰り返します。ループです。
まず.++
で$_
をインクリメントします。ループ変数です。
grep $_%%*,2..6
で2..6
のうち$_
を割り切る数だけを抜き出し、95 X+
でそれぞれに95
を加えます。出力すべき文字コードのリストになります。
chrs
に適用して文字コードに対応した文字列を得ます。空文字列だった場合はchrs()||$_
の右辺が評価され、$_
になります。
それを出力すればよいです。
Perl 53B
$i=//,print+(@a=grep$'%++$i<1,a..e)?@a:$',$/for 1..<>
後置forでループします。
//
は$_
とマッチングを試します。空文字列はいかなる文字列にもマッチするので、1
が返り、$i
に代入されます。
副作用として、$'
にマッチングした位置より後ろの文字列が代入されます。//
は文字列の先頭にマッチするはずなので、$' eq $_
が成り立ちます。
grep$'%++$i<1,a..e
で、a..e
のうち出力するべき文字を抜き出しています。
各ループで$i
はインクリメントされ、$i
は事前に1
に初期化されているので、a
には2
、b
には3
……とうまく対応できています。
こうして得られたリストを@a
に代入します。
三項演算子によって、@a
が空でなかった場合@a
が、空であれば$'
がprint
関数に渡され、$/
とともに出力されます。
このコードは%20さんによって52Bに縮められました。
F問題
N+1
項のコラッツ数列を作り出す10^16
未満の初期値を出力します。
Perl6 53B
(1789997546303,{$_%2??$_*3+1!!$_/2}...1)[1e3-get].say
N=1000
のときの答えを初期値にしてコラッツ数列を作り、第1001-N
項を出力します。
{$_%2??$_*3+1!!$_/2}
は数列を作る漸化式で、これと初項をもとに数列を作成できます。
1789997546303
を初期値にすると、最大値が10^16
未満であるコラッツ数列が得られるので、これを初項にすればよいです。
実は初期値は1412987847
でもよく、これを利用したriantkbさんによって50Bに縮められました。