def run_main(): args = get_args() prog = get_prog(args) icn = IntcodeComputerNode("ENIAC", prog, []) # I don't think there is a strategy that is guaranteed to win based on what we know # For example consider: # ###.#.#...# # ###.#...#.# # In the first case, you have to jump at step 3 or you lose # In the second case, you have to jump at step 1 or you lose # But it looks the same from the beginning. No way to tell them apart. # So no strategy is guaranteed to work. # A good solution would be something like: figure out rules which allow us to greedily go forward # until we have rules that are *good enough* to get us to the end. # Or, we can try a heuristic and go from there. Opting for this. # So, heuristic strategy: jump if ### 4 ahead is hull AND 3 ahead is not hull, OR 1 ahead is not hull # sure, we can refine from there as long as we take care to visualize the output. ss = ["NOT C J\n", "AND D J\n", "NOT A T\n", "OR T J\n", "WALK\n"] ss = [ord(v) for v in "".join(ss)] # print(ss) icn.inputs = ss icn.run_prog_from_current_state() outs = icn.outputs print(f"The outputs are: {outs}") ### Output a bunch of ascii-range integers and then a single giant integer which worked. ### Great but not the most satisfying I guess? return 0
def run_main(): args = get_args() prog = get_prog(args) icn = IntcodeComputerNode("ENIAC", prog, []) XX = 50 YY = 50 arr = np.zeros(shape=(XX, YY)) out_ptr = 0 for y in range(YY): for x in range(XX): # icn.run_prog_from_current_state() # print(icn.outputs) icn.reset() icn.inputs = [y, x] # print(f"Running with inputs: {icn.inputs}") icn.run_prog_from_current_state() # print(f"All outputs: {icn.outputs}") # print(f"Exit status: {icn.has_exited}") arr[y, x] = icn.outputs[out_ptr] # exit() # out_ptr += 1 # print(arr) # exit() for y in range(YY): row = "".join([str(int(v)) for v in arr[y, :]]) # print(row) row = row.replace('1', '#').replace('0', '.') print(row) total = np.sum(arr.flatten()) print(f"Total number of affected spots: {total}") return 0
def run_main(): args = get_args() prog = get_prog(args) icn = IntcodeComputerNode("ENIAC", prog, []) # Unlike in part 1 we might now have enough information to know what to do each time. # For example consider: # ###.#.#...# # ###.#...#.# # Now that we can see 9 tiles ahead, we know in part 1 we have to wait to jump, and in 2 we can't wait. # Now how can we translate this into spring code. Well, start with logic. # if 9 ahead is space, cant jump at 5 # if 8 ahead is space, cant jump at 4 # so, don't want to land at 4 unless there is a good jump after: # land at 4 if 4 hull AND: # 3 empty, AND # 8 hull, OR # 5 hull AND (9 hull OR (6 hull and 7 hull)) # OR 1 empty (no matter what) # eh still not perfect but better? # ((2 space and 5 space and 1 hull) OR...: NOT B T, NOT E J, AND J T, AND A T # always avoid a suicide jump next step at 1 # 6 hull and 7 hull: NOT F J, NOT J J, AND G J # result is in J # 9 hull OR that: OR I J # result is in J # 5 hull AND that: AND E J # result is in J # 8 hull OR that: OR H J # result in J # 4 hull AND that: AND D J # OR T J # finished OR from the very first step # 1 empty OR that: NOT A T, OR T J # always jump if we're about to die # that is 14. # ss = ["NOT F J\n","NOT J J\n", "AND G J\n", # "OR I J\n", # "AND E J\n", # "OR H J\n", # "NOT C T\n", "AND T J\n", # "AND D J\n", # "NOT A T\n", "OR T J\n", "RUN\n"] # ss = ["NOT B T\n","NOT E J\n", "AND J T\n", "AND A T\n", # "NOT F J\n", "NOT J J\n", "AND G J\n", # "OR I J\n", # "AND E J\n", # "OR H J\n", # "AND D J\n", # "OR T J\n", # "NOT A T\n", "OR T J\n", "RUN\n"] # ss = [ # "NOT F J\n", "NOT J J\n", # (((6 hull # "OR I J\n", # or 9 hull) # "AND E J\n", # and 5 hull) # "OR H J\n", # or 8 hull) # "AND D J\n", # and 4 hull # "NOT C T\n", "AND T J\n", # and 3 space # "NOT B T\n", # "AND E T\n", "NOT T T\n", # "AND A J\n", # "NOT A T\n", "OR T J\n", "RUN\n"] ############################################### #### ALRIGHT LOTS OF FALSE STARTS ABOVE but finally got something working: ss = [ "NOT B T\n", "NOT E J\n", "AND J T\n", "AND A T\n", # (if 2 space and 5 space and 1 hull, "NOT C J\n", "OR J T\n", # OR 3 space: TRUE -> T) "NOT E J\n", "NOT J J\n", # (5 hull "OR H J\n", # or 8 hull) "AND D J\n", # and 4 hull: TRUE -> J "AND T J\n" # T and J -> J "NOT A T\n", "OR T J\n", "RUN\n" ] # if 1 is space or J: J true # In english: # Jump if: # it would be a safe-ish jump (4 is hull AND 5 or 8 is hull), AND either # the next step leads to a suicide jump (2 space, 5 space, 1 hull) OR # 3 is a space # OR: 1 is a space (have to jump) ss = [ord(v) for v in "".join(ss)] # print(ss) icn.inputs = ss icn.run_prog_from_current_state() outs = icn.outputs print(f"The outputs are: {outs}") if outs[-1] <= 127: tumbled = "".join([chr(v) for v in outs]) print(tumbled) ### Output a bunch of ascii-range integers and then a single giant integer which worked. ### Cool. Not bad heuristic-finding exercise. Wonder if there was a more "code" way to do it. ### Some reddit solutions talk about SAT machines which could be entertaining. return 0