summaryrefslogtreecommitdiffstats
path: root/19
diff options
context:
space:
mode:
authorGustav Sörnäs <gusso230@student.liu.se>2019-12-21 18:13:13 +0100
committerGustav Sörnäs <gusso230@student.liu.se>2019-12-21 20:29:35 +0100
commit663d3b8ab5b0a20d965df40d71ca8d99e50b8595 (patch)
tree27a9624d3319d6f7d16b41ab0c72da015c7a19e4 /19
parent49280f2be70142633639618c8f8af0eb807fe429 (diff)
downloadaoc-663d3b8ab5b0a20d965df40d71ca8d99e50b8595.tar.gz
Call days 18-21 from main
Diffstat (limited to '19')
-rw-r--r--19/py/d19.py23
-rw-r--r--19/py/d20.py330
-rw-r--r--19/py/main.py33
3 files changed, 248 insertions, 138 deletions
diff --git a/19/py/d19.py b/19/py/d19.py
index 808e978..065d64e 100644
--- a/19/py/d19.py
+++ b/19/py/d19.py
@@ -32,7 +32,18 @@ def deploy(c, x, y):
break
return c.output
-def do(input):
+def pt1(input):
+ c = intcode.Computer([int(x) for x in input[0].split(",")])
+
+ amount = 0
+ for y in range(0, 50):
+ for x in range(0, 50):
+ if deploy(c, x, y) == 1:
+ amount += 1
+ return amount
+
+def pt2(input):
+ print("this works but takes a while")
amount = 0
c = intcode.Computer([int(x) for x in input[0].split(",")])
@@ -52,7 +63,7 @@ def do(input):
# first x of the row above)
y = 1000 # tested to not be 100 until after row 1000
- start_x = 0
+ x=start_x = 0
while True:
found = False
x = start_x
@@ -79,8 +90,10 @@ def do(input):
break
if amount_in_col >= 100:
# done
- return start_x+i, y
+ return (start_x+i) *10000 + y
y += 1
-input = open("../input/19", "r").readlines()
-print(do(input))
+if __name__ == "__main__":
+ input = open("../input/19", "r").readlines()
+ print(pt1(input))
+ print(pt2(input))
diff --git a/19/py/d20.py b/19/py/d20.py
index 039e092..2a248ac 100644
--- a/19/py/d20.py
+++ b/19/py/d20.py
@@ -1,8 +1,6 @@
import heapq as heap
import sys
-input = open("../input/20", "r").readlines()
-
def draw(maze, start=None, end=None, portals={}, min_x=0, max_x=0, min_y=0, max_y=0, around=None, visited=set()):
maze = maze.copy()
if start is not None:
@@ -42,119 +40,231 @@ def neighbours(p):
return [(p[0]+1, p[1]), (p[0]-1, p[1]), \
(p[0], p[1]+1), (p[0], p[1]-1)]
-maze = {}
-walls = set()
-tiles = set()
-max_x = 0
-max_y = 0
+def pt1(input):
+ maze = {}
+ walls = set()
+ tiles = set()
+ max_x = 0
+ max_y = 0
-for y in range(len(input)):
- max_y = max(max_y, y)
- for x in range(len(input[y])):
- max_x = max(max_x, x)
- p = (x,y)
- c = input[y][x]
- maze[p] = c
- if c == "#":
- walls.add(p)
- elif c == ".":
- tiles.add(p)
- else:
- del maze[p]
+ for y in range(len(input)):
+ max_y = max(max_y, y)
+ for x in range(len(input[y])):
+ max_x = max(max_x, x)
+ p = (x,y)
+ c = input[y][x]
+ maze[p] = c
+ if c == "#":
+ walls.add(p)
+ elif c == ".":
+ tiles.add(p)
+ else:
+ del maze[p]
-alone_portals = {} # { "JZ" : (25,50) ... }
-portal_pairs = {} # { (25,50) : (30,30) ... ] contains reverse as well
-portals = set()
-found_portals = set()
-checked = set()
-for y in range(len(input)):
- for x in range(len(input[y])):
- p = (x,y)
- if p in checked:
- continue
- c = input[y][x]
- if c.isalpha():
- # find the other letter
- p2 = None
- if x < max_x and input[y][x+1].isalpha():
- portal = "".join([c, input[y][x+1]])
- p2 = (x+1, y)
- elif x > 0 and input[y][x-1].isalpha():
- portal = "".join([input[y][x-1], c])
- p2 = (x-1, y)
- elif y < max_y and input[y+1][x].isalpha():
- portal = "".join([c, input[y+1][x]])
- p2 = (x, y+1)
- elif y > 0 and input[y-1][x].isalpha():
- portal = "".join([input[y-1][x], c])
- p2 = (x, y-1)
- if p2 is None:
- print("bad label near", p)
- sys.exit()
- checked.add(p2)
- # find the empty space
- location = None
- for n in neighbours(p) + neighbours(p2):
- if n in tiles:
- location = n
- if location is None:
- print("invalid location near", p)
- print(draw(maze, around=p))
- if portal == "AA":
- start = location
+ alone_portals = {} # { "JZ" : (25,50) ... }
+ portal_pairs = {} # { (25,50) : (30,30) ... ] contains reverse as well
+ portals = set()
+ found_portals = set()
+ checked = set()
+ for y in range(len(input)):
+ for x in range(len(input[y])):
+ p = (x,y)
+ if p in checked:
continue
- if portal == "ZZ":
- end = location
+ c = input[y][x]
+ if c.isalpha():
+ # find the other letter
+ p2 = None
+ if x < max_x and input[y][x+1].isalpha():
+ portal = "".join([c, input[y][x+1]])
+ p2 = (x+1, y)
+ elif x > 0 and input[y][x-1].isalpha():
+ portal = "".join([input[y][x-1], c])
+ p2 = (x-1, y)
+ elif y < max_y and input[y+1][x].isalpha():
+ portal = "".join([c, input[y+1][x]])
+ p2 = (x, y+1)
+ elif y > 0 and input[y-1][x].isalpha():
+ portal = "".join([input[y-1][x], c])
+ p2 = (x, y-1)
+ if p2 is None:
+ print("bad label near", p)
+ sys.exit()
+ checked.add(p2)
+ # find the empty space
+ location = None
+ for n in neighbours(p) + neighbours(p2):
+ if n in tiles:
+ location = n
+ if location is None:
+ print("invalid location near", p)
+ print(draw(maze, around=p))
+ if portal == "AA":
+ start = location
+ continue
+ if portal == "ZZ":
+ end = location
+ continue
+ if portal in alone_portals:
+ portal_pairs[alone_portals[portal]] = location
+ portal_pairs[location] = alone_portals[portal]
+ del alone_portals[portal]
+ continue
+ if portal in found_portals:
+ print("found double portal near", p)
+ print(draw(maze, around=p))
+ sys.exit()
+ alone_portals[portal] = location
+ #print(draw(maze, start=start, end=end, portals=portal_pairs))
+
+ INSIDE_X_LO = 20
+ INSIDE_X_HI = 120
+ INSIDE_Y_LO = 20
+ INSIDE_Y_HI = 100
+
+ # find shortest path between each portal (and start/end)
+ h = []
+ visited = set(start)
+ heap.heappush(h, (0, start))
+ while len(h) > 0:
+ cur = heap.heappop(h)
+ dist = cur[0]
+ point = cur[1]
+ x = point[0]
+ y = point[1]
+ if point == end:
+ return dist
+ if point in portal_pairs:
+ dist += 1
+ point = portal_pairs[point]
+ for n in neighbours(point):
+ if n not in maze:
continue
- if portal in alone_portals:
- portal_pairs[alone_portals[portal]] = location
- portal_pairs[location] = alone_portals[portal]
- del alone_portals[portal]
+ if n in visited:
continue
- if portal in found_portals:
- print("found double portal near", p)
- print(draw(maze, around=p))
- sys.exit()
- alone_portals[portal] = location
-#print(draw(maze, start=start, end=end, portals=portal_pairs))
+ if n not in walls:
+ visited.add(n)
+ heap.heappush(h, (dist+1, n))
+
+def pt2(input):
+ maze = {}
+ walls = set()
+ tiles = set()
+ max_x = 0
+ max_y = 0
-INSIDE_X_LO = 20
-INSIDE_X_HI = 120
-INSIDE_Y_LO = 20
-INSIDE_Y_HI = 100
+ for y in range(len(input)):
+ max_y = max(max_y, y)
+ for x in range(len(input[y])):
+ max_x = max(max_x, x)
+ p = (x,y)
+ c = input[y][x]
+ maze[p] = c
+ if c == "#":
+ walls.add(p)
+ elif c == ".":
+ tiles.add(p)
+ else:
+ del maze[p]
-# find shortest path between each portal (and start/end)
-h = []
-visited = {0: set()}
-visited[0].add(start)
-heap.heappush(h, (0, 0, start))
-while len(h) > 0:
- cur = heap.heappop(h)
- dist = cur[0]
- dimen = cur[1]
- point = cur[2]
- x = point[0]
- y = point[1]
- if point == end and dimen == 0:
- print(dist)
- break
- if point in portal_pairs:
- if INSIDE_X_LO < x < INSIDE_X_HI and INSIDE_Y_LO < y < INSIDE_Y_HI:
- # inside donut
- dimen += 1
- else:
- if dimen == 0:
+ alone_portals = {} # { "JZ" : (25,50) ... }
+ portal_pairs = {} # { (25,50) : (30,30) ... ] contains reverse as well
+ portals = set()
+ found_portals = set()
+ checked = set()
+ for y in range(len(input)):
+ for x in range(len(input[y])):
+ p = (x,y)
+ if p in checked:
+ continue
+ c = input[y][x]
+ if c.isalpha():
+ # find the other letter
+ p2 = None
+ if x < max_x and input[y][x+1].isalpha():
+ portal = "".join([c, input[y][x+1]])
+ p2 = (x+1, y)
+ elif x > 0 and input[y][x-1].isalpha():
+ portal = "".join([input[y][x-1], c])
+ p2 = (x-1, y)
+ elif y < max_y and input[y+1][x].isalpha():
+ portal = "".join([c, input[y+1][x]])
+ p2 = (x, y+1)
+ elif y > 0 and input[y-1][x].isalpha():
+ portal = "".join([input[y-1][x], c])
+ p2 = (x, y-1)
+ if p2 is None:
+ print("bad label near", p)
+ sys.exit()
+ checked.add(p2)
+ # find the empty space
+ location = None
+ for n in neighbours(p) + neighbours(p2):
+ if n in tiles:
+ location = n
+ if location is None:
+ print("invalid location near", p)
+ print(draw(maze, around=p))
+ if portal == "AA":
+ start = location
+ continue
+ if portal == "ZZ":
+ end = location
+ continue
+ if portal in alone_portals:
+ portal_pairs[alone_portals[portal]] = location
+ portal_pairs[location] = alone_portals[portal]
+ del alone_portals[portal]
+ continue
+ if portal in found_portals:
+ print("found double portal near", p)
+ print(draw(maze, around=p))
+ sys.exit()
+ alone_portals[portal] = location
+ #print(draw(maze, start=start, end=end, portals=portal_pairs))
+
+ INSIDE_X_LO = 20
+ INSIDE_X_HI = 120
+ INSIDE_Y_LO = 20
+ INSIDE_Y_HI = 100
+
+ # find shortest path between each portal (and start/end)
+ h = []
+ visited = {0: set()}
+ visited[0].add(start)
+ heap.heappush(h, (0, 0, start))
+ while len(h) > 0:
+ cur = heap.heappop(h)
+ dist = cur[0]
+ dimen = cur[1]
+ point = cur[2]
+ x = point[0]
+ y = point[1]
+ if point == end and dimen == 0:
+ return dist
+ if point in portal_pairs:
+ if INSIDE_X_LO < x < INSIDE_X_HI and INSIDE_Y_LO < y < INSIDE_Y_HI:
+ # inside donut
+ dimen += 1
+ else:
+ if dimen == 0:
+ continue
+ dimen -= 1
+ dist += 1
+ if dimen not in visited:
+ visited[dimen] = set()
+ point = portal_pairs[point]
+ for n in neighbours(point):
+ if n not in maze:
+ continue
+ if n in visited[dimen]:
continue
- dimen -= 1
- dist += 1
- if dimen not in visited:
- visited[dimen] = set()
- point = portal_pairs[point]
- for n in neighbours(point):
- if n not in maze:
- continue
- if n in visited[dimen]:
- continue
- if n not in walls:
- visited[dimen].add(n)
- heap.heappush(h, (dist+1, dimen, n))
+ if n not in walls:
+ visited[dimen].add(n)
+ heap.heappush(h, (dist+1, dimen, n))
+
+if __name__ == "__main__":
+ input = open("../input/20", "r").readlines()
+ print(pt1(input))
+ print(pt2(input))
+
diff --git a/19/py/main.py b/19/py/main.py
index 70cf792..d006d40 100644
--- a/19/py/main.py
+++ b/19/py/main.py
@@ -17,36 +17,23 @@ import d14
import d15
import d16
import d17
+import d18
+import d19
+import d20
+import d21
mods = [d01, d02, d03, d04, d05, d06, d07, d08, d09, d10, \
- d11, d12, d13, d14, d15, d16, d17]
+ d11, d12, d13, d14, d15, d16, d17, d18, d19, d20, \
+ d21]
skip = []
-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:
+ if day+1 == 18:
+ print("input changed between part 1 and part 2, run it separatly")
+ continue
+ elif 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()))
- #timings[day][0] = time.clock_gettime_ns(clock_type) - t0
- #t0 = time.clock_gettime_ns(clock_type)
print("Part", 2, mod.pt2(open("../input/" + str(day+1).zfill(2), "r").readlines()))
- #timings[day][1] = time.clock_gettime_ns(clock_type) - t0
-
-#print()
-#tot = 0
-#for day in range(len(timings)):
-# for part in range(2):
-# tot += timings[day][part]
-#for day in range(len(timings)):
-# 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")