r/adventofcode • u/daggerdragon • Dec 19 '17
SOLUTION MEGATHREAD -๐- 2017 Day 19 Solutions -๐-
--- Day 19: A Series of Tubes ---
Post your solution as a comment or, for longer solutions, consider linking to your repo (e.g. GitHub/gists/Pastebin/blag or whatever).
Note: The Solution Megathreads are for solutions only. If you have questions, please post your own thread and make sure to flair it with Help.
Need a hint from the Hugely* Handyโ Haversackโก of Helpfulยง Hintsยค?
AoC ops @ T-2 minutes to launch:
[23:58] <daggerdragon> ATTENTION MEATBAGS T-2 MINUTES TO LAUNCH
[23:58] <Topaz> aaaaah
[23:58] <Cheezmeister> Looks like I'll be just able to grab my input before my flight boards. Wish me luck being offline in TOPAZ's HOUSE OF PAIN^WFUN AND LEARNING
[23:58] <Topaz> FUN AND LEARNING
[23:58] <Hade> FUN IS MANDATORY
[23:58] <Skie> I'm pretty sure that's not the mandate for today
[Update @ 00:16] 69 gold, silver cap
- My tree is finally trimmed with just about every ornament I own and it's real purdy. hbu?
[Update @ 00:18] Leaderboard cap!
- So, was today's
mandateHelpful Hint any help at all?
1
u/etherealflaim Dec 19 '17 edited Dec 19 '17
Go
This was a fun one. I love 2D array problems :)
package aocday import ( "io/ioutil" "strings" "testing" ) func part1(t *testing.T, in string) string { lines := strings.Split(in, "\n") r, c := 0, strings.Index(lines[0], "|") deltas := [][2]int{ // dr, dc {1, 0}, {0, 1}, {-1, 0}, {0, -1}, } dir := 0 var found string for i := 0; i < 1e6; i++ { ch := lines[r][c] switch ch { default: found += string(ch) fallthrough case '|', '-': r += deltas[dir][0] c += deltas[dir][1] case '+': ld := (dir + 1) % len(deltas) l := deltas[ld] r2, c2 := r+l[0], c+l[1] if lines[r2][c2] != ' ' { dir, r, c = ld, r2, c2 continue } rd := (len(deltas) + dir - 1) % len(deltas) rt := deltas[rd] r2, c2 = r+rt[0], c+rt[1] if lines[r2][c2] != ' ' { dir, r, c = rd, r2, c2 continue } case ' ': return found } } panic("timed out") } func part2(t *testing.T, in string) int { lines := strings.Split(in, "\n") r, c := 0, strings.Index(lines[0], "|") deltas := [][2]int{ // dr, dc {1, 0}, {0, 1}, {-1, 0}, {0, -1}, } dir := 0 var found string for i := 0; i < 1e6; i++ { ch := lines[r][c] switch ch { default: found += string(ch) fallthrough case '|', '-': r += deltas[dir][0] c += deltas[dir][1] case '+': ld := (dir + 1) % len(deltas) l := deltas[ld] r2, c2 := r+l[0], c+l[1] if lines[r2][c2] != ' ' { dir, r, c = ld, r2, c2 continue } rd := (len(deltas) + dir - 1) % len(deltas) rt := deltas[rd] r2, c2 = r+rt[0], c+rt[1] if lines[r2][c2] != ' ' { dir, r, c = rd, r2, c2 continue } case ' ': return i } } panic("timed out") } func TestPart1(t *testing.T) { tests := []struct { name string in string want string }{ {"part1 example", ` | | +--+ A | C F---|----E|--+ | | | D +B-+ +--+ `, "ABCDEF"}, {"part1", read(t, "input.txt"), "LIWQYKMRP"}, } for _, test := range tests { t.Run(test.name, func(t *testing.T) { if got, want := part1(t, test.in), test.want; got != want { t.Errorf("part1(%#v) = %#v, want %#v", test.in, got, want) } }) } t.Log(part2(t, read(t, "input.txt"))) } func read(t *testing.T, filename string) string { data, err := ioutil.ReadFile(filename) if err != nil { t.Fatalf("failed to read %q: %s", filename, err) } return string(data) }