2009-08-03
asunderが短くできない
最初に考えたのが、入力を一気に繋げて文字列でとって、それぞれの文字の数を正規表現で求める、というもの。
$/=0,$a=<>;printf"$_:%3d ",''.(@a=$a=~/$_/g)for A..Z,a..z
57B。
正規表現のマッチの結果をリストコンテキストで取得してからスカラーコンテキストにして、…となんだかゴチャゴチャしてしまう。
で、やり方を変えてみたのが、各行毎でそれぞれの文字数をカウントアップしていって、そのデータを使って出力する、というもの。
s/./$a{$&}++/gefor<>;printf"$_:%3d ",$a{$_}for A..Z,a..z
56Bになった。
でも現在Perlのトップは、51B。まだまだ全然長過ぎる。。。orz
後者のやり方はあんまり短くできなそう。前者の方を頑張れば短く出来そうな気がする。
何とか自分で考えだしたいところ。そもそも全然知らない文法が必要なのかもしれないけども。
2009-07-24
Decompose integer into sum of squaresの件
anarchy golf - Decompose integer into sum of squares
anarchy golf の出題ミス? - TAKESAKOのはてな出張所
どうやら間違っていたらしく。全然気付かずにゴチャゴチャと書いたヤツが通っていたのでまったく気付きませんでした orz
たぶんこんなのを書きますた。
use List::Util 'sum';$c[sum map{$_**2}@$_]||=[grep$_,@$_]for map{@a=@$_;map[$_,@a],1..17}map{@a=@$_;map[$_,@a],0..12}map{@a=$_;map[$_,@a],0..8}0..2;print"$_: @{$c[$_]}\n"for 1..300
で、あらためて書き直してみた。
use List::Util 'sum';push@{$c[sum map$_**2,@$_]},[grep$_,@$_]for map{$a=$_;map{$b=$_;map{$c=$_;map[$a,$b,$c,$_],0..2}0..8}0..12}1..17;printf"$_: %s\n",join$",sort{$b<=>$a}@{(sort{@$a==@$b?sum(@$a)<=>sum@$b:@$a<=>@$b}@{$c[$_]})[0]}for 1..300
どっちにしても長過ぎる orz
こっちはsubmitしても通らない。
$ perl old.pl > old_output $ perl new.pl > new_output $ diff -u old_output new_output --- old_output 2009-07-24 11:25:42.000000000 +0900 +++ new_output 2009-07-24 11:26:56.000000000 +0900 @@ -60,7 +60,7 @@ 60: 7 3 1 1 61: 6 5 62: 6 5 1 -63: 6 5 1 1 +63: 7 3 2 1 64: 8 65: 8 1 66: 8 1 1 @@ -68,7 +68,7 @@ 68: 8 2 69: 8 2 1 70: 6 5 3 -71: 6 5 3 1 +71: 7 3 3 2 72: 6 6 73: 8 3 74: 7 5 @@ -126,7 +126,7 @@ 126: 11 2 1 127: 11 2 1 1 128: 8 8 -129: 8 8 1 +129: 11 2 2 130: 11 3 131: 11 3 1 132: 8 8 2 @@ -140,7 +140,7 @@ 140: 10 6 2 141: 11 4 2 142: 9 6 5 -143: 9 6 5 1 +143: 11 3 3 2 144: 12 145: 12 1 146: 11 5 @@ -153,7 +153,7 @@ 153: 12 3 154: 12 3 1 155: 11 5 3 -156: 11 5 3 1 +156: 12 2 2 2 157: 11 6 158: 11 6 1 159: 11 6 1 1 @@ -163,8 +163,8 @@ 163: 9 9 1 164: 10 8 165: 10 8 1 -166: 9 9 2 -167: 9 9 2 1 +166: 11 6 3 +167: 11 6 3 1 168: 10 8 2 169: 13 170: 13 1 @@ -179,8 +179,8 @@ 179: 13 3 1 180: 12 6 181: 10 9 -182: 10 9 1 -183: 10 9 1 1 +182: 13 3 2 +183: 13 3 2 1 184: 12 6 2 185: 13 4 186: 13 4 1 @@ -188,7 +188,7 @@ 188: 13 3 3 1 189: 13 4 2 190: 10 9 3 -191: 10 9 3 1 +191: 13 3 3 2 192: 8 8 8 193: 12 7 194: 13 5 @@ -206,7 +206,7 @@ 206: 14 3 1 207: 14 3 1 1 208: 12 8 -209: 12 8 1 +209: 14 3 2 210: 13 5 4 211: 11 9 3 212: 14 4 @@ -240,7 +240,7 @@ 240: 14 6 2 2 241: 15 4 242: 11 11 -243: 11 11 1 +243: 15 3 3 244: 12 10 245: 14 7 246: 14 7 1 @@ -294,7 +294,7 @@ 294: 17 2 1 295: 17 2 1 1 296: 14 10 -297: 14 10 1 +297: 17 2 2 298: 17 3 299: 17 3 1 300: 14 10 2
これで気付いたけど今の問題だと63とかは2通り考えられて「同じ個数、かつ合計数も同じ」というパターンが起こり得るなぁ。
実際のルールは「数字の個数が同じときは数字を降順に並べ、後ろから順に比較して小さい方を表示」ですかね
はてなブックマーク - yshlのマーキング痕
というのがやはり出題側の意図だったんだろうか?
2009-07-16
Golfにチャレンジ
golfの世界にも触れてみようと思って、チャレンジしてみた。
とりあえずこの問題を。
一晩考えてみたけど、この程度しか思いつかない ><
$c=$a,printf"A%-2d%5dmm x%5dmm ",$_,$a=$b/2||841,$b=$c||1189for 0..10
69B orz
現時点でPerlは61Bがトップ。
何かやり方が根本的に違うのかなぁ。むぅ…難しい けど面白い
追記
printf"A%-2d%5dmm x%5dmm ",$_,($a||=1682)/2,$a/=1.414for 0..10
62B! あと1歩で追いつけるぞ…
こういう反則的なやり方がGolfの技術なのかなw
追記
printf"A%-2d%5dmm x%5dmm ",$_,($a||=1683)/2,$a*=.707for 0..10
61B!! ktkr
0.707..のような少数は整数部分が0なら省略できるw
sqrt(2)/2 = 0.707106781186548だけど、3桁目までで何とかずれずに使える。
1189*sqrt(2)は1681.4999...とかでどう考えても1681か1682にすべきところを、あえて1683にすることで理想の出力が得られる。
もう一人の61BのヒトはStatisticsが違うから違うやり方なんだろうなぁ。他にどういう方法があるんだろう。。
追記
余計な演算子使わずに普通に最初に代入して使えばよかった。アホかw
追記
ちょっと変則的なカンジで60B。
printf"A%-2d%5dmm x%5dmm ",$a++,$b/2,$b*=.707for($b=1683)x11
しかし59Bは思いつかない…!!
