Compare commits
No commits in common. "e93f6d01cade8105fb4052aba503c49ad1355074" and "b6dacf5b4713f1ccd55a3517501cd4c108fb7261" have entirely different histories.
e93f6d01ca
...
b6dacf5b47
@ -1,7 +1,24 @@
|
|||||||
use std::collections::HashMap;
|
use std::{
|
||||||
|
collections::HashMap,
|
||||||
|
fmt::{Debug, Error, Formatter},
|
||||||
|
num::ParseIntError,
|
||||||
|
ops::{Index, IndexMut},
|
||||||
|
str::FromStr,
|
||||||
|
};
|
||||||
|
|
||||||
use anyhow::Result;
|
use anyhow::Result;
|
||||||
use aoc_runner_derive::aoc;
|
use aoc_runner_derive::{aoc, aoc_generator};
|
||||||
|
use thiserror::Error;
|
||||||
|
|
||||||
|
struct Node {
|
||||||
|
name: String,
|
||||||
|
small: bool,
|
||||||
|
neighbors: Vec<usize>,
|
||||||
|
}
|
||||||
|
|
||||||
|
struct Graph {
|
||||||
|
nodes: Vec<String>,
|
||||||
|
}
|
||||||
|
|
||||||
fn search(node: &str, nodes: &HashMap<&str, Vec<&str>>, path: String, paths: &mut Vec<String>) {
|
fn search(node: &str, nodes: &HashMap<&str, Vec<&str>>, path: String, paths: &mut Vec<String>) {
|
||||||
if node == "end" {
|
if node == "end" {
|
||||||
@ -10,8 +27,10 @@ fn search(node: &str, nodes: &HashMap<&str, Vec<&str>>, path: String, paths: &mu
|
|||||||
}
|
}
|
||||||
for neighbor in &nodes[node] {
|
for neighbor in &nodes[node] {
|
||||||
// If lowercase.
|
// If lowercase.
|
||||||
if neighbor.as_bytes()[0] & 0x20 != 0 && path.contains(neighbor) {
|
if neighbor.as_bytes()[0] & 0x20 != 0 {
|
||||||
continue;
|
if path.contains(neighbor) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
search(neighbor, nodes, format!("{},{}", path, neighbor), paths);
|
search(neighbor, nodes, format!("{},{}", path, neighbor), paths);
|
||||||
}
|
}
|
||||||
@ -20,6 +39,7 @@ fn search(node: &str, nodes: &HashMap<&str, Vec<&str>>, path: String, paths: &mu
|
|||||||
fn paths(nodes: &HashMap<&str, Vec<&str>>) -> usize {
|
fn paths(nodes: &HashMap<&str, Vec<&str>>) -> usize {
|
||||||
let mut paths = Vec::new();
|
let mut paths = Vec::new();
|
||||||
search("start", nodes, "start".to_string(), &mut paths);
|
search("start", nodes, "start".to_string(), &mut paths);
|
||||||
|
//dbg!(&paths);
|
||||||
paths.len()
|
paths.len()
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -28,78 +48,19 @@ fn part1(input: &str) -> Result<usize> {
|
|||||||
let mut nodes = HashMap::new();
|
let mut nodes = HashMap::new();
|
||||||
input.lines().for_each(|p| {
|
input.lines().for_each(|p| {
|
||||||
let (n1, n2) = p.split_once('-').expect("missing dash");
|
let (n1, n2) = p.split_once('-').expect("missing dash");
|
||||||
nodes.entry(n1).or_insert_with(Vec::new).push(n2);
|
nodes.entry(n1).or_insert(Vec::new()).push(n2);
|
||||||
nodes.entry(n2).or_insert_with(Vec::new).push(n1);
|
nodes.entry(n2).or_insert(Vec::new()).push(n1);
|
||||||
});
|
});
|
||||||
Ok(paths(&nodes))
|
Ok(paths(&nodes))
|
||||||
}
|
}
|
||||||
|
|
||||||
fn search2<'a>(
|
/*
|
||||||
node: &str,
|
|
||||||
nodes: &HashMap<&'a str, Vec<&'a str>>,
|
|
||||||
path: &[&'a str],
|
|
||||||
paths: &mut Vec<Vec<&'a str>>,
|
|
||||||
double: &'a str,
|
|
||||||
smalls: &[&'a str],
|
|
||||||
) {
|
|
||||||
if node == "end" {
|
|
||||||
paths.push(path.to_vec());
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
for neighbor in &nodes[node] {
|
|
||||||
// If lowercase.
|
|
||||||
if neighbor.as_bytes()[0] & 0x20 != 0 {
|
|
||||||
if neighbor == &double {
|
|
||||||
// Allow two passes for this small node.
|
|
||||||
if path.iter().filter(|p| p == &neighbor).count() >= 2 {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
// Only allow one pass for this small node.
|
|
||||||
if path.contains(neighbor) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
let mut child_path = path.to_vec();
|
|
||||||
child_path.push(neighbor);
|
|
||||||
search2(neighbor, nodes, &child_path, paths, double, smalls);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
fn paths2(nodes: &HashMap<&str, Vec<&str>>) -> usize {
|
|
||||||
let mut paths = Vec::new();
|
|
||||||
let smalls: Vec<_> = nodes
|
|
||||||
.keys()
|
|
||||||
.filter(|n| n.as_bytes()[0] & 0x20 != 0)
|
|
||||||
.filter(|&n| n != &"start" && n != &"end")
|
|
||||||
.cloned()
|
|
||||||
.collect();
|
|
||||||
|
|
||||||
for double in &smalls {
|
|
||||||
search2(
|
|
||||||
"start",
|
|
||||||
nodes,
|
|
||||||
&["start"],
|
|
||||||
&mut paths,
|
|
||||||
double,
|
|
||||||
smalls.as_slice(),
|
|
||||||
);
|
|
||||||
}
|
|
||||||
paths.sort();
|
|
||||||
paths.dedup();
|
|
||||||
paths.len()
|
|
||||||
}
|
|
||||||
|
|
||||||
#[aoc(day12, part2)]
|
#[aoc(day12, part2)]
|
||||||
fn part2(input: &str) -> Result<usize> {
|
fn part2(input: &[u64]) -> Result<u64> {
|
||||||
let mut nodes = HashMap::new();
|
todo!("part2");
|
||||||
input.lines().for_each(|p| {
|
Ok(0)
|
||||||
let (n1, n2) = p.split_once('-').expect("missing dash");
|
|
||||||
nodes.entry(n1).or_insert_with(Vec::new).push(n2);
|
|
||||||
nodes.entry(n2).or_insert_with(Vec::new).push(n1);
|
|
||||||
});
|
|
||||||
Ok(paths2(&nodes))
|
|
||||||
}
|
}
|
||||||
|
*/
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod tests {
|
mod tests {
|
||||||
@ -122,19 +83,14 @@ b-end
|
|||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
#[test]
|
#[test]
|
||||||
fn test_part2() -> Result<()> {
|
fn test_part2()->Result<()> {
|
||||||
let input = r#"
|
let input = r#"
|
||||||
start-A
|
|
||||||
start-b
|
|
||||||
A-c
|
|
||||||
A-b
|
|
||||||
b-d
|
|
||||||
A-end
|
|
||||||
b-end
|
|
||||||
"#
|
"#
|
||||||
.trim();
|
.trim();
|
||||||
assert_eq!(part2(input)?, 36);
|
assert_eq!(part2(&parse(input)?)?, u64::MAX);
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
*/
|
||||||
}
|
}
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user