Created
July 3, 2017 07:09
-
-
Save bgnori/c8beb6904cdbabd9e605e9af231dee55 to your computer and use it in GitHub Desktop.
ヒューマンリソースマシーン Year 10までなんとなく検証(入力がわからないので)
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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