Rust solutions
This commit is contained in:
commit
59264dfa91
|
@ -0,0 +1,56 @@
|
|||
# This file is automatically @generated by Cargo.
|
||||
# It is not intended for manual editing.
|
||||
[[package]]
|
||||
name = "aho-corasick"
|
||||
version = "0.7.15"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "7404febffaa47dac81aa44dba71523c9d069b1bdc50a77db41195149e17f68e5"
|
||||
dependencies = [
|
||||
"memchr",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "aoc"
|
||||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"regex",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "lazy_static"
|
||||
version = "1.4.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646"
|
||||
|
||||
[[package]]
|
||||
name = "memchr"
|
||||
version = "2.3.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "0ee1c47aaa256ecabcaea351eae4a9b01ef39ed810004e298d2511ed284b1525"
|
||||
|
||||
[[package]]
|
||||
name = "regex"
|
||||
version = "1.4.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "38cf2c13ed4745de91a5eb834e11c00bcc3709e773173b2ce4c56c9fbde04b9c"
|
||||
dependencies = [
|
||||
"aho-corasick",
|
||||
"memchr",
|
||||
"regex-syntax",
|
||||
"thread_local",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "regex-syntax"
|
||||
version = "0.6.21"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "3b181ba2dcf07aaccad5448e8ead58db5b742cf85dfe035e2227f137a539a189"
|
||||
|
||||
[[package]]
|
||||
name = "thread_local"
|
||||
version = "1.0.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d40c6d1b69745a6ec6fb1ca717914848da4b44ae29d9b3080cbee91d72a69b14"
|
||||
dependencies = [
|
||||
"lazy_static",
|
||||
]
|
|
@ -0,0 +1,10 @@
|
|||
[package]
|
||||
name = "aoc"
|
||||
version = "0.1.0"
|
||||
authors = ["Sijmen Schoon <me@sijmenschoon.nl>"]
|
||||
edition = "2018"
|
||||
|
||||
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
||||
|
||||
[dependencies]
|
||||
regex = "1.4.2"
|
|
@ -0,0 +1,286 @@
|
|||
use std::time::Duration;
|
||||
|
||||
mod day01 {
|
||||
use std::{collections::HashMap, time::Duration, time::Instant};
|
||||
|
||||
pub fn run(print: bool) -> Duration {
|
||||
let file_string = std::fs::read_to_string("inputs/day01").unwrap();
|
||||
let instant = Instant::now();
|
||||
|
||||
let entries: Vec<usize> = file_string.lines().flat_map(|line| line.parse()).collect();
|
||||
let mut sums = HashMap::new();
|
||||
|
||||
let mut part1 = None;
|
||||
for i in &entries {
|
||||
for j in &entries {
|
||||
if i + j < 2020 {
|
||||
sums.insert(i + j, i * j);
|
||||
} else if i + j == 2020 {
|
||||
part1 = Some(i * j);
|
||||
}
|
||||
}
|
||||
}
|
||||
let part1 = part1.unwrap();
|
||||
|
||||
let part2 = entries
|
||||
.iter()
|
||||
.find_map(|i| sums.get(&(2020 - i)).map(|mul| i * mul))
|
||||
.unwrap();
|
||||
|
||||
let elapsed = instant.elapsed();
|
||||
if print {
|
||||
dbg!(elapsed, part1, part2);
|
||||
}
|
||||
|
||||
elapsed
|
||||
}
|
||||
}
|
||||
|
||||
mod day02 {
|
||||
use std::time::{Duration, Instant};
|
||||
|
||||
pub fn run(print: bool) -> Duration {
|
||||
let file_string = std::fs::read_to_string("inputs/day02").unwrap();
|
||||
let instant = Instant::now();
|
||||
|
||||
let rules: Vec<(usize, usize, char, &str)> = file_string
|
||||
.lines()
|
||||
.flat_map(|rule| {
|
||||
let mut splitc = rule.splitn(2, ' ');
|
||||
let mut split_range = splitc.next()?.split('-');
|
||||
|
||||
let min: usize = split_range.next()?.parse().ok()?;
|
||||
let max: usize = split_range.next()?.parse().ok()?;
|
||||
|
||||
let rest = splitc.next()?;
|
||||
let c = rest.chars().next()?;
|
||||
let pw = &rest[3..];
|
||||
|
||||
Some((min, max, c, pw))
|
||||
})
|
||||
.collect();
|
||||
|
||||
let part1 = rules
|
||||
.iter()
|
||||
.filter(|(min, max, c, pw)| {
|
||||
let c = &pw.chars().filter(|n| n == c).count();
|
||||
min <= c && c <= max
|
||||
})
|
||||
.count();
|
||||
|
||||
let part2 = rules
|
||||
.iter()
|
||||
.filter(|(min, max, c, pw)| {
|
||||
let mut chars = pw.chars();
|
||||
let a = chars.nth(min - 1) == Some(*c);
|
||||
let b = chars.nth(max - min - 1) == Some(*c);
|
||||
a ^ b
|
||||
})
|
||||
.count();
|
||||
|
||||
let elapsed = instant.elapsed();
|
||||
if print {
|
||||
dbg!(elapsed, part1, part2);
|
||||
}
|
||||
elapsed
|
||||
}
|
||||
}
|
||||
|
||||
mod day03 {
|
||||
use std::time::{Duration, Instant};
|
||||
|
||||
fn count(rows: &[Vec<char>], dx: usize, dy: usize) -> usize {
|
||||
let mut x = 0;
|
||||
let mut trees = 0;
|
||||
for y in (0..rows.len()).step_by(dy) {
|
||||
let row = &rows[y];
|
||||
|
||||
if row[x] == '#' {
|
||||
trees += 1;
|
||||
}
|
||||
|
||||
x = (x + dx) % row.len();
|
||||
}
|
||||
trees
|
||||
}
|
||||
|
||||
pub fn run(print: bool) -> Duration {
|
||||
let file_string = std::fs::read_to_string("inputs/day3").unwrap();
|
||||
|
||||
let instant = Instant::now();
|
||||
|
||||
let rows: Vec<Vec<char>> = file_string
|
||||
.lines()
|
||||
.map(|line| line.chars().collect())
|
||||
.collect();
|
||||
|
||||
let part1 = count(&rows, 3, 1);
|
||||
|
||||
let part2 = part1
|
||||
* [(1, 1), (5, 1), (7, 1), (1, 2)]
|
||||
.iter()
|
||||
.map(|(dx, dy)| count(&rows, *dx, *dy))
|
||||
.fold(1, |acc, element| acc * element);
|
||||
|
||||
let elapsed = instant.elapsed();
|
||||
if print {
|
||||
dbg!(elapsed, part1, part2);
|
||||
}
|
||||
|
||||
elapsed
|
||||
}
|
||||
}
|
||||
|
||||
mod day04 {
|
||||
use std::time::{Duration, Instant};
|
||||
|
||||
fn between(field: &str, lower: i32, higher: i32) -> bool {
|
||||
let n: i32 = field.parse().unwrap();
|
||||
n >= lower && n <= higher
|
||||
}
|
||||
|
||||
pub fn run(print: bool) -> Duration {
|
||||
let input = std::fs::read_to_string("inputs/day04").unwrap();
|
||||
|
||||
let now = Instant::now();
|
||||
|
||||
let passports: Vec<_> = input
|
||||
.split("\n\n")
|
||||
.map(|p| p.replace('\n', " ").trim().to_string())
|
||||
.collect();
|
||||
|
||||
let valid_passports = passports.iter().filter(|p| {
|
||||
p.contains("byr")
|
||||
&& p.contains("iyr")
|
||||
&& p.contains("eyr")
|
||||
&& p.contains("hgt")
|
||||
&& p.contains("hcl")
|
||||
&& p.contains("ecl")
|
||||
&& p.contains("pid")
|
||||
});
|
||||
|
||||
let mut part1 = 0;
|
||||
|
||||
let part2 = valid_passports
|
||||
.filter(|p| {
|
||||
part1 += 1;
|
||||
|
||||
let mut valid = true;
|
||||
for field in p.split(' ') {
|
||||
let mut parts = field.split(':');
|
||||
let label = parts.next().unwrap();
|
||||
let value = parts.next().unwrap();
|
||||
|
||||
valid = valid
|
||||
&& match label {
|
||||
"byr" => between(value, 1920, 2002),
|
||||
"iyr" => between(value, 2010, 2020),
|
||||
"eyr" => between(value, 2020, 2030),
|
||||
"hgt" => {
|
||||
let height = &value[..value.len() - 2];
|
||||
(value.ends_with("in") && between(height, 59, 76))
|
||||
|| (value.ends_with("cm") && between(height, 150, 193))
|
||||
}
|
||||
"hcl" => value.starts_with("#"),
|
||||
"ecl" => {
|
||||
value == "amb"
|
||||
|| value == "blu"
|
||||
|| value == "brn"
|
||||
|| value == "gry"
|
||||
|| value == "grn"
|
||||
|| value == "hzl"
|
||||
|| value == "oth"
|
||||
}
|
||||
"pid" => value.len() == 9,
|
||||
"cid" => true,
|
||||
_ => false,
|
||||
}
|
||||
}
|
||||
valid
|
||||
})
|
||||
.count();
|
||||
|
||||
let elapsed = now.elapsed();
|
||||
if print {
|
||||
dbg!(elapsed, part1, part2);
|
||||
}
|
||||
|
||||
elapsed
|
||||
}
|
||||
}
|
||||
|
||||
mod day05 {
|
||||
use std::time::{Duration, Instant};
|
||||
|
||||
pub fn run(print: bool) -> Duration {
|
||||
let input = std::fs::read_to_string("inputs/day05").unwrap();
|
||||
let instant = Instant::now();
|
||||
|
||||
let passes: Vec<_> = input.lines().collect();
|
||||
let mut ids: Vec<_> = passes
|
||||
.iter()
|
||||
.map(|pass| {
|
||||
let mut row_min = 0;
|
||||
let mut row_max = 128;
|
||||
let mut column_min = 0;
|
||||
let mut column_max = 8;
|
||||
|
||||
for c in pass.chars() {
|
||||
match c {
|
||||
'F' => row_max = (row_min + row_max) / 2,
|
||||
'B' => row_min = (row_min + row_max) / 2,
|
||||
'L' => column_max = (column_min + column_max) / 2,
|
||||
'R' => column_min = (column_min + column_max) / 2,
|
||||
_ => (),
|
||||
};
|
||||
}
|
||||
|
||||
row_min * 8 + column_min
|
||||
})
|
||||
.collect();
|
||||
|
||||
ids.sort();
|
||||
|
||||
let part1 = ids.iter().max().unwrap();
|
||||
|
||||
let part2 = ids
|
||||
.windows(2)
|
||||
.find_map(|window| {
|
||||
if window[0] + 2 == window[1] {
|
||||
Some(window[0] + 1)
|
||||
} else {
|
||||
None
|
||||
}
|
||||
})
|
||||
.unwrap();
|
||||
|
||||
let elapsed = instant.elapsed();
|
||||
if print {
|
||||
dbg!(elapsed, part1, part2);
|
||||
}
|
||||
|
||||
elapsed
|
||||
}
|
||||
}
|
||||
|
||||
fn main() {
|
||||
let days = [day01::run, day02::run, day03::run, day04::run, day05::run];
|
||||
|
||||
if let Some(day) = std::env::args().nth(1) {
|
||||
let day: usize = day.parse().expect("day not an integer");
|
||||
if day > 0 {
|
||||
days[day - 1](true);
|
||||
}
|
||||
} else {
|
||||
let repetitions = 2000;
|
||||
let mut total = Duration::new(0, 0);
|
||||
|
||||
for day in 0..days.len() {
|
||||
for _ in 0..repetitions {
|
||||
total += days[day](false) / repetitions;
|
||||
}
|
||||
}
|
||||
|
||||
dbg!(total);
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue