Compare commits

..

4 commits

Author SHA1 Message Date
Tristan Daniël Maat 85bbc6e9d8
WIP: Re-implement using ndarray 2020-12-15 18:56:57 +00:00
Tristan Daniël Maat 3c3ef92ff8
Re-implement day 11.1 with graphs
This is to have a potentially nicer way to iterate neighbours, as well
as recursive directions.

While the former is neater than it was previously, the latter sadly
wasn't possible after all, and it's very inefficient.
2020-12-15 18:56:54 +00:00
Tristan Daniël Maat 3ec82e117e
Complete day 11.1 2020-12-15 18:56:51 +00:00
Tristan Daniël Maat a3b9b63181
Complete day 13 2020-12-14 03:53:34 +00:00
4 changed files with 262 additions and 0 deletions

78
day-13/Cargo.lock generated Normal file
View file

@ -0,0 +1,78 @@
# This file is automatically @generated by Cargo.
# It is not intended for manual editing.
[[package]]
name = "day-13"
version = "0.1.0"
dependencies = [
"indoc",
]
[[package]]
name = "indoc"
version = "0.3.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "47741a8bc60fb26eb8d6e0238bbb26d8575ff623fdc97b1a2c00c050b9684ed8"
dependencies = [
"indoc-impl",
"proc-macro-hack",
]
[[package]]
name = "indoc-impl"
version = "0.3.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ce046d161f000fffde5f432a0d034d0341dc152643b2598ed5bfce44c4f3a8f0"
dependencies = [
"proc-macro-hack",
"proc-macro2",
"quote",
"syn",
"unindent",
]
[[package]]
name = "proc-macro-hack"
version = "0.5.19"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "dbf0c48bc1d91375ae5c3cd81e3722dff1abcf81a30960240640d223f59fe0e5"
[[package]]
name = "proc-macro2"
version = "1.0.24"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1e0704ee1a7e00d7bb417d0770ea303c1bccbabf0ef1667dae92b5967f5f8a71"
dependencies = [
"unicode-xid",
]
[[package]]
name = "quote"
version = "1.0.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "aa563d17ecb180e500da1cfd2b028310ac758de548efdd203e18f283af693f37"
dependencies = [
"proc-macro2",
]
[[package]]
name = "syn"
version = "1.0.54"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9a2af957a63d6bd42255c359c93d9bfdb97076bd3b820897ce55ffbfbf107f44"
dependencies = [
"proc-macro2",
"quote",
"unicode-xid",
]
[[package]]
name = "unicode-xid"
version = "0.2.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f7fe0bb3479651439c9112f72b6c505038574c9fbb575ed1bf3b797fa39dd564"
[[package]]
name = "unindent"
version = "0.1.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f14ee04d9415b52b3aeab06258a3f07093182b88ba0f9b8d203f211a7a7d41c7"

10
day-13/Cargo.toml Normal file
View file

@ -0,0 +1,10 @@
[package]
name = "day-13"
version = "0.1.0"
authors = ["Tristan Daniël Maat <tm@tlater.net>"]
edition = "2018"
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
[dependencies]
indoc = "0.3"

2
day-13/input Normal file
View file

@ -0,0 +1,2 @@
1000391
19,x,x,x,x,x,x,x,x,x,x,x,x,37,x,x,x,x,x,383,x,x,x,x,x,x,x,23,x,x,x,x,13,x,x,x,x,x,x,x,x,x,x,x,x,x,x,x,29,x,457,x,x,x,x,x,x,x,x,x,41,x,x,x,x,x,x,17

172
day-13/src/main.rs Normal file
View file

@ -0,0 +1,172 @@
use std::fs;
fn main() -> Result<(), Box<dyn std::error::Error>> {
let input = fs::read_to_string("input")?;
let (time, ids) = parse_notes(&input)?;
// Part 1
let (earliest, arrival) = find_closest_bus(time, &ids);
println!("{}", (arrival - time) * earliest);
// Part 2
let timestamp = find_gauss(&ids);
println!("{}", timestamp);
Ok(())
}
fn parse_notes(input: &str) -> Result<(u32, Vec<u32>), &str> {
let mut lines = input.lines();
let estimate = lines
.next()
.ok_or("Input too short")?
.parse()
.map_err(|_| "Estimate is not a number")?;
let ids = lines
.next()
.ok_or("Input too short")?
.split(',')
.map(|id| id.parse().unwrap_or(1))
.collect();
Ok((estimate, ids))
}
fn find_closest_bus(time: u32, ids: &Vec<u32>) -> (u32, u32) {
ids.iter()
.filter(|id| **id != 1)
.map(|id| {
let mut arrival = *id;
while arrival < time {
arrival += id
}
(*id, arrival)
})
.min_by_key(|id| id.1)
.expect("Must have at least one bus ID")
}
fn find_gauss(ids: &Vec<u32>) -> u128 {
let ids: Vec<u128> = ids.iter().map(|id| *id as u128).collect();
let product: u128 = ids.iter().product();
let gauss = |mut n: u128, mut d: u128, m: u128| -> u128 {
while d != 1 {
if m == 1 {
return 0;
};
let multiplier = if m > d {
m / d + (m % d != 0) as u128
} else {
1
};
n = (n * multiplier) % m;
d = (d * multiplier) % m;
}
n / d
};
(0..ids.len())
.map(|a| {
let b = product / ids[a];
let bi = gauss(1, b, ids[a]);
let a = (ids[a] * a as u128 - a as u128) % ids[a] as u128;
a * b * bi
})
.sum::<u128>()
% product
}
#[cfg(test)]
mod tests {
use super::*;
use indoc::indoc;
#[test]
fn test_simple() -> Result<(), Box<dyn std::error::Error>> {
let input = indoc!(
"939
7,13,x,x,59,x,31,19
"
);
let (time, ids) = parse_notes(input)?;
let (earliest, arrival) = find_closest_bus(time, &ids);
assert_eq!(arrival, 944);
Ok(())
}
#[test]
fn test_simple2() -> Result<(), Box<dyn std::error::Error>> {
let input = indoc!(
"939
17,x,13,19
"
);
let (time, ids) = parse_notes(input)?;
let timestamp = find_gauss(&ids);
assert_eq!(timestamp, 3417);
Ok(())
}
#[test]
fn test_simple3() -> Result<(), Box<dyn std::error::Error>> {
let input = indoc!(
"939
7,13,x,x,59,x,31,19
"
);
let (time, ids) = parse_notes(input)?;
let timestamp = find_gauss(&ids);
assert_eq!(timestamp, 1068781);
Ok(())
}
#[test]
fn test_simple4() -> Result<(), Box<dyn std::error::Error>> {
let input = indoc!(
"939
67,7,59,61
"
);
let (time, ids) = parse_notes(input)?;
let timestamp = find_gauss(&ids);
assert_eq!(timestamp, 754018);
Ok(())
}
#[test]
fn test_simple5() -> Result<(), Box<dyn std::error::Error>> {
let input = indoc!(
"939
67,x,7,59,61
"
);
let (time, ids) = parse_notes(input)?;
let timestamp = find_gauss(&ids);
assert_eq!(timestamp, 779210);
Ok(())
}
}