fuck this i give up

filtered
master
Avril 4 years ago
parent 2cdad0e0e6
commit 8c72063cd4
Signed by: flanchan
GPG Key ID: 284488987C31F630

@ -1,29 +0,0 @@
#![feature(str_split_once)]
#![allow(dead_code)]
use std::{
io::BufReader,
fs::OpenOptions,
collections::HashSet,
};
#[cfg(feature="test")]
const INPUT: &str ="input-test";
#[cfg(not(feature="test"))]
const INPUT: &str = "input";
mod parse;
mod bag;
fn main() -> Result<(), Box<dyn std::error::Error>> {
let parsed: HashSet<_> = parse::parse(BufReader::new(OpenOptions::new().read(true).open(INPUT)?)).collect();
#[cfg(debug_assertions)]
for x in parsed.iter() {
eprintln!("{:?}", x);
}
Ok(())
}

@ -20,6 +20,12 @@ impl Borrow<String> for Rule
&self.bag &self.bag
} }
} }
impl Borrow<str> for Rule
{
fn borrow(&self) -> &str {
self.name()
}
}
impl Hash for Rule { impl Hash for Rule {
fn hash<H: Hasher>(&self, state: &mut H) { fn hash<H: Hasher>(&self, state: &mut H) {
@ -37,7 +43,7 @@ impl Rule
/// Find the rules for each inner bag within this context /// Find the rules for each inner bag within this context
pub fn inner_rules<'a>(&'a self, hashes: &'a Bags) -> impl Iterator<Item = &'a Rule> + 'a pub fn inner_rules<'a>(&'a self, hashes: &'a Bags) -> impl Iterator<Item = &'a Rule> + 'a
{ {
self.contains.iter().filter_map(move |(_, re)| hashes.get(re)) self.contains.iter().filter_map(move |(n, re)| Some(std::iter::repeat(hashes.get(re)?).take(*n))).flatten()
} }
#[inline] pub fn new(bag: impl Into<String>, contains: impl IntoIterator<Item = (usize, String)>) -> Self #[inline] pub fn new(bag: impl Into<String>, contains: impl IntoIterator<Item = (usize, String)>) -> Self
{ {
@ -59,6 +65,7 @@ impl Rule
} }
} }
#[derive(Debug)]
pub struct RuleIterator<'a> pub struct RuleIterator<'a>
{ {
base: std::slice::Iter<'a, (usize, BagRef)>, base: std::slice::Iter<'a, (usize, BagRef)>,
@ -66,6 +73,20 @@ pub struct RuleIterator<'a>
held: Vec<&'a Rule>, held: Vec<&'a Rule>,
} }
impl<'a> RuleIterator<'a>
{
pub fn search(self, s: impl AsRef<str>) -> Option<&'a Rule>
{
let s= s.as_ref();
for rule in self {
if rule.name() == s {
return Some(rule);
}
}
None
}
}
impl<'a> Iterator for RuleIterator<'a> impl<'a> Iterator for RuleIterator<'a>
{ {
type Item = &'a Rule; type Item = &'a Rule;
@ -73,8 +94,11 @@ impl<'a> Iterator for RuleIterator<'a>
{ {
if self.held.is_empty() { if self.held.is_empty() {
match self.base.next() { match self.base.next() {
Some((_, re)) => { Some((n, re)) => {
self.held.push(self.hashes.get(re).unwrap()); let ins = self.hashes.get(re).unwrap();
for _ in 0..*n {
self.held.push(ins);
}
}, },
None => return None, None => return None,
} }

@ -0,0 +1,64 @@
#![feature(str_split_once)]
#![allow(dead_code)]
use std::{
io::BufReader,
fs::OpenOptions,
collections::HashSet,
};
#[cfg(feature="test")]
const INPUT: &str ="input-test2";
#[cfg(not(feature="test"))]
const INPUT: &str = "input";
const NEEDLE: &str = "shiny gold";
mod parse;
mod bag;
fn cnt_rules(rule: &bag::Rule, set: &HashSet<bag::Rule>) -> usize
{
let mut already_done: HashSet<&bag::Rule> = HashSet::new();
rule.all_rules(set).map(|x| {
let mut o = cnt_rules(x, set) + x.inner_rules(set).count();
if already_done.insert(x) || true {
if o > 0 {
eprintln!("{:?} -> {}", x, o);
o+=1;
} else if !already_done.contains(x) {
eprintln!("{:?} -> {}", x ,1);
return 1;
}
o
} else {
0
}
}).sum()
}
fn main() -> Result<(), Box<dyn std::error::Error>> {
let parsed: HashSet<_> = parse::parse(BufReader::new(OpenOptions::new().read(true).open(INPUT)?)).collect();
let mut found=0;
for rule in parsed.iter() {
#[cfg(debug_assertions)]
eprintln!("{:?}", rule);
if rule.name() != NEEDLE {
if rule.all_rules(&parsed).search(NEEDLE).is_some() {
found +=1;
}
}
}
println!("{}", found);
//#[cfg(feature="part2")]
{
println!("{}", cnt_rules(parsed.get(NEEDLE).unwrap(), &parsed));
}
Ok(())
}
Loading…
Cancel
Save