aboutsummaryrefslogtreecommitdiffhomepage
path: root/1-sliding-puzzle
diff options
context:
space:
mode:
Diffstat (limited to '1-sliding-puzzle')
-rw-r--r--1-sliding-puzzle/authors.markdown3
-rw-r--r--1-sliding-puzzle/entry.pretty.rb80
-rw-r--r--1-sliding-puzzle/entry.rb44
-rw-r--r--1-sliding-puzzle/remarks.markdown90
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.