solution: day6
This commit is contained in:
		
							
								
								
									
										27
									
								
								Cargo.lock
									
									
									
										generated
									
									
									
								
							
							
						
						
									
										27
									
								
								Cargo.lock
									
									
									
										generated
									
									
									
								
							| @@ -2,6 +2,15 @@ | ||||
| # It is not intended for manual editing. | ||||
| 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]] | ||||
| name = "aoc" | ||||
| version = "0.1.0" | ||||
| @@ -11,6 +20,7 @@ dependencies = [ | ||||
|  "itertools", | ||||
|  "lazy_static", | ||||
|  "pico-args", | ||||
|  "regex", | ||||
|  "reqwest", | ||||
|  "rust-crypto", | ||||
| ] | ||||
| @@ -591,6 +601,23 @@ dependencies = [ | ||||
|  "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]] | ||||
| name = "remove_dir_all" | ||||
| version = "0.5.3" | ||||
|   | ||||
| @@ -13,5 +13,6 @@ hex-literal = "0.3.4" | ||||
| itertools = "0.10.5" | ||||
| lazy_static = "1.4.0" | ||||
| pico-args = "0.5.0" | ||||
| regex = "1.7.0" | ||||
| reqwest = { version = "0.11.13", features = ["blocking"] } | ||||
| rust-crypto = "0.2.36" | ||||
|   | ||||
							
								
								
									
										139
									
								
								src/bin/06.rs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										139
									
								
								src/bin/06.rs
									
									
									
									
									
										Normal file
									
								
							| @@ -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)); | ||||
|     } | ||||
| } | ||||
							
								
								
									
										3
									
								
								src/test_inputs/06.txt
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										3
									
								
								src/test_inputs/06.txt
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,3 @@ | ||||
| turn on 0,0 through 999,999 | ||||
| toggle 0,0 through 999,0 | ||||
| turn off 499,499 through 500,500 | ||||
		Reference in New Issue
	
	Block a user