diff --git a/2016/day19/main.go b/2016/day19/main.go new file mode 100644 index 0000000..5068fef --- /dev/null +++ b/2016/day19/main.go @@ -0,0 +1,105 @@ +package main + +import ( + "fmt" + + "../../" +) + +// pt1 input: 3014387 +func main() { + partOne := aoc.ArgIsSet("-1") + num := 3014387 + if aoc.ArgIsSet("-test") { + num = 5 // Example + } + firstElf := CreateElf(1) + t := CreateElf(2) + firstElf.setLeft(t) + t.setRight(firstElf) + fmt.Println("Generating Elves...") + for i := 3; i <= num; i++ { + nextElf := CreateElf(i) + nextElf.setRight(t) + t.setLeft(nextElf) + t = nextElf + } + t.setLeft(firstElf) + firstElf.setRight(t) + + fmt.Println(num, "Elves Generated.") + fmt.Println("Initiating Greed Injection...") + + t = firstElf + if !partOne { + t = GetElfAcrossCircle(t, num) + } + for t.getLeft() != t { + if partOne { + // Remove the elf to the left + t = t.getLeft() + t = t.remove() + num-- + } else { + // Remove the current elf, the next elf to be removed is the one to the left + // (remove() returns a pointer to the elf to it's left) + t = t.remove() + if num%2 == 1 { + // Unless we have an odd number of elves, then we skip this one + t = t.getLeft() + } + num-- + } + } + fmt.Println("The lucky elf is elf #", t.getId()) +} + +func GetElfAcrossCircle(e *Elf, num int) *Elf { + retElf := e + for i := 0; i < num/2; i++ { + retElf = retElf.getLeft() + } + return retElf +} + +type Elf struct { + id int + out bool + toRight *Elf + toLeft *Elf +} + +// To keep the game running smoothly, an elf is required to +// let the gamemaster know who the elf to their left is when they +// are eliminated +func (e *Elf) remove() *Elf { + e.getLeft().setRight(e.getRight()) + e.getRight().setLeft(e.getLeft()) + return e.getLeft() +} + +func (e *Elf) getId() int { + return e.id +} + +func (e *Elf) getRight() *Elf { + return e.toRight +} + +func (e *Elf) setRight(r *Elf) { + e.toRight = r +} + +func (e *Elf) getLeft() *Elf { + return e.toLeft +} + +func (e *Elf) setLeft(l *Elf) { + e.toLeft = l +} + +func CreateElf(id int) *Elf { + r := new(Elf) + r.id = id + return r +} diff --git a/2016/day19/problem b/2016/day19/problem new file mode 100644 index 0000000..6397ccc --- /dev/null +++ b/2016/day19/problem @@ -0,0 +1,106 @@ +Advent of Code + +--- Day 19: An Elephant Named Joseph --- + + The Elves contact you over a highly secure emergency channel. Back at the + North Pole, the Elves are busy misunderstanding White Elephant parties. + + Each Elf brings a present. They all sit in a circle, numbered starting + with position 1. Then, starting with the first Elf, they take turns + stealing all the presents from the Elf to their left. An Elf with no + presents is removed from the circle and does not take turns. + + For example, with five Elves (numbered 1 to 5): + + 1 + 5 2 + 4 3 + + • Elf 1 takes Elf 2's present. + • Elf 2 has no presents and is skipped. + • Elf 3 takes Elf 4's present. + • Elf 4 has no presents and is also skipped. + • Elf 5 takes Elf 1's two presents. + • Neither Elf 1 nor Elf 2 have any presents, so both are skipped. + • Elf 3 takes Elf 5's three presents. + + So, with five Elves, the Elf that sits starting in position 3 gets all the + presents. + + With the number of Elves given in your puzzle input, which Elf gets all + the presents? + + Your puzzle input was 3014387. + + Your puzzle answer was __________. + +--- Part Two --- + + Realizing the folly of their present-exchange rules, the Elves agree to + instead steal presents from the Elf directly across the circle. If two + Elves are across the circle, the one on the left (from the perspective of + the stealer) is stolen from. The other rules remain unchanged: Elves with + no presents are removed from the circle entirely, and the other elves move + in slightly to keep the circle evenly spaced. + + For example, with five Elves (again numbered 1 to 5): + + • The Elves sit in a circle; Elf 1 goes first: + + 1 + 5 2 + 4 3 + + • Elves 3 and 4 are across the circle; Elf 3's present is stolen, being + the one to the left. Elf 3 leaves the circle, and the rest of the + Elves move in: + + 1 1 + 5 2 --> 5 2 + 4 - 4 + + • Elf 2 steals from the Elf directly across the circle, Elf 5: + + 1 1 + - 2 --> 2 + 4 4 + + • Next is Elf 4 who, choosing between Elves 1 and 2, steals from Elf 1: + + - 2 + 2 --> + 4 4 + + • Finally, Elf 2 steals from Elf 4: + + 2 + --> 2 + - + + So, with five Elves, the Elf that sits starting in position 2 gets all the + presents. + + With the number of Elves given in your puzzle input, which Elf now gets + all the presents? + + Your puzzle input was 3014387. + + Your puzzle answer was __________. + +References + + Visible links + . http://adventofcode.com/ + . http://adventofcode.com/2016/about + . http://adventofcode.com/2016/support + . http://adventofcode.com/2016/events + . http://adventofcode.com/2016/settings + . http://adventofcode.com/2016/auth/logout + . http://adventofcode.com/2016 + . http://adventofcode.com/2016 + . http://adventofcode.com/2016/leaderboard + . http://adventofcode.com/2016/stats + . http://adventofcode.com/2016/sponsors + . http://adventofcode.com/2016/sponsors + . https://en.wikipedia.org/wiki/White_elephant_gift_exchange + . http://adventofcode.com/2016 diff --git a/helpers.go b/helpers.go index e8483df..fcf236c 100644 --- a/helpers.go +++ b/helpers.go @@ -7,8 +7,28 @@ import ( "log" "os" "strconv" + "strings" ) +func ArgIsSet(a string) bool { + for i := range os.Args { + if os.Args[i] == a || strings.HasPrefix(os.Args[i], a+"=") { + return true + } + } + return false +} + +func GetArgValue(a string) string { + for i := range os.Args { + if strings.HasPrefix(os.Args[i], a+"=") { + return strings.TrimPrefix(os.Args[i], a+"=") + } + } + return "" + +} + func StdinToStringSlice() []string { var input []string scanner := bufio.NewScanner(os.Stdin)