Skip to content

Instantly share code, notes, and snippets.

@n4o847
Created May 7, 2020 05:48
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/c66df01e6dc22419176791fd6f7145f3 to your computer and use it in GitHub Desktop.
Save n4o847/c66df01e6dc22419176791fd6f7145f3 to your computer and use it in GitHub Desktop.
第6回東大京大コードゴルフ大会
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.out", data)
puts "done: #{data.size} bytes"
end
end
Hanoi.new.exec do
pop :A, :u32
32.times do |i|
pop :A
pop :A
copy :A, :B
pop :A
xor :A, :B
pop :B
iszero :C
goto [:L1, i]
pop :C
copy :A, :C
pop :A
pop :A
goto [:L2, i]
label [:L1, i]
pop :A
pop :A
pop :C
copy :A, :C
label [:L2, i]
pop :A
pop :A
pop :A
end
32.times do
print :C
pop :C
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment