Skip to content

Commit

Permalink
Year 2015: Day 24
Browse files Browse the repository at this point in the history
  • Loading branch information
joshleaves committed Mar 2, 2024
1 parent f463d09 commit 1f190c1
Show file tree
Hide file tree
Showing 7 changed files with 148 additions and 2 deletions.
2 changes: 1 addition & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[package]
name = "advent-rs"
version = "2015.23.1"
version = "2015.24.1"
edition = "2021"
authors = ["Arnaud 'red' Rouyer"]
readme = "README.md"
Expand Down
25 changes: 25 additions & 0 deletions NOTES_2015.md
Original file line number Diff line number Diff line change
Expand Up @@ -663,3 +663,28 @@ year_2015::day_23/year_2015::day_23_v2
</details>
Heh, I love this one, whether it's in Ruby or in Rust.

## Day 24: It Hangs in the Balance

<details>
<summary>📊Tests and benchmarks</summary>

```
test year_2015::day_24::tests::works_with_samples_v1 ... ok
test year_2015::day_24::tests::works_with_samples_v2 ... ok
test year_2015::tests::day_24 ... ok
year_2015::day_24/year_2015::day_24_v1
time: [15.294 ms 15.326 ms 15.360 ms]
year_2015::day_24/year_2015::day_24_v2
time: [3.5474 ms 3.5596 ms 3.5719 ms]
```
</details>

<details>
<summary>Ruby version comments</summary>

>While this looks like YABA (Yet Another Bruteforce Algorithm), Ruby's got a very useful [`#combination`](https://ruby-doc.org/3.2.2/Array.html#method-i-combination) method that will generate permutations around for you. And of course, knowing when to exit the loop at the best time is half the battle.
</details>
Would you believe it? The `combinations(n)` method also exists in Rust!
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
As I said, [Consistency is hard](https://github.com/joshleaves/advent-rb), and I haven't taken the time to pick up a new language in quite a while.

I'm also adding notes that may be useful if you're (like me) discovering Rust:
- [2015, up to day 23](NOTES_2015.md)
- [2015, up to day 24](NOTES_2015.md)

# Regarding style rules
I'm gonna use a mix of what `cargo fmt` does, with some stuff that feels more natural to me.
Expand Down
11 changes: 11 additions & 0 deletions benches/advent-bench.rs
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ use advent_rs::year_2015::day_20;
use advent_rs::year_2015::day_21;
use advent_rs::year_2015::day_22;
use advent_rs::year_2015::day_23;
use advent_rs::year_2015::day_24;
use criterion::{black_box, criterion_group, criterion_main, Criterion};

pub fn year_2015_benchmark(c: &mut Criterion) {
Expand Down Expand Up @@ -255,6 +256,16 @@ pub fn year_2015_benchmark(c: &mut Criterion) {
b.iter(|| day_23::day_23_v2(black_box(input_year_2015_day_23)))
});
g2015_day_23.finish();

let mut g2015_day_24 = c.benchmark_group("year_2015::day_24");
let input_year_2015_day_24 = include_str!("../inputs/year_2015_day_24_input");
g2015_day_24.bench_function("year_2015::day_24_v1", |b| {
b.iter(|| day_24::day_24_v1(black_box(input_year_2015_day_24)))
});
g2015_day_24.bench_function("year_2015::day_24_v2", |b| {
b.iter(|| day_24::day_24_v2(black_box(input_year_2015_day_24)))
});
g2015_day_24.finish();
}

criterion_group!(benches, year_2015_benchmark);
Expand Down
28 changes: 28 additions & 0 deletions inputs/year_2015_day_24_input
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
1
3
5
11
13
17
19
23
29
31
37
41
43
47
53
59
67
71
73
79
83
89
97
101
103
107
109
113
9 changes: 9 additions & 0 deletions src/year_2015.rs
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,7 @@ pub mod day_20;
pub mod day_21;
pub mod day_22;
pub mod day_23;
pub mod day_24;

/// Returns the solution for a specified exercise and input.
///
Expand Down Expand Up @@ -108,6 +109,7 @@ pub fn solve(day: u8, part: u8, input: impl Into<String>) -> Option<String> {
21 => Some(format!("{}", day_21::day_21(part, input))),
22 => Some(format!("{}", day_22::day_22(part, input))),
23 => Some(format!("{}", day_23::day_23(part, input))),
24 => Some(format!("{}", day_24::day_24(part, input))),
_ => None,
}
}
Expand Down Expand Up @@ -275,4 +277,11 @@ mod tests {
assert_eq!(day_23::day_23_v1(input), 307);
assert_eq!(day_23::day_23_v2(input), 160);
}

#[test]
fn day_24() {
let input = include_str!("../inputs/year_2015_day_24_input");
assert_eq!(day_24::day_24_v1(input), 10_439_961_859);
assert_eq!(day_24::day_24_v2(input), 72_050_269);
}
}
73 changes: 73 additions & 0 deletions src/year_2015/day_24.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
//! Advent of Code 2015: Day 24: It Hangs in the Balance
use itertools::Itertools;

fn solve(numbers: &Vec<u64>, magic: u64) -> u64 {
let mut combos: Vec<Vec<&u64>> = vec![];
for i in 1..=numbers.len() {
let mut results: Vec<Vec<&u64>> = numbers.iter().combinations(i).collect_vec();
results.retain(|arr| arr.iter().copied().sum::<u64>() == magic);
if results.is_empty() {
continue;
}
if results.len() > 0 {
combos = results;
break;
}
}
let combos_values: Vec<u64> = combos
.iter()
.map(|combo| combo.iter().fold(1, |acc, elt| acc * *elt))
.collect_vec();

if let Some(min_value) = combos_values.iter().min() {
*min_value
} else {
0
}
}

fn parse_input(input: &str) -> Vec<u64> {
let mut numbers: Vec<u64> = vec![];
for line in input.lines() {
let Ok(number) = line.parse::<u64>() else {
panic!("Invalid input: {}", line)
};
numbers.push(number);
}

numbers
}

pub fn day_24_v1(input: impl Into<String>) -> u64 {
let numbers = parse_input(&input.into());
let magic = numbers.iter().sum::<u64>() / 3;

solve(&numbers, magic)
}

pub fn day_24_v2(input: impl Into<String>) -> u64 {
let numbers = parse_input(&input.into());
let magic = numbers.iter().sum::<u64>() / 4;

solve(&numbers, magic)
}

solvable!(day_24, day_24_v1, day_24_v2, u64);

#[cfg(test)]
mod tests {
use super::*;

#[test]
fn works_with_samples_v1() {
let sample_one = "1\n2\n3\n4\n5\n7\n8\n9\n10\n11";
assert_eq!(day_24_v1(sample_one), 99);
}

#[test]
fn works_with_samples_v2() {
let sample_one = "1\n2\n3\n4\n5\n7\n8\n9\n10\n11";
assert_eq!(day_24_v2(sample_one), 44);
}
}

0 comments on commit 1f190c1

Please sign in to comment.