106 lines
1.8 KiB
Go
106 lines
1.8 KiB
Go
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
|
|
}
|