-
Notifications
You must be signed in to change notification settings - Fork 5
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
165a7c2
commit 0352883
Showing
8 changed files
with
122 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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 | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -53,6 +53,7 @@ mod year2019 { | |
mod day09_test; | ||
mod day10_test; | ||
mod day11_test; | ||
mod day12_test; | ||
} | ||
|
||
mod year2020 { | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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); | ||
} |