Skip to content

Instantly share code, notes, and snippets.

@n4o847
Created June 22, 2019 02:49
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save n4o847/310f9285376fec7ad5c4cdfc5b04c428 to your computer and use it in GitHub Desktop.
Save n4o847/310f9285376fec7ad5c4cdfc5b04c428 to your computer and use it in GitHub Desktop.
class Hanoi
STACK = { :A => 0, :B => 1, :C => 2 }
BYTES = { :u8 => 0, :u16 => 1, :u32 => 2, :u64 => 3 }
def pair(x, y)
a, b = STACK[x], STACK[y]
raise "" if a == b
b -= 1 if a < b
[a, b]
end
{
:add => 0b000,
:sub => 0b001,
:mul => 0b010,
:div => 0b011,
:mod => 0b100,
:or => 0b101,
:and => 0b110,
:xor => 0b111,
}.each do |name, xxx|
define_method(name) do |from, to, size = :u8|
yy, z = pair(from, to)
nn = BYTES[size]
@out << "001%03b%02b%01b%02b00000" % [xxx, yy, z, nn]
@ip += 1
end
end
def copy(from, to, size = :u8)
xx, y = pair(from, to)
nn = BYTES[size]
@out << "0001%02b%01b%02b0000000" % [xx, y, nn]
@ip += 1
end
def push(st, vvvvvvvv)
xx = STACK[st]
@out << "01%02b%08b0000" % [xx, vvvvvvvv]
@ip += 1
end
def print(st)
xx = STACK[st]
@out << "00001%02b000000000" % [xx]
@ip += 1
end
def pop(st, size = :u8)
xx = STACK[st]
nn = BYTES[size]
@out << "000000%02b%02b000000" % [xx, nn]
@ip += 1
end
def goto(name)
@ip += 1
@out << [name, @ip]
end
# def jmp(s, vvvvvvvvvvvvvv)
# @out << "1%01b%014b" % [s, vvvvvvvvvvvvvv]
# end
def iszero(st, size = :u8)
xx = STACK[st]
nn = BYTES[size]
@out << "000001%02b%02b000000" % [xx, nn]
@ip += 1
end
def label(name)
@labels[name] = @ip
end
def exec(&block)
@out = []
@ip = 0
@labels = {}
instance_eval(&block)
data = @out.map {|op|
if op.is_a?(Array)
name, from = op
to = @labels[name]
s = to - from < 0 ? 1 : 0
vvvvvvvvvvvvvv = (to - from).abs
op = "1%01b%014b" % [s, vvvvvvvvvvvvvv]
end
op.to_i(2)
}.pack("S<*")
File.write("./hanoi.txt", data)
puts "done: #{data.size} bytes"
end
end
Hanoi.new.exec do
pop :A, :u32 # [ 0 .. N | | ]
push :B, 50 # [ 0 .. N | 51 | ]
label :L5
push :C, 84 # [ 0 .. N | x | 85 ]
sub :C, :A # [ 0 .. N | x (N-85) | 85 ]
pop :C # [ 0 .. N | x (N-85) | ]
iszero :B
goto :L1
label :L2
pop :B # [ 0 .. T | x | ]
push :C, 32
print :C
pop :C
push :C, 1 # [ 0 .. T | x | 1 ]
sub :B, :C # [ 0 .. T (x-1) | x | 1 ]
pop :C # [ 0 .. T (x-1) | x | ]
pop :B # [ 0 .. T (x-1) | | ]
copy :A, :B # [ 0 .. T (x-1) | (x-1) | ]
copy :A, :B # [ 0 .. T (x-1) | (x-1) (x-1) | ]
pop :A # [ 0 .. T | (x-1) (x-1) | ]
iszero :B
goto :L2
goto :L3
label :L1
pop :B # [ 0 .. N | x | ]
push :C, 1 # [ 0 .. N | x | 1 ]
sub :B, :C # [ 0 .. N (x-1) | x | 1 ]
pop :C # [ 0 .. N (x-1) | x | ]
pop :B # [ 0 .. N (x-1) | | ]
copy :A, :B # [ 0 .. N (x-1) | (x-1) | ]
pop :A # [ 0 .. N | (x-1) | ]
iszero :B
goto :L4
pop :B
push :B, 51 # [ 0 .. N | 51 | ]
label :L4
copy :A, :C # [ 0 .. N | (x-1) | N ]
pop :A # [ 0 .. N-1 | (x-1) | N ]
goto :L5
label :L3
pop :B # [ 0 .. T | 0 | ]
pop :B
push :B, 51 # [ .. N | 51 | .. M ]
push :B, 0
label :L6
pop :B
iszero :B
goto :L7
pop :A
push :A, 35
pop :B
push :B, 51
label :L7
print :A
copy :C, :A # [ .. N M | 51 | .. M ]
pop :C # [ .. M | 51 | .. L ]
push :C, 1 # [ .. M | x | .. L 1 ]
sub :B, :C # [ .. M (x-1) | x | .. L 1 ]
pop :C # [ .. M (x-1) | x | .. L ]
pop :B # [ .. M (x-1) | | .. L ]
copy :A, :B # [ .. M (x-1) | (x-1) | .. L ]
pop :A # [ .. M | (x-1) | .. L ]
push :C, 75 # [ .. M | (x-1) | .. L 75 ]
sub :C, :A # [ .. M | (x-1) (M-75) | .. L 75 ]
pop :C # [ .. M | (x-1) (M-75) | .. L ]
iszero :B
goto :L6
pop :B
print :A
label :L8
print :A
push :C, 1
sub :B, :C
pop :C
pop :B
copy :A, :B
pop :A
iszero :B
goto :L8
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment