problem 7 (cheated a lil bit) and template for 8

master
mitchellhansen 4 years ago
parent 7b93826c56
commit e238e0e9b2

@ -10,3 +10,4 @@ edition = "2018"
reqwest = "0.9.22" reqwest = "0.9.22"
tempfile = "3.1.0" tempfile = "3.1.0"
futures = "0.3.1" futures = "0.3.1"
petgraph = "0.5.1"

@ -1,3 +1,4 @@
#![feature(str_strip)]
extern crate reqwest; extern crate reqwest;
extern crate tempfile; extern crate tempfile;
@ -8,6 +9,7 @@ use crate::problem4::lib::Problem4;
use crate::problem5::lib::Problem5; use crate::problem5::lib::Problem5;
use crate::problem6::lib::Problem6; use crate::problem6::lib::Problem6;
use crate::problem7::lib::Problem7; use crate::problem7::lib::Problem7;
use crate::problem8::lib::Problem8;
mod problem1; mod problem1;
mod problem2; mod problem2;
@ -16,6 +18,7 @@ mod problem4;
mod problem5; mod problem5;
mod problem6; mod problem6;
mod problem7; mod problem7;
mod problem8;
mod util; mod util;
@ -53,7 +56,11 @@ fn main() {
// problem6.run_part1(); // problem6.run_part1();
// problem6.run_part2(); // problem6.run_part2();
let problem7 = Problem7::new(&util::get_problem(7)); /*let problem7 = Problem7::new(&util::get_problem(7));
problem7.run_part1(); problem7.run_part1();
problem7.run_part2(); problem7.run_part2();*/
let problem8 = Problem8::new(&util::get_problem(8));
problem8.run_part1();
problem8.run_part2();
} }

@ -1,46 +1,169 @@
use std::collections::{HashMap, HashSet};
use petgraph::algo::{all_simple_paths, has_path_connecting};
use petgraph::Graph;
use petgraph::graph::{DiGraph, Node, NodeIndex, node_index};
use petgraph::dot::{Dot, Config};
use crate::Problem; use crate::Problem;
use std::collections::HashSet; use std::fs::File;
use std::io::Write;
use petgraph::visit::{Dfs, depth_first_search, DfsEvent};
pub struct Problem7 { pub struct Problem7 {
groups: Vec<HashSet<char>>, // <nodes, edges>
rules: DiGraph<String, i32>,
node_lookup: HashMap<String, NodeIndex>,
} }
impl Problem7 {
impl Problem7 {} fn index_to_name(&self, node_ind: NodeIndex<u32>) -> Option<String> {
let v = self.node_lookup.iter().filter_map(|(k, v)| {
if *v == node_index(node_ind.index()){
Some(k.clone())
} else {
None
}
}).collect::<Vec<String>>();
match v.first() {
None => {None}
Some(v) => {Some(v.clone())}
}
}
fn dfs(&self, multiplier: u64, node: NodeIndex<u32>) -> u64 {
println!("starting dfs at {:?}, {:?}", multiplier, node);
let mut sum : u64 = 0;
let mut multiplier : u64 = multiplier;
let mut last_multiple : Vec<u64> = vec![1];
let result = depth_first_search(&self.rules, Some(node), |event| {
match event {
DfsEvent::Discover(q, e) => {
println!("Discover Node : Node : {:?}", self.index_to_name(q));
Ok(())
}
DfsEvent::BackEdge(q, e) => {
println!("Back Edge : NodeA : {:?} ---> NodeB : {:?}", self.index_to_name(q), self.index_to_name(e));
Err(event)
}
DfsEvent::TreeEdge(q, e) => {
println!("Tree : NodeA : {:?} ---> NodeB : {:?}", self.index_to_name(q), self.index_to_name(e));
let edge_weight = *(self.rules.edges_connecting(q, e).filter_map(|a| {
Some(*a.weight())
}).collect::<Vec<i32>>().first().unwrap());
multiplier *= edge_weight as u64;
println!("Tree Meta : Multiplier : {:?} ==== Edge Weight : {:?}", multiplier, edge_weight);
last_multiple.push(edge_weight as u64);
Ok(())
}
DfsEvent::CrossForwardEdge(q, e) => {
println!("Cross : Start {:?} ---> End {:?} ==== Sum@Now {}", self.index_to_name(q), self.index_to_name(e), sum);
let edge_weight = *(self.rules.edges_connecting(q, e).filter_map(|a| {
Some(*a.weight())
}).collect::<Vec<i32>>().first().unwrap());
multiplier *= edge_weight as u64;
println!("Cross Meta : Multiplier : {:?} ==== Edge Weight : {:?}", multiplier, edge_weight);
last_multiple.push(edge_weight as u64);
sum += self.dfs(multiplier, e);
println!("Sum after : {}", sum);
Ok(())
}
DfsEvent::Finish(q, e) => { // finds leaf and reverses back up
println!("Finish : Node {:?}", self.index_to_name(q));
sum += multiplier as u64;
multiplier /= last_multiple.pop().unwrap();
if last_multiple.len() == 0 {
sum -= 1;
println!("reached root");
}
println!("Finish - calcs : sum {:?}, multiplier {:?}", sum, multiplier);
Ok(())
}
}
});
println!("exiting dfs");
sum
}
}
impl Problem for Problem7 { impl Problem for Problem7 {
fn new(input: &String) -> Self { fn new(input: &String) -> Self {
Problem7 { let mut r = Problem7 {
groups: input rules: DiGraph::new(),
.split("\n\n") node_lookup: Default::default(),
.filter_map(|s| { };
let s = s.trim().split("\n"); r.node_lookup.insert("shiny gold bag".to_string(), r.rules.add_node("shiny gold bag".to_string()));
let mut sets = Vec::new(); for line in input.split("\n") {
for i in s { let s = line.trim();
let v : HashSet<char> = i.chars().filter_map(|c| { if !s.is_empty() {
if c.is_whitespace() { let mut split = s.split("contain");
None let mut node = split.next().unwrap().trim();
} else { if node.ends_with("s") {
Some(c) node = &node[0..node.len() - 1]
} }
}).collect::<HashSet<char>>();
sets.push(v); r.node_lookup.insert(node.to_string(), r.rules.add_node(node.to_string()));
} }
let mut iter = sets.iter();
let intersection : HashSet<char> =
iter.next().map(|set| iter.fold(set.clone(), |set1, set2| set1.intersection(set2).map(|c| *c).collect())).unwrap().clone();
Some(intersection)
}).collect(),
} }
for line in input.split("\n") {
let s = line.trim();
if !s.is_empty() {
let mut split = s.split("contain");
let mut node = split.next().unwrap().trim();
if node.ends_with("s") {
node = &node[0..node.len() - 1]
}
let root = r.node_lookup.get(node).unwrap();
let raw_subs = split.next().unwrap().split(", ");
for i in raw_subs {
let item = i.trim();
if item.starts_with(char::is_numeric) {
let mut node = (&item[2..]).split(".").next().unwrap();
if node.ends_with("s") {
node = &node[0..node.len() - 1]
}
let count = &item[..1].parse::<i32>().unwrap();
r.rules.add_edge(*root, *r.node_lookup.get(node).unwrap(), *count);
}
}
}
}
r
} }
fn run_part1(&self) { fn run_part1(&self) {
// println!("{:?}", self.node_lookup);
// let mut count = 0;
// for (k, v) in &self.node_lookup {
// let r = has_path_connecting(&self.rules,
// *self.node_lookup.get(k).unwrap(),
// *self.node_lookup.get("shiny gold bag").unwrap(), None);
// println!("{} : {}", k, r);
// if r {
// count += 1
// }
// }
// println!("{}", count);
// let mut f = File::create("example.dot").unwrap();
// let output = format!("{}", Dot::with_config(&self.rules, &[Config::EdgeNoLabel]));
// f.write_all(&output.as_bytes()).expect("could not write file");
} }
fn run_part2(&self) { fn run_part2(&self) {
println!("ending count = {:?}", self.dfs(1, node_index(self.node_lookup.get("shiny gold bag").unwrap().index())));
} }
} }

@ -0,0 +1,34 @@
use crate::Problem;
pub struct Problem8 {
number_list: Vec<i32>,
}
impl Problem8 {}
impl Problem for Problem8 {
fn new(input: &String) -> Self {
Problem8 {
number_list: input
.split("\n")
.filter_map(|s| {
let s = s.trim();
if !s.is_empty() {
Some(s.parse::<i32>().unwrap())
} else {
None
}
}).collect(),
}
}
fn run_part1(&self) {
}
fn run_part2(&self) {
}
}

@ -0,0 +1 @@
pub mod lib;
Loading…
Cancel
Save