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 }