Day 16
This commit is contained in:
parent
849cc76034
commit
4246a04138
4 changed files with 153 additions and 32 deletions
32
src/day10.rs
32
src/day10.rs
|
@ -37,38 +37,8 @@ fn solve_part_2_rec(
|
||||||
// println!("-{}", node);
|
// println!("-{}", node);
|
||||||
ret
|
ret
|
||||||
}
|
}
|
||||||
|
|
||||||
fn solve_part_2_it(node: u16, goal: u16, map: &HashMap<u16, HashSet<u16>>) -> usize {
|
|
||||||
// let mut cache: HashMap<(u16, u16), usize> = HashMap::new();
|
|
||||||
// let mut used = HashSet::new();
|
|
||||||
// let mut stack=Vec::new();
|
|
||||||
// // stack.push((node);
|
|
||||||
// if node == goal {
|
|
||||||
// return 1;
|
|
||||||
// }
|
|
||||||
// let mut ret = 0;
|
|
||||||
// while let Some(node) = stack.pop() {
|
|
||||||
// for next in map.get(&node).iter().map(|v| v.iter()).flatten() {
|
|
||||||
// if used.contains(next) {
|
|
||||||
// continue;
|
|
||||||
// };
|
|
||||||
// used.insert(*next);
|
|
||||||
// let value = match cache.get(&(node, *next)) {
|
|
||||||
// Some(value) => *value,
|
|
||||||
// None => {
|
|
||||||
// let value = solve_part_2_rec(*next, goal, map, used, cache);
|
|
||||||
// cache.insert((node, *next), value);
|
|
||||||
// value
|
|
||||||
// }
|
|
||||||
// };
|
|
||||||
// ret += value;
|
|
||||||
// used.remove(next);
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
pub struct Data(pub Vec<u16>);
|
pub struct Data(pub Vec<u16>);
|
||||||
|
|
||||||
impl Data {
|
impl Data {
|
||||||
#[inline(always)]
|
#[inline(always)]
|
||||||
fn count_paths(&self) -> usize {
|
fn count_paths(&self) -> usize {
|
||||||
|
|
|
@ -73,7 +73,7 @@ pub fn input_generator(input: &str) -> Data {
|
||||||
let mut mask_and = 0;
|
let mut mask_and = 0;
|
||||||
let mut mask_or = 0;
|
let mut mask_or = 0;
|
||||||
let mut char_buf = vec![];
|
let mut char_buf = vec![];
|
||||||
for (n, c) in line.split("=").nth(1).unwrap().trim().chars().enumerate() {
|
for (_, c) in line.split("=").nth(1).unwrap().trim().chars().enumerate() {
|
||||||
char_buf.push(c);
|
char_buf.push(c);
|
||||||
mask_and <<= 1;
|
mask_and <<= 1;
|
||||||
mask_or <<= 1;
|
mask_or <<= 1;
|
||||||
|
|
149
src/day16.rs
Normal file
149
src/day16.rs
Normal file
|
@ -0,0 +1,149 @@
|
||||||
|
use aoc_runner_derive::{aoc, aoc_generator};
|
||||||
|
use std::collections::{HashMap, HashSet};
|
||||||
|
#[derive(Debug)]
|
||||||
|
pub struct Input {
|
||||||
|
ranges: HashMap<String, Vec<(usize, usize)>>,
|
||||||
|
my_ticket: Vec<usize>,
|
||||||
|
other_tickets: Vec<Vec<usize>>,
|
||||||
|
}
|
||||||
|
|
||||||
|
type Data = Input;
|
||||||
|
|
||||||
|
#[aoc_generator(day16)]
|
||||||
|
pub fn input_generator(input: &str) -> Data {
|
||||||
|
let l = input.lines();
|
||||||
|
let ranges: HashMap<String, Vec<(usize, usize)>> = l
|
||||||
|
.take_while(|l| l.trim().len() != 0)
|
||||||
|
.map(|s| {
|
||||||
|
let parts: Vec<_> = s.to_owned().split(": ").map(|v| v.to_owned()).collect();
|
||||||
|
let name = parts.get(0).unwrap().trim().to_owned();
|
||||||
|
let ranges: Vec<(usize, usize)> = parts
|
||||||
|
.get(1)
|
||||||
|
.unwrap()
|
||||||
|
.to_owned()
|
||||||
|
.split(" or ")
|
||||||
|
.map(|l| {
|
||||||
|
let r: Vec<usize> = l
|
||||||
|
.to_owned()
|
||||||
|
.split("-")
|
||||||
|
.map(|v| v.to_owned().parse().unwrap())
|
||||||
|
.collect();
|
||||||
|
(r[0], r[1])
|
||||||
|
})
|
||||||
|
.collect();
|
||||||
|
(name, ranges)
|
||||||
|
})
|
||||||
|
.collect();
|
||||||
|
let mut l = input.lines().skip(ranges.len() + 2);
|
||||||
|
let my_ticket = l
|
||||||
|
.next()
|
||||||
|
.unwrap()
|
||||||
|
.split(",")
|
||||||
|
.map(|v| v.parse().unwrap())
|
||||||
|
.collect();
|
||||||
|
let other_tickets = l
|
||||||
|
.skip(2)
|
||||||
|
.map(|nums| nums.split(",").map(|v| v.parse().unwrap()).collect())
|
||||||
|
.collect();
|
||||||
|
Data {
|
||||||
|
ranges,
|
||||||
|
my_ticket,
|
||||||
|
other_tickets,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn in_ranges(num: usize, ranges: &Vec<(usize, usize)>) -> bool {
|
||||||
|
let mut in_range = false;
|
||||||
|
for (min, max) in ranges {
|
||||||
|
in_range |= (num >= *min) && (num <= *max);
|
||||||
|
}
|
||||||
|
return in_range;
|
||||||
|
}
|
||||||
|
|
||||||
|
#[aoc(day16, part1)]
|
||||||
|
pub fn solve_part1(input: &Data) -> usize {
|
||||||
|
let mut inv_nums = vec![];
|
||||||
|
for ticket in &input.other_tickets {
|
||||||
|
for num in ticket {
|
||||||
|
let mut in_any_range = false;
|
||||||
|
for range in input.ranges.values() {
|
||||||
|
let mut in_range = false;
|
||||||
|
for (min, max) in range {
|
||||||
|
in_range |= (num >= min) && (num <= max);
|
||||||
|
}
|
||||||
|
in_any_range |= in_range;
|
||||||
|
}
|
||||||
|
if !in_any_range {
|
||||||
|
inv_nums.push(*num);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
inv_nums.iter().sum()
|
||||||
|
}
|
||||||
|
|
||||||
|
#[aoc(day16, part2)]
|
||||||
|
pub fn solve_part2(input: &Data) -> usize {
|
||||||
|
let mut field_candicates: Vec<HashSet<String>> = vec![HashSet::new(); input.my_ticket.len()];
|
||||||
|
let mut valid_tickets = vec![];
|
||||||
|
for ticket in &input.other_tickets {
|
||||||
|
let mut valid = true;
|
||||||
|
for num in ticket {
|
||||||
|
let mut in_any_range = false;
|
||||||
|
for range in input.ranges.values() {
|
||||||
|
let mut in_range = false;
|
||||||
|
for (min, max) in range {
|
||||||
|
in_range |= (num >= min) && (num <= max);
|
||||||
|
}
|
||||||
|
in_any_range |= in_range;
|
||||||
|
}
|
||||||
|
if !in_any_range {
|
||||||
|
valid = false;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if valid {
|
||||||
|
valid_tickets.push(ticket.clone());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
for field in input.ranges.keys() {
|
||||||
|
for f in field_candicates.iter_mut() {
|
||||||
|
f.insert(field.clone());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
for (field, ranges) in &input.ranges {
|
||||||
|
for ticket in &valid_tickets {
|
||||||
|
for (i, num) in ticket.iter().enumerate() {
|
||||||
|
if !in_ranges(*num, ranges) {
|
||||||
|
field_candicates[i].remove(field);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
let mut fixed: HashSet<String> = HashSet::new();
|
||||||
|
let mut field_candicates: Vec<(usize, HashSet<String>)> =
|
||||||
|
field_candicates.drain(..).enumerate().collect();
|
||||||
|
field_candicates.sort_unstable_by_key(|(_, v)| v.len());
|
||||||
|
while field_candicates.iter().any(|(_, v)| v.len() != 1) {
|
||||||
|
for c in field_candicates.iter_mut() {
|
||||||
|
if c.1.len() == 1 {
|
||||||
|
fixed.extend(c.1.iter().cloned());
|
||||||
|
} else {
|
||||||
|
for val in &fixed {
|
||||||
|
c.1.remove(val);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
field_candicates.sort_unstable_by_key(|(n, _)| *n);
|
||||||
|
let field_names: Vec<String> = field_candicates
|
||||||
|
.drain(..)
|
||||||
|
.map(|(_, n)| n.iter().next().unwrap().clone())
|
||||||
|
.collect();
|
||||||
|
let mut ret = 1;
|
||||||
|
for (field, value) in field_names.iter().zip(input.my_ticket.iter()) {
|
||||||
|
if field.starts_with("departure") {
|
||||||
|
ret *= value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return ret;
|
||||||
|
}
|
|
@ -13,4 +13,6 @@ pub mod day11;
|
||||||
pub mod day12;
|
pub mod day12;
|
||||||
pub mod day13;
|
pub mod day13;
|
||||||
pub mod day14;
|
pub mod day14;
|
||||||
|
pub mod day15;
|
||||||
|
pub mod day16;
|
||||||
aoc_lib! { year = 2020 }
|
aoc_lib! { year = 2020 }
|
||||||
|
|
Loading…
Reference in a new issue