From de1a181ba56d929e1ca5be7ce1149c6438874e33 Mon Sep 17 00:00:00 2001 From: Jos van Goor Date: Sun, 7 Dec 2025 18:18:40 +0100 Subject: [PATCH] Advent 2015 Day 7, 8 & 9 Parts 1 & 2 --- advent_of_code_2015/Cargo.lock | 16 + advent_of_code_2015/Cargo.toml | 7 + advent_of_code_2015/rustfmt.toml | 14 + .../{day1 => src/day1_cpp}/input.in | 0 .../{day1 => src/day1_cpp}/main1.cc | 0 .../{day1 => src/day1_cpp}/main2.cc | 0 .../{day2 => src/day2_cpp}/input.in | 0 .../{day2 => src/day2_cpp}/main1.cc | 0 .../{day3 => src/day3_cpp}/input.in | 0 .../{day3 => src/day3_cpp}/main1.cc | 0 .../{day3 => src/day3_cpp}/main2.cc | 0 .../{day4 => src/day4_cpp}/main1.cc | 0 .../{day4 => src/day4_cpp}/md5.cpp | 0 .../{day4 => src/day4_cpp}/md5.hpp | 0 .../{day5 => src/day5_cpp}/input.in | 0 .../{day5 => src/day5_cpp}/main1.cc | 0 .../{day5 => src/day5_cpp}/main2.cc | 0 .../{day6 => src/day6_cpp}/input.in | 0 .../{day6 => src/day6_cpp}/main.ih | 0 .../{day6 => src/day6_cpp}/main1.cc | 0 .../{day6 => src/day6_cpp}/main2.cc | 0 advent_of_code_2015/src/day7/input.txt | 339 ++++++++++++++++++ advent_of_code_2015/src/day7/mod.rs | 2 + advent_of_code_2015/src/day7/part1.rs | 102 ++++++ advent_of_code_2015/src/day7/part2.rs | 105 ++++++ advent_of_code_2015/src/day7/test.txt | 8 + advent_of_code_2015/src/day8/input.txt | 300 ++++++++++++++++ advent_of_code_2015/src/day8/mod.rs | 2 + advent_of_code_2015/src/day8/part1.rs | 33 ++ advent_of_code_2015/src/day8/part2.rs | 29 ++ advent_of_code_2015/src/day8/test.txt | 4 + advent_of_code_2015/src/day9/input.txt | 28 ++ advent_of_code_2015/src/day9/mod.rs | 2 + advent_of_code_2015/src/day9/part1.rs | 55 +++ advent_of_code_2015/src/day9/part2.rs | 55 +++ advent_of_code_2015/src/day9/test.txt | 3 + advent_of_code_2015/src/main.rs | 7 + .../src/utility/inputstring.rs | 10 + advent_of_code_2015/src/utility/mod.rs | 6 + advent_of_code_2015/src/utility/solveday.rs | 31 ++ 40 files changed, 1158 insertions(+) create mode 100644 advent_of_code_2015/Cargo.lock create mode 100644 advent_of_code_2015/Cargo.toml create mode 100644 advent_of_code_2015/rustfmt.toml rename advent_of_code_2015/{day1 => src/day1_cpp}/input.in (100%) rename advent_of_code_2015/{day1 => src/day1_cpp}/main1.cc (100%) rename advent_of_code_2015/{day1 => src/day1_cpp}/main2.cc (100%) rename advent_of_code_2015/{day2 => src/day2_cpp}/input.in (100%) rename advent_of_code_2015/{day2 => src/day2_cpp}/main1.cc (100%) rename advent_of_code_2015/{day3 => src/day3_cpp}/input.in (100%) rename advent_of_code_2015/{day3 => src/day3_cpp}/main1.cc (100%) rename advent_of_code_2015/{day3 => src/day3_cpp}/main2.cc (100%) rename advent_of_code_2015/{day4 => src/day4_cpp}/main1.cc (100%) rename advent_of_code_2015/{day4 => src/day4_cpp}/md5.cpp (100%) rename advent_of_code_2015/{day4 => src/day4_cpp}/md5.hpp (100%) rename advent_of_code_2015/{day5 => src/day5_cpp}/input.in (100%) rename advent_of_code_2015/{day5 => src/day5_cpp}/main1.cc (100%) rename advent_of_code_2015/{day5 => src/day5_cpp}/main2.cc (100%) rename advent_of_code_2015/{day6 => src/day6_cpp}/input.in (100%) rename advent_of_code_2015/{day6 => src/day6_cpp}/main.ih (100%) rename advent_of_code_2015/{day6 => src/day6_cpp}/main1.cc (100%) rename advent_of_code_2015/{day6 => src/day6_cpp}/main2.cc (100%) create mode 100644 advent_of_code_2015/src/day7/input.txt create mode 100644 advent_of_code_2015/src/day7/mod.rs create mode 100644 advent_of_code_2015/src/day7/part1.rs create mode 100644 advent_of_code_2015/src/day7/part2.rs create mode 100644 advent_of_code_2015/src/day7/test.txt create mode 100644 advent_of_code_2015/src/day8/input.txt create mode 100644 advent_of_code_2015/src/day8/mod.rs create mode 100644 advent_of_code_2015/src/day8/part1.rs create mode 100644 advent_of_code_2015/src/day8/part2.rs create mode 100644 advent_of_code_2015/src/day8/test.txt create mode 100644 advent_of_code_2015/src/day9/input.txt create mode 100644 advent_of_code_2015/src/day9/mod.rs create mode 100644 advent_of_code_2015/src/day9/part1.rs create mode 100644 advent_of_code_2015/src/day9/part2.rs create mode 100644 advent_of_code_2015/src/day9/test.txt create mode 100644 advent_of_code_2015/src/main.rs create mode 100644 advent_of_code_2015/src/utility/inputstring.rs create mode 100644 advent_of_code_2015/src/utility/mod.rs create mode 100644 advent_of_code_2015/src/utility/solveday.rs diff --git a/advent_of_code_2015/Cargo.lock b/advent_of_code_2015/Cargo.lock new file mode 100644 index 0000000..6d7513a --- /dev/null +++ b/advent_of_code_2015/Cargo.lock @@ -0,0 +1,16 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +version = 4 + +[[package]] +name = "advent_of_code_2025" +version = "0.1.0" +dependencies = [ + "paste", +] + +[[package]] +name = "paste" +version = "1.0.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "57c0d7b74b563b49d38dae00a0c37d4d6de9b432382b2892f0574ddcae73fd0a" diff --git a/advent_of_code_2015/Cargo.toml b/advent_of_code_2015/Cargo.toml new file mode 100644 index 0000000..74028a7 --- /dev/null +++ b/advent_of_code_2015/Cargo.toml @@ -0,0 +1,7 @@ +[package] +name = "advent_of_code_2025" +version = "0.1.0" +edition = "2024" + +[dependencies] +paste = "1.0" \ No newline at end of file diff --git a/advent_of_code_2015/rustfmt.toml b/advent_of_code_2015/rustfmt.toml new file mode 100644 index 0000000..b04e7a7 --- /dev/null +++ b/advent_of_code_2015/rustfmt.toml @@ -0,0 +1,14 @@ +binop_separator = "Back" +brace_style = "PreferSameLine" +edition = "2024" +enum_discrim_align_threshold = 120 +fn_single_line = false +group_imports = "StdExternalCrate" +imports_granularity = "Module" +indent_style = "Block" +max_width = 160 +reorder_impl_items = false +struct_field_align_threshold = 120 +unstable_features = true +use_small_heuristics = "Max" +where_single_line = true \ No newline at end of file diff --git a/advent_of_code_2015/day1/input.in b/advent_of_code_2015/src/day1_cpp/input.in similarity index 100% rename from advent_of_code_2015/day1/input.in rename to advent_of_code_2015/src/day1_cpp/input.in diff --git a/advent_of_code_2015/day1/main1.cc b/advent_of_code_2015/src/day1_cpp/main1.cc similarity index 100% rename from advent_of_code_2015/day1/main1.cc rename to advent_of_code_2015/src/day1_cpp/main1.cc diff --git a/advent_of_code_2015/day1/main2.cc b/advent_of_code_2015/src/day1_cpp/main2.cc similarity index 100% rename from advent_of_code_2015/day1/main2.cc rename to advent_of_code_2015/src/day1_cpp/main2.cc diff --git a/advent_of_code_2015/day2/input.in b/advent_of_code_2015/src/day2_cpp/input.in similarity index 100% rename from advent_of_code_2015/day2/input.in rename to advent_of_code_2015/src/day2_cpp/input.in diff --git a/advent_of_code_2015/day2/main1.cc b/advent_of_code_2015/src/day2_cpp/main1.cc similarity index 100% rename from advent_of_code_2015/day2/main1.cc rename to advent_of_code_2015/src/day2_cpp/main1.cc diff --git a/advent_of_code_2015/day3/input.in b/advent_of_code_2015/src/day3_cpp/input.in similarity index 100% rename from advent_of_code_2015/day3/input.in rename to advent_of_code_2015/src/day3_cpp/input.in diff --git a/advent_of_code_2015/day3/main1.cc b/advent_of_code_2015/src/day3_cpp/main1.cc similarity index 100% rename from advent_of_code_2015/day3/main1.cc rename to advent_of_code_2015/src/day3_cpp/main1.cc diff --git a/advent_of_code_2015/day3/main2.cc b/advent_of_code_2015/src/day3_cpp/main2.cc similarity index 100% rename from advent_of_code_2015/day3/main2.cc rename to advent_of_code_2015/src/day3_cpp/main2.cc diff --git a/advent_of_code_2015/day4/main1.cc b/advent_of_code_2015/src/day4_cpp/main1.cc similarity index 100% rename from advent_of_code_2015/day4/main1.cc rename to advent_of_code_2015/src/day4_cpp/main1.cc diff --git a/advent_of_code_2015/day4/md5.cpp b/advent_of_code_2015/src/day4_cpp/md5.cpp similarity index 100% rename from advent_of_code_2015/day4/md5.cpp rename to advent_of_code_2015/src/day4_cpp/md5.cpp diff --git a/advent_of_code_2015/day4/md5.hpp b/advent_of_code_2015/src/day4_cpp/md5.hpp similarity index 100% rename from advent_of_code_2015/day4/md5.hpp rename to advent_of_code_2015/src/day4_cpp/md5.hpp diff --git a/advent_of_code_2015/day5/input.in b/advent_of_code_2015/src/day5_cpp/input.in similarity index 100% rename from advent_of_code_2015/day5/input.in rename to advent_of_code_2015/src/day5_cpp/input.in diff --git a/advent_of_code_2015/day5/main1.cc b/advent_of_code_2015/src/day5_cpp/main1.cc similarity index 100% rename from advent_of_code_2015/day5/main1.cc rename to advent_of_code_2015/src/day5_cpp/main1.cc diff --git a/advent_of_code_2015/day5/main2.cc b/advent_of_code_2015/src/day5_cpp/main2.cc similarity index 100% rename from advent_of_code_2015/day5/main2.cc rename to advent_of_code_2015/src/day5_cpp/main2.cc diff --git a/advent_of_code_2015/day6/input.in b/advent_of_code_2015/src/day6_cpp/input.in similarity index 100% rename from advent_of_code_2015/day6/input.in rename to advent_of_code_2015/src/day6_cpp/input.in diff --git a/advent_of_code_2015/day6/main.ih b/advent_of_code_2015/src/day6_cpp/main.ih similarity index 100% rename from advent_of_code_2015/day6/main.ih rename to advent_of_code_2015/src/day6_cpp/main.ih diff --git a/advent_of_code_2015/day6/main1.cc b/advent_of_code_2015/src/day6_cpp/main1.cc similarity index 100% rename from advent_of_code_2015/day6/main1.cc rename to advent_of_code_2015/src/day6_cpp/main1.cc diff --git a/advent_of_code_2015/day6/main2.cc b/advent_of_code_2015/src/day6_cpp/main2.cc similarity index 100% rename from advent_of_code_2015/day6/main2.cc rename to advent_of_code_2015/src/day6_cpp/main2.cc diff --git a/advent_of_code_2015/src/day7/input.txt b/advent_of_code_2015/src/day7/input.txt new file mode 100644 index 0000000..5080c3d --- /dev/null +++ b/advent_of_code_2015/src/day7/input.txt @@ -0,0 +1,339 @@ +bn RSHIFT 2 -> bo +lf RSHIFT 1 -> ly +fo RSHIFT 3 -> fq +cj OR cp -> cq +fo OR fz -> ga +t OR s -> u +lx -> a +NOT ax -> ay +he RSHIFT 2 -> hf +lf OR lq -> lr +lr AND lt -> lu +dy OR ej -> ek +1 AND cx -> cy +hb LSHIFT 1 -> hv +1 AND bh -> bi +ih AND ij -> ik +c LSHIFT 1 -> t +ea AND eb -> ed +km OR kn -> ko +NOT bw -> bx +ci OR ct -> cu +NOT p -> q +lw OR lv -> lx +NOT lo -> lp +fp OR fv -> fw +o AND q -> r +dh AND dj -> dk +ap LSHIFT 1 -> bj +bk LSHIFT 1 -> ce +NOT ii -> ij +gh OR gi -> gj +kk RSHIFT 1 -> ld +lc LSHIFT 1 -> lw +lb OR la -> lc +1 AND am -> an +gn AND gp -> gq +lf RSHIFT 3 -> lh +e OR f -> g +lg AND lm -> lo +ci RSHIFT 1 -> db +cf LSHIFT 1 -> cz +bn RSHIFT 1 -> cg +et AND fe -> fg +is OR it -> iu +kw AND ky -> kz +ck AND cl -> cn +bj OR bi -> bk +gj RSHIFT 1 -> hc +iu AND jf -> jh +NOT bs -> bt +kk OR kv -> kw +ks AND ku -> kv +hz OR ik -> il +b RSHIFT 1 -> v +iu RSHIFT 1 -> jn +fo RSHIFT 5 -> fr +be AND bg -> bh +ga AND gc -> gd +hf OR hl -> hm +ld OR le -> lf +as RSHIFT 5 -> av +fm OR fn -> fo +hm AND ho -> hp +lg OR lm -> ln +NOT kx -> ky +kk RSHIFT 3 -> km +ek AND em -> en +NOT ft -> fu +NOT jh -> ji +jn OR jo -> jp +gj AND gu -> gw +d AND j -> l +et RSHIFT 1 -> fm +jq OR jw -> jx +ep OR eo -> eq +lv LSHIFT 15 -> lz +NOT ey -> ez +jp RSHIFT 2 -> jq +eg AND ei -> ej +NOT dm -> dn +jp AND ka -> kc +as AND bd -> bf +fk OR fj -> fl +dw OR dx -> dy +lj AND ll -> lm +ec AND ee -> ef +fq AND fr -> ft +NOT kp -> kq +ki OR kj -> kk +cz OR cy -> da +as RSHIFT 3 -> au +an LSHIFT 15 -> ar +fj LSHIFT 15 -> fn +1 AND fi -> fj +he RSHIFT 1 -> hx +lf RSHIFT 2 -> lg +kf LSHIFT 15 -> kj +dz AND ef -> eh +ib OR ic -> id +lf RSHIFT 5 -> li +bp OR bq -> br +NOT gs -> gt +fo RSHIFT 1 -> gh +bz AND cb -> cc +ea OR eb -> ec +lf AND lq -> ls +NOT l -> m +hz RSHIFT 3 -> ib +NOT di -> dj +NOT lk -> ll +jp RSHIFT 3 -> jr +jp RSHIFT 5 -> js +NOT bf -> bg +s LSHIFT 15 -> w +eq LSHIFT 1 -> fk +jl OR jk -> jm +hz AND ik -> im +dz OR ef -> eg +1 AND gy -> gz +la LSHIFT 15 -> le +br AND bt -> bu +NOT cn -> co +v OR w -> x +d OR j -> k +1 AND gd -> ge +ia OR ig -> ih +NOT go -> gp +NOT ed -> ee +jq AND jw -> jy +et OR fe -> ff +aw AND ay -> az +ff AND fh -> fi +ir LSHIFT 1 -> jl +gg LSHIFT 1 -> ha +x RSHIFT 2 -> y +db OR dc -> dd +bl OR bm -> bn +ib AND ic -> ie +x RSHIFT 3 -> z +lh AND li -> lk +ce OR cd -> cf +NOT bb -> bc +hi AND hk -> hl +NOT gb -> gc +1 AND r -> s +fw AND fy -> fz +fb AND fd -> fe +1 AND en -> eo +z OR aa -> ab +bi LSHIFT 15 -> bm +hg OR hh -> hi +kh LSHIFT 1 -> lb +cg OR ch -> ci +1 AND kz -> la +gf OR ge -> gg +gj RSHIFT 2 -> gk +dd RSHIFT 2 -> de +NOT ls -> lt +lh OR li -> lj +jr OR js -> jt +au AND av -> ax +0 -> c +he AND hp -> hr +id AND if -> ig +et RSHIFT 5 -> ew +bp AND bq -> bs +e AND f -> h +ly OR lz -> ma +1 AND lu -> lv +NOT jd -> je +ha OR gz -> hb +dy RSHIFT 1 -> er +iu RSHIFT 2 -> iv +NOT hr -> hs +as RSHIFT 1 -> bl +kk RSHIFT 2 -> kl +b AND n -> p +ln AND lp -> lq +cj AND cp -> cr +dl AND dn -> do +ci RSHIFT 2 -> cj +as OR bd -> be +ge LSHIFT 15 -> gi +hz RSHIFT 5 -> ic +dv LSHIFT 1 -> ep +kl OR kr -> ks +gj OR gu -> gv +he RSHIFT 5 -> hh +NOT fg -> fh +hg AND hh -> hj +b OR n -> o +jk LSHIFT 15 -> jo +gz LSHIFT 15 -> hd +cy LSHIFT 15 -> dc +kk RSHIFT 5 -> kn +ci RSHIFT 3 -> ck +at OR az -> ba +iu RSHIFT 3 -> iw +ko AND kq -> kr +NOT eh -> ei +aq OR ar -> as +iy AND ja -> jb +dd RSHIFT 3 -> df +bn RSHIFT 3 -> bp +1 AND cc -> cd +at AND az -> bb +x OR ai -> aj +kk AND kv -> kx +ao OR an -> ap +dy RSHIFT 3 -> ea +x RSHIFT 1 -> aq +eu AND fa -> fc +kl AND kr -> kt +ia AND ig -> ii +df AND dg -> di +NOT fx -> fy +k AND m -> n +bn RSHIFT 5 -> bq +km AND kn -> kp +dt LSHIFT 15 -> dx +hz RSHIFT 2 -> ia +aj AND al -> am +cd LSHIFT 15 -> ch +hc OR hd -> he +he RSHIFT 3 -> hg +bn OR by -> bz +NOT kt -> ku +z AND aa -> ac +NOT ak -> al +cu AND cw -> cx +NOT ie -> if +dy RSHIFT 2 -> dz +ip LSHIFT 15 -> it +de OR dk -> dl +au OR av -> aw +jg AND ji -> jj +ci AND ct -> cv +dy RSHIFT 5 -> eb +hx OR hy -> hz +eu OR fa -> fb +gj RSHIFT 3 -> gl +fo AND fz -> gb +1 AND jj -> jk +jp OR ka -> kb +de AND dk -> dm +ex AND ez -> fa +df OR dg -> dh +iv OR jb -> jc +x RSHIFT 5 -> aa +NOT hj -> hk +NOT im -> in +fl LSHIFT 1 -> gf +hu LSHIFT 15 -> hy +iq OR ip -> ir +iu RSHIFT 5 -> ix +NOT fc -> fd +NOT el -> em +ck OR cl -> cm +et RSHIFT 3 -> ev +hw LSHIFT 1 -> iq +ci RSHIFT 5 -> cl +iv AND jb -> jd +dd RSHIFT 5 -> dg +as RSHIFT 2 -> at +NOT jy -> jz +af AND ah -> ai +1 AND ds -> dt +jx AND jz -> ka +da LSHIFT 1 -> du +fs AND fu -> fv +jp RSHIFT 1 -> ki +iw AND ix -> iz +iw OR ix -> iy +eo LSHIFT 15 -> es +ev AND ew -> ey +ba AND bc -> bd +fp AND fv -> fx +jc AND je -> jf +et RSHIFT 2 -> eu +kg OR kf -> kh +iu OR jf -> jg +er OR es -> et +fo RSHIFT 2 -> fp +NOT ca -> cb +bv AND bx -> by +u LSHIFT 1 -> ao +cm AND co -> cp +y OR ae -> af +bn AND by -> ca +1 AND ke -> kf +jt AND jv -> jw +fq OR fr -> fs +dy AND ej -> el +NOT kc -> kd +ev OR ew -> ex +dd OR do -> dp +NOT cv -> cw +gr AND gt -> gu +dd RSHIFT 1 -> dw +NOT gw -> gx +NOT iz -> ja +1 AND io -> ip +NOT ag -> ah +b RSHIFT 5 -> f +NOT cr -> cs +kb AND kd -> ke +jr AND js -> ju +cq AND cs -> ct +il AND in -> io +NOT ju -> jv +du OR dt -> dv +dd AND do -> dq +b RSHIFT 2 -> d +jm LSHIFT 1 -> kg +NOT dq -> dr +bo OR bu -> bv +gk OR gq -> gr +he OR hp -> hq +NOT h -> i +hf AND hl -> hn +gv AND gx -> gy +x AND ai -> ak +bo AND bu -> bw +hq AND hs -> ht +hz RSHIFT 1 -> is +gj RSHIFT 5 -> gm +g AND i -> j +gk AND gq -> gs +dp AND dr -> ds +b RSHIFT 3 -> e +gl AND gm -> go +gl OR gm -> gn +y AND ae -> ag +hv OR hu -> hw +1674 -> b +ab AND ad -> ae +NOT ac -> ad +1 AND ht -> hu +NOT hn -> ho \ No newline at end of file diff --git a/advent_of_code_2015/src/day7/mod.rs b/advent_of_code_2015/src/day7/mod.rs new file mode 100644 index 0000000..8e2a92e --- /dev/null +++ b/advent_of_code_2015/src/day7/mod.rs @@ -0,0 +1,2 @@ +pub mod part1; +pub mod part2; \ No newline at end of file diff --git a/advent_of_code_2015/src/day7/part1.rs b/advent_of_code_2015/src/day7/part1.rs new file mode 100644 index 0000000..5fefc78 --- /dev/null +++ b/advent_of_code_2015/src/day7/part1.rs @@ -0,0 +1,102 @@ +use std::collections::HashMap; + +#[derive(Debug, Clone)] +pub enum Value { + Literal(u16), + Identifier(String), +} + +#[derive(Debug, Clone, Copy)] +pub enum Operator { + And, + Or, + RShift, + LShift, + Not +} + +#[derive(Debug, Clone)] +pub enum Expression { + Assign(Value), // 1 token before arrow + Binary(Operator, Value, Value), // 3 tokens before arrow + Unary(Value), // always not // 2 tokens before arrow +} + +fn parse_operator(name: &str) -> Operator { + match name { + "AND" => Operator::And, + "OR" => Operator::Or, + "RSHIFT" => Operator::RShift, + "LSHIFT" => Operator::LShift, + _ => panic!("unexpected operator: {}", name) + } +} + +fn parse_value(value: &str) -> Value { + if let Ok(num) = value.parse::() { + Value::Literal(num) + } else { + Value::Identifier(value.into()) + } +} + +fn solve_value(value: &Value, expressions: &HashMap, cache: &mut HashMap) -> u16 { + match value { + Value::Literal(num) => *num, + Value::Identifier(name) => { + let result = calculate_wire(name, expressions, cache); + cache.insert(name.clone(), result); + result + }, + } +} + +fn calculate_wire(ident: &String, expressions: &HashMap, cache: &mut HashMap) -> u16 { + if let Some(num) = cache.get(ident) { + return *num; + } + + match expressions.get(ident).unwrap() { + Expression::Assign(value) => { + solve_value(value, expressions, cache) + }, + Expression::Binary(operator, lhs, rhs) => { + match operator { + Operator::And => solve_value(lhs, expressions, cache) & solve_value(rhs, expressions, cache), + Operator::Or => solve_value(lhs, expressions, cache) | solve_value(rhs, expressions, cache), + Operator::RShift => solve_value(lhs, expressions, cache) >> solve_value(rhs, expressions, cache), + Operator::LShift => solve_value(lhs, expressions, cache) << solve_value(rhs, expressions, cache), + Operator::Not => todo!(), + } + }, + Expression::Unary(value) => { + !solve_value(value, expressions, cache) + }, + } +} + +pub fn solve(input: &str) { + let mut value_cache: HashMap = HashMap::new(); + let expressions = input.lines().map(|line| { + let (expr, into) = line.split_once(" -> ").unwrap(); + let parts = expr.split(" ").collect::>(); + + let parsed = match parts.len() { + 1 => { // assignment + Expression::Assign(parse_value(expr)) + }, + 2 => { + Expression::Unary(parse_value(parts[1])) + }, + 3 => { + Expression::Binary(parse_operator(parts[1]), parse_value(parts[0]), parse_value(parts[2])) + }, + _ => panic!("unexpected number of parts: {line}") + }; + + // println!("parsed: {into} -> {parsed:?}"); + (into.to_string(), parsed) + }).collect::>(); + + println!("solve for a: {}", calculate_wire(&"a".into(), &expressions, &mut value_cache)); +} diff --git a/advent_of_code_2015/src/day7/part2.rs b/advent_of_code_2015/src/day7/part2.rs new file mode 100644 index 0000000..1c6cc47 --- /dev/null +++ b/advent_of_code_2015/src/day7/part2.rs @@ -0,0 +1,105 @@ +use std::collections::HashMap; + +#[derive(Debug, Clone)] +pub enum Value { + Literal(u16), + Identifier(String), +} + +#[derive(Debug, Clone, Copy)] +pub enum Operator { + And, + Or, + RShift, + LShift, + Not +} + +#[derive(Debug, Clone)] +pub enum Expression { + Assign(Value), // 1 token before arrow + Binary(Operator, Value, Value), // 3 tokens before arrow + Unary(Value), // always not // 2 tokens before arrow +} + +fn parse_operator(name: &str) -> Operator { + match name { + "AND" => Operator::And, + "OR" => Operator::Or, + "RSHIFT" => Operator::RShift, + "LSHIFT" => Operator::LShift, + _ => panic!("unexpected operator: {}", name) + } +} + +fn parse_value(value: &str) -> Value { + if let Ok(num) = value.parse::() { + Value::Literal(num) + } else { + Value::Identifier(value.into()) + } +} + +fn solve_value(value: &Value, expressions: &HashMap, cache: &mut HashMap) -> u16 { + match value { + Value::Literal(num) => *num, + Value::Identifier(name) => { + if let Some(num) = cache.get(name) { + return *num; + } + + let result = calculate_wire(name, expressions, cache); + cache.insert(name.clone(), result); + result + }, + } +} + +fn calculate_wire(ident: &String, expressions: &HashMap, cache: &mut HashMap) -> u16 { + match expressions.get(ident).unwrap() { + Expression::Assign(value) => { + solve_value(value, expressions, cache) + }, + Expression::Binary(operator, lhs, rhs) => { + match operator { + Operator::And => solve_value(lhs, expressions, cache) & solve_value(rhs, expressions, cache), + Operator::Or => solve_value(lhs, expressions, cache) | solve_value(rhs, expressions, cache), + Operator::RShift => solve_value(lhs, expressions, cache) >> solve_value(rhs, expressions, cache), + Operator::LShift => solve_value(lhs, expressions, cache) << solve_value(rhs, expressions, cache), + Operator::Not => todo!(), + } + }, + Expression::Unary(value) => { + !solve_value(value, expressions, cache) + }, + } +} + +pub fn solve(input: &str) { + let mut value_cache: HashMap = HashMap::new(); + let expressions = input.lines().map(|line| { + let (expr, into) = line.split_once(" -> ").unwrap(); + let parts = expr.split(" ").collect::>(); + + let parsed = match parts.len() { + 1 => { // assignment + Expression::Assign(parse_value(expr)) + }, + 2 => { + Expression::Unary(parse_value(parts[1])) + }, + 3 => { + Expression::Binary(parse_operator(parts[1]), parse_value(parts[0]), parse_value(parts[2])) + }, + _ => panic!("unexpected number of parts: {line}") + }; + + // println!("parsed: {into} -> {parsed:?}"); + (into.to_string(), parsed) + }).collect::>(); + + let a = calculate_wire(&"a".into(), &expressions, &mut value_cache); + value_cache.clear(); + value_cache.insert("b".into(), a); + println!("value for a: {}", calculate_wire(&"a".into(), &expressions, &mut value_cache)); +} diff --git a/advent_of_code_2015/src/day7/test.txt b/advent_of_code_2015/src/day7/test.txt new file mode 100644 index 0000000..febb2a0 --- /dev/null +++ b/advent_of_code_2015/src/day7/test.txt @@ -0,0 +1,8 @@ +123 -> x +456 -> y +x AND y -> d +x OR y -> e +x LSHIFT 2 -> f +y RSHIFT 2 -> g +NOT x -> h +NOT y -> i \ No newline at end of file diff --git a/advent_of_code_2015/src/day8/input.txt b/advent_of_code_2015/src/day8/input.txt new file mode 100644 index 0000000..51c17a7 --- /dev/null +++ b/advent_of_code_2015/src/day8/input.txt @@ -0,0 +1,300 @@ +"sjdivfriyaaqa\xd2v\"k\"mpcu\"yyu\"en" +"vcqc" +"zbcwgmbpijcxu\"yins\"sfxn" +"yumngprx" +"bbdj" +"czbggabkzo\"wsnw\"voklp\"s" +"acwt" +"aqttwnsohbzian\"evtllfxwkog\"cunzw" +"ugvsgfv" +"xlnillibxg" +"kexh\"pmi" +"syvugow" +"m\"ktqnw" +"yrbajyndte\\rm" +"f\"kak\x70sn\xc4kjri" +"yxthr" +"alvumfsjni\"kohg" +"trajs\x5brom\xf1yoijaumkem\"\"tahlzs" +"\"oedr\"pwdbnnrc" +"qsmzhnx\"" +"\"msoytqimx\\tbklqz" +"mjdfcgwdshrehgs" +"\"rivyxahf\"" +"ciagc\x04bp" +"xkfc" +"xrgcripdu\x4c\xc4gszjhrvumvz\"mngbirb" +"gvmae\"yiiujoqvr\"mkxmgbbut\"u" +"ih" +"ncrqlejehs" +"mkno\x43pcfdukmemycp" +"uanzoqxkpsksbvdnkji\"feamp" +"axoufpnbx\\ao\x61pfj\"b" +"dz\\ztawzdjy" +"ihne\"enumvswypgf" +"\"dgazthrphbshdo\\vuqoiy\"" +"dlnmptzt\\zahwpylc\\b\"gmslrqysk" +"mhxznyzcp" +"rebr\"amvxw\x5fmbnfpkkeghlntavj" +"lades\x47ncgdof\"\"jmbbk" +"dwxuis\xa5wdkx\\z\"admgnoddpgkt\\zs" +"g\\k\x27qsl\x34hwfglcdxqbeclt\xca\\" +"lhyjky\\m\"pvnm\\xmynpxnlhndmahjl" +"c\"uxabbgorrpprw\"xas\\vefkxioqpt" +"rfrvjxpevcmma\x71gtfipo" +"fgh\"kcwoqwfnjgdlzfclprg\"q" +"onxnwykrba" +"hkkg\x60f\"tjzsanpvarzgkfipl" +"\"aintes\"ofq\"juiaqlqxmvpe\\a" +"wiyczzs\"ciwk" +"mfqeu" +"v\xe1z\x7ftzalmvdmncfivrax\\rjwq" +"k\"vtg" +"exhrtdugeml\xf0" +"behnchkpld" +"mhgxy\"mfcrg\xc5gnp\"\"osqhj" +"rlvjy" +"awe" +"ctwy" +"vt" +"\x54t" +"zugfmmfomz" +"cv\"cvcvfaada\x04fsuqjinbfh\xa9cq\xd2c\"d" +"oj" +"xazanf\"wbmcrn" +"\\\\zkisyjpbzandqikqjqvee" +"dpsnbzdwnxk\\v" +"sj\"tuupr\\oyoh" +"myvkgnw\x81q\xaaokt\\emgejbsyvxcl\\\xee" +"ejeuqvunjcirdkkpt\"nlns" +"twmlvwxyvfyqqzu" +"\"xwtzdp\x98qkcis\"dm\\\"ep\"xyykq" +"vvcq\\expok" +"wgukjfanjgpdjb" +"\"mjcjajnxy\\dcpc" +"wdvgnecw\\ab\x44klceduzgsvu" +"dqtqkukr\"iacngufbqkdpxlwjjt" +"\"xj\"\x66qofsqzkoah" +"nptiwwsqdep" +"gsnlxql\x30mjl" +"yeezwokjwrhelny\"" +"bjauamn\\izpmzqqasid" +"tvjdbkn\"tiziw\x82r" +"w" +"xwoakbbnjnypnaa\xa9wft\"slrmoqkl" +"vwxtnlvaaasyruykgygrvpiopzygf\"vq" +"qdancvnvmhlmpj\\isdxs" +"xzc\\elw" +"b\"wxeqvy\"qf\"g\xcaoklsucwicyw\"dovr" +"yomlvvjdbngz\"rly\"afr" +"bfb\"x\"aweuwbwmoa\x13\"t\"zhr" +"\"dmfoxb\"qvpjzzhykt\xd2\"\"ryhxi" +"psqef\"yu\\qiflie\"\x79w" +"arzewkej\"lqmh\\sayyusxxo\\" +"vuvvp" +"hc\"lg\x6bcpupsewzklai\"l" +"cjdfygc\"auorqybnuqghsh\x10" +"j" +"wqjexk\"eyq\\lbroqhk\\dqzsqk" +"dws\"ru\"dvxfiwapif\"oqwzmle" +"agcykg\\jt\\vzklqjvknoe" +"kksd\"jmslja\\z\"y\\b\xaagpyojct" +"nnpipxufvbfpoz\"jno" +"dtw" +"xlolvtahvgqkx\\dgnhj\\spsclpcxv\\" +"mxea\\mbjpi" +"lgbotkk\"zmxh\\\\qji\"jszulnjsxkqf" +"lwckmhwhx\"gmftlb\x91am" +"xxdxqyxth" +"\"lmqhwkjxmvayxy" +"tf" +"qy" +"wdqmwxdztax\"m\"\x09\x11xdxmfwxmtqgwvf" +"\xcbnazlf\"ghziknszmsrahaf" +"e\x6aupmzhxlvwympgjjpdvo\"kylfa" +"\x81vhtlillb\xactgoatva" +"dvnlgr" +"f" +"xg\xfacwizsadgeclm" +"vnnrzbtw\"\\prod\\djbyppngwayy\"" +"lrt\xf4jahwvfz" +"aqpnjtom\"ymkak\\dadfybqrso\\fwv" +"gz\"aac\"mrbk\"ktommrojraqh" +"wycamwoecsftepfnlcdkm" +"nrhddblbuzlqsl\x9cben" +"vckxhyqkmqmdseazcykrbysm" +"sil\xbbtevmt\"gvrvybui\"faw\"j" +"cjex\\tp\x45pzf" +"asjobvtxszfodgf\"ibftg" +"gkyjyjdrxdcllnh\"sjcibenrdnxv" +"oswsdpjyxpbwnqbcpl\"yrdvs\\zq" +"\"\"tyowzc\\fycbp\"jbwrbvgui" +"cbpcabqkdgzmpgcwjtrchxp" +"iyrzfh\x45gw\"fdlfpiaap\x31xqq" +"evgksznidz" +"b\\w\\" +"loufizbiy\x57aim\"bgk" +"qjfyk" +"g\"anmloghvgr\x07zwqougqhdz" +"usbbmwcxd\\bdgg" +"htitqcpczml" +"eke\\cqvpexqqk\"to\"tqmljrpn\xe6lji\"" +"g\xd2ifdsej" +"h\"sk\"haajajpagtcqnzrfqn\xe6btzo" +"wfkuffdxlvm\\cvlyzlbyunclhmpp" +"myaavh\"spue" +"hqvez\x68d\"eo\"eaioh" +"s\"qd\"oyxxcglcdnuhk" +"ilqvar" +"srh" +"puuifxrfmpc\"bvalwi\x2blu\\" +"yywlbutufzysbncw\\nqsfbhpz\"mngjq" +"zbl\\jfcuop" +"hjdouiragzvxsqkreup\\" +"qi" +"ckx\\funlj\xa7ahi" +"k" +"ufrcnh\"ajteit" +"cqv\"bgjozjj\x60x\xa8yhvmdvutchjotyuz" +"hkuiet\"oku\x8cfhumfpasl" +"\"\\sbe\x4d" +"vhknazqt" +"eyyizvzcahgflvmoowvs\\jhvygci" +"kki\x3ewcefkgtjap\"xtpxh\"lzepoqj" +"wvtk" +"\"ynet" +"zh\\obk\"otagx\x59txfzf" +"ocowhxlx\xe6zqg\x63wx\\tclkhq\\vmaze" +"w\"cf" +"qpniprnrzrnvykghqnalr" +"jctcqra\"\x05dhlydpqamorqjsijt\\xjdgt" +"sig" +"qhlbidbflwxe\"xljbwls\x20vht" +"irmrebfla\xefsg\"j" +"nep" +"hjuvsqlizeqobepf" +"guzbcdp\"obyh" +"\"mjagins\xf9tqykaxy\"" +"knvsdnmtr\"zervsb" +"hzuy" +"zza\"k\"buapb\\elm\xfeya" +"lrqar\"dfqwkaaqifig\"uixjsz" +"\"azuo\x40rmnlhhluwsbbdb\x32pk\\yu\"pbcf" +"dplkdyty" +"rfoyciebwlwphcycmguc" +"ivnmmiemhgytmlprq\\eh" +"lhkyzaaothfdhmbpsqd\\yyw" +"tnlzifupcjcaj" +"\\qiyirsdrfpmu\\\x15xusifaag" +"\\lcomf\\s" +"uramjivcirjhqcqcg" +"kkbaklbxfxikffnuhtu\xc6t\"d" +"n\xefai" +"\"toy\"bnbpevuzoc\"muywq\"gz\"grbm" +"\"muu\\wt" +"\\srby\"ee" +"erf\"gvw\"swfppf" +"pbqcgtn\"iuianhcdazfvmidn\\nslhxdf" +"uxbp" +"up\\mgrcyaegiwmjufn" +"nulscgcewj\\dvoyvhetdegzhs\"" +"masv\"k\\rzrb" +"qtx\x79d\"xdxmbxrvhj" +"fid\\otpkgjlh\"qgsvexrckqtn\xf4" +"tagzu" +"bvl\\\"noseec" +"\\xgicuuh" +"w\"a\"npemf" +"sxp" +"nsmpktic\x8awxftscdcvijjobnq\"gjd" +"uks\"\"jxvyvfezz\"aynxoev\"cuoav" +"m" +"lkvokj" +"vkfam\"yllr\"q\x92o\x4ebecnvhshhqe\\" +"efdxcjkjverw" +"lmqzadwhfdgmep\x02tzfcbgrbfekhat" +"cpbk\x9azqegbpluczssouop\x36ztpuoxsw" +"cqwoczxdd\"erdjka" +"cwvqnjgbw\\fxdlby" +"mvtm" +"lt\"bbqzpumplkg" +"ntd\xeeuwweucnuuslqfzfq" +"y\xabl\"dbebxjrlbmuoo\\\x1au" +"qjoqx\\a" +"pu\"ekdnfpmly\xbago\"" +"fjhhdy" +"arl" +"xcywisim\"bwuwf\"\"raepeawwjub" +"pbe" +"dbnqfpzyaumxtqnd\xc5dcqrkwyop" +"ojv\x40vtkwgkqepm\x8bzft\\vedrry" +"wggqkfbwqumsgajqwphjec\"mstxpwz" +"zjkbem" +"icpfqxbelxazlls" +"pvpqs\\abcmtyielugfgcv\"tjxapxqxnx" +"oqddwlvmtv\"\x39lyybylfb\"jmngnpjrdw" +"gisgbve" +"\"aglg" +"y\"\"ss\xafvhxlrjv" +"qbgqjsra" +"ihshbjgqpdcljpmdwdprwloy" +"djja\\wcdn\"svkrgpqn\"uz\"hc\x43hj" +"cbjm" +"pnn" +"pqvh\"noh" +"\"\\fdktlp" +"ncea" +"pqgzphiyy" +"\xbedovhxuipaohlcvkwtxwmpz\"ckaif\"r" +"arjuzbjowqciunfwgxtph\"vlhy\"n" +"c" +"nrpdxunulgudqzlhtae" +"iefheu\"uru\"" +"aqijysxuijud\"np\\opbichhudil\xbesum" +"pfpevmtstl\"lde\"bzr\"vspdxs" +"vparfbdjwvzsocpnzhp" +"g\x4ffxaarafrsjthq\\\xc1rw" +"ng\\rqx\\gwpzucbh\xafl" +"rw\"nf\\dna" +"jkkeahxurxla\\g\xb3czrlsyimmwcwthr" +"twaailoypu\"oas\"kpuuyedlaw\\\xb0vzt" +"hznex\\gdiqvtugi" +"imdibsunjeswhk" +"ta\\icileuzpxro\"cfmv\"mzp" +"coykr\x57luiysucfaflmilhlehmvzeiepo" +"u\x3dfh\xd4yt" +"piw\x1bz\"eowy\"vfk\"wqiekw" +"gan\"y" +"p\"bevidoazcznr\"hddxuuq\"" +"bwzucczznutbxe" +"z\"viqgyqjisior\\iecosmjbknol" +"dmlpcglcfkfsctxydjvayhymv\x3c\\gp" +"bfvkqrintbbvgfv" +"xlzntrgdck\"cprc\xadczyarbznqmuhxyuh" +"uqdxnuwioc\"kdytxq\\ig" +"xrafmucpmfi" +"vr\"hltmfrge" +"eonf\"nt\\wtcnsocs" +"j\xb7xoslyjeyjksplkqixncgkylkw" +"njw\"pefgfbez\x9axshdmplxzquqe" +"di\x58bvptfsafirpc" +"l\x1fkco" +"x" +"mprndo\"n" +"psegit" +"svbdnkkuuqs\"sqxu\"oqcyz\"aizashk" +"cwkljukxer\\\"\\nff\"esjwiyaoy" +"ilxrkgbjjxpvhdtq\"cpiuoofdnkpp" +"hlngi\"ulxep\\qohtmqnqjb\"rkgerho" +"gxws\"bcgm\"p" +"bv\"mds\\zhfusiepgrz\\b\x32fscdzz" +"l\xfampwtme\x69qvxnx\"\"\xc4jruuymjxrpsv" +"qqmxhrn" +"xziq\\\x18ybyv\x9am\"neacoqjzytertisysza" +"aqcbvlvcrzceeyx\\j\"\"x" +"yjuhhb" +"\x5em\"squulpy" +"dpbntplgmwb" +"utsgfkm\\vbftjknlktpthoeo" +"ccxjgiocmuhf\"ycnh" +"lltj\"kbbxi" \ No newline at end of file diff --git a/advent_of_code_2015/src/day8/mod.rs b/advent_of_code_2015/src/day8/mod.rs new file mode 100644 index 0000000..8e2a92e --- /dev/null +++ b/advent_of_code_2015/src/day8/mod.rs @@ -0,0 +1,2 @@ +pub mod part1; +pub mod part2; \ No newline at end of file diff --git a/advent_of_code_2015/src/day8/part1.rs b/advent_of_code_2015/src/day8/part1.rs new file mode 100644 index 0000000..5e05292 --- /dev/null +++ b/advent_of_code_2015/src/day8/part1.rs @@ -0,0 +1,33 @@ +pub fn solve(input: &str) { + let lines = input.lines().collect::>(); + + let mut code_counter: u64 = 0; + let mut char_counter: u64 = 0; + + for line in lines { + let mut caret = 0; + let mut raw = line.as_bytes(); + + while caret < raw.len() { + match raw[caret] { + b'"' => (), + b'\\' => { + if raw[caret + 1] == b'x' { + caret += 3; + char_counter += 1; + } else { + caret += 1; + char_counter += 1; + } + }, + _ => { + char_counter += 1; + } + } + caret += 1; + } + code_counter += line.len() as u64; + } + + println!("chars: {char_counter}, code: {code_counter}, result: {}", code_counter - char_counter); +} diff --git a/advent_of_code_2015/src/day8/part2.rs b/advent_of_code_2015/src/day8/part2.rs new file mode 100644 index 0000000..bc5bad5 --- /dev/null +++ b/advent_of_code_2015/src/day8/part2.rs @@ -0,0 +1,29 @@ +pub fn solve(input: &str) { + let lines = input.lines().collect::>(); + + let mut additional_characters = 0; + + for line in lines { + let mut caret = 0; + let mut raw = line.as_bytes(); + + while caret < raw.len() { + match raw[caret] { + b'"' => additional_characters += 2, + b'\\' => { + if raw[caret + 1] == b'x' { + caret += 3; + additional_characters += 1; + } else { + caret += 1; + additional_characters += 2; + } + }, + _ => {} + } + caret += 1; + } + } + + println!("additional characters: {additional_characters}"); +} diff --git a/advent_of_code_2015/src/day8/test.txt b/advent_of_code_2015/src/day8/test.txt new file mode 100644 index 0000000..f99c16f --- /dev/null +++ b/advent_of_code_2015/src/day8/test.txt @@ -0,0 +1,4 @@ +"" +"abc" +"aaa\"aaa" +"\x27" \ No newline at end of file diff --git a/advent_of_code_2015/src/day9/input.txt b/advent_of_code_2015/src/day9/input.txt new file mode 100644 index 0000000..38d4369 --- /dev/null +++ b/advent_of_code_2015/src/day9/input.txt @@ -0,0 +1,28 @@ +Faerun to Norrath = 129 +Faerun to Tristram = 58 +Faerun to AlphaCentauri = 13 +Faerun to Arbre = 24 +Faerun to Snowdin = 60 +Faerun to Tambi = 71 +Faerun to Straylight = 67 +Norrath to Tristram = 142 +Norrath to AlphaCentauri = 15 +Norrath to Arbre = 135 +Norrath to Snowdin = 75 +Norrath to Tambi = 82 +Norrath to Straylight = 54 +Tristram to AlphaCentauri = 118 +Tristram to Arbre = 122 +Tristram to Snowdin = 103 +Tristram to Tambi = 49 +Tristram to Straylight = 97 +AlphaCentauri to Arbre = 116 +AlphaCentauri to Snowdin = 12 +AlphaCentauri to Tambi = 18 +AlphaCentauri to Straylight = 91 +Arbre to Snowdin = 129 +Arbre to Tambi = 53 +Arbre to Straylight = 40 +Snowdin to Tambi = 15 +Snowdin to Straylight = 99 +Tambi to Straylight = 70 \ No newline at end of file diff --git a/advent_of_code_2015/src/day9/mod.rs b/advent_of_code_2015/src/day9/mod.rs new file mode 100644 index 0000000..8e2a92e --- /dev/null +++ b/advent_of_code_2015/src/day9/mod.rs @@ -0,0 +1,2 @@ +pub mod part1; +pub mod part2; \ No newline at end of file diff --git a/advent_of_code_2015/src/day9/part1.rs b/advent_of_code_2015/src/day9/part1.rs new file mode 100644 index 0000000..861de19 --- /dev/null +++ b/advent_of_code_2015/src/day9/part1.rs @@ -0,0 +1,55 @@ +use std::collections::{HashMap, HashSet}; + +fn generate_routes(current: String, mut destinations: HashSet) -> Vec> { + destinations.remove(¤t); + let mut routes = Vec::new(); + + if destinations.is_empty() { + routes.push([current].to_vec()); + return routes; + } + + for destination in destinations.iter() { + routes.append(&mut generate_routes(destination.clone(), destinations.clone())); + } + + for route in routes.iter_mut() { + route.push(current.clone()); + } + + routes +} + +pub fn solve(input: &str) { + let mut distances: HashMap> = HashMap::new(); + + input.lines().for_each(|line| { + let (from, tail) = line.split_once(" to ").unwrap(); + let (to, distance) = tail.split_once(" = ").unwrap(); + + distances.entry(from.into()).or_default().insert(to.to_string(), distance.parse().unwrap()); + distances.entry(to.into()).or_default().insert(from.to_string(), distance.parse().unwrap()); + }); + + let cities = distances.keys().cloned().collect::>(); + let mut routes: Vec> = Vec::new(); + + for city in cities.iter() { + routes.append(&mut generate_routes(city.clone(), cities.clone())); + } + + + let route_lengths = routes.iter().map(|route| { + let mut distance = 0u64; + for idx in 0..(route.len() - 1) { + distance += distances[&route[idx]][&route[idx + 1]]; + } + distance + }).collect::>(); + + // for (route, length) in routes.iter().zip(route_lengths) { + // println!("route: {route:?}, distance: {length}"); + // } + + println!("shortest route: {}", route_lengths.iter().min().unwrap()); +} diff --git a/advent_of_code_2015/src/day9/part2.rs b/advent_of_code_2015/src/day9/part2.rs new file mode 100644 index 0000000..9423c58 --- /dev/null +++ b/advent_of_code_2015/src/day9/part2.rs @@ -0,0 +1,55 @@ +use std::collections::{HashMap, HashSet}; + +fn generate_routes(current: String, mut destinations: HashSet) -> Vec> { + destinations.remove(¤t); + let mut routes = Vec::new(); + + if destinations.is_empty() { + routes.push([current].to_vec()); + return routes; + } + + for destination in destinations.iter() { + routes.append(&mut generate_routes(destination.clone(), destinations.clone())); + } + + for route in routes.iter_mut() { + route.push(current.clone()); + } + + routes +} + +pub fn solve(input: &str) { + let mut distances: HashMap> = HashMap::new(); + + input.lines().for_each(|line| { + let (from, tail) = line.split_once(" to ").unwrap(); + let (to, distance) = tail.split_once(" = ").unwrap(); + + distances.entry(from.into()).or_default().insert(to.to_string(), distance.parse().unwrap()); + distances.entry(to.into()).or_default().insert(from.to_string(), distance.parse().unwrap()); + }); + + let cities = distances.keys().cloned().collect::>(); + let mut routes: Vec> = Vec::new(); + + for city in cities.iter() { + routes.append(&mut generate_routes(city.clone(), cities.clone())); + } + + + let route_lengths = routes.iter().map(|route| { + let mut distance = 0u64; + for idx in 0..(route.len() - 1) { + distance += distances[&route[idx]][&route[idx + 1]]; + } + distance + }).collect::>(); + + // for (route, length) in routes.iter().zip(route_lengths) { + // println!("route: {route:?}, distance: {length}"); + // } + + println!("longest route: {}", route_lengths.iter().max().unwrap()); +} diff --git a/advent_of_code_2015/src/day9/test.txt b/advent_of_code_2015/src/day9/test.txt new file mode 100644 index 0000000..d8224f9 --- /dev/null +++ b/advent_of_code_2015/src/day9/test.txt @@ -0,0 +1,3 @@ +London to Dublin = 464 +London to Belfast = 518 +Dublin to Belfast = 141 \ No newline at end of file diff --git a/advent_of_code_2015/src/main.rs b/advent_of_code_2015/src/main.rs new file mode 100644 index 0000000..f6e935d --- /dev/null +++ b/advent_of_code_2015/src/main.rs @@ -0,0 +1,7 @@ +#![allow(dead_code, unused)] + +use paste::paste; +mod utility; + +solve_day!{9} +// test_day!{9} diff --git a/advent_of_code_2015/src/utility/inputstring.rs b/advent_of_code_2015/src/utility/inputstring.rs new file mode 100644 index 0000000..e9653ef --- /dev/null +++ b/advent_of_code_2015/src/utility/inputstring.rs @@ -0,0 +1,10 @@ +use std::fs::read_to_string; + +pub fn get_input_string(day: u8) -> String { + read_to_string(format!("src/day{}/input.txt", day)).expect("Failed to read input file.") +} + +pub fn get_test_string(day: u8, file: Option<&str>) -> String { + let filename = file.unwrap_or("test.txt"); + read_to_string(format!("src/day{}/{}", day, filename)).expect("Failed to read input file.") +} \ No newline at end of file diff --git a/advent_of_code_2015/src/utility/mod.rs b/advent_of_code_2015/src/utility/mod.rs new file mode 100644 index 0000000..cd9db7a --- /dev/null +++ b/advent_of_code_2015/src/utility/mod.rs @@ -0,0 +1,6 @@ +#![allow(unused)] + +mod inputstring; +pub use inputstring::{get_input_string, get_test_string}; + +mod solveday; \ No newline at end of file diff --git a/advent_of_code_2015/src/utility/solveday.rs b/advent_of_code_2015/src/utility/solveday.rs new file mode 100644 index 0000000..d68ac7f --- /dev/null +++ b/advent_of_code_2015/src/utility/solveday.rs @@ -0,0 +1,31 @@ +#[macro_export] +macro_rules! solve_day { + ($day:literal) => { + paste! {mod [];} + + pub fn main() { + println!("-- Day {} --", $day); + let input = utility::get_input_string($day); + paste! { [] ::part1::solve(&input) }; + paste! { [] ::part2::solve(&input) }; + } + }; + ($day:literal, $filename:literal) => { + paste! {mod [];} + + pub fn main() { + println!("-- Day {} --", $day); + let input = utility::get_test_string($day, Some($filename)); + paste! { [] ::part1::solve(&input) }; + println!("\n---\n"); + paste! { [] ::part2::solve(&input) }; + } + }; +} + +#[macro_export] +macro_rules! test_day { + ($day:literal) => { + solve_day!($day, "test.txt"); + }; +}