Compare commits

...

2 Commits

Author SHA1 Message Date
55a53e14f7 [CLEANUP] Removed some unused Day13 code 2020-12-14 09:09:16 +01:00
1b1fe127c3 [TASK] Solved day 13 2020-12-14 09:05:46 +01:00
4 changed files with 102 additions and 3 deletions

2
input/day13.txt Normal file
View File

@@ -0,0 +1,2 @@
1006605
19,x,x,x,x,x,x,x,x,x,x,x,x,37,x,x,x,x,x,883,x,x,x,x,x,x,x,23,x,x,x,x,13,x,x,x,17,x,x,x,x,x,x,x,x,x,x,x,x,x,797,x,x,x,x,x,x,x,x,x,41,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,29

7
input/day13_example.txt Normal file
View File

@@ -0,0 +1,7 @@
939
3,7919
7,31
67,7,x,59,61
1789,37,47,1889
7,13,x,x,59,x,31,19
67,x,7,59,61

73
src/day13.rs Normal file
View File

@@ -0,0 +1,73 @@
use super::util;
pub fn solve() {
let lines = util::read_file("input/day13.txt");
let target_time = lines[0].parse::<u32>().unwrap();
let part1 = lines[1].split(",").filter(|s| s != &"x")
.map(|s| s.parse::<u32>().unwrap())
.map(|t| (t, t - (target_time % t)))
.min_by_key(|t| t.1)
.map(|bt| bt.0 * bt.1)
.unwrap();
println!("Day 13 Part 1: {}", part1);
let schedule_parts = lines[1].split(",").collect::<Vec<_>>();
let mut schedules = Vec::new();
// print!("[");
for i in 0..schedule_parts.len() {
let s = schedule_parts[i];
if s == "x" { continue; }
let bus_id = s.parse::<u64>().unwrap();
let mut offset = i as u64;
if offset > bus_id { offset = offset % bus_id; }
// print!("(x + {}) mod {} = 0, ", offset, bus_id );
schedules.push(Schedule {
bus_id, offset
});
}
// println!("]");
schedules.sort_by_key(|s| u64::max_value() - s.bus_id);
let part2 = find_fitting(&schedules);
println!("Day 13 Part 2: {}", part2);
}
fn find_fitting(schedules: &Vec<Schedule>) -> u64 {
let mut root_schedule = find_fitting_match(&schedules[0], &schedules[1]);
for schedule in schedules.iter().skip(2) {
root_schedule = find_fitting_match(schedule, &root_schedule)
}
return root_schedule.bus_id - root_schedule.offset;
}
fn find_fitting_match(s1: &Schedule, s2: &Schedule) -> Schedule {
// We know that the pattern repeats every s1.bus_id * s2.bus_id (and at no other times, since all bus_ids are at least co-prime).
// So all we need to do is find out what offset works:
let match_bus_id = s1.bus_id * s2.bus_id;
for mult in 0..s1.bus_id {
let offset = mult * s2.bus_id + s2.offset;
assert!(offset < match_bus_id, "Offset must not be bigger than the bus_id");
let solution = match_bus_id - offset;
if (solution + s1.offset) % s1.bus_id == 0 {
return Schedule {
bus_id: match_bus_id,
offset,
}
}
}
panic!("Couldn't find match!!!");
}
#[derive(Debug)]
struct Schedule {
bus_id: u64,
offset: u64,
}

View File

@@ -14,9 +14,10 @@ mod day9;
mod day10;
mod day11;
mod day12;
mod day13;
const MAX_DAY: u8 = 12;
const BENCHMARK_AMOUNT: u32 = 100;
const MAX_DAY: u8 = 13;
const BENCHMARK_AMOUNT: u32 = 1000;
fn solve(day: u8) {
match day {
@@ -32,13 +33,13 @@ fn solve(day: u8) {
10 => day10::solve(),
11 => day11::solve(),
12 => day12::solve(),
13 => day13::solve(),
_ => println!("This day is not yet implemented")
}
}
fn main() {
let args: Vec<String> = std::env::args().collect();
let day_arg_idx = args.iter().position(|a| a == "-d");
@@ -51,8 +52,11 @@ fn main() {
// This is essentially the warmup for the benchmark:
run_once(single_day, day, &mut bench_results);
let first_run_time = bench_results[0];
if benchmark {
// Ignore the warmup run in the rest of the benchmark:
bench_results.clear();
for _ in 0..BENCHMARK_AMOUNT {
run_once(single_day, day, &mut bench_results);
}
@@ -61,6 +65,19 @@ fn main() {
let avg_runtime: u128 = bench_results.iter().sum::<u128>() / (bench_results.len() as u128);
println!("Execution took {} μs {}", avg_runtime, if benchmark { "on average" } else { "" });
if benchmark {
bench_results.sort();
println!("Min: {} μs, Max: {} μs, Median: {} μs",
bench_results[0],
bench_results[bench_results.len() - 1],
bench_results[bench_results.len() / 2]
);
println!("First time took {} μs", first_run_time);
for res in bench_results {
println!("{}", res);
}
}
}
fn run_once(single_day: bool, day: u8, bench_results: &mut Vec<u128>) {