diff --git a/.gitignore b/.gitignore index 9bcfa63..24b64db 100644 --- a/.gitignore +++ b/.gitignore @@ -1 +1,2 @@ /challenge.bin +/dumps diff --git a/README.md b/README.md index 7e0cdd6..a3fd7cd 100644 --- a/README.md +++ b/README.md @@ -1,3 +1,23 @@ # synacor.py My sort-of-OOP, ~~poorly-documented~~concise response to the Synacor challenge + +## Debug commands + +At any time the program is waiting for input, a string of the following form may be input: + + . + +This will execute the file `.py` with `dbg_args[0]` set to `` and `` stored in `dbg_args[1..n]`. + +For example, the self-test and decryption at the beginning of the program takes a comparatively long time. To save the state to the `dumps/init` file, enter: + + .dbg_dump dumps/init + +Similarly, debug commands may be passed as command-line arguments to `synacor.py` in the form: + + ./synacor.py + +For example, to load the `dumps/init` state to skip the self-test and decryption, run: + + ./synacor.py dbg_load dumps/init diff --git a/dbg_dump.py b/dbg_dump.py new file mode 100644 index 0000000..89acbb2 --- /dev/null +++ b/dbg_dump.py @@ -0,0 +1,30 @@ +# synacor.py - An implementation of the Synacor Challenge +# Copyright © 2016 RunasSudo +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU Affero General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Affero General Public License for more details. +# +# You should have received a copy of the GNU Affero General Public License +# along with this program. If not, see . + +import pickle + +if len(dbg_args) < 2: + print('Usage: .{} '.format(dbg_args[0])) +else: + model = { + 'SYN_PTR': SYN_PTR, + 'SYN_MEM': SYN_MEM, + 'SYN_REG': SYN_REG, + 'SYN_STK': SYN_STK + } + + with open(dbg_args[1], 'wb') as f: + pickle.dump(model, f) diff --git a/dbg_load.py b/dbg_load.py new file mode 100644 index 0000000..0e46501 --- /dev/null +++ b/dbg_load.py @@ -0,0 +1,28 @@ +# synacor.py - An implementation of the Synacor Challenge +# Copyright © 2016 RunasSudo +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU Affero General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Affero General Public License for more details. +# +# You should have received a copy of the GNU Affero General Public License +# along with this program. If not, see . + +import pickle + +if len(dbg_args) < 2: + print('Usage: {} {} '.format(sys.argv[0], dbg_args[0])) +else: + with open(dbg_args[1], 'rb') as f: + model = pickle.load(f) + + SYN_PTR = model['SYN_PTR'] + SYN_MEM = model['SYN_MEM'] + SYN_REG = model['SYN_REG'] + SYN_STK = model['SYN_STK'] diff --git a/synacor.py b/synacor.py index 074768b..c329c93 100755 --- a/synacor.py +++ b/synacor.py @@ -22,6 +22,7 @@ SYN_PTR = 0 SYN_MEM = [0] * 32768 SYN_REG = [0] * 8 SYN_STK = [] +SYN_STDIN_BUF = [] class OpLiteral: def __init__(self, value): @@ -52,16 +53,20 @@ def swallowOp(): SYN_PTR += 1 return op -# Read code into memory -with open('challenge.bin', 'rb') as data: - while True: - byteData = data.read(2) - if len(byteData) < 2: - break - SYN_MEM[SYN_PTR] = struct.unpack(' 1: + dbg_args = sys.argv[1:] + with open(dbg_args[0] + '.py', 'r') as f: + exec(f.read(), globals(), locals()) +else: + # Read code into memory + with open('challenge.bin', 'rb') as data: + while True: + byteData = data.read(2) + if len(byteData) < 2: + break + SYN_MEM[SYN_PTR] = struct.unpack('