2019 Day 12 Complete
This commit is contained in:
parent
0362762d6f
commit
1400400fe0
4
2019/day12/input
Normal file
4
2019/day12/input
Normal file
@ -0,0 +1,4 @@
|
|||||||
|
<x=15, y=-2, z=-6>
|
||||||
|
<x=-5, y=-4, z=-11>
|
||||||
|
<x=0, y=-6, z=0>
|
||||||
|
<x=5, y=9, z=6>
|
178
2019/day12/main.go
Normal file
178
2019/day12/main.go
Normal file
@ -0,0 +1,178 @@
|
|||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
|
||||||
|
helpers "git.bullercodeworks.com/brian/adventofcode/helpers"
|
||||||
|
)
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
inp := helpers.StdinToStringSlice()
|
||||||
|
|
||||||
|
part1(inp)
|
||||||
|
part2(inp)
|
||||||
|
}
|
||||||
|
|
||||||
|
func part1(inp []string) {
|
||||||
|
s := NewSystem(inp)
|
||||||
|
for i := 1; i <= 1000; i++ {
|
||||||
|
s.Step()
|
||||||
|
}
|
||||||
|
fmt.Println("System Energy:", s.GetTotalEnergy())
|
||||||
|
}
|
||||||
|
|
||||||
|
func part2(inp []string) {
|
||||||
|
s := NewSystem(inp)
|
||||||
|
sInit := NewSystem(inp)
|
||||||
|
// Find how long it takes for all planets to repeat
|
||||||
|
done := make([]bool, 3)
|
||||||
|
count := make([]int, 3)
|
||||||
|
for !AllTrue(done...) {
|
||||||
|
s.Step()
|
||||||
|
for i := 0; i < len(done); i++ {
|
||||||
|
if !done[i] {
|
||||||
|
equal := true
|
||||||
|
for pi := range s.moons {
|
||||||
|
switch i {
|
||||||
|
case 0:
|
||||||
|
if s.moons[pi].posX != sInit.moons[pi].posX || s.moons[pi].velX != sInit.moons[pi].velX {
|
||||||
|
equal = false
|
||||||
|
}
|
||||||
|
case 1:
|
||||||
|
if s.moons[pi].posY != sInit.moons[pi].posY || s.moons[pi].velY != sInit.moons[pi].velY {
|
||||||
|
equal = false
|
||||||
|
}
|
||||||
|
case 2:
|
||||||
|
if s.moons[pi].posZ != sInit.moons[pi].posZ || s.moons[pi].velZ != sInit.moons[pi].velZ {
|
||||||
|
equal = false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if equal {
|
||||||
|
done[i] = true
|
||||||
|
} else {
|
||||||
|
count[i]++
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
fmt.Println(count[0], count[1], count[2])
|
||||||
|
fmt.Println(helpers.Lcm(count[0]+1, count[1]+1, count[2]+1))
|
||||||
|
}
|
||||||
|
|
||||||
|
func AllTrue(done ...bool) bool {
|
||||||
|
for _, v := range done {
|
||||||
|
if !v {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
type System struct {
|
||||||
|
moons []*Moon
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewSystem(inp []string) *System {
|
||||||
|
s := &System{}
|
||||||
|
for k := range inp {
|
||||||
|
var x, y, z int
|
||||||
|
_, err := fmt.Sscanf(inp[k], "<x=%d, y=%d, z=%d>", &x, &y, &z)
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
s.AddMoon(NewMoon(x, y, z))
|
||||||
|
}
|
||||||
|
return s
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *System) AddMoon(m *Moon) {
|
||||||
|
s.moons = append(s.moons, m)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *System) Step() {
|
||||||
|
for i := range s.moons {
|
||||||
|
for j := i + 1; j < len(s.moons); j++ {
|
||||||
|
s.moons[i].Interact(s.moons[j])
|
||||||
|
}
|
||||||
|
}
|
||||||
|
for i := range s.moons {
|
||||||
|
s.moons[i].Step()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *System) GetTotalEnergy() int {
|
||||||
|
var ret int
|
||||||
|
for v := range s.moons {
|
||||||
|
ret = ret + (s.moons[v].GetPotentialEnergy() * s.moons[v].GetKineticEnergy())
|
||||||
|
}
|
||||||
|
return ret
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s System) String() string {
|
||||||
|
var ret string
|
||||||
|
for k := range s.moons {
|
||||||
|
ret = ret + s.moons[k].String() + "\n"
|
||||||
|
}
|
||||||
|
return ret
|
||||||
|
}
|
||||||
|
|
||||||
|
type Moon struct {
|
||||||
|
posX, posY, posZ int
|
||||||
|
velX, velY, velZ int
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewMoon(x, y, z int) *Moon {
|
||||||
|
return &Moon{
|
||||||
|
posX: x, posY: y, posZ: z,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (m *Moon) GetPotentialEnergy() int {
|
||||||
|
return helpers.AbsInt(m.posX) + helpers.AbsInt(m.posY) + helpers.AbsInt(m.posZ)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (m *Moon) GetKineticEnergy() int {
|
||||||
|
return helpers.AbsInt(m.velX) + helpers.AbsInt(m.velY) + helpers.AbsInt(m.velZ)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (m *Moon) Interact(n *Moon) {
|
||||||
|
if n.posX > m.posX {
|
||||||
|
n.velX--
|
||||||
|
m.velX++
|
||||||
|
} else if n.posX < m.posX {
|
||||||
|
n.velX++
|
||||||
|
m.velX--
|
||||||
|
}
|
||||||
|
if n.posY > m.posY {
|
||||||
|
n.velY--
|
||||||
|
m.velY++
|
||||||
|
} else if n.posY < m.posY {
|
||||||
|
n.velY++
|
||||||
|
m.velY--
|
||||||
|
}
|
||||||
|
if n.posZ > m.posZ {
|
||||||
|
n.velZ--
|
||||||
|
m.velZ++
|
||||||
|
} else if n.posZ < m.posZ {
|
||||||
|
n.velZ++
|
||||||
|
m.velZ--
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (m *Moon) Step() {
|
||||||
|
m.posX += m.velX
|
||||||
|
m.posY += m.velY
|
||||||
|
m.posZ += m.velZ
|
||||||
|
}
|
||||||
|
|
||||||
|
func (m *Moon) PosEquals(n *Moon) (bool, bool, bool) {
|
||||||
|
return (m.posX == n.posX), (m.posY == n.posY), (m.posZ == n.posZ)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (m Moon) String() string {
|
||||||
|
return fmt.Sprintf("pos=<x=%3d, y=%3d, z=%3d>, vel=<x=%3d, y=%3d, z=%3d>",
|
||||||
|
m.posX, m.posY, m.posZ,
|
||||||
|
m.velX, m.velY, m.velZ,
|
||||||
|
)
|
||||||
|
}
|
4
2019/day12/testinput1
Normal file
4
2019/day12/testinput1
Normal file
@ -0,0 +1,4 @@
|
|||||||
|
<x=-1, y=0, z=2>
|
||||||
|
<x=2, y=-10, z=-7>
|
||||||
|
<x=4, y=-8, z=8>
|
||||||
|
<x=3, y=5, z=-1>
|
4
2019/day12/testinput2
Normal file
4
2019/day12/testinput2
Normal file
@ -0,0 +1,4 @@
|
|||||||
|
<x=-8, y=-10, z=0>
|
||||||
|
<x=5, y=5, z=10>
|
||||||
|
<x=1, y=-7, z=3>
|
||||||
|
<x=9, y=-8, z=-3>
|
@ -27,6 +27,23 @@ const (
|
|||||||
MIN_INT = -MAX_INT - 1
|
MIN_INT = -MAX_INT - 1
|
||||||
)
|
)
|
||||||
|
|
||||||
|
// Find the greatest common denominator
|
||||||
|
func Gcd(x, y int) int {
|
||||||
|
for y != 0 {
|
||||||
|
x, y = y, x%y
|
||||||
|
}
|
||||||
|
return x
|
||||||
|
}
|
||||||
|
|
||||||
|
// Find the least common multiple, using gcd
|
||||||
|
func Lcm(a, b int, integers ...int) int {
|
||||||
|
result := a * b / Gcd(a, b)
|
||||||
|
for i := 0; i < len(integers); i++ {
|
||||||
|
result = Lcm(result, integers[i])
|
||||||
|
}
|
||||||
|
return result
|
||||||
|
}
|
||||||
|
|
||||||
func AbsInt(i int) int {
|
func AbsInt(i int) int {
|
||||||
if i < 0 {
|
if i < 0 {
|
||||||
return i * -1
|
return i * -1
|
||||||
|
Loading…
Reference in New Issue
Block a user