def solve( self, name: str, src_model: Optional[bytes], tgt_model: Optional[bytes]) -> SolverResult: if src_model is not None: Model.parse(src_model) # as a sanity check if tgt_model is not None: Model.parse(tgt_model) # as a sanity check trace_data = data_files.full_default_trace(name) return SolverResult(trace_data)
def main(): from production import data_files task_name = sys.argv[1] if len(sys.argv) > 1 else 'FA001' data_src, data_tgt = data_files.full_problem(task_name) m_src = m_tgt = None if data_src is not None: m_src = Model.parse(data_src) if data_tgt is not None: m_tgt = Model.parse(data_tgt) commands = default_disassembly(m_src, m_tgt) trace = compose_commands(commands) write_solution(trace, task_name)
def solve(self, name: str, src_model: Optional[bytes], tgt_model: Optional[bytes]) -> SolverResult: m_src = m_tgt = None if src_model is not None: m_src = Model.parse(src_model) strategy = default_disassembly if tgt_model is not None: m_tgt = Model.parse(tgt_model) strategy = default_assembly if src_model is not None and tgt_model is not None: strategy = default_reassembly trace = strategy(m_src, m_tgt) trace_data = compose_commands(trace) return SolverResult(trace_data, extra={})
def test_is_inside_region(): matrix = [ # z # ----> [ [1, 0, 0], # | [0, 1, 0], # | y [0, 0, 0] ], # v # x = 0 [[0, 0, 0], [0, 1, 0], [0, 0, 0]], # x = 1 [[0, 0, 0], [1, 1, 0], [0, 0, 0]], # x = 2 ] m = Model(3) for x, slice in enumerate(matrix): for y, row in enumerate(slice): for z, cell in enumerate(row): m[Pos(x, y, z)] = bool(cell) bbox_min, bbox_max = bounding_box(m) assert is_inside_region(Pos(1, 1, 1), bbox_min, bbox_max) assert is_inside_region(Pos(2, 0, 0), bbox_min, bbox_max) assert not is_inside_region(Pos(2, 0, 3), bbox_min, bbox_max)
def solve(self, name: str, src_model: Optional[bytes], tgt_model: Optional[bytes]) -> SolverResult: assert tgt_model is None m = Model.parse(src_model) trace = cubical(m, high=self.high) trace_data = compose_commands(trace) return SolverResult(trace_data, extra={})
def default_disassembly(model_src, model_tgt=None) -> List[Command]: finish, start = bounding_box(model_src) start = Pos(finish.x, start.y, finish.z) return apply_default_strategy(model_src, Model(model_src.R), (3, -1, 1), start, False)
def solve(self, name: str, src_model: Optional[bytes], tgt_model: Optional[bytes]) -> SolverResult: assert src_model is None m = Model.parse(tgt_model) trace_data = compose_commands( solve_gen(m, self.w, self.h, low=self.low)) return SolverResult(trace_data, extra={})
def main(): from production import data_files task_number = int(sys.argv[1]) if len(sys.argv) > 1 else 1 m = Model.parse(lightning_problem_by_id(task_number)) solve(up_pass, m, task_number)
class State: # TODO: from model def __init__(self, R): self.R = R self.matrix = Model(R) self.harmonics = LOW self.energy = 0 self.bots = [Bot(1, Pos(0, 0, 0), list(range(39)))] # TODO def __setitem__(self, pos: Pos, value): assert value == 0 or value == 1 self.matrix[pos] = bool(value) def __getitem__(self, pos: Pos): return self.matrix[pos] def assert_well_formed(self): if self.harmonics == LOW: grounded = self.matrix.grounded_voxels() for p in self.enum_voxels(): if self[p] == 1: assert p in grounded bids = {bot.bid for bot in self.bots} assert len(bids) == len(self.bots), 'bids not unique' poss = {bot.pos for bot in self.bots} assert len(poss) == len(self.bots), 'positions not unique' for bot in self.bots: assert matrix[bot.pos.x][bot.pos.y][ bot.pos.z] == 0, 'bot in Full voxel' all_seeds = {seed for bot in self.bots for seed in bot.seeds} assert len(all_seeds) == sum(len(bot.seeds) for bot in self.bots) for bot in self.bots: assert bot.bid not in all_seeds def time_step(self, trace): assert len(trace) >= len(self.bots) # TODO: check preconditions # TODO: check volatile sets don't overlap if self.harmonics == HIGH: self.energy += 30 * self.R**3 elif self.harmonics == LOW: self.energy += 3 * self.R**3 else: assert False, self.harmonics self.energy += 20 * len(self.bots)
def main(): from production import data_files name = 'LA004' m = Model.parse(data_files.lightning_problem(f'{name}_tgt.mdl')) trace_name = f'{name}.nbt' trace = parse_commands(buf=data_files.lightning_default_trace(trace_name), source=trace_name) state = State(m.R) state.time_step(trace)
def solve(self, name: str, src_model: Optional[bytes], tgt_model: Optional[bytes]) -> SolverResult: assert src_model is None model = Model.parse(tgt_model) model_height = get_model_height(model) plots = create_plots(model) trace = single_bot_trace(model, model_height, plots) trace_data = compose_commands(trace) return SolverResult(trace_data, extra={})
def solve(self, name: str, src_model: Optional[bytes], tgt_model: Optional[bytes]) -> SolverResult: assert src_model is None m = Model.parse(tgt_model) try: trace_data = compose_commands(self.solve_gen(m)) return SolverResult(trace_data, extra={}) except KeyboardInterrupt: raise except: exc = StringIO() traceback.print_exc(file=exc) return SolverResult(Fail(), extra=dict(tb=exc.getvalue()))
def test_full(): assert 'FR042' in full_names() src_model, tgt_model = full_problem('FA001') assert src_model is None Model.parse(tgt_model) src_model, tgt_model = full_problem('FD001') Model.parse(src_model) assert tgt_model is None src_model, tgt_model = full_problem('FR001') Model.parse(src_model) Model.parse(tgt_model) trace = full_default_trace('FR001') parse_commands(trace, source='FR001.nbt')
def set_cpp_state(): m = Model(5) m[Pos(2, 0, 2)] = True m[Pos(2, 1, 2)] = True m[Pos(2, 2, 2)] = True m[Pos(2, 3, 2)] = True s = State(5) s.matrix = m s.harmonics = LOW s.energy = 0 s.bots = [ Bot(bid=1, pos=Pos(0, 0, 1), seeds=[]), Bot(bid=2, pos=Pos(0, 0, 2), seeds=list(range(4, 40))), Bot(bid=40, pos=Pos(1, 0, 0), seeds=[]) ] return state_to_cpp(s)
def test_projection_top(): matrix = [ # z # ----> [ [1, 0, 0], # | [0, 1, 0], # | y [0, 0, 0] ], # v # x = 0 [[0, 0, 0], [0, 1, 0], [0, 0, 0]], # x = 1 [[0, 0, 0], [1, 1, 0], [0, 0, 0]], # x = 2 ] m = Model(3) for x, slice in enumerate(matrix): for y, row in enumerate(slice): for z, cell in enumerate(row): m[Pos(x, y, z)] = bool(cell) assert projection_top(m) == [[1, 1, 0], [0, 1, 0], [1, 1, 0]]
def test_bounding_box(): matrix = [ # z # ----> [ [1, 0, 0], # | [0, 1, 0], # | y [0, 0, 0] ], # v # x = 0 [[0, 0, 0], [0, 1, 0], [0, 0, 0]], # x = 1 [[0, 0, 0], [1, 1, 0], [0, 0, 0]], # x = 2 ] m = Model(3) for x, slice in enumerate(matrix): for y, row in enumerate(slice): for z, cell in enumerate(row): m[Pos(x, y, z)] = bool(cell) assert bounding_box(m) == (Pos(0, 0, 0), Pos(2, 1, 1))
yield Cmd.Halt() def solve_gen(self, model: 'Model'): self.commands = iter([]) self.state = State(model.R) voxels_to_fill = breadth_first_search(floor_contact(model), filled_neighbors(model)) for voxel in voxels_to_fill: current_position = self.state.bots[0].pos self.add_commands(navigate_near_voxel(current_position, voxel)) current_position = self.state.bots[0].pos self.add_commands([Cmd.Fill(voxel - current_position)]) self.add_commands(self.finish()) return self.commands if __name__ == '__main__': task_number = int(sys.argv[1]) if len(sys.argv) > 1 else 1 name = 'LA{0:03d}_tgt.mdl'.format(task_number) data = data_files.lightning_problem(name) m = Model.parse(data) with open('LA{0:03d}.nbt'.format(task_number), 'wb') as f: solver = BFSSolver(None) for cmd in solver.solve_gen(m): f.write(bytearray(cmd.compose()))
# Returns [] on failure def navigate(m, src, dst): return [x for x in navigate_gen(m, src, dst)] def test_navigation(m, a, b): pos = a for diff in [x.lld for x in navigate(m, a, b)]: new_pos = pos + diff assert (region_is_clear(m, pos, new_pos)) pos = new_pos assert (pos == b) if __name__ == '__main__': test_navigation(Model(3), Pos(0, 0, 0), Pos(2, 2, 2)) m1 = Model(3) m1[Pos(0, 0, 1)] = True m1[Pos(1, 0, 1)] = True m1[Pos(2, 0, 1)] = True m1[Pos(0, 1, 1)] = True m1[Pos(1, 1, 1)] = True m1[Pos(2, 1, 1)] = True m1[Pos(1, 2, 1)] = True m1[Pos(2, 2, 1)] = True test_navigation(m1, Pos(0, 0, 0), Pos(2, 0, 2)) m2 = Model(3) m2[Pos(0, 0, 1)] = True m2[Pos(1, 0, 1)] = True
def __init__(self, R): self.R = R self.matrix = Model(R) self.harmonics = LOW self.energy = 0 self.bots = [Bot(1, Pos(0, 0, 0), list(range(39)))] # TODO
def main_run_interactive(): import production.utils as utils # assuming we have left state and expecting right state # x-> # z ... ... ... | 2.. ... ... # | 2o. ... ... | .o. .o. ... # v ... ... ... | 3.. ... ... # y ----------> m = Model(3) m[Pos(1, 0, 1)] = 1 s = State(3) s.matrix = m s.harmonics = LOW s.energy = 30 s.bots = [Bot(bid=2, pos=Pos(0, 0, 1), seeds=[3, 4, 5])] cmds = [ commands.Fill(Diff(1, 1, 0)), commands.Fission(Diff(0, 0, 1), 2), commands.SMove(Diff(0, 0, -1)), commands.Wait() ] # pass state to emulator (step count set to 0) em = Cpp.Emulator(state_to_cpp(s)) # LOGGING -- temporary out of service # if no logfile name given, emulator doesn't log # problemname & solutionname are optional from production import utils em.setlogfile(str(utils.project_root() / 'outputs' / 'cpp_emulator.log')) em.setproblemname("some handmade problem") em.setsolutionname("John Doe's ingenious alg") # OPTION 1: Run set of commands cpp_cmds = list(map(cmd_to_cpp, cmds)) em.run_commands(cpp_cmds) cs = em.get_state() print("Energy: ", cs.energy) print("Central cell: ", cs[Cpp.Pos(1, 1, 1)]) print("Active bots: ", sum(b.active for b in cs.bots)) # OPTION 2: Command by command # x-> # z 2.. ... ... # | .o. .o. ... # v 3.. ... ... # y ----------> ccmd = cmd_to_cpp(commands.LMove(Diff(1, 0, 0), Diff(0, 0, 1))) msg = em.check_command(ccmd) print(msg == '', 'Error: ', msg) # void string if command is valid ccmd = cmd_to_cpp(commands.Fill(Diff(0, 0, 1))) msg = em.check_command(ccmd) print(msg == '', 'Error: ', msg) em.add_command(ccmd) ccmd = cmd_to_cpp(commands.SMove(Diff(0, 0, -1))) msg = em.check_command(ccmd) print(msg == '', 'Error: ', msg) # to check command and add iff it's valid ccmd = cmd_to_cpp(commands.Wait()) msg = em.check_add_command(ccmd) print(msg == '', 'Error: ', msg) # if there are enough commands for next step, new commands cannot # be checked until change of state, and every check will fail ccmd = cmd_to_cpp(commands.Wait()) msg = em.check_add_command(ccmd) print(msg == '', 'Error: ', msg) # you can still add command without checks print('Trace is full: ', em.steptrace_is_complete()) print('Energy: ', em.energy()) em.add_command(ccmd) em.run_step() print('Trace is full: ', em.steptrace_is_complete()) print('Energy: ', em.energy())
def get_model(model_id): return Model.parse(lightning_problem_by_id(model_id))
def main(): logging.basicConfig( level=logging.INFO, format='%(levelname).1s %(module)10.10s:%(lineno)-4d %(message)s') conn = db.get_conn() cur = conn.cursor() for name in sorted(data_files.full_names()): if not name.startswith('FR'): continue logging.info(name) src_data, tgt_data = data_files.full_problem(name) tgt_data = None stats = {} if src_data is not None: m = Model.parse(src_data) num_full_voxels = 0 for pos in m.enum_voxels(): if m[pos]: num_full_voxels += 1 stats.update(R=m.R, src_size=num_full_voxels) src_data = zlib.compress(src_data) if tgt_data is not None: m = Model.parse(tgt_data) num_full_voxels = 0 for pos in m.enum_voxels(): if m[pos]: num_full_voxels += 1 stats.update(R=m.R, tgt_size=num_full_voxels) tgt_data = zlib.compress(tgt_data) logging.info(stats) name = name.replace('FR', 'ZD') logging.info(name) extra = {} cur.execute( ''' INSERT INTO problems( name, src_data, tgt_data, stats, extra, invocation_id, timestamp) VALUES (%s, %s, %s, %s, %s, %s, %s) ON CONFLICT DO NOTHING RETURNING id ''', [ name, src_data, tgt_data, json.dumps(stats), json.dumps(extra), db.get_this_invocation_id(conn), time.time() ]) res = cur.fetchall() if res: [[model_id]] = res logger.info(f'Recorded as model/{model_id}') else: logger.info(f'Model {name!r} already exists') conn.commit()
def default_assembly(model_src, model_tgt) -> List[Command]: start, finish = bounding_box(model_tgt) return apply_default_strategy(Model(model_tgt.R), model_tgt, (3, 1, 1), start)