This commit is contained in:
2021-12-12 23:08:37 +01:00
parent c56fcff09c
commit dfe8f1dfe8
4 changed files with 152 additions and 0 deletions

8
december_12/Cargo.toml Normal file
View File

@@ -0,0 +1,8 @@
[package]
name = "december_12"
version = "0.1.0"
edition = "2021"
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
[dependencies]

10
december_12/example.txt Normal file
View File

@@ -0,0 +1,10 @@
dc-end
HN-start
start-kj
dc-start
dc-HN
LN-dc
HN-end
kj-sa
kj-HN
kj-dc

21
december_12/input.txt Normal file
View File

@@ -0,0 +1,21 @@
cz-end
cz-WR
TD-end
TD-cz
start-UM
end-pz
kb-UM
mj-UM
cz-kb
WR-start
WR-pz
kb-WR
TD-kb
mj-kb
TD-pz
UM-pz
kb-start
pz-mj
WX-cz
sp-WR
mj-WR

113
december_12/src/main.rs Normal file
View File

@@ -0,0 +1,113 @@
use std::fs::File;
use std::io::{BufReader};
use std::io::prelude::*;
fn main(){
let file = File::open("./input.txt").expect("Read failed");
let reader = BufReader::new(file);
let mut unique_points: Vec<String> = Vec::new();
let mut neighbours: Vec<Vec<usize>> = Vec::new();
let mut line_vec = Vec::new();
for line in reader.lines() {
line_vec.push(line.unwrap());
}
unique_points.push("start".to_string());
for line in &line_vec{
let split_line: Vec<&str> = line.split('-').collect();
let origin = split_line[0].to_owned();
let destination = split_line[1].to_owned();
if !unique_points.contains(&origin) && origin != "end" && origin != "start" {unique_points.push(origin)}
if !unique_points.contains(&destination) && destination != "end" && destination != "start" {unique_points.push(destination)}
}
unique_points.push("end".to_string());
for _i in 0..unique_points.len() {
neighbours.push(Vec::new());
}
for line in &line_vec{
let split_line: Vec<&str> = line.split('-').collect();
let origin = split_line[0].to_owned();
let destination = split_line[1].to_owned();
let origin_int = unique_points.iter().position(|r| r == &origin).unwrap();
let destination_int = unique_points.iter().position(|r| r == &destination).unwrap();
if !neighbours[origin_int].contains(&destination_int) {neighbours[origin_int].push(destination_int)}
if !neighbours[destination_int].contains(&origin_int) {neighbours[destination_int].push(origin_int)}
}
let mut possible_paths: Vec<Vec<usize>> = Vec::new();
//let mut empty_path = ;
possible_paths.append(&mut check_neighbours(&neighbours, 0, Vec::new(), &unique_points)
);
let mut possible_paths_converted = Vec::new();
for path in &possible_paths{
let mut temp_vec = Vec::new();
for symbol in path {
temp_vec.push(&unique_points[symbol.to_owned()]);
}
possible_paths_converted.push(temp_vec);
}
println!("Number of paths: {}", &possible_paths.len());
}
fn check_neighbours(neighbours: &Vec<Vec<usize>>, new_node: usize, path: Vec<usize>, unique_points: &Vec<String>) -> Vec<Vec<usize>> {
let mut local_path = path.to_owned();
let mut return_list = Vec::new();
if unique_points[new_node] == "end" {
local_path.push(new_node);
return_list.push(local_path);
return return_list;
}
local_path.push(new_node);
let mut number_caves = Vec::new();
for _ in unique_points {
number_caves.push(0);
}
for node in &local_path{
number_caves[node.to_owned()] += 1;
}
let mut allowed_to_visit_twice = true;
for node in &local_path{
let lowercase = unique_points[node.to_owned()] == unique_points[node.to_owned()].to_lowercase();
if lowercase && number_caves[node.to_owned()] > 1 {
allowed_to_visit_twice = false;
}
}
print!("");
for neighbour in &neighbours[new_node] {
let n = neighbour.to_owned();
let lowercase = unique_points[n] == unique_points[n].to_lowercase();
let uppercase = unique_points[n] == unique_points[n].to_uppercase();
let _valid = ( uppercase || ((lowercase && allowed_to_visit_twice) || (lowercase && number_caves[n] < 1) ) ) && unique_points[n] != "start";
print!("");
if ( uppercase || ((lowercase && allowed_to_visit_twice) || (lowercase && number_caves[n] < 1) ) ) && unique_points[n] != "start" {
let mut temp = check_neighbours(&neighbours, n, local_path.to_owned(), unique_points);
return_list.append(&mut temp);
}
}
return return_list;
}