Add day 5 and day 7 solutions
[?]
Dec 24, 2020, 3:03 AM
6S7OD5A7AFBHTY55VATYR74O3TGMIOR7Y4ITUI6RKGLDMUWY2JNQCDependencies
- [2]
B527MN66Solve day 1 for 2020
Change contents
- file addition: day5.rs[2.17]
use std::convert::TryFrom;fn find_seat<I: Iterator<Item=char>>(source: &mut I) -> (u8, u8) {let mut row = 0;let mut col = 0;for c in source {match c {'F' => { row *= 2; },'B' => { row = row * 2 + 1; },'L' => { col *= 2; },'R' => { col = col * 2 + 1; },_ => (),}}(row,col)}fn seat_id(row: u8, col: u8) -> u16 {u16::from(row) * 8 + u16::from(col)}fn max_seat<I: Iterator<Item=u16>>(ids: &mut I) -> u16 {ids.max().unwrap()}fn my_seat<I: Iterator<Item=u16>>(ids: &mut I) -> u16 {let mut filled: Vec<bool> = Vec::with_capacity(1024);filled.resize(1024, false);for seat in ids {filled[usize::from(seat)] = true;};for (i,f) in filled.iter().enumerate() {if !f && i < 1023 && i > 0 && filled[i + 1] && filled[i - 1] {return u16::try_from(i).unwrap();}}panic!("not found")}fn main() {use std::env;use std::io::BufRead;let args: Vec<_> = env::args().collect();let lines = std::io::BufReader::new(std::fs::File::open(&args[1]).unwrap()).lines();let mut seats = lines.map(|l| {let (row,col) = find_seat(&mut l.unwrap().chars());seat_id(row, col)});println!("{}", match args[2].as_ref() {"1" => max_seat(&mut seats),"2" => my_seat(&mut seats),_ => panic!("unknown problem"),});} - file addition: day7.rs[2.17]
use std::str::FromStr;use std::num::ParseIntError;struct Rule {outer: String,inner: Vec<(String,u8)>,}#[derive(Debug,Clone)]enum RuleParseError {Numeric(ParseIntError),Other,}impl From<ParseIntError> for RuleParseError {fn from(src: ParseIntError) -> Self {Self::Numeric(src)}}impl FromStr for Rule {type Err = RuleParseError;fn from_str(s: &str) -> Result<Self, Self::Err> {let mut words = s.split_whitespace();let mut outer = Vec::new();for w in words.by_ref() {if w == "bags" {break;} else {outer.push(w);}}let outer = Intercalate::new(outer.iter(), &" ").map(std::ops::Deref::deref).collect::<String>();match words.next() {Some("contain") => Ok(()),_ => Err(RuleParseError::Other),}?;let mut inner = Vec::new();loop {let count = match words.next() {None => Err(RuleParseError::Other),Some(w) => if w == "no" {match words.next() {Some("other") => Ok(()),_ => Err(RuleParseError::Other),}?;match words.next() {Some("bags.") => Ok(()),_ => Err(RuleParseError::Other),}?;return Ok(Rule {outer: outer, inner: inner});} else {w.parse().or_else(|e| Err(RuleParseError::Numeric(e)))},}?;let mut color = Vec::new();for w in words.by_ref() {if w == "bag," || w == "bags," || w == "bag." || w == "bags." {inner.push((Intercalate::new(color.iter(), &" ").map(std::ops::Deref::deref).collect::<String>(), count));if w.chars().next_back() == Some('.') {return Ok(Rule { outer: outer, inner: inner });} else {break;}} else {color.push(w);}}}}}struct Intercalate<I: Iterator> {sep: <I as Iterator>::Item,inner: std::iter::Peekable<I>,sep_phase: bool,}impl<I: Iterator> Intercalate<I> {fn new(inner: I, sep: <I as Iterator>::Item) -> Self {Self { sep: sep, inner: inner.peekable(), sep_phase: false }}}impl<I: Iterator> Iterator for Intercalate<I> where I::Item: Clone {type Item = I::Item;fn next(&mut self) -> Option<Self::Item> {if self.sep_phase {match self.inner.peek() {Some(_) => {self.sep_phase = false;Some(self.sep.clone())},None => None}} else {self.sep_phase = true;self.inner.next()}}}fn count_colors_containing(rules: Vec<Rule>, innermost: Vec<String>) -> usize {use std::collections::HashMap;use std::collections::HashSet;let mut flowback = HashMap::new();for rule in rules.iter() {for (inner,_) in rule.inner.iter() {flowback.entry(inner).or_insert_with(Vec::new).push(rule.outer.clone());}}let mut hits = HashSet::new();let mut q: Vec<String> = innermost.clone();loop {match q.pop() {None => break,Some(color) => {if !hits.contains(&color) {hits.insert(color.clone());match flowback.get(&color) {None => (),Some(colors) => q.append(&mut colors.clone()),}}},}};for color in innermost.iter() {hits.remove(color);}hits.len()}fn count_bags_in(rules: Vec<Rule>, outer: String) -> usize {use std::collections::HashMap;let mut counted: HashMap<String,usize> = HashMap::new();let tree: HashMap<_,_> = rules.iter().map(|rule| (rule.outer.clone(), rule.inner.clone())).collect();let mut q = vec![outer.clone()];loop {match q.pop() {None => break,Some(c) => match counted.get(&c) {Some(_) => (),None => if tree.get(&c).iter().flat_map(|v| v.iter()).all(|(r,_)|counted.contains_key(r)) {counted.insert(c.clone(), tree.get(&c).iter().flat_map(|v| v.iter()).map(|(r,n)|(1 + counted.get(r).map(|x| *x).unwrap_or(0)) * usize::from(*n)).sum());} else {q.push(c.clone());for (r,_) in tree.get(&c).iter().flat_map(|v| v.iter()) {q.push(r.clone())}},},}};match counted.get(&outer) {Some(r) => *r,None => 0,}}fn main() {use std::env;use std::io::BufRead;let args: Vec<_> = env::args().collect();let rules: Vec<Rule> = std::io::BufReader::new(std::fs::File::open(&args[1]).unwrap()).lines().map(Result::unwrap).map(|s| s.parse()).map(Result::unwrap).collect();println!("{}", match args[2].as_ref() {"1" => count_colors_containing(rules, vec![String::from("shiny gold")]),"2" => count_bags_in(rules, String::from("shiny gold")),_ => panic!("No such problem"),});}