summaryrefslogtreecommitdiff
path: root/2018/aoc2018-d18.py
diff options
context:
space:
mode:
Diffstat (limited to '2018/aoc2018-d18.py')
-rw-r--r--2018/aoc2018-d18.py131
1 files changed, 131 insertions, 0 deletions
diff --git a/2018/aoc2018-d18.py b/2018/aoc2018-d18.py
new file mode 100644
index 0000000..8d85635
--- /dev/null
+++ b/2018/aoc2018-d18.py
@@ -0,0 +1,131 @@
+#advent of code 2018
+#day 18
+#part 1 and part 2
+
+#at first I thought I can find the loop by simply registering when a value "part2" is repeated once
+#(kind of like in an earlier puzzle for that year)
+#then I had a correct idea how to find the pattern,
+#but didn't really know how to implement it efficently
+#pattern recognition is an implementation of solution provided by Michael Fogleman
+#adjusted to my current code
+#another issue I had was that I resumed the calculations for part 2 from the state after 10 minutes (part1)
+#I needed to save the initial state and then start over
+#could probably reduce the code to single loop instead of two separate loops for each part
+
+f = open("input.txt",'r');
+Testing = False;
+#Testing = True;
+if Testing:
+ f.close();
+ f = open("testinput.txt",'r');
+
+size = 50;
+if Testing: size = 10;
+
+#part 1
+
+CurrentState = {};
+
+for r,l in enumerate(f):
+ #print(len(l));
+ for c,a in enumerate(l):
+ CurrentState.update({(r,c):a});
+InitialState = CurrentState.copy();
+f.close();
+
+for x in range(size):
+ for y in range(size):
+ print(CurrentState[(x,y)],end="");
+ print();
+
+#check if each adjacent position is still within grid range
+def GetAdjacent(Cords):
+ Adjacent = [];
+ if (Cords[0] -1 >= 0 and Cords[1]-1 >=0):
+ Adjacent.append( (Cords[0] -1,Cords[1]-1) );
+ if (Cords[0] -1 >= 0):
+ Adjacent.append( (Cords[0] -1,Cords[1]) );
+ if (Cords[0] -1 >= 0 and Cords[1]+1 < size):
+ Adjacent.append( (Cords[0] -1,Cords[1]+1) );
+ if (Cords[1]+1 < size):
+ Adjacent.append( (Cords[0],Cords[1]+1) );
+ if (Cords[1]-1 >= 0):
+ Adjacent.append( (Cords[0],Cords[1]-1) );
+ if (Cords[0] +1 < size and Cords[1]-1 >=0):
+ Adjacent.append( (Cords[0] +1,Cords[1]-1) );
+ if (Cords[0] +1 < size):
+ Adjacent.append( (Cords[0] +1,Cords[1]) );
+ if (Cords[0] +1 < size and Cords[1]+1 < size):
+ Adjacent.append( (Cords[0] +1,Cords[1]+1) );
+ return Adjacent;
+
+def GetAcres(area, adj):
+ acres = [];
+ for c in adj:
+ acres.append(area[c]);
+ return acres;
+
+def ChangeState(area, Cords):
+ s = area[Cords];
+ adj = GetAdjacent(Cords);
+ Acres = GetAcres(area, adj);
+ if (s == "." and Acres.count("|")>=3):
+ s = "|";
+ elif (s == "|" and Acres.count("#")>=3):
+ s = "#";
+ elif (s == "#" and Acres.count("#")>=1 and Acres.count("|")>=1):
+ s = "#";
+ elif (s == "#"):
+ s = ".";
+ return s;
+
+SimTime = 10; #minutes
+
+InitialState = CurrentState.copy();
+for t in range(SimTime):
+ NextState = {};
+ for x in range(size):
+ for y in range(size):
+ NextState.update({(x,y):ChangeState(CurrentState,(x,y))});
+ CurrentState = NextState.copy();
+ '''
+ print("MINUTE ",t);
+ for x in range(size):
+ for y in range(size):
+ print(CurrentState[(x,y)],end="");
+ print();
+ print();
+ '''
+summary = list(CurrentState.values());
+
+woods = summary.count("|");
+lumbs = summary.count("#");
+part1 = woods*lumbs;
+print("part 1 = ", part1);
+
+#part 2
+
+SimTime2 = 1000000000; #minutes for part2
+values = {};
+prev = 0;
+
+CurrentState = InitialState.copy();
+for t in range(1,SimTime2):
+ NextState = {};
+ for x in range(size):
+ for y in range(size):
+ NextState.update({(x,y):ChangeState(CurrentState,(x,y))});
+ CurrentState = NextState.copy();
+ summary = list(CurrentState.values());
+ woods = summary.count("|");
+ lumbs = summary.count("#");
+ part2 = woods*lumbs;
+ loop = t - values.get(part2,0);
+ if (loop == prev):
+ if SimTime2%loop == t%loop:
+ break;
+ values[part2]=t;
+ prev = loop;
+
+print("part 2 = ", part2);
+