Skip to content

Commit

Permalink
Year 2019 Day 12
Browse files Browse the repository at this point in the history
  • Loading branch information
maneatingape committed Sep 4, 2023
1 parent 165a7c2 commit 0352883
Show file tree
Hide file tree
Showing 8 changed files with 122 additions and 0 deletions.
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -204,6 +204,7 @@ pie
| 9 | [Sensor Boost](https://adventofcode.com/2019/day/9) | [Source](src/year2019/day09.rs) | 1356 |
| 10 | [Monitoring Station](https://adventofcode.com/2019/day/10) | [Source](src/year2019/day10.rs) | 1001 |
| 11 | [Space Police](https://adventofcode.com/2019/day/11) | [Source](src/year2019/day11.rs) | 470 |
| 12 | [The N-Body Problem](https://adventofcode.com/2019/day/12) | [Source](src/year2019/day12.rs) | 1024 |

## 2015

Expand Down
1 change: 1 addition & 0 deletions benches/benchmark.rs
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,7 @@ mod year2019 {
benchmark!(year2019, day09);
benchmark!(year2019, day10);
benchmark!(year2019, day11);
benchmark!(year2019, day12);
}

mod year2020 {
Expand Down
4 changes: 4 additions & 0 deletions input/year2019/day12.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
<x=17, y=-12, z=13>
<x=2, y=1, z=1>
<x=-1, y=-17, z=7>
<x=12, y=-14, z=18>
1 change: 1 addition & 0 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -113,6 +113,7 @@ pub mod year2019 {
pub mod day09;
pub mod day10;
pub mod day11;
pub mod day12;
}

/// # What could go wrong trying to enjoy a well deserved vacation?
Expand Down
1 change: 1 addition & 0 deletions src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -98,6 +98,7 @@ fn all_solutions() -> Vec<Solution> {
solution!(year2019, day09),
solution!(year2019, day10),
solution!(year2019, day11),
solution!(year2019, day12),
// 2020
solution!(year2020, day01),
solution!(year2020, day02),
Expand Down
94 changes: 94 additions & 0 deletions src/year2019/day12.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,94 @@
//! # The N-Body Problem
//!
//! There are two insights needed to solve part two:
//!
//! * Each axis is independent
//! * Each axis is periodic somewhat like
//! [simple harmonic motion](https://en.wikipedia.org/wiki/Simple_harmonic_motion).
//! The velocity returns to zero twice per period.
//!
//! First find the period of each axis, then the answer is the
//! [least common multiple](https://en.wikipedia.org/wiki/Least_common_multiple) of all three
//! combined.
//!
//! The [`signum`] function comes in handy when updating the velocity.
//!
//! [`signum`]: i32::signum
use crate::util::math::*;
use crate::util::parse::*;

type Axis = [i32; 8];
type Input = [Axis; 3];

/// Group each axis together
pub fn parse(input: &str) -> Input {
let n: Vec<_> = input.iter_signed().collect();
[
[n[0], n[3], n[6], n[9], 0, 0, 0, 0],
[n[1], n[4], n[7], n[10], 0, 0, 0, 0],
[n[2], n[5], n[8], n[11], 0, 0, 0, 0],
]
}

pub fn part1(input: &Input) -> i32 {
let [mut x, mut y, mut z] = *input;

for _ in 0..1000 {
x = step(x);
y = step(y);
z = step(z);
}

let e: Vec<_> = (0..8).map(|i| x[i].abs() + y[i].abs() + z[i].abs()).collect();
e[0] * e[4] + e[1] * e[5] + e[2] * e[6] + e[3] * e[7]
}

pub fn part2(input: &Input) -> usize {
let [mut x, mut y, mut z] = *input;
let [mut a, mut b, mut c] = [0, 0, 0];
let mut count = 0;

while a == 0 || b == 0 || c == 0 {
count += 1;

if a == 0 {
x = step(x);
if stopped(x) {
a = count;
}
}

if b == 0 {
y = step(y);
if stopped(y) {
b = count;
}
}

if c == 0 {
z = step(z);
if stopped(z) {
c = count;
}
}
}

// a, b and c are the half period, so multiply by 2 to get final result.
2 * a.lcm(b.lcm(c))
}

fn step(axis: Axis) -> Axis {
// "p" is position and "v" velocity
let [p0, p1, p2, p3, v0, v1, v2, v3] = axis;

let n0 = v0 + (p1 - p0).signum() + (p2 - p0).signum() + (p3 - p0).signum();
let n1 = v1 + (p0 - p1).signum() + (p2 - p1).signum() + (p3 - p1).signum();
let n2 = v2 + (p0 - p2).signum() + (p1 - p2).signum() + (p3 - p2).signum();
let n3 = v3 + (p0 - p3).signum() + (p1 - p3).signum() + (p2 - p3).signum();

[p0 + n0, p1 + n1, p2 + n2, p3 + n3, n0, n1, n2, n3]
}

fn stopped(axis: Axis) -> bool {
axis[4] == 0 && axis[5] == 0 && axis[6] == 0 && axis[7] == 0
}
1 change: 1 addition & 0 deletions tests/test.rs
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,7 @@ mod year2019 {
mod day09_test;
mod day10_test;
mod day11_test;
mod day12_test;
}

mod year2020 {
Expand Down
19 changes: 19 additions & 0 deletions tests/year2019/day12_test.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
use aoc::year2019::day12::*;

const EXAMPLE: &str = "
<x=-8, y=-10, z=0>
<x=5, y=5, z=10>
<x=2, y=-7, z=3>
<x=9, y=-8, z=-3>";

#[test]
fn part1_test() {
let input = parse(EXAMPLE);
assert_eq!(part1(&input), 14645);
}

#[test]
fn part2_test() {
let input = parse(EXAMPLE);
assert_eq!(part2(&input), 4686774924);
}

0 comments on commit 0352883

Please sign in to comment.