diff options
Diffstat (limited to '2018/aoc2018-d18.py')
-rw-r--r-- | 2018/aoc2018-d18.py | 131 |
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); + |