Skip to content

Instantly share code, notes, and snippets.

@bgnori
Created July 3, 2017 07:09
Show Gist options
  • Save bgnori/c8beb6904cdbabd9e605e9af231dee55 to your computer and use it in GitHub Desktop.
Save bgnori/c8beb6904cdbabd9e605e9af231dee55 to your computer and use it in GitHub Desktop.
ヒューマンリソースマシーン Year 10までなんとなく検証(入力がわからないので)
import io
from enum import Enum, auto
class Inst(Enum):
inbox = auto()
outbox = auto()
d_copyfrom = auto()
i_copyfrom = auto()
d_copyto = auto()
i_copyto = auto()
d_add = auto()
i_add = auto()
d_sub = auto()
i_sub = auto()
d_bumpp = auto()
i_bumpp = auto()
d_bumpm = auto()
i_bumpm = auto()
jump = auto()
jump_if_zero = auto()
jump_if_neg = auto()
nop = auto()
DEBUG = True
def assemble(f):
d = {}
for inst in Inst:
d[inst.name] = inst
code = []
for line in f:
i, p = line.split()[:2]
code.append((d[i], p))
return code
def loadbox(f):
xs = []
for line in f:
xs.extend(line.split())
return xs
class Machine:
def __init__(self, inbox, code, carpet, expected):
self.inbox = inbox
self.outbox = []
self.carpet = carpet
self.code = code
self.expected = expected
self.reg = None
self.pc = 0
def is_done(self):
for i, out in enumerate(self.outbox):
if out != self.expected[i]:
raise
else:
if len(self.outbox) == len(self.expected):
return True
return False
def run(self):
while not self.is_done():
inst, param = self.code[self.pc]
if DEBUG:
print(self.pc, inst, param)
got = self.evalone(inst, param)
if DEBUG:
print("--->", got)
self.pc += 1
def evalone(self, inst, param):
f = getattr(self, "do_"+inst.name)
return f(param)
def do_nop(self, param):
pass
def do_inbox(self, param):
self.reg = self.inbox.pop()
return self.reg
def do_outbox(self, param):
self.outbox.append(self.reg)
return self.reg
def do_nop(self, param):
return None
def do_d_copyfrom(self, param):
self.reg = self.carpet[int(param)]
return self.reg
def do_i_copyfrom(self, param):
self.reg = self.carpet[self.carpet[int(param)]]
return self.reg
def do_d_copyto(self, param):
self.carpet[int(param)] = self.reg
return self.reg
def do_i_copyto(self, param):
self.carpet[self.carpet[int(param)]] = self.reg
return self.reg
def do_d_add(self, param):
self.reg = "{0}".format(int(self.reg) + int(self.carpet[int(param)]))
return self.reg
def do_i_add(self, param):
self.reg = "{0}".format(int(self.reg) + int(self.carpet[self.carpet[int(param)]]))
return self.reg
def do_d_sub(self, param):
self.reg = "{0}".format(int(self.reg) + int(self.carpet[int(param)]))
return self.reg
def do_i_sub(self, param):
self.reg = "{0}".format(int(self.reg) + int(self.carpet[self.carpet[int(param)]]))
return self.reg
def do_d_bumpp(self, param):
self.carpet[int(param)] +=1
return self.carpet[int(param)]
def do_i_bumpp(self, param):
self.carpet[self.carpet[int(param)]] +=1
return self.carpet[self.carpet[int(param)]]
def do_d_bumpm(self, param):
self.carpet[int(param)] -=1
return self.carpet[int(param)]
def do_i_bumpm(self, param):
self.carpet[self.carpet[int(param)]] -=1
return self.carpet[self.carpet[int(param)]]
def do_jump(self, param):
self.pc = int(param)
return self.pc
def do_jump_if_zero(self, param):
try:
if int(self.reg) == 0:
self.pc = int(param)
return self.pc
except ValueError:
return self.pc
def do_jump_if_neg(self, param):
if int(self.reg) < 0:
self.pc = int(param)
return self.pc
if __name__ == "__main__":
import argparse
parser = argparse.ArgumentParser()
parser.add_argument("inbox", type=argparse.FileType('r'))
parser.add_argument("code", type=argparse.FileType('r'))
parser.add_argument("expected", type=argparse.FileType('r'))
parser.add_argument("--carpet", type=argparse.FileType('r'))
arg = parser.parse_args()
inbox = loadbox(arg.inbox)
code = assemble(arg.code)
expected = loadbox(arg.expected)
if arg.carpet:
carpet = { i: v for i,v in enumerate(loadbox(arg.carpet))}
else:
carpet = {}
m = Machine(inbox, code, carpet, expected)
print(code)
print(m.inbox, m.outbox)
m.run()
print(m.inbox, m.outbox)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment