diff options
| author | nsfisis <nsfisis@gmail.com> | 2025-04-16 03:28:54 +0900 |
|---|---|---|
| committer | nsfisis <nsfisis@gmail.com> | 2025-04-16 03:28:54 +0900 |
| commit | 52c3d0499e3fbf4930034ab452af3f562f5672ed (patch) | |
| tree | d3c165f9362b9c6768b4c1af0fd4e6f1b5951015 /1-sliding-puzzle | |
| parent | 0d39bfde42901478e8ca5e22b146263b94658a5f (diff) | |
| download | trick-2025-main.tar.gz trick-2025-main.tar.zst trick-2025-main.zip | |
Diffstat (limited to '1-sliding-puzzle')
| -rw-r--r-- | 1-sliding-puzzle/authors.markdown | 3 | ||||
| -rw-r--r-- | 1-sliding-puzzle/entry.pretty.rb | 80 | ||||
| -rw-r--r-- | 1-sliding-puzzle/entry.rb | 44 | ||||
| -rw-r--r-- | 1-sliding-puzzle/remarks.markdown | 90 |
4 files changed, 217 insertions, 0 deletions
diff --git a/1-sliding-puzzle/authors.markdown b/1-sliding-puzzle/authors.markdown new file mode 100644 index 0000000..f308e56 --- /dev/null +++ b/1-sliding-puzzle/authors.markdown @@ -0,0 +1,3 @@ +* Kensuke Imamura (@nsfisis) + * nsfisis@gmail.com + * cctld: jp diff --git a/1-sliding-puzzle/entry.pretty.rb b/1-sliding-puzzle/entry.pretty.rb new file mode 100644 index 0000000..80e493e --- /dev/null +++ b/1-sliding-puzzle/entry.pretty.rb @@ -0,0 +1,80 @@ +$b = 'bcdefghia'; +eval($s=' +t = { + h: [1, 0], + j: [0, -1], + k: [0, 1], + l: [-1, 0], + i: [0, 0] +}; +p = -> a, b { + i = $b.index(?a); + x = i % 3 + a; + y = i / 3 + b; + (x < 0 || 2 < x || y < 0 || 2 < y) || + ($b[j = y * 3 + x], $b[i] = $b[i], $b[j]) +}; +i = (o = :"#{$*[0]}") == :i; +while (o != :q); + if (q = t[o]); + p[*q]; + else; + (o = o.to_s.to_i) > 0 && ( + srand(o); + a = b = n = 45; + (p[*(a, b = (t.values - [[-a, -b], [0, 0]]).sample)] && n -= 1) while (n > 0); + ); + end; + print("$b=\47#$b\47;eval($s=\47"); + n = "1111141424414143341142414424344111143434".scan(/.{,5}/); + m = "000001100101111".scan(/.{,3}/); + s = 0; + b = -> _ = 1 {_.times{print($s[(s += 1) - 1])}}; + w = -> _ = 13 {print "\40" * _}; + b[22]; + puts; + 3.times {|y| + b[45]; + puts; + b[2]; + w[]; + b[]; + w[]; + b[]; + w[]; + b[2]; + puts; + 10.times {|l| + b[2]; + 3.times {|x| + w[2]; + $b[y * 3 + x] == ?a ? ( + (l == 3 && !print("\40\40\124\122\111\103\113\40\40")) || + (l == 5 && !print("\105\120\111\123\117\104\105\40\111")) || + w[9] + ) : + m[n[$b[y * 3 + x].ord - 98][l / 2].to_i].chars{(_1 == ?1 ? b : w)[3]}; + w[2]; + b[x / 2 + 1] + }; + puts + }; + b[2]; + w[]; + b[]; + w[]; + b[]; + w[]; + b[2]; + puts; + b[45]; + puts + }; + b[9]; + puts("\47.gsub(/[[:space:][:upper:]]/,%%%));"); + i || + break; + print("\12enter\40[hjkl]\40or\40[q]uit\40>\40"); + o = :"#{$stdin.gets.chomp}"; + puts; +end'.gsub(/[[:space:][:upper:]]/,%%%)); diff --git a/1-sliding-puzzle/entry.rb b/1-sliding-puzzle/entry.rb new file mode 100644 index 0000000..2f3f31e --- /dev/null +++ b/1-sliding-puzzle/entry.rb @@ -0,0 +1,44 @@ +$b='bcdefghia';eval($s='t={h:[1,0],j:[0,-1],k: +[0,1],l:[-1,0],i:[0,0]};p=->a,b{i=$b.index(?a +); x = i% +3+ a;y = i/3+b;(x< 0 ||2<x||y< 0| +|2 <y) | |($b[j=y* 3 +x],$b[i] =$ +b[ i], $ b[j ] )}; i= +(o =:" # {$* [ 0]} ") +== :i; w hile(o!=: q );if(q=t[ o] +); p[* q ];else;(o = o.to_s.to _i +)> 0&& ( sra n d(o ); +a= b=n = 45; ( p[* (a +,b =(t . values-[[ - a,-b],[0, 0] +]) .sa m ple)]&&n- = 1)while(n >0 +); ) ; en +d;print("$b=\47#$b\47;eval($s=\47");n="111114 +1424414143341142414424344111143434".scan(/.{, +5} / ) ;m +=" 000 001 1 00101111" . scan(/.{, 3} +/) ;s= 0;b = ->_=1{_.t i mes{print ($ +s[ (s+ =1) - 1]) } };w =- +>_ =13 {pr i nt" \ 40" *_ +}; b[22];put s ;3.times{ | y|b[45];p ut +s; b[2];w[]; b [];w[];b[ ] ;w[];b[2] ;p +ut s;1 0 .ti m es{ |l| b[ +2] ;3. t ime s {|x |w[ 2] +;$ b[y * 3+x]==?a? ( (l==3&&!p ri +nt ("\ 4 0\40\124\ 1 22\111\10 3\ +11 3 \ 40 +\40"))||(l==5&&!print("\105\120\111\123\117\1 +04\105\40\111"))||w[9]):m[n[$b[y*3+x].ord-98] +[l / 2 ]. +to _i].chars { (_1==?1?b : w) +[3 ]};w[2];b [ x/2+1]};p u ts +}; b[2 ] ;w[ ];b [ ]; +w[ ];b [ ];w []; b TRICK [2 +]; put s ;b[45];pu t s} +;b [9] ; puts("\47 . EPISODE I gs +ub (/[ [ :sp ace : ][ +:u ppe r :]] /,% % %) +); "); i ||break;p r in +t( "\1 2 enter\40[ h jk +l] \ 4 0o +r\40[q]uit\40>\40");o=:"#{$stdin.gets.chomp}" +;puts;end'.gsub(/[[:space:][:upper:]]/,%%%)); diff --git a/1-sliding-puzzle/remarks.markdown b/1-sliding-puzzle/remarks.markdown new file mode 100644 index 0000000..c5bb8ae --- /dev/null +++ b/1-sliding-puzzle/remarks.markdown @@ -0,0 +1,90 @@ +# 3x3 Sliding Puzzle Quine + + + +## Remarks + +This is a quine-like program. + +When run without arguments, it outputs `entry.rb` itself: + +``` +$ ruby entry.rb +$ ruby entry.rb | ruby +$ ruby entry.rb | ruby | ruby +``` + +It has been tested with the following environment: + +``` +$ ruby --version +ruby 3.4.1 (2024-12-25 revision 48d4efcb85) +PRISM [x86_64-linux] +``` + + + +## Description + +This program is not only a quine but also a 3x3 sliding puzzle. + + +### How to Play + +You can move a tile adjacent to the empty slot using `h` (left), `j` (down), `k` (up), `l` (right). +For example: + +``` +$ ruby entry.rb l +``` + +This command moves `8` to right. +Of course, the output source code is still a quine. These two commands' output are identical: + +``` +$ ruby entry.rb l +$ ruby entry.rb l | ruby +``` + + +### How to Shuffle + +You can shuffle the board by passing a seed as an argument: + +``` +$ ruby entry.rb 2025 +``` + +The output puzzle can be solved using the following move sequence: + +``` +$ ruby entry.rb 2025 | \ + ruby - k | ruby - l | ruby - k | ruby - j | ruby - h | \ + ruby - j | ruby - l | ruby - k | ruby - h | ruby - j | \ + ruby - h | ruby - l | ruby - k | ruby - k | ruby - l | \ + ruby - j | ruby - h | ruby - h | ruby - k | ruby - j | \ + ruby - l | ruby - l | ruby - k | ruby - h | ruby - h > solved.rb +$ diff entry.rb solved.rb +``` + + +### Interactive mode + +In addition, it supports interactive mode. Simply run: + +``` +$ ruby entry.rb i +``` + +It will display the current board and ask for your next move. +You can exit by typing `q` in interactive mode. + + + +## Internals + +* `entry.pretty.rb` is a human-readable version. +* `$b` represents the board's current state. +* `$s` is the program's own source code for quine generation. It contains no "padding" characters, such as unnecessary parentheses, semicolons, or comments. +* Font data is encoded in the variables `n` and `m`. +* The string "TRICK EPISODE I" shown in the empty slot is removed using `gsub(/[[:upper:]]/)`. This works because there are no uppercase letters in `$s` except for that. +* The size of the `entry.rb` is 2025 byte. |
