solution: day6
This commit is contained in:
parent
000000809c
commit
00000090cf
|
@ -2,6 +2,15 @@
|
||||||
# It is not intended for manual editing.
|
# It is not intended for manual editing.
|
||||||
version = 3
|
version = 3
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "aho-corasick"
|
||||||
|
version = "0.7.20"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "cc936419f96fa211c1b9166887b38e5e40b19958e5b895be7c1f93adec7071ac"
|
||||||
|
dependencies = [
|
||||||
|
"memchr",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "aoc"
|
name = "aoc"
|
||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
|
@ -11,6 +20,7 @@ dependencies = [
|
||||||
"itertools",
|
"itertools",
|
||||||
"lazy_static",
|
"lazy_static",
|
||||||
"pico-args",
|
"pico-args",
|
||||||
|
"regex",
|
||||||
"reqwest",
|
"reqwest",
|
||||||
"rust-crypto",
|
"rust-crypto",
|
||||||
]
|
]
|
||||||
|
@ -591,6 +601,23 @@ dependencies = [
|
||||||
"bitflags",
|
"bitflags",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "regex"
|
||||||
|
version = "1.7.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "e076559ef8e241f2ae3479e36f97bd5741c0330689e217ad51ce2c76808b868a"
|
||||||
|
dependencies = [
|
||||||
|
"aho-corasick",
|
||||||
|
"memchr",
|
||||||
|
"regex-syntax",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "regex-syntax"
|
||||||
|
version = "0.6.28"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "456c603be3e8d448b072f410900c09faf164fbce2d480456f50eea6e25f9c848"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "remove_dir_all"
|
name = "remove_dir_all"
|
||||||
version = "0.5.3"
|
version = "0.5.3"
|
||||||
|
|
|
@ -13,5 +13,6 @@ hex-literal = "0.3.4"
|
||||||
itertools = "0.10.5"
|
itertools = "0.10.5"
|
||||||
lazy_static = "1.4.0"
|
lazy_static = "1.4.0"
|
||||||
pico-args = "0.5.0"
|
pico-args = "0.5.0"
|
||||||
|
regex = "1.7.0"
|
||||||
reqwest = { version = "0.11.13", features = ["blocking"] }
|
reqwest = { version = "0.11.13", features = ["blocking"] }
|
||||||
rust-crypto = "0.2.36"
|
rust-crypto = "0.2.36"
|
||||||
|
|
|
@ -0,0 +1,139 @@
|
||||||
|
use std::collections::HashMap;
|
||||||
|
|
||||||
|
use lazy_static::lazy_static;
|
||||||
|
use regex::Regex;
|
||||||
|
use Instruction::*;
|
||||||
|
|
||||||
|
#[derive(Debug)]
|
||||||
|
struct Point {
|
||||||
|
x: u32,
|
||||||
|
y: u32,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl FromIterator<u32> for Point {
|
||||||
|
fn from_iter<T: IntoIterator<Item = u32>>(iter: T) -> Self {
|
||||||
|
let mut it = iter.into_iter();
|
||||||
|
Point {
|
||||||
|
x: it.next().unwrap(),
|
||||||
|
y: it.next().unwrap(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug)]
|
||||||
|
enum Instruction {
|
||||||
|
On,
|
||||||
|
Off,
|
||||||
|
Toggle,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug)]
|
||||||
|
struct Command {
|
||||||
|
instruction: Instruction,
|
||||||
|
from: Point,
|
||||||
|
to: Point,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl From<&str> for Command {
|
||||||
|
fn from(value: &str) -> Self {
|
||||||
|
lazy_static! {
|
||||||
|
static ref RE: Regex = Regex::new(
|
||||||
|
r"(turn on|turn off|toggle) (\d{1,3},\d{1,3}) through (\d{1,3},\d{1, 3})"
|
||||||
|
)
|
||||||
|
.unwrap();
|
||||||
|
}
|
||||||
|
|
||||||
|
let capture = RE.captures(value).unwrap();
|
||||||
|
|
||||||
|
let instruction = match capture[1].as_ref() {
|
||||||
|
"turn on" => On,
|
||||||
|
"turn off" => Off,
|
||||||
|
"toggle" => Toggle,
|
||||||
|
_ => unreachable!(),
|
||||||
|
};
|
||||||
|
|
||||||
|
let from: Point = capture[2]
|
||||||
|
.split(',')
|
||||||
|
.map(|x| x.parse::<u32>().unwrap())
|
||||||
|
.collect();
|
||||||
|
|
||||||
|
let to: Point = capture[3]
|
||||||
|
.split(',')
|
||||||
|
.map(|x| x.parse::<u32>().unwrap())
|
||||||
|
.collect();
|
||||||
|
|
||||||
|
Command {
|
||||||
|
instruction,
|
||||||
|
from,
|
||||||
|
to,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn part_one(input: &str) -> Option<u32> {
|
||||||
|
let mut map = HashMap::<(u32, u32), bool>::new();
|
||||||
|
for line in input.trim().split('\n') {
|
||||||
|
let Command {
|
||||||
|
instruction,
|
||||||
|
from,
|
||||||
|
to,
|
||||||
|
} = Command::from(line);
|
||||||
|
for x in from.x..=to.x {
|
||||||
|
for y in from.y..=to.y {
|
||||||
|
match instruction {
|
||||||
|
On => *map.entry((x, y)).or_default() = true,
|
||||||
|
Off => *map.entry((x, y)).or_default() = false,
|
||||||
|
Toggle => {
|
||||||
|
map.entry((x, y)).or_default();
|
||||||
|
map.insert((x, y), !map[&(x, y)]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Some(map.values().filter(|&x| *x).count() as u32)
|
||||||
|
}
|
||||||
|
pub fn part_two(input: &str) -> Option<u32> {
|
||||||
|
let mut map = HashMap::<(u32, u32), u32>::new();
|
||||||
|
for line in input.trim().split('\n') {
|
||||||
|
let Command {
|
||||||
|
instruction,
|
||||||
|
from,
|
||||||
|
to,
|
||||||
|
} = Command::from(line);
|
||||||
|
for x in from.x..=to.x {
|
||||||
|
for y in from.y..=to.y {
|
||||||
|
match instruction {
|
||||||
|
On => *map.entry((x, y)).or_default() += 1,
|
||||||
|
Toggle => *map.entry((x, y)).or_default() += 2,
|
||||||
|
Off => {
|
||||||
|
map.entry((x, y)).or_default();
|
||||||
|
if map[&(x, y)] > 0 {
|
||||||
|
*map.entry((x, y)).or_default() -= 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Some(map.values().into_iter().sum())
|
||||||
|
}
|
||||||
|
fn main() {
|
||||||
|
let input = &aoc::read_file("inputs", 6);
|
||||||
|
aoc::solve!(1, part_one, input);
|
||||||
|
aoc::solve!(2, part_two, input);
|
||||||
|
}
|
||||||
|
#[cfg(test)]
|
||||||
|
mod tests {
|
||||||
|
use super::*;
|
||||||
|
#[test]
|
||||||
|
fn test_part_one() {
|
||||||
|
let input = aoc::read_file("test_inputs", 6);
|
||||||
|
assert_eq!(part_one(&input), Some(998996));
|
||||||
|
}
|
||||||
|
#[test]
|
||||||
|
fn test_part_two() {
|
||||||
|
let input = aoc::read_file("test_inputs", 6);
|
||||||
|
assert_eq!(part_two(&input), Some(1001996));
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,3 @@
|
||||||
|
turn on 0,0 through 999,999
|
||||||
|
toggle 0,0 through 999,0
|
||||||
|
turn off 499,499 through 500,500
|
Loading…
Reference in New Issue