day16
This commit is contained in:
11
src/day13.rs
11
src/day13.rs
@@ -23,18 +23,11 @@ fn solve_d13_p1(input: &str) -> usize {
|
||||
},
|
||||
|min, bus_id| {
|
||||
let offset = t % bus_id;
|
||||
let wait_time = if offset == 0 {
|
||||
0
|
||||
} else {
|
||||
bus_id - offset
|
||||
};
|
||||
let wait_time = if offset == 0 { 0 } else { bus_id - offset };
|
||||
if min.wait_time < wait_time {
|
||||
min
|
||||
} else {
|
||||
WaitTime{
|
||||
bus_id,
|
||||
wait_time,
|
||||
}
|
||||
WaitTime { bus_id, wait_time }
|
||||
}
|
||||
},
|
||||
);
|
||||
|
||||
13
src/day14.rs
13
src/day14.rs
@@ -92,7 +92,7 @@ impl Mask2 {
|
||||
let mut or_mask = 0;
|
||||
for (idx, b) in mask.iter().enumerate() {
|
||||
match b {
|
||||
b'0' => {},
|
||||
b'0' => {}
|
||||
b'1' => {
|
||||
or_mask |= 1 << 35 - idx;
|
||||
}
|
||||
@@ -107,7 +107,7 @@ impl Mask2 {
|
||||
|
||||
fn set_memory(&self, mem: &mut HashMap<u64, u64>, address: u64, value: u64) {
|
||||
let offset = address | self.or_mask;
|
||||
for mut floating_value in 0 .. 2 << self.floating.count_ones() {
|
||||
for mut floating_value in 0..2 << self.floating.count_ones() {
|
||||
let mut addr = offset;
|
||||
for bit in BitIndexes::new(self.floating) {
|
||||
addr = set_bit(addr, bit, (floating_value & 1) == 1);
|
||||
@@ -126,13 +126,16 @@ fn set_bit(value: u64, bit_idx: u64, enabled: bool) -> u64 {
|
||||
}
|
||||
}
|
||||
|
||||
struct BitIndexes{
|
||||
struct BitIndexes {
|
||||
value: u64,
|
||||
current_idx: u64,
|
||||
}
|
||||
impl BitIndexes {
|
||||
fn new(value: u64) -> Self {
|
||||
BitIndexes{value, current_idx: 0}
|
||||
BitIndexes {
|
||||
value,
|
||||
current_idx: 0,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -168,4 +171,4 @@ fn solve_d14_p2(input: &str) -> u64 {
|
||||
}
|
||||
}
|
||||
memory.values().sum()
|
||||
}
|
||||
}
|
||||
|
||||
129
src/day16.rs
Normal file
129
src/day16.rs
Normal file
@@ -0,0 +1,129 @@
|
||||
use aoc_runner_derive::aoc;
|
||||
use std::ops::RangeInclusive;
|
||||
|
||||
fn split_once<'a>(input: &'a str, delimeter: &str) -> Option<(&'a str, &'a str)> {
|
||||
let idx = input.find(delimeter)?;
|
||||
Some((&input[..idx], &input[idx + delimeter.len()..]))
|
||||
}
|
||||
|
||||
struct Rule<'a> {
|
||||
name: &'a str,
|
||||
a: RangeInclusive<usize>,
|
||||
b: RangeInclusive<usize>,
|
||||
}
|
||||
impl<'a> Rule<'a> {
|
||||
fn parse(input: &'a str) -> Option<Self> {
|
||||
let (name, rem) = split_once(input, ": ")?;
|
||||
let (a, b) = split_once(rem, " or ")?;
|
||||
let a = {
|
||||
let (start, end) = split_once(a, "-")?;
|
||||
RangeInclusive::<usize>::new(start.parse().ok()?, end.parse().ok()?)
|
||||
};
|
||||
let b = {
|
||||
let (start, end) = split_once(b, "-")?;
|
||||
RangeInclusive::<usize>::new(start.parse().ok()?, end.parse().ok()?)
|
||||
};
|
||||
Some(Rule { name, a, b })
|
||||
}
|
||||
|
||||
fn matches(&self, value: usize) -> bool {
|
||||
self.a.contains(&value) || self.b.contains(&value)
|
||||
}
|
||||
}
|
||||
|
||||
#[aoc(day16, part1)]
|
||||
fn solve_d16_p1(input: &str) -> usize {
|
||||
let (rules, rem) = split_once(input, "\n\nyour ticket:\n").unwrap();
|
||||
let (_your_ticket, nearby_tickets) = split_once(rem, "\n\nnearby tickets:\n").unwrap();
|
||||
|
||||
let rules: Vec<_> = rules.split('\n').map(|x| Rule::parse(x).unwrap()).collect();
|
||||
nearby_tickets
|
||||
.split('\n')
|
||||
.flat_map(|line| line.split(','))
|
||||
.filter_map(|x| {
|
||||
let value: usize = x.parse().unwrap();
|
||||
if rules.iter().any(|rule| rule.matches(value)) {
|
||||
None
|
||||
} else {
|
||||
Some(value)
|
||||
}
|
||||
})
|
||||
.sum()
|
||||
}
|
||||
|
||||
#[aoc(day16, part2)]
|
||||
fn solve_d16_p2(input: &str) -> usize {
|
||||
let (rules, rem) = split_once(input, "\n\nyour ticket:\n").unwrap();
|
||||
let (my_ticket, nearby_tickets) = split_once(rem, "\n\nnearby tickets:\n").unwrap();
|
||||
|
||||
let rules: Vec<_> = rules.split('\n').map(|x| Rule::parse(x).unwrap()).collect();
|
||||
assert!(rules.len() < 63);
|
||||
let mut candidates = vec![(1u64 << rules.len()) - 1; rules.len()];
|
||||
let mut scratch = Vec::with_capacity(rules.len());
|
||||
for line in nearby_tickets.split('\n') {
|
||||
scratch.clear();
|
||||
scratch.extend(line.split(',').map(|field| {
|
||||
let value = field.parse().unwrap();
|
||||
// Initialize a bitmap of which rules the field is valid for. `1`
|
||||
// indicates the value is valid for that field. `0` is invalid.
|
||||
let mut bitmap = 0u64;
|
||||
for (rule_idx, rule) in rules.iter().enumerate() {
|
||||
if rule.matches(value) {
|
||||
bitmap |= 1 << rule_idx;
|
||||
}
|
||||
}
|
||||
bitmap
|
||||
}));
|
||||
if scratch.iter().copied().any(|x| x == 0) {
|
||||
continue;
|
||||
}
|
||||
candidates
|
||||
.iter_mut()
|
||||
.zip(scratch.iter())
|
||||
.for_each(|(candidate, valid_bitmask)| {
|
||||
*candidate &= valid_bitmask;
|
||||
});
|
||||
}
|
||||
while candidates.iter().copied().any(|x| x.count_ones() > 1) {
|
||||
for idx in 0..candidates.len() {
|
||||
let candidate = candidates[idx];
|
||||
if candidate.count_ones() == 1 {
|
||||
let mask = !candidate;
|
||||
for before in &mut candidates[..idx] {
|
||||
*before &= mask;
|
||||
}
|
||||
for after in &mut candidates[idx + 1..] {
|
||||
*after &= mask;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
my_ticket
|
||||
.split(',')
|
||||
.map(|x| x.parse::<usize>().unwrap())
|
||||
.zip(candidates.into_iter().map(|x| x.trailing_zeros() as usize))
|
||||
.filter_map(|(field, rule_idx)| {
|
||||
if rules[rule_idx].name.starts_with("departure") {
|
||||
Some(field)
|
||||
} else {
|
||||
None
|
||||
}
|
||||
})
|
||||
.product()
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_foo() {
|
||||
const INPUT: &str = "class: 0-1 or 4-19
|
||||
row: 0-5 or 8-19
|
||||
seat: 0-13 or 16-19
|
||||
|
||||
your ticket:
|
||||
11,12,13
|
||||
|
||||
nearby tickets:
|
||||
3,9,18
|
||||
15,1,5
|
||||
5,14,9";
|
||||
solve_d16_p2(INPUT);
|
||||
}
|
||||
@@ -5,6 +5,7 @@ pub mod day12;
|
||||
pub mod day13;
|
||||
pub mod day14;
|
||||
pub mod day15;
|
||||
pub mod day16;
|
||||
pub mod day2;
|
||||
pub mod day3;
|
||||
pub mod day4;
|
||||
|
||||
Reference in New Issue
Block a user