diff options
| author | Gustav Sörnäs <gusso230@student.liu.se> | 2019-12-17 10:32:50 +0100 |
|---|---|---|
| committer | Gustav Sörnäs <gusso230@student.liu.se> | 2019-12-17 10:32:50 +0100 |
| commit | c03a47188746c5e5aea1600ba4fe5fb656d71d48 (patch) | |
| tree | 889ff79a984fce461562cbc43ada8dd9e9ff64bb | |
| parent | da575538ccf54cefafc361628ff990ba879b385a (diff) | |
| download | aoc-c03a47188746c5e5aea1600ba4fe5fb656d71d48.tar.gz | |
Day 17 py
Also skip d16 when calling from main
| -rw-r--r-- | solutions/py/d17.py | 360 | ||||
| -rw-r--r-- | solutions/py/main.py | 16 |
2 files changed, 219 insertions, 157 deletions
diff --git a/solutions/py/d17.py b/solutions/py/d17.py index 3741763..42ba045 100644 --- a/solutions/py/d17.py +++ b/solutions/py/d17.py @@ -38,69 +38,6 @@ def neighbours(p): return [(p[0]+1, p[1]), (p[0]-1, p[1]), \ (p[0], p[1]+1), (p[0], p[1]-1)] -c = intcode.Computer([int(x) for x in open("../input/17", "r").readlines()[0].split(",")]) - -view = {} -scaffolds = [] -buffer = "" -x=y = 0 -while not c.SIG_HALT: - c.step() - if c.SIG_INPUT: - print("input??") - break - if c.SIG_OUTPUT: - if c.output == 10: - y += 1 - x = 0 - elif c.output == 35: - view[(x,y)] = "#" - scaffolds.append((x,y)) - x += 1 - elif c.output == 46: - view[(x,y)] = "." - x += 1 - else: - view[(x,y)] = "#" - scaffolds.append((x,y)) - robot = (x,y) - if c.output == 60: # < - direction = 2 - elif c.output == 62: # > - direction = 0 - elif c.output == 94: # ^ - direction = 3 - elif c.output == 86 or c.output == 118: # V or v - direction = 1 - else: - print("????????????????") - break - x += 1 - buffer = "" - c.output = None - c.SIG_OUTPUT = False -print(draw(view)) - -intersections = set() -al_sum = 0 -for s in scaffolds: - ns = 0 - for n in neighbours(s): - if n in scaffolds: - ns += 1 - if ns == 4: - intersections.add(s) - al_sum += s[0] * s[1] -print(intersections) -print(draw(view, intersections=intersections, robot=robot, direction=direction)) -print(al_sum) - -x,y = robot -visited = set() -left = set() -for s in scaffolds: - left.add(s) - def get_infront(robot, direction): dx=dy = 0 if direction == 0: @@ -160,104 +97,221 @@ def get_turnable_points(scaffolds, robot, direction): valid.add(n) return list(valid) -''' -For each path, take steps until a wall is reached. For each intersection on the -way, queue new searches with turns (but don't start them, FIFO). When a wall is -reached, check if each point has been visited. If all points have been visited, -done. Else, +def pt1(input): + c = intcode.Computer([int(x) for x in open("../input/17", "r").readlines()[0].split(",")]) -Structure of a deque-element: -Each search-element consists of a single tuple. The tuple contains - - The robot's position - - The robot's direction (after turning) - - The instruction-set up to that point - - The current WIP instruction - - All points that have been visited (as a set) + view = {} + scaffolds = [] + buffer = "" + x=y = 0 + while not c.SIG_HALT: + c.step() + if c.SIG_INPUT: + print("input??") + break + if c.SIG_OUTPUT: + if c.output == 10: + y += 1 + x = 0 + elif c.output == 35: + view[(x,y)] = "#" + scaffolds.append((x,y)) + x += 1 + elif c.output == 46: + view[(x,y)] = "." + x += 1 + else: + view[(x,y)] = "#" + scaffolds.append((x,y)) + robot = (x,y) + if c.output == 60: # < + direction = 2 + elif c.output == 62: # > + direction = 0 + elif c.output == 94: # ^ + direction = 3 + elif c.output == 86 or c.output == 118: # V or v + direction = 1 + else: + print("????????????????") + break + x += 1 + buffer = "" + c.output = None + c.SIG_OUTPUT = False + #print(draw(view)) -Structure of the instruction-set: -The instruction-set consists of a list of tuples. The tuples contain - - A turn-instruction - - The number of steps to take (after turning) -For example: -[(R,8), (R,8), (R,4), (R,4), (R,8)] -''' + intersections = set() + al_sum = 0 + for s in scaffolds: + ns = 0 + for n in neighbours(s): + if n in scaffolds: + ns += 1 + if ns == 4: + intersections.add(s) + al_sum += s[0] * s[1] + #print(intersections) + #print(draw(view, intersections=intersections, robot=robot, direction=direction)) + return al_sum -current = None -direction = 2 -paths = deque() -visited = set() -visited.add(robot) -paths.append((robot, direction, [], ["L", 0], visited)) -while True: - if current is None: - current = paths.popleft() - robot = current[0] - direction = current[1] - instruction_set = current[2] - wip_instruction = current[3] - visited = current[4].copy() - if len(visited) == len(scaffolds): - print("len(visited) == len(scaffolds)") - instruction_set.append(wip_instruction) +def pt2(input): + c = intcode.Computer([int(x) for x in open("../input/17", "r").readlines()[0].split(",")]) + + view = {} + scaffolds = [] + buffer = "" + x=y = 0 + while not c.SIG_HALT: + c.step() + if c.SIG_INPUT: + print("input??") break - if get_infront(robot, direction) not in scaffolds: - # wall in front. save - instruction_set.append(wip_instruction) - avail_points = get_turnable_points(scaffolds, robot, direction) - if len(avail_points) == 0: + if c.SIG_OUTPUT: + if c.output == 10: + y += 1 + x = 0 + elif c.output == 35: + view[(x,y)] = "#" + scaffolds.append((x,y)) + x += 1 + elif c.output == 46: + view[(x,y)] = "." + x += 1 + else: + view[(x,y)] = "#" + scaffolds.append((x,y)) + robot = (x,y) + if c.output == 60: # < + direction = 2 + elif c.output == 62: # > + direction = 0 + elif c.output == 94: # ^ + direction = 3 + elif c.output == 86 or c.output == 118: # V or v + direction = 1 + else: + print("????????????????") + break + x += 1 + buffer = "" + c.output = None + c.SIG_OUTPUT = False + #print(draw(view)) + + intersections = set() + for s in scaffolds: + ns = 0 + for n in neighbours(s): + if n in scaffolds: + ns += 1 + if ns == 4: + intersections.add(s) + + ''' + For each path, take steps until a wall is reached. When a wall is reached, tuirn + towards the next unvisited point. Repeat until the end is reached. + + Structure of a deque-element: + Each search-element consists of a single tuple. The tuple contains + - The robot's position + - The robot's direction (after turning) + - The instruction-set up to that point + - The current WIP instruction + - All points that have been visited (as a set) + + Structure of the instruction-set: + The instruction-set consists of a list of tuples. The tuples contain + - A turn-instruction + - The number of steps to take (after turning) + For example: + [(R,8), (R,8), (R,4), (R,4), (R,8)] + ''' + + current = None + direction = 2 + paths = deque() + visited = set() + visited.add(robot) + paths.append((robot, direction, [], ["L", 0], visited)) + while True: + if current is None: + current = paths.popleft() + robot = current[0] + direction = current[1] + instruction_set = current[2] + wip_instruction = current[3] + visited = current[4].copy() if len(visited) == len(scaffolds): + #print("len(visited) == len(scaffolds)") + instruction_set.append(wip_instruction) break - else: - current = None - continue - wip_instruction = [get_turn(robot, direction, avail_points[0]), 0] - direction = get_direction(direction, get_turn(robot, direction, avail_points[0])) - paths.append((robot, direction, instruction_set, wip_instruction, visited)) - current = None - else: # wall not in front - ''' - if robot in intersections and wip_instruction[1] != 0: - # queue intersections - new_instruction_set = instruction_set.copy() - new_instruction_set.append(wip_instruction.copy()) - paths.append((robot, get_direction(direction, "L"), \ - new_instruction_set.copy(), ["L", 0], visited)) - paths.append((robot, get_direction(direction, "R"), \ - new_instruction_set.copy(), ["R", 0], visited)) - ''' - # take step - robot = get_infront(robot, direction) - visited.add(robot) - wip_instruction[1] += 1 + if get_infront(robot, direction) not in scaffolds: + # wall in front. save + instruction_set.append(wip_instruction) + avail_points = get_turnable_points(scaffolds, robot, direction) + if len(avail_points) == 0: + if len(visited) == len(scaffolds): + break + else: + current = None + continue + wip_instruction = [get_turn(robot, direction, avail_points[0]), 0] + direction = get_direction(direction, get_turn(robot, direction, avail_points[0])) + paths.append((robot, direction, instruction_set, wip_instruction, visited)) + current = None + else: # wall not in front + ''' + if robot in intersections and wip_instruction[1] != 0: + # queue intersections + new_instruction_set = instruction_set.copy() + new_instruction_set.append(wip_instruction.copy()) + paths.append((robot, get_direction(direction, "L"), \ + new_instruction_set.copy(), ["L", 0], visited)) + paths.append((robot, get_direction(direction, "R"), \ + new_instruction_set.copy(), ["R", 0], visited)) + ''' + # take step + robot = get_infront(robot, direction) + visited.add(robot) + wip_instruction[1] += 1 -print(instruction_set) -s = "" -for instruction in instruction_set: - s += str(instruction[0]) + "," + str(instruction[1]) + "\n" -print(s) + #print(instruction_set) + s = "" + for instruction in instruction_set: + s += str(instruction[0]) + "," + str(instruction[1]) + "\n" + #print(s) -main_routine = "A,A,B,C,C,A,C,B,C,B" -routine_a = "L,4,L,4,L,6,R,10,L,6" -routine_b = "L,12,L,6,R,10,L,6" -routine_c = "R,8,R,10,L,6" + # hard-coded >:( + main_routine = "A,A,B,C,C,A,C,B,C,B" + routine_a = "L,4,L,4,L,6,R,10,L,6" + routine_b = "L,12,L,6,R,10,L,6" + routine_c = "R,8,R,10,L,6" -msg = deque() -for s in [main_routine, routine_a, routine_b, routine_c]: - for ch in s: - msg.append(ord(ch)) + msg = deque() + for s in [main_routine, routine_a, routine_b, routine_c]: + for ch in s: + msg.append(ord(ch)) + msg.append(10) + msg.append(ord("n")) msg.append(10) -msg.append(ord("n")) -msg.append(10) -print(msg) + #print(msg) + + c.reset() + c.memory[0] = 2 + output = [] + while not c.SIG_HALT: + c.step() + if c.SIG_INPUT: + c.input = msg.popleft() + c.SIG_INPUT = False + if c.SIG_OUTPUT: + output.append(c.output) + c.output = None + c.SIG_OUTPUT = False + return output[-1] -c.reset() -c.memory[0] = 2 -while not c.SIG_HALT: - c.step() - if c.SIG_INPUT: - c.input = msg.popleft() - c.SIG_INPUT = False - if c.SIG_OUTPUT: - print(c.output) - c.output = None - c.SIG_OUTPUT = False +if __name__ == "__main__": + input = open("../input/17", "r") + print(pt1(input)) + print(pt2(input)) diff --git a/solutions/py/main.py b/solutions/py/main.py index 56a7866..e454eb5 100644 --- a/solutions/py/main.py +++ b/solutions/py/main.py @@ -16,14 +16,19 @@ import d13 import d14 import d15 import d16 +import d17 mods = [d01, d02, d03, d04, d05, d06, d07, d08, d09, d10, \ - d11, d12, d13, d14, d15, d16] + d11, d12, d13, d14, d15, d16, d17] + +skip = [16] timings = [[0 for _ in range(2)] for _ in range(len(mods))] clock_type = time.CLOCK_MONOTONIC for mod, day in zip(mods, range(len(mods))): + if day+1 in skip: + continue print("Day", str(day+1).zfill(2)) t0 = time.clock_gettime_ns(clock_type) print("Part", 1, mod.pt1(open("../input/" + str(day+1).zfill(2), "r").readlines())) @@ -38,7 +43,10 @@ for day in range(len(timings)): for part in range(2): tot += timings[day][part] for day in range(len(timings)): - for part in range(2): - print("day {0}-{1}: {2:.2f}ms\t({3:.1f}%)".format(str(day+1).zfill(2), part+1, \ - timings[day][part] / 1000000, 100*timings[day][part] / tot)) + if day+1 in skip: + print("day {0} skipped".format(str(day+1))) + else: + for part in range(2): + print("day {0}-{1}: {2:.2f}ms\t({3:.1f}%)".format(str(day+1).zfill(2), part+1, \ + timings[day][part] / 1000000, 100*timings[day][part] / tot)) print("sum", tot / 1000000, "ms") |
