15quzzle.rb

15 パズルを quine で作ってみました。

eval((%w[a=0;loop{a=(0..15).sort_by{rand};b=a.reverse;b=a[0,4]+b[8,4]+a
[8,4]+b[0,4];n=0;16.times{|i|b[i]>0&&(0..i).map{|j|b[j]>b[i]&&n+=1}};n%
2>0&&break;};eval$s="b=0x#{a.map{|n|"%x"%n}.join}"+%w[;i=(m=0..15).find
{|i|1>b&m=15<<4*i};t=m|n=m<<4*o=("AdABrBlBAuA"=~/(.)#{ARGV*''}\1/||04||
0)-4;(  n<1       ||n>1<<64||[255<<12]&[t>>040||0,t>>16,  t]!=[])?t=0:i
+=o;; ## s ####### ="eval$s=%%w[b=0x%016x"%(b^=t.&b|m&b ## >>o*4)+$s.gs
ub(/ ### ( ##     \|_+\d+)+/,'')[/;.*/]+"]*''||0"<<92|| ## 1;z=s=s.scan
(/. #### { ##    13}/);3.times{|j|s[(i||0)/4*8+i+j*4,0] ## =m=(z=32.chr
)*13  ## } ###### ;c=b   ;  4.t  ime  s       {       p ## ut    s((0..
3.tim ## e ##   ## s{ ### ## p ## u ## ####### #######  ## t #### s((s.
slice ## !(  0, ## 4 ##  ### ) ## * ##     ## z    ## ) ##  ##  ## .rst
rip)} ## ).map{ ## j ## = ## c ## % ## 16 ## ;c/= ## 16 ## ##    ## ;;(
0||0) ## <(  j) ## ? ## " ## | ## " ## + ## j.to ## _s. ## ######## rju
st(12 ## , ## " ## _ ## " ## ) ## : ##  ## m}*( ## z||0 ## ##      ),z)
};b== ## 0 ##   ## x ##  ### f ##  ### ##      ##     e ##  ##   ## dcb
a9876 ## 54 ##### 321 ### ## && ### ## ####### #######  ## ( ##### "%b"
%"1tv7  c1th     0wyle    ## l73   b  a       3       5k  nw3     t".to
_i(36)).tr("01",".#").sca ## n(/.{25}/){puts$&}]*'';puts("$!Jotusvdujpo
;++$!tivggmf;+$!%!svcz!26r  v{{mf/sc!?!26r/sc++$!npwf!vq;+$!%!svcz!26r/
sc!v++$!npwf!epxo;+$!%!svcz!26r/sc!v!}!svcz!.!e++$!npwf!mfgu;+$!%!svcz!
26r/sc!v!}!svcz!.!e!}!svcz!.!m++$!npwf!sjhiu;+$!%!svcz!26r/sc!v!}!svcz!
.!e!}!svcz!.!m!}!svcz!.!s++$!)d*!Z/Foepi!311:+".unpack("C*").map{|x|x-1
}.pack("C*").tr("*","\n"))]*'').gsub(/\#{2,}/,'')) #.. (c) Y.Endoh 2009

実行すると、こんな感じのコードで書かれた盤面が出ます。

eval$s=%w[b=0 xb7cf59ea068d 1324;i=(m=0.. 15).find{|i|1
>b&m=15<<4*i} ;t=m|n=m<<4*o =("AdABrBlBAu A"=~/(.)#{ARG
V*''}\1/||04| |0)-4;(n<1||n >1<<64||[255< <12]&[t>>040|
|___________4 |___________2 |___________3 |___________1

|0,t>>16,t]!= [])?t=0:i+=o; ;s="eval$s=%%
w[b=0x%016x"% (b^=t.&b|m&b> >o*4)+$s.gsub
(/(\|_+\d+)+/ ,'')[/;.*/]+" ]*''||0"<<92|
|__________13 |___________8 |___________6

|1;z=s=s.scan (/.{13}/);3.t imes{|j|s[(i| |0)/4*8+i+j*4
,0]=m=(z=32.c hr)*13};c=b;4 .times{puts(( 0..3.times{pu
ts((s.slice!( 0,4)*z).rstri p)}).map{j=c% 16;c/=16;;(0|
|__________10 |__________14 |___________9 |___________5

|0)<(j)?"|"+j .to_s.rjust(1 2,"_"):m}*(z| |0),z)};b==0x
fedcba9876543 21&&("%b"%"1t v7c1th0wylel7 3ba35knw3t".t
o_i(36)).tr(" 01",".#").sca n(/.{25}/){pu ts$&}]*''||0\
|__________15 |__________12 |___________7 |__________11

パネルをひとつ右に動かしてみる。

$ ruby 15q.rb r
eval$s=%w[b=0 xb7cf59ea608d 1324;i=(m=0.. 15).find{|i|1
>b&m=15<<4*i} ;t=m|n=m<<4*o =("AdABrBlBAu A"=~/(.)#{ARG
V*''}\1/||04| |0)-4;(n<1||n >1<<64||[255< <12]&[t>>040|
|___________4 |___________2 |___________3 |___________1

|0,t>>16,t]!= [])?t=0:i+=o;               ;s="eval$s=%%
w[b=0x%016x"% (b^=t.&b|m&b>               >o*4)+$s.gsub
(/(\|_+\d+)+/ ,'')[/;.*/]+"               ]*''||0"<<92|
|__________13 |___________8               |___________6

|1;z=s=s.scan (/.{13}/);3.t imes{|j|s[(i| |0)/4*8+i+j*4
,0]=m=(z=32.c hr)*13};c=b;4 .times{puts(( 0..3.times{pu
ts((s.slice!( 0,4)*z).rstri p)}).map{j=c% 16;c/=16;;(0|
|__________10 |__________14 |___________9 |___________5

|0)<(j)?"|"+j .to_s.rjust(1 2,"_"):m}*(z| |0),z)};b==0x
fedcba9876543 21&&("%b"%"1t v7c1th0wylel7 3ba35knw3t".t
o_i(36)).tr(" 01",".#").sca n(/.{25}/){pu ts$&}]*''||0\
|__________15 |__________12 |___________7 |__________11

もうひとつ右に。

$ ruby 15q.rb r | ruby - r
eval$s=%w[b=0 xb7cf59ea680d 1324;i=(m=0.. 15).find{|i|1
>b&m=15<<4*i} ;t=m|n=m<<4*o =("AdABrBlBAu A"=~/(.)#{ARG
V*''}\1/||04| |0)-4;(n<1||n >1<<64||[255< <12]&[t>>040|
|___________4 |___________2 |___________3 |___________1

|0,t>>16,t]!=               [])?t=0:i+=o; ;s="eval$s=%%
w[b=0x%016x"%               (b^=t.&b|m&b> >o*4)+$s.gsub
(/(\|_+\d+)+/               ,'')[/;.*/]+" ]*''||0"<<92|
|__________13               |___________8 |___________6

|1;z=s=s.scan (/.{13}/);3.t imes{|j|s[(i| |0)/4*8+i+j*4
,0]=m=(z=32.c hr)*13};c=b;4 .times{puts(( 0..3.times{pu
ts((s.slice!( 0,4)*z).rstri p)}).map{j=c% 16;c/=16;;(0|
|__________10 |__________14 |___________9 |___________5

|0)<(j)?"|"+j .to_s.rjust(1 2,"_"):m}*(z| |0),z)};b==0x
fedcba9876543 21&&("%b"%"1t v7c1th0wylel7 3ba35knw3t".t
o_i(36)).tr(" 01",".#").sca n(/.{25}/){pu ts$&}]*''||0\
|__________15 |__________12 |___________7 |__________11

今度は上に。

$ ruby 15q.rb r | ruby - r | ruby - u
eval$s=%w[b=0 xb7cf590a68ed 1324;i=(m=0.. 15).find{|i|1
>b&m=15<<4*i} ;t=m|n=m<<4*o =("AdABrBlBAu A"=~/(.)#{ARG
V*''}\1/||04| |0)-4;(n<1||n >1<<64||[255< <12]&[t>>040|
|___________4 |___________2 |___________3 |___________1

|0,t>>16,t]!= [])?t=0:i+=o; ;s="eval$s=%% w[b=0x%016x"%
(b^=t.&b|m&b> >o*4)+$s.gsub (/(\|_+\d+)+/ ,'')[/;.*/]+"
]*''||0"<<92| |1;z=s=s.scan (/.{13}/);3.t imes{|j|s[(i|
|__________13 |__________14 |___________8 |___________6

|0)/4*8+i+j*4               ,0]=m=(z=32.c hr)*13};c=b;4
.times{puts((               0..3.times{pu ts((s.slice!(
0,4)*z).rstri               p)}).map{j=c% 16;c/=16;;(0|
|__________10               |___________9 |___________5

|0)<(j)?"|"+j .to_s.rjust(1 2,"_"):m}*(z| |0),z)};b==0x
fedcba9876543 21&&("%b"%"1t v7c1th0wylel7 3ba35knw3t".t
o_i(36)).tr(" 01",".#").sca n(/.{25}/){pu ts$&}]*''||0\
|__________15 |__________12 |___________7 |__________11

こんな感じで全部の数字を左上からそろえてください。


quineclock より地味だけど、quineclock の 10 倍は難し面白かった。|| のショートカットでパネル番号の行を華麗にスキップするとことか気持ちいい。あと不正なムーブをはじくのと、転倒数の計算のバグに地味に苦労した。ゴルフ力が足りなくてパネルが横長になったのが少し悔しい。特にビット演算力が足りないと思う。