Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit 440cd13

Browse files
committed
After another long hiatus, day 18 is done.
1 parent 4ba2136 commit 440cd13

File tree

1 file changed

+200
-0
lines changed

1 file changed

+200
-0
lines changed

‎2018/day18/eighteen.go‎

Lines changed: 200 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,200 @@
1+
package main
2+
3+
import (
4+
"fmt"
5+
"os"
6+
"strings"
7+
)
8+
9+
func main() {
10+
// partOne()
11+
partTwo()
12+
}
13+
14+
func partOne() {
15+
area := area()
16+
17+
for row := range area {
18+
fmt.Printf("%c", area[row])
19+
fmt.Println()
20+
}
21+
22+
for range 10 {
23+
area = changeState(area)
24+
}
25+
26+
fmt.Println("After")
27+
for row := range area {
28+
fmt.Printf("%c", area[row])
29+
fmt.Println()
30+
}
31+
32+
wood := countChar2D(area, '|')
33+
lumber := countChar2D(area, '#')
34+
35+
fmt.Printf("Part 1 : Total resource value: %d\n", wood*lumber)
36+
37+
}
38+
39+
func partTwo() {
40+
area := area()
41+
lastGen := 0
42+
visited := map[[50][50]rune]int{}
43+
// Get the wood and lumber counts for each generation that we're testing to see
44+
// if we can discover a pattern
45+
for minutes := 0; minutes < 1000000000; minutes++ {
46+
area = changeState(area)
47+
48+
if visited[area] != 0 {
49+
firstOccurrence := visited[area]
50+
period := minutes - firstOccurrence // Repeats after X steps
51+
fmt.Println("Period:", period)
52+
// Skip the minutes ahead
53+
minutes = ((1000000000-firstOccurrence)/period)*period + firstOccurrence
54+
}
55+
56+
wood := countChar2D(area, '|')
57+
lumber := countChar2D(area, '#')
58+
resources := wood * lumber
59+
fmt.Printf("For %d Minutes, Total resource value: %d | Diff to previous: %d\n", minutes+1, resources, resources-lastGen)
60+
lastGen = resources
61+
62+
visited[area] = minutes
63+
}
64+
// The cycle repeats every 28 iterations. The cycle is as follows:
65+
// For 49972 Minutes, Total resource value: 210824 | Diff to previous: 320
66+
// For 49973 Minutes, Total resource value: 207282 | Diff to previous: -3542
67+
// For 49974 Minutes, Total resource value: 205320 | Diff to previous: -1962
68+
// For 49975 Minutes, Total resource value: 204125 | Diff to previous: -1195
69+
// For 49976 Minutes, Total resource value: 197316 | Diff to previous: -6809
70+
// For 49977 Minutes, Total resource value: 192984 | Diff to previous: -4332
71+
// For 49978 Minutes, Total resource value: 188914 | Diff to previous: -4070
72+
// For 49979 Minutes, Total resource value: 181485 | Diff to previous: -7429
73+
// For 49980 Minutes, Total resource value: 177416 | Diff to previous: -4069
74+
// For 49981 Minutes, Total resource value: 173910 | Diff to previous: -3506
75+
// For 49982 Minutes, Total resource value: 167475 | Diff to previous: -6435
76+
// For 49983 Minutes, Total resource value: 164424 | Diff to previous: -3051
77+
// For 49984 Minutes, Total resource value: 164079 | Diff to previous: -345
78+
// For 49985 Minutes, Total resource value: 163631 | Diff to previous: -448
79+
// For 49986 Minutes, Total resource value: 163248 | Diff to previous: -383
80+
// For 49987 Minutes, Total resource value: 167090 | Diff to previous: 3842
81+
// For 49988 Minutes, Total resource value: 168562 | Diff to previous: 1472
82+
// For 49989 Minutes, Total resource value: 171588 | Diff to previous: 3026
83+
// For 49990 Minutes, Total resource value: 172852 | Diff to previous: 1264
84+
// For 49991 Minutes, Total resource value: 174900 | Diff to previous: 2048
85+
// For 49992 Minutes, Total resource value: 176012 | Diff to previous: 1112
86+
// For 49993 Minutes, Total resource value: 182574 | Diff to previous: 6562
87+
// For 49994 Minutes, Total resource value: 187272 | Diff to previous: 4698
88+
// For 49995 Minutes, Total resource value: 193888 | Diff to previous: 6616
89+
// For 49996 Minutes, Total resource value: 199167 | Diff to previous: 5279
90+
// For 49997 Minutes, Total resource value: 203648 | Diff to previous: 4481
91+
// For 49998 Minutes, Total resource value: 204832 | Diff to previous: 1184
92+
// For 49999 Minutes, Total resource value: 210504 | Diff to previous: 5672
93+
// ...
94+
// For 100000 Minutes, Total resource value: 176012 | Diff to previous: 1112
95+
// Since 1000000000-ひく100000 = 999900000
96+
// 999900000 % 28 = 8
97+
// We know that at 1 bilion, the iteration will be the 8th, from where the 100000 is currently at.
98+
// So its the one with the Diff = 320
99+
// The above was my first solution, which was by hand. I later added a programmatic one, which skips steps ahead.
100+
101+
wood := countChar2D(area, '|')
102+
lumber := countChar2D(area, '#')
103+
fmt.Printf("Part 2 : Total resource value: %d\n", wood*lumber)
104+
}
105+
106+
func changeState(area [50][50]rune) [50][50]rune {
107+
deepCopy := deepCopy(area) // We need an exact copy, so we dont alter the original adjacent values while iterating
108+
109+
for row := range area {
110+
for cell, space := range area[row] {
111+
adjacents := adjacentSquares(area, row, cell) // Get the adjancets from the original
112+
switch space {
113+
case '.':
114+
if n := countChar(adjacents, '|'); n >= 3 {
115+
deepCopy[row][cell] = '|'
116+
}
117+
case '|':
118+
if n := countChar(adjacents, '#'); n >= 3 {
119+
deepCopy[row][cell] = '#'
120+
}
121+
case '#':
122+
l := countChar(adjacents, '#')
123+
t := countChar(adjacents, '|')
124+
if l == 0 || t == 0 {
125+
deepCopy[row][cell] = '.'
126+
}
127+
}
128+
}
129+
}
130+
131+
return deepCopy
132+
}
133+
134+
func adjacentSquares(area [50][50]rune, row, cell int) []rune {
135+
a := []rune{}
136+
137+
// Go along all the adjacent squares. be mindfull of edges.
138+
for i := row - 1; i <= row+1; i++ {
139+
if i < 0 || i >= len(area) { // Row edges, top and bottom
140+
continue
141+
}
142+
for j := cell - 1; j <= cell+1; j++ {
143+
if j < 0 || j >= len(area) { // Column edges, left and right
144+
continue
145+
}
146+
if i == row && j == cell { // Dont append the current character were checking
147+
continue
148+
}
149+
a = append(a, area[i][j]) // Append the rest
150+
}
151+
}
152+
return a
153+
}
154+
155+
// Count occurrences of any given char.
156+
func countChar(array []rune, char rune) int {
157+
c := 0
158+
for i := range array {
159+
if array[i] == char {
160+
c++
161+
}
162+
}
163+
return c
164+
}
165+
166+
// Count occurrences of any given char.
167+
func countChar2D(array [50][50]rune, char rune) int {
168+
c := 0
169+
for i := range array {
170+
for j := range array[i] {
171+
if array[i][j] == char {
172+
c++
173+
}
174+
}
175+
}
176+
return c
177+
}
178+
179+
func area() [50][50]rune {
180+
area := [50][50]rune{}
181+
f, _ := os.ReadFile("input.txt")
182+
lines := strings.Split(strings.TrimSpace(string(f)), "\n")
183+
184+
for i, line := range lines {
185+
characters := []rune(line)
186+
copy(area[i][:], characters)
187+
}
188+
189+
return area
190+
}
191+
192+
func deepCopy(original [50][50]rune) [50][50]rune {
193+
c := [50][50]rune{}
194+
195+
for i := range original {
196+
copy(c[i][:], original[i][:])
197+
}
198+
199+
return c
200+
}

0 commit comments

Comments
(0)

AltStyle によって変換されたページ (->オリジナル) /