commit c9479238ea02674b65fde86c1723427ee65834c9
parent 745524e95d34e597a62a3d0c8fdb5a16ef203dfb
Author: Louis Burda <quent.burda@gmail.com>
Date: Sat, 18 Dec 2021 16:01:35 +0100
Refactor all repo structure
Diffstat:
24 files changed, 274 insertions(+), 322 deletions(-)
diff --git a/lib/aoc/src/lib.rs b/lib/aoc/src/lib.rs
@@ -2,19 +2,24 @@ use std::env;
use std::fs;
use std::process::exit;
+#[derive(PartialEq, PartialOrd)]
pub enum Loglvl {
LogNone = 0,
LogVerb,
+ LogDebug,
LogAll
}
pub struct Info {
- pub debug: Loglvl,
+ pub verbose: bool,
+ pub debug: bool,
+
pub filename: String,
pub input: String,
- pub solution: Option<String>,
+ pub part: u32,
+
+ pub solution: Option<&'static str>,
pub answer: Option<String>,
- pub part: u32
}
#[macro_export]
@@ -25,6 +30,24 @@ macro_rules! die {
}
}
+#[macro_export]
+macro_rules! debug {
+ ($aoc:expr, $( $arg:expr ),*) => {
+ if $aoc.debug {
+ eprint!($( $arg ), *);
+ }
+ }
+}
+
+#[macro_export]
+macro_rules! verbose {
+ ($aoc:expr, $( $arg:expr ),*) => {
+ if $aoc.verbose {
+ eprint!($( $arg ), *);
+ }
+ }
+}
+
pub fn to_loglvl(val: u32) -> Loglvl {
match val {
0 => return Loglvl::LogNone,
@@ -36,12 +59,13 @@ pub fn to_loglvl(val: u32) -> Loglvl {
pub fn run(part1: fn(info: &mut Info), part2: fn(info: &mut Info)) {
let mut info = Info {
+ verbose: false,
+ debug: false,
filename: "input".to_string(),
- debug: Loglvl::LogNone,
input: "".to_string(),
+ part: 0,
solution: None,
answer: None,
- part: 0
};
let input_file = env::var("AOCINPUT");
@@ -58,7 +82,9 @@ pub fn run(part1: fn(info: &mut Info), part2: fn(info: &mut Info)) {
let debug = env::var("AOCDEBUG");
if debug.is_ok() {
let num = debug.unwrap().parse::<u32>().unwrap();
- info.debug = to_loglvl(num);
+ let lvl = to_loglvl(num);
+ info.verbose = lvl >= Loglvl::LogVerb;
+ info.debug = lvl >= Loglvl::LogDebug;
}
let args: Vec<String> = env::args().collect();
diff --git a/src/01/src/main.rs b/src/01/src/main.rs
@@ -1,5 +1,5 @@
-fn part1(info: &mut aoc::Info) {
- let vals : Vec<u32> = info.input.lines()
+fn part1(aoc: &mut aoc::Info) {
+ let vals : Vec<u32> = aoc.input.lines()
.map(|x| x.parse().unwrap())
.collect();
@@ -12,12 +12,12 @@ fn part1(info: &mut aoc::Info) {
prev = v;
}
- info.solution = Some("1692".to_string());
- info.answer = Some(format!("{}", count));
+ aoc.answer = Some(format!("{}", count));
+ aoc.solution = Some("1692");
}
-fn part2(info: &mut aoc::Info) {
- let vals : Vec<u32> = info.input.lines()
+fn part2(aoc: &mut aoc::Info) {
+ let vals : Vec<u32> = aoc.input.lines()
.map(|x| x.parse().unwrap())
.collect();
@@ -31,8 +31,8 @@ fn part2(info: &mut aoc::Info) {
prev = Some(sum);
}
- info.solution = Some("1724".to_string());
- info.answer = Some(format!("{}", count));
+ aoc.answer = Some(format!("{}", count));
+ aoc.solution = Some("1724");
}
fn main() {
diff --git a/src/02/Cargo.toml b/src/02/Cargo.toml
@@ -1,7 +1,7 @@
[package]
-name = "aoc"
+name = "day02"
version = "0.1.0"
edition = "2021"
[dependencies]
-
+aoc = { path = "../../lib/aoc" }
diff --git a/src/02/src/main.rs b/src/02/src/main.rs
@@ -1,20 +1,5 @@
-use std::fs;
-use std::env;
-
-fn main() {
- let args: Vec<String> = env::args().collect();
- if args[1] == "1" {
- part1();
- } else if args[1] == "2" {
- part2();
- } else {
- eprintln!("No such part\n");
- }
-}
-
-fn part1() {
- let content : String = fs::read_to_string("input").expect("no file");
- let lines : Vec<&str> = content.lines().collect();
+fn part1(aoc: &mut aoc::Info) {
+ let lines : Vec<&str> = aoc.input.lines().collect();
let mut dist : u32 = 0;
let mut depth : u32 = 0;
@@ -29,12 +14,13 @@ fn part1() {
depth -= val;
}
}
- println!("{}", depth * dist);
+
+ aoc.answer = Some(format!("{}", depth * dist));
+ aoc.solution = Some("2039912");
}
-fn part2() {
- let content : String = fs::read_to_string("input").expect("no file");
- let lines : Vec<&str> = content.lines().collect();
+fn part2(aoc: &mut aoc::Info) {
+ let lines : Vec<&str> = aoc.input.lines().collect();
let mut dist : u32 = 0;
let mut aim : u32 = 0;
@@ -51,6 +37,11 @@ fn part2() {
aim -= val;
}
}
- println!("{}", depth * dist);
+
+ aoc.answer = Some(format!("{}", depth * dist));
+ aoc.solution = Some("1942068080");
}
+fn main() {
+ aoc::run(part1, part2);
+}
diff --git a/src/03/Cargo.toml b/src/03/Cargo.toml
@@ -1,7 +1,7 @@
[package]
-name = "aoc"
+name = "day03"
version = "0.1.0"
edition = "2021"
[dependencies]
-
+aoc = { path = "../../lib/aoc" }
diff --git a/src/03/src/main.rs b/src/03/src/main.rs
@@ -1,17 +1,3 @@
-use std::fs;
-use std::env;
-
-fn main() {
- let args: Vec<String> = env::args().collect();
- if args[1] == "1" {
- part1();
- } else if args[1] == "2" {
- part2();
- } else {
- eprintln!("No such part\n");
- }
-}
-
fn filter_lines<T>(lines: &Vec<&str>, char_sel : T) -> u32 where T: Fn(u32, u32) -> char {
let mut cands : Vec<&str> = lines.clone();
let bits = cands[0].len();
@@ -37,14 +23,13 @@ fn filter_lines<T>(lines: &Vec<&str>, char_sel : T) -> u32 where T: Fn(u32, u32)
return u32::from_str_radix(cands[0], 2).unwrap();
}
-fn part1() {
- let content = fs::read_to_string("input").expect("no file");
- let lines : Vec<&str> = content.lines().collect();
-
+fn part1(aoc: &mut aoc::Info) {
+ let lines : Vec<&str> = aoc.input.lines().collect();
assert_ne!(lines.len(), 0);
- let valcount : u32 = lines.len().try_into().unwrap();
+
+ let valcount : usize = lines.len();
let bits : usize = lines[0].len();
- let mut bitcounts : Vec<u32> = vec![0; bits];
+ let mut bitcounts : Vec<usize> = vec![0; bits];
bitcounts.fill(0);
for line in lines {
@@ -67,16 +52,28 @@ fn part1() {
}
}
- println!("{}", gamma * epsilon);
+ aoc.answer = Some(format!("{}", gamma * epsilon));
+ aoc.solution = Some("3958484");
}
-fn part2() {
- let content = fs::read_to_string("input").expect("no file");
- let lines : Vec<&str> = content.lines().collect();
+fn part2(aoc: &mut aoc::Info) {
+ let lines : Vec<&str> = aoc.input.lines().collect();
assert_ne!(lines.len(), 0);
- let oxygen = filter_lines(&lines, |count,valcount| if (count as f32) >= ((valcount as f32) / 2.0).ceil() { '1' } else { '0' });
- let co2 = filter_lines(&lines, |count,valcount| if (count as f32) < ((valcount as f32) / 2.0).floor() { '1' } else { '0' });
+ let oxyfn = |count,valcount|
+ if (count as f32) >= ((valcount as f32) / 2.0).ceil()
+ { '1' } else { '0' };
+ let oxygen = filter_lines(&lines, oxyfn);
+
+ let co2fn = |count,valcount|
+ if (count as f32) < ((valcount as f32) / 2.0).floor()
+ { '1' } else { '0' };
+ let co2 = filter_lines(&lines, co2fn);
- println!("{}", oxygen * co2);
+ aoc.answer = Some(format!("{}", oxygen * co2));
+ aoc.solution = Some("1613181");
+}
+
+fn main() {
+ aoc::run(part1, part2);
}
diff --git a/src/04/Cargo.toml b/src/04/Cargo.toml
@@ -1,7 +1,7 @@
[package]
-name = "aoc"
+name = "day04"
version = "0.1.0"
edition = "2021"
[dependencies]
-
+aoc = { path = "../../lib/aoc" }
diff --git a/src/04/src/main.rs b/src/04/src/main.rs
@@ -1,14 +1,10 @@
use std::io::BufRead;
-use std::io::BufReader;
-
-use std::fs::File;
-use std::env;
struct Board {
fields: Vec<Vec<u32>>
}
-fn read_board(reader: &mut BufReader<File>, boards: &mut Vec<Board>) -> bool {
+fn read_board<'a>(reader: &mut &'a[u8], boards: &mut Vec<Board>) -> bool {
let mut line = String::new();
let mut board = Board {
fields: Vec::new()
@@ -20,7 +16,8 @@ fn read_board(reader: &mut BufReader<File>, boards: &mut Vec<Board>) -> bool {
let len = reader.read_line(&mut line).unwrap();
if len == 0 { return false; }
line = line.trim_end().to_string();
- let vals: Vec<u32> = line.split_whitespace().map(|x| x.parse().unwrap()).collect();
+ let vals: Vec<u32> = line.split_whitespace()
+ .map(|x| x.parse().unwrap()).collect();
board.fields.push(vals);
}
@@ -62,20 +59,8 @@ fn calc_score(board: &Board, nums: &[u32]) -> u32 {
return sum * nums.last().unwrap();
}
-fn main() {
- let args: Vec<String> = env::args().collect();
- if args[1] == "1" {
- part1();
- } else if args[1] == "2" {
- part2();
- } else {
- eprintln!("No such part\n");
- }
-}
-
-fn part1() {
- let file = File::open("input").expect("");
- let mut reader = BufReader::new(file);
+fn part1(aoc: &mut aoc::Info) {
+ let mut reader = aoc.input.as_bytes();
let mut line = String::new();
let mut boards = Vec::new();
@@ -85,23 +70,27 @@ fn part1() {
while read_board(&mut reader, &mut boards) {}
+ let mut score: u32 = 0;
for i in 1..marked.len() {
let curvals = &marked[..i];
for b in &boards {
if board_win(&b, curvals) {
- let score = calc_score(&b, curvals);
- println!("{}", score);
- return;
+ score = calc_score(&b, curvals);
+ break;
}
}
+ if score > 0 {
+ break;
+ }
}
+ assert!(score > 0, "Didnt work!");
- println!("didnt work!");
+ aoc.answer = Some(format!("{}", score));
+ aoc.solution = Some("58838");
}
-fn part2() {
- let file = File::open("input").expect("");
- let mut reader = BufReader::new(file);
+fn part2(aoc: &mut aoc::Info) {
+ let mut reader = aoc.input.as_bytes();
let mut line = String::new();
reader.read_line(&mut line).unwrap();
@@ -126,5 +115,10 @@ fn part2() {
}
let score = calc_score(lastboard.unwrap(), lastvals.unwrap());
- println!("{}", score);
+ aoc.answer = Some(format!("{}", score));
+ aoc.solution = Some("6256");
+}
+
+fn main() {
+ aoc::run(part1, part2);
}
diff --git a/src/05/Cargo.toml b/src/05/Cargo.toml
@@ -1,7 +1,7 @@
[package]
-name = "aoc"
+name = "day05"
version = "0.1.0"
edition = "2021"
[dependencies]
-
+aoc = { path = "../../lib/aoc" }
diff --git a/src/05/src/main.rs b/src/05/src/main.rs
@@ -1,8 +1,6 @@
use std::collections::HashMap;
use std::hash::Hash;
use std::clone::Clone;
-use std::env;
-use std::fs;
#[derive(PartialEq, Clone, Eq, Hash)]
struct Pos {
@@ -47,20 +45,9 @@ fn inc_count(map: &mut HashMap<Pos, i32>, pos: &Pos) {
}
}
-fn main() {
- let args: Vec<String> = env::args().collect();
- if args[1] == "1" {
- part1();
- } else if args[1] == "2" {
- part2();
- } else {
- eprintln!("No such part\n");
- }
-}
-
-fn part1() {
- let lines: Vec<Line> = fs::read_to_string("input").unwrap()
- .lines().map(|x| parse_line(x)).collect();
+fn part1(aoc: &mut aoc::Info) {
+ let lines: Vec<Line> = aoc.input.lines()
+ .map(|x| parse_line(x)).collect();
let mut points: HashMap<Pos, i32> = HashMap::new();
for line in lines {
@@ -76,12 +63,13 @@ fn part1() {
}
let score = points.values().filter(|&v| *v >= 2).count();
- println!("{}", score);
+ aoc.answer = Some(format!("{}", score));
+ aoc.solution = Some("7644");
}
-fn part2() {
- let lines: Vec<Line> = fs::read_to_string("input").unwrap()
- .lines().map(|x| parse_line(x)).collect();
+fn part2(aoc: &mut aoc::Info) {
+ let lines: Vec<Line> = aoc.input.lines()
+ .map(|x| parse_line(x)).collect();
let mut points: HashMap<Pos, i32> = HashMap::new();
for line in lines {
@@ -96,6 +84,10 @@ fn part2() {
}
let score = points.values().filter(|&v| *v >= 2).count();
- println!("{}", score);
+ aoc.answer = Some(format!("{}", score));
+ aoc.solution = Some("18627");
+}
+fn main() {
+ aoc::run(part1, part2);
}
diff --git a/src/06/Cargo.toml b/src/06/Cargo.toml
@@ -1,8 +1,9 @@
[package]
-name = "aoc"
+name = "day06"
version = "0.1.0"
edition = "2021"
[dependencies]
+aoc = { path = "../../lib/aoc" }
num-bigint = "0.4.3"
num-traits = "*"
diff --git a/src/06/src/main.rs b/src/06/src/main.rs
@@ -1,19 +1,6 @@
-use std::fs;
-use std::env;
use num_bigint::BigUint;
use num_traits::{FromPrimitive,ToPrimitive,Zero};
-fn main() {
- let args: Vec<String> = env::args().collect();
- if args[1] == "1" {
- part1();
- } else if args[1] == "2" {
- part2();
- } else {
- eprintln!("No such part\n");
- }
-}
-
fn step_time_p1(les_fish: &mut Vec<u32>) {
let mut new_count: u32 = 0;
for fish in les_fish.iter_mut() {
@@ -36,24 +23,21 @@ fn step_time_p2(cur_fish: &mut Vec<BigUint>) {
cur_fish[6] = cur_fish[6].clone() + cur_fish[8].clone();
}
-fn part1() {
- let mut fish: Vec<u32> = fs::read_to_string("input").expect("no fish")
- .strip_suffix("\n").unwrap()
- .split(",")
- .map(|x| x.parse().unwrap()).collect();
+fn part1(aoc: &mut aoc::Info) {
+ let mut fish: Vec<u32> = aoc.input.strip_suffix("\n").unwrap()
+ .split(",").map(|x| x.parse().unwrap()).collect();
for _i in 0..80 {
step_time_p1(&mut fish);
}
- println!("{}", fish.len());
+ aoc.answer = Some(format!("{}", fish.len()));
+ aoc.solution = Some("350605");
}
-fn part2() {
- let fish: Vec<BigUint> = fs::read_to_string("input").expect("no fish")
- .strip_suffix("\n").unwrap()
- .split(",")
- .map(|x| x.parse().unwrap()).collect();
+fn part2(aoc: &mut aoc::Info) {
+ let fish: Vec<u32> = aoc.input.strip_suffix("\n").unwrap()
+ .split(",").map(|x| x.parse().unwrap()).collect();
let mut count: Vec<BigUint> = vec![Zero::zero(); 9];
for i in 0..9 {
@@ -65,6 +49,10 @@ fn part2() {
step_time_p2(&mut count);
}
- println!("{}", count.iter().sum::<BigUint>());
+ aoc.answer = Some(format!("{}", count.iter().sum::<BigUint>()));
+ aoc.solution = Some("1592778185024");
}
+fn main() {
+ aoc::run(part1, part2);
+}
diff --git a/src/07/Cargo.toml b/src/07/Cargo.toml
@@ -1,7 +1,8 @@
[package]
-name = "aoc"
+name = "day07"
version = "0.1.0"
edition = "2021"
[dependencies]
+aoc = { path = "../../lib/aoc" }
diff --git a/src/07/src/main.rs b/src/07/src/main.rs
@@ -1,17 +1,3 @@
-use std::fs;
-use std::env;
-
-fn main() {
- let args: Vec<String> = env::args().collect();
- if args[1] == "1" {
- part1();
- } else if args[1] == "2" {
- part2();
- } else {
- eprintln!("No such part\n");
- }
-}
-
fn best_loc(crabs: &mut Vec<i32>) -> i32 {
crabs.sort();
return crabs[crabs.len() / 2];
@@ -41,24 +27,21 @@ fn fuel_cost_p2_deriv(crabs: &Vec<i32>, loc: i32) -> i32 {
return val2 - val1;
}
-fn part1() {
- let mut crabs: Vec<i32> = fs::read_to_string("input").expect("no file")
- .strip_suffix("\n").unwrap()
- .split(",")
- .map(|x| x.parse().expect("invalid crab"))
+fn part1(aoc: &mut aoc::Info) {
+ let mut crabs: Vec<i32> = aoc.input.strip_suffix("\n").unwrap()
+ .split(",").map(|x| x.parse().expect("invalid crab"))
.collect();
let loc = best_loc(&mut crabs);
let answer = fuel_cost_p1(&crabs, loc);
- println!("{}", answer);
+ aoc.answer = Some(format!("{}", answer));
+ aoc.solution = Some("336721");
}
-fn part2() {
- let crabs: Vec<i32> = fs::read_to_string("input").expect("no file")
- .strip_suffix("\n").unwrap()
- .split(",")
- .map(|x| x.parse().expect("invalid crab"))
+fn part2(aoc: &mut aoc::Info) {
+ let crabs: Vec<i32> = aoc.input.strip_suffix("\n").unwrap()
+ .split(",").map(|x| x.parse().expect("invalid crab"))
.collect();
let mut low: i32 = *crabs.iter().min().unwrap();
@@ -76,6 +59,10 @@ fn part2() {
}
};
- println!("{}", fuel_cost_p2(&crabs, low));
+ aoc.answer = Some(format!("{}", fuel_cost_p2(&crabs, low)));
+ aoc.solution = Some("91638945");
}
+fn main() {
+ aoc::run(part1, part2);
+}
diff --git a/src/08/Cargo.toml b/src/08/Cargo.toml
@@ -1,7 +1,8 @@
[package]
-name = "aoc"
+name = "day08"
version = "0.1.0"
edition = "2021"
[dependencies]
+aoc = { path = "../../lib/aoc" }
diff --git a/src/08/src/main.rs b/src/08/src/main.rs
@@ -1,36 +1,5 @@
-use std::fs;
-use std::env;
use std::collections::HashMap;
-fn main() {
- let args: Vec<String> = env::args().collect();
- if args[1] == "1" {
- part1();
- } else if args[1] == "2" {
- part2();
- } else {
- eprintln!("No such part\n");
- }
-}
-
-fn part1() {
- let content: String = fs::read_to_string("input").expect("no input");
- let display_digits: Vec<Vec<&str>> = content.lines()
- .map(|x| x.split_once(" | ").unwrap().1.split(" ").collect()).collect();
- let accepted: Vec<usize> = vec![2, 3, 4, 7];
- let mut count: u32 = 0;
-
- for digits in display_digits {
- for d in digits {
- if accepted.contains(&d.len()) {
- count += 1;
- }
- }
- }
-
- println!("{}", count);
-}
-
fn code2bin(code: &str) -> u32 {
let alph = "abcdefg";
let mut val: u32 = 0;
@@ -57,7 +26,8 @@ fn bits_set(bin: u32) -> u32 {
return cnt;
}
-fn decode_value(codes: &Vec<&str>, out_codes: &Vec<&str>) -> u32 {
+fn decode_value(aoc: &mut aoc::Info,
+ codes: &Vec<&str>, out_codes: &Vec<&str>) -> u32 {
let len2code: HashMap<u32,u32> = HashMap::from([
(2, 1),
(3, 7),
@@ -106,25 +76,26 @@ fn decode_value(codes: &Vec<&str>, out_codes: &Vec<&str>) -> u32 {
for digit in 0..10 {
fit = true;
for cmp in 0..10 {
- // println!("-- {} {} --", digit, cmp);
+ aoc::debug!(aoc, "-- {} {} --\n", digit, cmp);
let cmplen = overlaps[digit][cmp];
if digit == cmp && bits_set(code) != cmplen {
- // println!("wrong length");
+ aoc::debug!(aoc, "wrong length\n");
fit = false;
break;
}
if mapping[cmp] == 0 { continue; }
if bits_set(code & mapping[cmp]) != cmplen {
- // println!("wrong # of same bits: {:08b} & {:08b} != {}", code, mapping[cmp], cmplen);
+ aoc::debug!(aoc, "wrong # of same bits: {:08b} & {:08b} != {}\n",
+ code, mapping[cmp], cmplen);
fit = false;
break;
}
- // println!("{}: {:08b} {:08b}", cmplen, code, mapping[cmp]);
+ aoc::debug!(aoc, "{}: {:08b} {:08b}\n", cmplen, code, mapping[cmp]);
}
if fit == true {
- // println!("add {:08b} => {}", code, digit);
+ aoc::debug!(aoc, "add {:08b} => {}\n", code, digit);
mapping[digit] = code;
break;
}
@@ -144,16 +115,43 @@ fn decode_value(codes: &Vec<&str>, out_codes: &Vec<&str>) -> u32 {
return output;
}
-fn part2() {
- let content: String = fs::read_to_string("input").expect("no input");
+fn part1(aoc: &mut aoc::Info) {
+ let display_digits: Vec<Vec<&str>> = aoc.input.lines()
+ .map(|x| x.split_once(" | ").unwrap().1.split(" ").collect())
+ .collect();
+
+ let accepted: Vec<usize> = vec![2, 3, 4, 7];
+ let mut count: u32 = 0;
+
+ for digits in display_digits {
+ for d in digits {
+ if accepted.contains(&d.len()) {
+ count += 1;
+ }
+ }
+ }
+
+ aoc.answer = Some(format!("{}", count));
+ aoc.solution = Some("237");
+}
+
+fn part2(aoc: &mut aoc::Info) {
+ let content = aoc.input.clone();
let lines: Vec<&str> = content.lines().collect();
let mut sum: u32 = 0;
for line in lines {
- let sig_codes: Vec<&str> = line.split_once(" | ").unwrap().0.split(" ").collect();
- let out_codes: Vec<&str> = line.split_once(" | ").unwrap().1.split(" ").collect();
- sum += decode_value(&sig_codes, &out_codes);
+ let sig_codes: Vec<&str> = line.split_once(" | ").unwrap().0
+ .split(" ").collect();
+ let out_codes: Vec<&str> = line.split_once(" | ").unwrap().1
+ .split(" ").collect();
+ sum += decode_value(aoc, &sig_codes, &out_codes);
}
- println!("{}", sum);
+ aoc.answer = Some(format!("{}", sum));
+ aoc.solution = Some("1009098");
+}
+
+fn main() {
+ aoc::run(part1, part2);
}
diff --git a/src/09/Cargo.toml b/src/09/Cargo.toml
@@ -1,7 +1,8 @@
[package]
-name = "aoc"
+name = "day09"
version = "0.1.0"
edition = "2021"
[dependencies]
+aoc = { path = "../../lib/aoc" }
diff --git a/src/09/src/main.rs b/src/09/src/main.rs
@@ -1,6 +1,3 @@
-use std::fs;
-use std::env;
-
#[derive(PartialEq,Eq)]
struct Pos {
x: i32,
@@ -14,21 +11,10 @@ const DIRS: [Pos; 4] = [
Pos { x: -1, y: 0 },
];
-fn main() {
- let args: Vec<String> = env::args().collect();
- if args[1] == "1" {
- part1();
- } else if args[1] == "2" {
- part2();
- } else {
- eprintln!("No such part\n");
- }
-}
-
-fn part1() {
- let content = fs::read_to_string("input").expect("no file");
- let map: Vec<Vec<i32>> = content.lines()
- .map(|x| x.chars().map(|c| c.to_digit(10).unwrap() as i32).collect()).collect();
+fn part1(aoc: &mut aoc::Info) {
+ let map: Vec<Vec<i32>> = aoc.input.lines()
+ .map(|x| x.chars().map(|c| c.to_digit(10).unwrap() as i32).collect())
+ .collect();
assert_ne!(map.len(), 0);
let width = map[0].len();
@@ -55,13 +41,14 @@ fn part1() {
}
}
- println!("{}", sum);
+ aoc.answer = Some(format!("{}", sum));
+ aoc.solution = Some("417");
}
-fn part2() {
- let content = fs::read_to_string("input").expect("no file");
- let map: Vec<Vec<i32>> = content.lines()
- .map(|x| x.chars().map(|c| c.to_digit(10).unwrap() as i32).collect()).collect();
+fn part2(aoc: &mut aoc::Info) {
+ let map: Vec<Vec<i32>> = aoc.input.lines()
+ .map(|x| x.chars().map(|c| c.to_digit(10).unwrap() as i32).collect())
+ .collect();
assert_ne!(map.len(), 0);
let width = map[0].len();
@@ -77,7 +64,8 @@ fn part2() {
let ny = (y as i32) + d.y;
let inrange_x = nx >= 0 && nx < (width as i32);
let inrange_y = ny >= 0 && ny < (height as i32);
- if inrange_x && inrange_y && map[ny as usize][nx as usize] <= curh {
+ if inrange_x && inrange_y
+ && map[ny as usize][nx as usize] <= curh {
is_lowest = false;
break;
}
@@ -90,7 +78,10 @@ fn part2() {
let mut basin_sizes: Vec<usize> = Vec::new();
for start in lowest {
- // println!("S {} {}", start.x, start.y);
+ if aoc.debug {
+ println!("START {} {}", start.x, start.y);
+ }
+
let mut visited: Vec<Pos> = Vec::new();
let mut outer: Vec<Pos> = Vec::new();
@@ -99,11 +90,16 @@ fn part2() {
let mut new_outer: Vec<Pos> = Vec::new();
for pos in &outer {
for d in DIRS {
- let npos = Pos { x: (pos.x as i32) + d.x, y: (pos.y as i32) + d.y };
+ let npos = Pos {
+ x: (pos.x as i32) + d.x,
+ y: (pos.y as i32) + d.y
+ };
let inrange_x = npos.x >= 0 && npos.x < (width as i32);
let inrange_y = npos.y >= 0 && npos.y < (height as i32);
- if inrange_x && inrange_y && map[npos.y as usize][npos.x as usize] != 9
- && !visited.contains(&npos) && !new_outer.contains(&npos) {
+ if inrange_x && inrange_y
+ && map[npos.y as usize][npos.x as usize] != 9
+ && !visited.contains(&npos)
+ && !new_outer.contains(&npos) {
new_outer.push(Pos { x: npos.x, y: npos.y });
}
}
@@ -112,7 +108,10 @@ fn part2() {
outer = new_outer;
}
- // println!("{}", visited.len());
+ if aoc.debug {
+ println!("VISITED COUNT: {}", visited.len());
+ }
+
basin_sizes.push(visited.len());
}
@@ -120,5 +119,11 @@ fn part2() {
basin_sizes.reverse();
assert!(basin_sizes.len() > 3);
- println!("{}", basin_sizes[0] * basin_sizes[1] * basin_sizes[2]);
+ let product = basin_sizes[0] * basin_sizes[1] * basin_sizes[2];
+ aoc.answer = Some(format!("{}", product));
+ aoc.solution = Some("1148965");
+}
+
+fn main() {
+ aoc::run(part1, part2);
}
diff --git a/src/10/Cargo.toml b/src/10/Cargo.toml
@@ -1,8 +1,9 @@
[package]
-name = "aoc"
+name = "day10"
version = "0.1.0"
edition = "2021"
[dependencies]
+aoc = { path = "../../lib/aoc" }
lazy_static = "*"
bimap = "*"
diff --git a/src/10/src/main.rs b/src/10/src/main.rs
@@ -1,6 +1,3 @@
-use std::fs;
-use std::env;
-
#[macro_use]
extern crate lazy_static;
@@ -37,22 +34,9 @@ lazy_static! {
const OPENING: [char; 4] = ['(', '[', '{', '<'];
const CLOSING: [char; 4] = [')', ']', '}', '>'];
-fn main() {
- let args: Vec<String> = env::args().collect();
- if args[1] == "1" {
- part1();
- } else if args[1] == "2" {
- part2();
- } else {
- eprintln!("No such part\n");
- }
-}
-
-fn part1() {
- let content = fs::read_to_string("input").expect("no file");
-
+fn part1(aoc: &mut aoc::Info) {
let mut score: usize = 0;
- for line in content.lines() {
+ for line in aoc.input.lines() {
let mut stack: Vec<char> = Vec::new();
for c in line.chars() {
if OPENING.contains(&c) {
@@ -69,14 +53,13 @@ fn part1() {
/* ignore incomplete for now */
}
- println!("{}", score);
+ aoc.answer = Some(format!("{}", score));
+ aoc.solution = Some("167379");
}
-fn part2() {
- let content = fs::read_to_string("input").expect("no file");
-
+fn part2(aoc: &mut aoc::Info) {
let mut scores: Vec<usize> = Vec::new();
- for line in content.lines() {
+ for line in aoc.input.lines() {
let mut stack: Vec<char> = Vec::new();
let mut corrupt = false;
@@ -103,9 +86,14 @@ fn part2() {
scores.push(score);
}
}
+ assert!(scores.len() % 2 == 1);
scores.sort();
- assert!(scores.len() % 2 == 1);
- println!("{}", scores[scores.len() / 2]);
+ aoc.answer = Some(format!("{}", scores[scores.len() / 2]));
+ aoc.solution = Some("2776842859");
+}
+
+fn main() {
+ aoc::run(part1, part2);
}
diff --git a/src/11/Cargo.toml b/src/11/Cargo.toml
@@ -1,7 +1,8 @@
[package]
-name = "aoc"
+name = "day11"
version = "0.1.0"
edition = "2021"
[dependencies]
+aoc = { path = "../../lib/aoc" }
diff --git a/src/11/src/main.rs b/src/11/src/main.rs
@@ -1,6 +1,3 @@
-use std::fs;
-use std::env;
-
#[derive(PartialEq,Eq)]
struct Pos {
x: i32,
@@ -18,17 +15,6 @@ const SURROUNDING: [Pos; 8] = [
Pos { x: 1, y: 1 }
];
-fn main() {
- let args: Vec<String> = env::args().collect();
- if args[1] == "1" {
- part1();
- } else if args[1] == "2" {
- part2();
- } else {
- eprintln!("No such part\n");
- }
-}
-
fn print_octos(octos: &Vec<Vec<u32>>) {
for row in octos {
for octo in row {
@@ -76,10 +62,10 @@ fn sim_step(octos: &mut Vec<Vec<u32>>) -> usize {
return flashed.len();
}
-fn part1() {
- let content = fs::read_to_string("input").expect("no file");
- let mut octos: Vec<Vec<u32>> = content.lines()
- .map(|l| l.chars().map(|c| c.to_digit(10).unwrap()).collect()).collect();
+fn part1(aoc: &mut aoc::Info) {
+ let mut octos: Vec<Vec<u32>> = aoc.input.lines()
+ .map(|l| l.chars().map(|c| c.to_digit(10).unwrap()).collect())
+ .collect();
let mut flashes: usize = 0;
for _i in 0..100 {
@@ -89,10 +75,10 @@ fn part1() {
println!("{}", flashes);
}
-fn part2() {
- let content = fs::read_to_string("input").expect("no file");
- let mut octos: Vec<Vec<u32>> = content.lines()
- .map(|l| l.chars().map(|c| c.to_digit(10).unwrap()).collect()).collect();
+fn part2(aoc: &mut aoc::Info) {
+ let mut octos: Vec<Vec<u32>> = aoc.input.lines()
+ .map(|l| l.chars().map(|c| c.to_digit(10).unwrap()).collect())
+ .collect();
let height = octos.len();
let width = octos[0].len();
@@ -104,5 +90,9 @@ fn part2() {
step += 1;
}
- println!("{}", step);
+ aoc.answer = Some(format!("{}", step));
+}
+
+fn main() {
+ aoc::run(part1, part2);
}
diff --git a/src/12/Cargo.toml b/src/12/Cargo.toml
@@ -1,7 +1,7 @@
[package]
-name = "aoc"
+name = "day12"
version = "0.1.0"
edition = "2021"
[dependencies]
-
+aoc = { path = "../../lib/aoc" }
diff --git a/src/12/src/main.rs b/src/12/src/main.rs
@@ -1,6 +1,4 @@
use std::collections::HashMap;
-use std::env;
-use std::fs;
/* assume no two big caves are next to each other
* => otherwise infinite paths possible */
@@ -17,22 +15,10 @@ struct NodeState<'a> {
index: usize
}
-fn main() {
- let args: Vec<String> = env::args().collect();
- if args[1] == "1" {
- part1();
- } else if args[1] == "2" {
- part2();
- } else {
- eprintln!("No such part\n");
- }
-}
-
-fn parse_input() -> HashMap<String, Node> {
+fn parse_input(input: &String) -> HashMap<String, Node> {
let mut nodes: HashMap<String, Node> = HashMap::new();
- let content = fs::read_to_string("input").expect("no file");
- for line in content.lines() {
+ for line in input.lines() {
let parts: Vec<String> = line.split("-").map(|x| x.to_string()).collect();
for key in &parts {
if !nodes.contains_key(key) {
@@ -53,8 +39,8 @@ fn parse_input() -> HashMap<String, Node> {
return nodes;
}
-fn part1() {
- let nodes = parse_input();
+fn part1(aoc: &mut aoc::Info) {
+ let nodes = parse_input(&aoc.input);
let mut path: Vec<&Node> = Vec::new();
let mut adj_index = 0;
@@ -91,8 +77,8 @@ fn part1() {
println!("{}", paths);
}
-fn part2() {
- let nodes = parse_input();
+fn part2(aoc: &mut aoc::Info) {
+ let nodes = parse_input(&aoc.input);
let mut path: Vec<NodeState> = Vec::new();
@@ -106,9 +92,9 @@ fn part2() {
current.index += 1;
if adj.name == "end" {
for p in &path {
- print!("{} -> ", p.node.name);
+ aoc::debug!(aoc, "{} -> ", p.node.name);
}
- println!("end");
+ aoc::debug!(aoc, "end\n");
paths += 1;
} else if adj.name != "start"
&& path.iter().filter(|x| x.node == adj).count() <= 1 || !adj.small {
@@ -122,3 +108,7 @@ fn part2() {
println!("{}", paths);
}
+
+fn main() {
+ aoc::run(part1, part2);
+}