Compare commits
6 Commits
d3ce12693b
...
main
Author | SHA1 | Date | |
---|---|---|---|
77fba87ef6
|
|||
8b8ed2a323
|
|||
6efb9e0f83
|
|||
237ca36381
|
|||
d3bade1bdd
|
|||
50a197856a
|
Binary file not shown.
Before Width: | Height: | Size: 7.5 KiB After Width: | Height: | Size: 9.1 KiB |
Binary file not shown.
Before Width: | Height: | Size: 3.5 KiB After Width: | Height: | Size: 8.3 KiB |
Binary file not shown.
Before Width: | Height: | Size: 4.0 KiB After Width: | Height: | Size: 7.1 KiB |
@ -1,6 +1,6 @@
|
|||||||
<!-- AOC TILES BEGIN -->
|
<!-- AOC TILES BEGIN -->
|
||||||
<h1 align="center">
|
<h1 align="center">
|
||||||
2024 - 44 ⭐ - Rust
|
2024 - 48 ⭐ - Rust
|
||||||
</h1>
|
</h1>
|
||||||
<a href="src/day1.rs">
|
<a href="src/day1.rs">
|
||||||
<img src=".aoc_tiles/tiles/2024/01.png" width="161px">
|
<img src=".aoc_tiles/tiles/2024/01.png" width="161px">
|
||||||
@ -71,4 +71,10 @@
|
|||||||
<a href="src/day23.rs">
|
<a href="src/day23.rs">
|
||||||
<img src=".aoc_tiles/tiles/2024/23.png" width="161px">
|
<img src=".aoc_tiles/tiles/2024/23.png" width="161px">
|
||||||
</a>
|
</a>
|
||||||
|
<a href="src/day24.rs">
|
||||||
|
<img src=".aoc_tiles/tiles/2024/24.png" width="161px">
|
||||||
|
</a>
|
||||||
|
<a href="src/day25.rs">
|
||||||
|
<img src=".aoc_tiles/tiles/2024/25.png" width="161px">
|
||||||
|
</a>
|
||||||
<!-- AOC TILES END -->
|
<!-- AOC TILES END -->
|
||||||
|
78
src/day23.rs
78
src/day23.rs
@ -1,8 +1,7 @@
|
|||||||
use std::fmt::Debug;
|
|
||||||
|
|
||||||
use aoc_runner_derive::aoc;
|
use aoc_runner_derive::aoc;
|
||||||
use itertools::Itertools;
|
use itertools::Itertools;
|
||||||
use rustc_hash::{FxHashMap, FxHashSet};
|
use rustc_hash::{FxHashMap, FxHashSet};
|
||||||
|
use std::fmt::{Debug, Display};
|
||||||
|
|
||||||
#[derive(Copy, Clone, Ord, PartialOrd, Eq, PartialEq, Hash)]
|
#[derive(Copy, Clone, Ord, PartialOrd, Eq, PartialEq, Hash)]
|
||||||
struct Node([char; 2]);
|
struct Node([char; 2]);
|
||||||
@ -13,9 +12,15 @@ impl Debug for Node {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl Display for Node {
|
||||||
|
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||||
|
f.write_fmt(format_args!("{}", self.0.iter().join("")))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl From<[char; 2]> for Node {
|
impl From<[char; 2]> for Node {
|
||||||
fn from(value: [char; 2]) -> Self {
|
fn from(value: [char; 2]) -> Self {
|
||||||
Node(value)
|
Self(value)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -28,8 +33,8 @@ impl TryFrom<Vec<char>> for Node {
|
|||||||
}
|
}
|
||||||
|
|
||||||
struct Network {
|
struct Network {
|
||||||
nodes: Vec<Node>,
|
nodes: FxHashSet<Node>,
|
||||||
edges: FxHashMap<Node, Vec<Node>>,
|
edges: FxHashMap<Node, FxHashSet<Node>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Network {
|
impl Network {
|
||||||
@ -51,11 +56,52 @@ impl Network {
|
|||||||
}
|
}
|
||||||
sets
|
sets
|
||||||
}
|
}
|
||||||
|
// Had to study Wikipedia for this one
|
||||||
|
// https://en.wikipedia.org/wiki/Bron%E2%80%93Kerbosch_algorithm
|
||||||
|
fn bron_kerbosch(
|
||||||
|
&self,
|
||||||
|
r: FxHashSet<Node>,
|
||||||
|
mut p: FxHashSet<Node>,
|
||||||
|
mut x: FxHashSet<Node>,
|
||||||
|
) -> Vec<FxHashSet<Node>> {
|
||||||
|
let mut results = Vec::new();
|
||||||
|
if p.is_empty() && x.is_empty() {
|
||||||
|
return vec![r];
|
||||||
|
} else if p.is_empty() {
|
||||||
|
return Vec::new();
|
||||||
|
}
|
||||||
|
// choose the pivot with the most neighbours, to minimize the size of p_iter
|
||||||
|
let p_iter = if let Some(pivot) = p.union(&x).max_by(|a, b| self.edges[a].len().cmp(&self.edges[b].len())) {
|
||||||
|
FxHashSet::from_iter(p.difference(self.edges.get(pivot).unwrap()).copied())
|
||||||
|
} else {
|
||||||
|
p.clone()
|
||||||
|
};
|
||||||
|
for node in &p_iter {
|
||||||
|
let mut new_r = r.clone();
|
||||||
|
new_r.insert(*node);
|
||||||
|
|
||||||
|
let neighbours = FxHashSet::from_iter(self.edges.get(node).unwrap().iter().copied());
|
||||||
|
let new_p = FxHashSet::from_iter(p.intersection(&neighbours).copied());
|
||||||
|
let new_x = FxHashSet::from_iter(x.intersection(&neighbours).copied());
|
||||||
|
|
||||||
|
results.extend(self.bron_kerbosch(new_r, new_p, new_x).into_iter());
|
||||||
|
p.remove(node);
|
||||||
|
x.insert(*node);
|
||||||
|
}
|
||||||
|
results
|
||||||
|
}
|
||||||
|
fn maximal_subgraphs(&self) -> Vec<FxHashSet<Node>> {
|
||||||
|
self.bron_kerbosch(
|
||||||
|
FxHashSet::default(),
|
||||||
|
FxHashSet::from_iter(self.nodes.iter().copied()),
|
||||||
|
FxHashSet::default(),
|
||||||
|
)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl From<&str> for Network {
|
impl From<&str> for Network {
|
||||||
fn from(input: &str) -> Self {
|
fn from(input: &str) -> Self {
|
||||||
let mut nodes = Vec::new();
|
let mut nodes = FxHashSet::default();
|
||||||
let mut edges = FxHashMap::default();
|
let mut edges = FxHashMap::default();
|
||||||
for line in input.lines() {
|
for line in input.lines() {
|
||||||
let (node1, node2) = line.split_once('-').unwrap();
|
let (node1, node2) = line.split_once('-').unwrap();
|
||||||
@ -64,13 +110,13 @@ impl From<&str> for Network {
|
|||||||
node2.chars().collect_vec().try_into().unwrap(),
|
node2.chars().collect_vec().try_into().unwrap(),
|
||||||
);
|
);
|
||||||
if !nodes.contains(&node1) {
|
if !nodes.contains(&node1) {
|
||||||
nodes.push(node1);
|
nodes.insert(node1);
|
||||||
}
|
}
|
||||||
if !nodes.contains(&node2) {
|
if !nodes.contains(&node2) {
|
||||||
nodes.push(node2);
|
nodes.insert(node2);
|
||||||
}
|
}
|
||||||
edges.entry(node1).or_insert(Vec::new()).push(node2);
|
edges.entry(node1).or_insert(FxHashSet::default()).insert(node2);
|
||||||
edges.entry(node2).or_insert(Vec::new()).push(node1);
|
edges.entry(node2).or_insert(FxHashSet::default()).insert(node1);
|
||||||
}
|
}
|
||||||
Self { nodes, edges }
|
Self { nodes, edges }
|
||||||
}
|
}
|
||||||
@ -83,17 +129,21 @@ fn parse(input: &str) -> Network {
|
|||||||
#[aoc(day23, part1)]
|
#[aoc(day23, part1)]
|
||||||
pub fn part1(input: &str) -> i64 {
|
pub fn part1(input: &str) -> i64 {
|
||||||
let network = parse(input);
|
let network = parse(input);
|
||||||
println!("edges: {:?}", network.edges);
|
|
||||||
let sets = network.groups_3();
|
let sets = network.groups_3();
|
||||||
let t_count = sets.iter().filter(|set| set.iter().any(|s| s.0[0] == 't')).count();
|
let t_count = sets.iter().filter(|set| set.iter().any(|s| s.0[0] == 't')).count();
|
||||||
println!("groups: {:?}", sets);
|
|
||||||
|
|
||||||
t_count as i64
|
t_count as i64
|
||||||
}
|
}
|
||||||
|
|
||||||
#[aoc(day23, part2)]
|
#[aoc(day23, part2)]
|
||||||
pub fn part2(input: &str) -> String {
|
pub fn part2(input: &str) -> String {
|
||||||
todo!()
|
let network = parse(input);
|
||||||
|
let best_sets = network.maximal_subgraphs();
|
||||||
|
let largest_set = best_sets.iter().max_by(|a, b| a.len().cmp(&b.len())).unwrap();
|
||||||
|
let mut largest = largest_set.iter().collect_vec();
|
||||||
|
largest.sort();
|
||||||
|
largest.iter().join(",")
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
|
229
src/day24.rs
Normal file
229
src/day24.rs
Normal file
@ -0,0 +1,229 @@
|
|||||||
|
use aoc_runner_derive::aoc;
|
||||||
|
use itertools::Itertools;
|
||||||
|
use nom::And;
|
||||||
|
use regex::Regex;
|
||||||
|
use rustc_hash::FxHashMap;
|
||||||
|
|
||||||
|
#[derive(Copy, Clone, Debug)]
|
||||||
|
enum Op {
|
||||||
|
And,
|
||||||
|
Or,
|
||||||
|
Xor,
|
||||||
|
Constant,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl From<&str> for Op {
|
||||||
|
fn from(value: &str) -> Self {
|
||||||
|
match value {
|
||||||
|
"AND" => Self::And,
|
||||||
|
"OR" => Self::Or,
|
||||||
|
"XOR" => Self::Xor,
|
||||||
|
s => panic!("invalid operation {}", s),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Clone, Debug)]
|
||||||
|
struct Gate {
|
||||||
|
op: Op,
|
||||||
|
value: Option<bool>,
|
||||||
|
arguments: [String; 2],
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Gate {
|
||||||
|
fn eval(&self, machine: &GateMachine) -> bool {
|
||||||
|
match self.op {
|
||||||
|
Op::And => machine.val_of(&self.arguments[0]) && machine.val_of(&self.arguments[1]),
|
||||||
|
Op::Or => machine.val_of(&self.arguments[0]) || machine.val_of(&self.arguments[1]),
|
||||||
|
Op::Xor => machine.val_of(&self.arguments[0]) ^ machine.val_of(&self.arguments[1]),
|
||||||
|
Op::Constant => self.value.unwrap(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug)]
|
||||||
|
struct GateMachine {
|
||||||
|
gates: FxHashMap<String, Gate>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl GateMachine {
|
||||||
|
fn val_of(&self, gate: &str) -> bool {
|
||||||
|
println!("gate: {}", gate);
|
||||||
|
if let Some(val) = self.gates[gate].value {
|
||||||
|
val
|
||||||
|
} else {
|
||||||
|
self.gates[gate].eval(self)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn parse(input: &str) -> GateMachine {
|
||||||
|
let mut gates = FxHashMap::default();
|
||||||
|
for line in input.lines() {
|
||||||
|
println!("{line}");
|
||||||
|
let const_re = Regex::new(r"^([xyz][0-9]{2}): ([01])$").unwrap();
|
||||||
|
let gate_re = Regex::new(r"^([a-z0-9]{3}) (AND|XOR|OR) ([a-z0-9]{3}) -> ([a-z0-9]{3})$").unwrap();
|
||||||
|
|
||||||
|
if let Some(caps) = const_re.captures(line) {
|
||||||
|
println!(" is const: {:?}", caps);
|
||||||
|
gates.insert(
|
||||||
|
caps[1].to_string(),
|
||||||
|
Gate {
|
||||||
|
op: Op::Constant,
|
||||||
|
value: if &caps[2] == "1" { Some(true) } else { Some(false) },
|
||||||
|
arguments: [String::new(), String::new()],
|
||||||
|
},
|
||||||
|
);
|
||||||
|
} else if let Some(caps) = gate_re.captures(line) {
|
||||||
|
println!(" is gate: {:?}", caps);
|
||||||
|
gates.insert(
|
||||||
|
caps[4].to_string(),
|
||||||
|
Gate {
|
||||||
|
op: Op::from(&caps[2]),
|
||||||
|
value: None,
|
||||||
|
arguments: [caps[1].to_string(), caps[3].to_string()],
|
||||||
|
},
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
GateMachine { gates }
|
||||||
|
}
|
||||||
|
|
||||||
|
#[aoc(day24, part1)]
|
||||||
|
pub fn part1(input: &str) -> i64 {
|
||||||
|
let machine = parse(input);
|
||||||
|
let z_gates = machine
|
||||||
|
.gates
|
||||||
|
.keys()
|
||||||
|
.filter(|k| k.starts_with('z'))
|
||||||
|
.map(|s| (s, s.split_at(1).1.parse::<usize>().unwrap()));
|
||||||
|
let bit_vals = z_gates
|
||||||
|
.map(|(name, bit)| if machine.val_of(name) { 1 << bit } else { 0 })
|
||||||
|
.fold(0, |accum, val| accum | val);
|
||||||
|
bit_vals
|
||||||
|
}
|
||||||
|
|
||||||
|
#[aoc(day24, part2)]
|
||||||
|
pub fn part2(input: &str) -> i64 {
|
||||||
|
0
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(test)]
|
||||||
|
mod tests {
|
||||||
|
use super::*;
|
||||||
|
const EXAMPLE1: &str = "x00: 1
|
||||||
|
x01: 1
|
||||||
|
x02: 1
|
||||||
|
y00: 0
|
||||||
|
y01: 1
|
||||||
|
y02: 0
|
||||||
|
|
||||||
|
x00 AND y00 -> z00
|
||||||
|
x01 XOR y01 -> z01x00: 1
|
||||||
|
x01: 0
|
||||||
|
x02: 1
|
||||||
|
x03: 1
|
||||||
|
x04: 0
|
||||||
|
y00: 1
|
||||||
|
y01: 1
|
||||||
|
y02: 1
|
||||||
|
y03: 1
|
||||||
|
y04: 1
|
||||||
|
|
||||||
|
ntg XOR fgs -> mjb
|
||||||
|
y02 OR x01 -> tnw
|
||||||
|
kwq OR kpj -> z05
|
||||||
|
x00 OR x03 -> fst
|
||||||
|
tgd XOR rvg -> z01
|
||||||
|
vdt OR tnw -> bfw
|
||||||
|
bfw AND frj -> z10
|
||||||
|
ffh OR nrd -> bqk
|
||||||
|
y00 AND y03 -> djm
|
||||||
|
y03 OR y00 -> psh
|
||||||
|
bqk OR frj -> z08
|
||||||
|
tnw OR fst -> frj
|
||||||
|
gnj AND tgd -> z11
|
||||||
|
bfw XOR mjb -> z00
|
||||||
|
x03 OR x00 -> vdt
|
||||||
|
gnj AND wpb -> z02
|
||||||
|
x04 AND y00 -> kjc
|
||||||
|
djm OR pbm -> qhw
|
||||||
|
nrd AND vdt -> hwm
|
||||||
|
kjc AND fst -> rvg
|
||||||
|
y04 OR y02 -> fgs
|
||||||
|
y01 AND x02 -> pbm
|
||||||
|
ntg OR kjc -> kwq
|
||||||
|
psh XOR fgs -> tgd
|
||||||
|
qhw XOR tgd -> z09
|
||||||
|
pbm OR djm -> kpj
|
||||||
|
x03 XOR y03 -> ffh
|
||||||
|
x00 XOR y04 -> ntg
|
||||||
|
bfw OR bqk -> z06
|
||||||
|
nrd XOR fgs -> wpb
|
||||||
|
frj XOR qhw -> z04
|
||||||
|
bqk OR frj -> z07
|
||||||
|
y03 OR x01 -> nrd
|
||||||
|
hwm AND bqk -> z03
|
||||||
|
tgd XOR rvg -> z12
|
||||||
|
tnw OR pbm -> gnj
|
||||||
|
x02 OR y02 -> z02";
|
||||||
|
|
||||||
|
const EXAMPLE2: &str = "x00: 1
|
||||||
|
x01: 0
|
||||||
|
x02: 1
|
||||||
|
x03: 1
|
||||||
|
x04: 0
|
||||||
|
y00: 1
|
||||||
|
y01: 1
|
||||||
|
y02: 1
|
||||||
|
y03: 1
|
||||||
|
y04: 1
|
||||||
|
|
||||||
|
ntg XOR fgs -> mjb
|
||||||
|
y02 OR x01 -> tnw
|
||||||
|
kwq OR kpj -> z05
|
||||||
|
x00 OR x03 -> fst
|
||||||
|
tgd XOR rvg -> z01
|
||||||
|
vdt OR tnw -> bfw
|
||||||
|
bfw AND frj -> z10
|
||||||
|
ffh OR nrd -> bqk
|
||||||
|
y00 AND y03 -> djm
|
||||||
|
y03 OR y00 -> psh
|
||||||
|
bqk OR frj -> z08
|
||||||
|
tnw OR fst -> frj
|
||||||
|
gnj AND tgd -> z11
|
||||||
|
bfw XOR mjb -> z00
|
||||||
|
x03 OR x00 -> vdt
|
||||||
|
gnj AND wpb -> z02
|
||||||
|
x04 AND y00 -> kjc
|
||||||
|
djm OR pbm -> qhw
|
||||||
|
nrd AND vdt -> hwm
|
||||||
|
kjc AND fst -> rvg
|
||||||
|
y04 OR y02 -> fgs
|
||||||
|
y01 AND x02 -> pbm
|
||||||
|
ntg OR kjc -> kwq
|
||||||
|
psh XOR fgs -> tgd
|
||||||
|
qhw XOR tgd -> z09
|
||||||
|
pbm OR djm -> kpj
|
||||||
|
x03 XOR y03 -> ffh
|
||||||
|
x00 XOR y04 -> ntg
|
||||||
|
bfw OR bqk -> z06
|
||||||
|
nrd XOR fgs -> wpb
|
||||||
|
frj XOR qhw -> z04
|
||||||
|
bqk OR frj -> z07
|
||||||
|
y03 OR x01 -> nrd
|
||||||
|
hwm AND bqk -> z03
|
||||||
|
tgd XOR rvg -> z12
|
||||||
|
tnw OR pbm -> gnj";
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn part1_example() {
|
||||||
|
assert_eq!(part1(EXAMPLE1), 4);
|
||||||
|
assert_eq!(part1(EXAMPLE2), 2024);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn part2_example() {
|
||||||
|
assert_eq!(part2(EXAMPLE1), 0);
|
||||||
|
}
|
||||||
|
}
|
143
src/day25.rs
Normal file
143
src/day25.rs
Normal file
@ -0,0 +1,143 @@
|
|||||||
|
use aoc_runner_derive::aoc;
|
||||||
|
use itertools::Itertools;
|
||||||
|
|
||||||
|
enum LockKey {
|
||||||
|
Lock,
|
||||||
|
Key,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Clone, Debug)]
|
||||||
|
struct LockPile {
|
||||||
|
keys: Vec<Vec<usize>>,
|
||||||
|
locks: Vec<Vec<usize>>,
|
||||||
|
}
|
||||||
|
|
||||||
|
fn parse_grid(lines: &Vec<&str>) -> (LockKey, Vec<usize>) {
|
||||||
|
assert_eq!(lines.len(), 7);
|
||||||
|
if lines[0].chars().all(|c| c == '#') {
|
||||||
|
// lock
|
||||||
|
let mut pins = vec![0; 5];
|
||||||
|
for row in 1..lines.len() {
|
||||||
|
let row_s = lines[row];
|
||||||
|
for i in 0..row_s.len() {
|
||||||
|
if row_s.chars().nth(i) == Some('#') {
|
||||||
|
pins[i] = row
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
(LockKey::Lock, pins)
|
||||||
|
} else if lines[6].chars().all(|c| c == '#') {
|
||||||
|
// key
|
||||||
|
let mut pins = vec![5; 5];
|
||||||
|
for row in (1..lines.len()).rev() {
|
||||||
|
let row_s = lines[row];
|
||||||
|
for i in 0..row_s.len() {
|
||||||
|
if row_s.chars().nth(i) == Some('#') {
|
||||||
|
pins[i] = 6 - row
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
(LockKey::Key, pins)
|
||||||
|
} else {
|
||||||
|
panic!("not a lock or a key: {:?}", lines);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn parse(input: &str) -> LockPile {
|
||||||
|
let mut locks = Vec::new();
|
||||||
|
let mut keys = Vec::new();
|
||||||
|
let mut accum: Vec<&str> = Vec::new();
|
||||||
|
for line in input.lines() {
|
||||||
|
if line == "" {
|
||||||
|
let (lk, pins) = parse_grid(&accum);
|
||||||
|
match lk {
|
||||||
|
LockKey::Lock => locks.push(pins),
|
||||||
|
LockKey::Key => keys.push(pins),
|
||||||
|
}
|
||||||
|
accum.clear();
|
||||||
|
} else {
|
||||||
|
accum.push(line);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if accum.len() != 0 {
|
||||||
|
let (lk, pins) = parse_grid(&accum);
|
||||||
|
match lk {
|
||||||
|
LockKey::Lock => locks.push(pins),
|
||||||
|
LockKey::Key => keys.push(pins),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
LockPile { keys, locks }
|
||||||
|
}
|
||||||
|
|
||||||
|
fn test_lock_key(lock: &Vec<usize>, key: &Vec<usize>) -> bool {
|
||||||
|
!lock.iter().zip(key.iter()).any(|(lp, kp)| lp + kp > 5)
|
||||||
|
}
|
||||||
|
|
||||||
|
#[aoc(day25, part1)]
|
||||||
|
pub fn part1(input: &str) -> i64 {
|
||||||
|
let lockpile = parse(input);
|
||||||
|
|
||||||
|
lockpile
|
||||||
|
.locks
|
||||||
|
.iter()
|
||||||
|
.cartesian_product(lockpile.keys.iter())
|
||||||
|
.filter(|(l, k)| test_lock_key(l, k))
|
||||||
|
.count() as i64
|
||||||
|
}
|
||||||
|
|
||||||
|
#[aoc(day25, part2)]
|
||||||
|
pub fn part2(_input: &str) -> String {
|
||||||
|
"run the other solutions for day 25 part 2!".to_string()
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(test)]
|
||||||
|
mod tests {
|
||||||
|
use super::*;
|
||||||
|
const EXAMPLE: &str = "#####
|
||||||
|
.####
|
||||||
|
.####
|
||||||
|
.####
|
||||||
|
.#.#.
|
||||||
|
.#...
|
||||||
|
.....
|
||||||
|
|
||||||
|
#####
|
||||||
|
##.##
|
||||||
|
.#.##
|
||||||
|
...##
|
||||||
|
...#.
|
||||||
|
...#.
|
||||||
|
.....
|
||||||
|
|
||||||
|
.....
|
||||||
|
#....
|
||||||
|
#....
|
||||||
|
#...#
|
||||||
|
#.#.#
|
||||||
|
#.###
|
||||||
|
#####
|
||||||
|
|
||||||
|
.....
|
||||||
|
.....
|
||||||
|
#.#..
|
||||||
|
###..
|
||||||
|
###.#
|
||||||
|
###.#
|
||||||
|
#####
|
||||||
|
|
||||||
|
.....
|
||||||
|
.....
|
||||||
|
.....
|
||||||
|
#....
|
||||||
|
#.#..
|
||||||
|
#.#.#
|
||||||
|
#####";
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn part1_example() {
|
||||||
|
assert_eq!(part1(EXAMPLE), 3);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn part2_example() {}
|
||||||
|
}
|
@ -14,6 +14,8 @@ pub mod day20;
|
|||||||
pub mod day21;
|
pub mod day21;
|
||||||
pub mod day22;
|
pub mod day22;
|
||||||
pub mod day23;
|
pub mod day23;
|
||||||
|
pub mod day24;
|
||||||
|
pub mod day25;
|
||||||
pub mod day3;
|
pub mod day3;
|
||||||
pub mod day4;
|
pub mod day4;
|
||||||
pub mod day5;
|
pub mod day5;
|
||||||
|
Reference in New Issue
Block a user