summaryrefslogtreecommitdiff
path: root/2018/aoc2018-d20.py
blob: 06241f5e6052b6337ad688198c03495170b7e287 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
#advent of code 2018 
#day 20
#part 1 and part 2

#I struggled with indexing when parsing the input
#I was getting more doors mapped than there really were
#the issue was that after parsing the content of a bracket
#I was retreiving a ")" sign instead of the following instruction like N or W
#+1 to the index did the work 
#a bit disappointed with part 2, on which I spent more time reading it than coding

f = open("input.txt",'r');
Testing = False;
#Testing = True; 
if Testing:
	f.close();
	f = open("testinput.txt",'r');

inputline = f.readline();
inputline = inputline[1:-1];
f.close();
#split the contents of a bracket into separate strings, return a list of those strings
def parse_brackets(regex):
	regex = regex[1:];
	close_brackets_sign = ")";
	close_brackets_count = 1;
	subsets = [];
	subset = "";
	for i, c in enumerate(regex):
		if c == "(":
			close_brackets_count += 1;
			subset += c;
		elif c == close_brackets_sign:
			if close_brackets_count == 1:
				subsets.append(subset);
				break;
			else:
				close_brackets_count -= 1;
				subset += c;
		elif c == "|":
			if close_brackets_count == 1:
				subsets.append(subset);
				subset = "";
			else: subset += c;
		else: subset += c;
	return i, subsets;
#fill up the "area" dictionary with rooms and doors based on provided instruction
#recursive function, the function is called again if the path is branching due to brackets
def parse_input(inputline, Cords, grid):
	i = 0;
	d = (0,0);
	CurrentCords = Cords;
	CurrentCords = (CurrentCords[0] +d[0],CurrentCords[1] +d[1]);
	while i < len(inputline):
		c = inputline[i];
		if c == "(":
			x, subs = parse_brackets(inputline[i:]);
			for s in subs:
				parse_input(s, CurrentCords, grid);
			i += x+1;
		elif c == "$":
			break;
		else:
			if c == "N":
				d = (0,-1);
			elif c == "S":
				d = (0,1);
			elif c == "W":
				d = (-1,0);
			elif c == "E":
				d = (1,0);
			CurrentCords = (CurrentCords[0] +d[0],CurrentCords[1] +d[1]);
			grid.update({CurrentCords:"D"});
			CurrentCords = (CurrentCords[0] +d[0],CurrentCords[1] +d[1]);
			grid.update({CurrentCords:"."});
		i += 1;

area = {};
p = (0,0);
area.update({p:"."});

parse_input(inputline, p, area);
#print the map of the area
'''
maxX = max([x[0] for x in area]);
minX = min([x[0] for x in area]);
maxY = max([y[1] for y in area]);
minY = min([y[1] for y in area]);

for y in range(minY-1, maxY+1+1):
	for x in range(minX-1, maxX+1+1):
		cp = area.get((x,y),"#");
		if x==0 and y==0: cp = "X";
		print(cp, end="");
	print();
'''

distances = {};
queue = [(0,0,0)];

while queue:
	x,y,d = queue.pop();
	if ((x,y) in distances and distances.get((x,y)) <= d):
		continue;
	distances.update({(x,y):d});
	if (x+1,y) in area and (x+2,y) in area: queue.append((x+2,y,d+1));
	if (x-1,y) in area and (x-2,y) in area: queue.append((x-2,y,d+1));
	if (x,y+1) in area and (x,y+2) in area: queue.append((x,y+2,d+1));
	if (x,y-1) in area and (x,y-2) in area: queue.append((x,y-2,d+1));

part1 = max([distances[dist] for dist in distances]);
print("part1 = ", part1);

part2 =len([distances[dist] for dist in distances if distances[dist]>=1000]);
print("part2 = ", part2);