diff --git a/.idea/advent_of_code_2022.iml b/.idea/advent_of_code_2022.iml index a802623..95ca2a2 100644 --- a/.idea/advent_of_code_2022.iml +++ b/.idea/advent_of_code_2022.iml @@ -7,6 +7,7 @@ + diff --git a/Cargo.toml b/Cargo.toml index 9246031..2ebb35e 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,2 +1,2 @@ [workspace] -members = ['common', 'cli', 'day_01', 'day_02', 'day_03'] +members = ['common', 'cli', 'day_01', 'day_02', 'day_03', 'day_04'] diff --git a/cli/Cargo.toml b/cli/Cargo.toml index 5736a0c..b0cf484 100644 --- a/cli/Cargo.toml +++ b/cli/Cargo.toml @@ -10,4 +10,5 @@ clap = { version = "4.0", features = ["derive"] } day_01 = { path = "../day_01"} day_02 = { path = "../day_02"} day_03 = { path = "../day_03"} +day_04 = { path = "../day_04"} common = { path = "../common"} diff --git a/cli/src/main.rs b/cli/src/main.rs index f98db12..ea9c1ae 100644 --- a/cli/src/main.rs +++ b/cli/src/main.rs @@ -71,6 +71,21 @@ fn main() -> Result<(), Box> { ); Ok(()) } + (day @ Day::Four, part @ Part::One) => { + println!( + "{}", + day_04::run_day_and_part(day, part, input_str.as_str()) + ); + Ok(()) + } + (day @ Day::Four, part @ Part::Two) => { + println!( + "{}", + day_04::run_day_and_part(day, part, input_str.as_str()) + ); + Ok(()) + } + (_, _) => { unimplemented!() diff --git a/common/src/lib.rs b/common/src/lib.rs index 72d951c..1ee9994 100644 --- a/common/src/lib.rs +++ b/common/src/lib.rs @@ -5,6 +5,7 @@ pub enum Day { One, Two, Three, + Four, } #[derive(ValueEnum, Copy, Clone, Debug)] diff --git a/day_04/Cargo.toml b/day_04/Cargo.toml new file mode 100644 index 0000000..1c6fabb --- /dev/null +++ b/day_04/Cargo.toml @@ -0,0 +1,10 @@ +[package] +name = "day_04" +version = "0.0.0" +edition = "2021" + +# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html + +[dependencies] +common = {path = '../common'} +nom = "7.1.1" diff --git a/day_04/input/input b/day_04/input/input new file mode 100644 index 0000000..f8b658d --- /dev/null +++ b/day_04/input/input @@ -0,0 +1,1000 @@ +13-53,17-82 +32-32,32-42 +85-85,8-86 +78-80,79-91 +60-71,59-70 +91-92,4-90 +90-90,1-90 +35-49,38-50 +31-51,31-52 +78-80,81-81 +85-86,86-94 +52-95,96-97 +1-39,1-40 +8-68,7-24 +83-89,58-78 +96-98,98-99 +26-27,26-74 +9-43,8-44 +3-8,9-89 +3-77,7-26 +1-88,2-2 +30-53,31-52 +3-47,46-86 +8-78,7-9 +53-92,6-52 +84-97,49-97 +38-67,38-68 +13-13,12-95 +7-13,52-87 +18-18,17-79 +65-65,64-64 +12-92,11-91 +67-67,2-68 +14-89,13-92 +13-44,12-14 +20-42,21-24 +9-47,7-11 +99-99,32-97 +22-37,21-36 +24-98,24-99 +62-76,62-77 +49-50,49-98 +92-98,26-79 +5-10,9-95 +24-92,24-91 +13-13,14-30 +56-97,5-97 +8-33,9-34 +18-76,18-75 +16-80,12-17 +8-99,8-95 +4-97,3-96 +11-12,11-86 +5-90,1-89 +32-71,31-84 +12-96,14-91 +9-9,12-71 +13-93,8-92 +4-77,78-93 +4-6,5-89 +18-52,17-51 +35-65,11-64 +76-77,1-76 +24-24,26-43 +4-8,7-48 +85-85,5-86 +1-86,4-85 +10-44,10-45 +19-91,36-79 +63-95,75-98 +59-86,59-87 +87-91,42-90 +49-98,48-96 +2-28,2-27 +4-91,4-90 +93-98,28-91 +5-91,90-90 +67-77,82-85 +98-98,66-94 +19-36,33-46 +6-54,6-53 +52-82,87-90 +94-99,1-94 +2-2,1-96 +43-46,42-45 +20-23,25-30 +7-93,6-92 +18-56,17-19 +40-95,39-96 +35-90,91-99 +15-17,15-19 +29-31,37-99 +2-91,6-92 +11-28,7-7 +10-50,9-11 +27-89,10-26 +33-60,33-61 +66-68,55-67 +11-11,10-90 +10-20,9-11 +73-96,20-98 +6-85,6-86 +7-82,6-8 +37-54,10-57 +36-87,35-86 +46-86,86-93 +4-68,7-69 +25-26,20-26 +99-99,2-89 +1-10,3-17 +6-92,5-5 +29-87,1-30 +7-74,12-74 +26-36,25-97 +29-83,16-84 +13-97,13-98 +34-72,35-72 +55-62,61-61 +24-95,59-95 +4-38,4-37 +62-73,8-77 +5-35,2-2 +79-79,4-78 +18-51,18-50 +10-12,9-9 +44-83,6-44 +71-81,95-98 +36-98,26-97 +67-74,19-74 +81-89,40-80 +26-81,53-94 +64-64,26-63 +34-67,11-75 +13-56,14-56 +55-55,44-56 +3-51,3-97 +76-80,75-77 +5-66,77-89 +49-70,18-49 +32-53,14-33 +30-30,30-31 +3-7,14-47 +33-33,1-33 +7-9,11-95 +92-92,37-92 +40-90,4-90 +33-79,7-46 +50-64,26-49 +3-94,37-94 +32-68,68-77 +5-17,1-6 +6-86,3-6 +26-46,21-76 +14-74,38-75 +3-86,20-85 +60-70,60-69 +10-32,11-33 +43-43,11-43 +17-96,9-95 +36-96,37-95 +11-94,87-95 +9-94,8-94 +60-61,45-60 +25-58,24-58 +46-81,45-92 +37-77,38-80 +95-95,2-96 +57-71,56-70 +28-93,59-94 +16-88,15-90 +12-38,12-22 +13-88,87-99 +7-38,7-37 +3-70,4-69 +44-77,45-76 +4-69,2-98 +45-79,44-78 +39-91,2-33 +33-78,33-77 +91-91,16-90 +63-94,95-97 +1-97,1-97 +19-38,3-19 +95-95,91-96 +53-77,15-78 +8-53,7-53 +20-41,28-42 +5-7,7-90 +55-86,85-87 +2-92,9-80 +17-79,79-89 +43-77,44-78 +61-66,60-60 +8-76,5-8 +40-83,39-83 +69-79,79-80 +51-51,50-92 +29-99,18-99 +18-75,17-18 +17-39,8-59 +9-35,34-79 +8-52,7-53 +51-95,75-94 +94-94,1-94 +37-55,32-56 +6-84,1-6 +19-19,18-40 +95-97,28-95 +89-99,82-92 +11-47,46-47 +4-98,4-99 +12-16,23-94 +18-50,17-49 +37-72,35-57 +23-77,22-24 +54-65,6-54 +61-74,39-73 +83-94,52-90 +13-99,2-14 +10-98,11-99 +30-98,29-99 +38-90,37-90 +63-66,64-68 +49-93,49-95 +84-88,79-88 +11-35,35-83 +2-59,3-59 +42-64,57-64 +14-62,15-88 +52-54,53-71 +37-66,38-67 +20-96,21-92 +5-82,4-6 +13-52,13-52 +10-69,4-21 +5-69,26-98 +41-57,40-42 +8-94,9-93 +6-27,26-61 +27-65,27-66 +97-98,1-97 +46-85,45-86 +43-48,38-43 +5-49,48-48 +14-59,12-58 +30-97,7-96 +62-70,64-69 +31-79,12-78 +10-18,9-17 +74-76,72-76 +29-69,29-70 +15-93,93-95 +66-68,67-73 +2-89,1-2 +2-95,9-96 +4-89,6-45 +98-98,28-99 +16-77,4-77 +16-86,87-87 +17-17,18-83 +18-82,29-81 +21-99,7-98 +36-85,1-85 +9-70,70-90 +38-95,60-94 +94-94,24-95 +4-63,3-63 +40-72,73-88 +3-4,3-99 +1-27,3-93 +15-26,16-27 +10-89,20-34 +16-18,6-39 +34-48,28-34 +5-83,6-6 +37-49,38-50 +39-86,9-38 +12-74,74-75 +16-80,15-81 +26-67,24-85 +5-7,12-19 +40-68,69-69 +17-79,80-95 +17-63,16-18 +69-72,16-75 +15-24,48-89 +12-12,13-96 +4-4,6-89 +79-84,5-39 +23-25,24-61 +26-97,6-96 +4-97,5-97 +55-91,56-91 +25-80,80-81 +52-76,53-75 +45-61,44-61 +65-81,64-82 +65-74,3-64 +4-73,72-72 +54-54,53-57 +51-51,29-50 +1-14,3-36 +93-95,57-92 +85-86,6-85 +3-98,3-15 +21-21,20-54 +18-72,19-73 +27-49,47-53 +20-77,21-78 +52-76,38-76 +82-87,14-87 +3-79,1-4 +1-97,1-1 +39-40,40-91 +6-11,5-10 +5-98,4-6 +36-36,9-37 +6-69,7-7 +77-93,76-95 +41-94,26-93 +70-81,7-70 +1-72,71-72 +30-90,29-98 +68-76,12-76 +28-42,15-19 +76-96,39-77 +30-32,46-90 +83-98,83-92 +1-98,9-98 +17-93,16-92 +17-89,3-8 +61-67,62-67 +19-63,18-20 +51-53,52-98 +20-21,20-58 +5-86,6-87 +23-85,24-84 +34-54,22-53 +20-67,20-68 +26-88,26-26 +26-94,27-94 +27-29,29-84 +42-73,2-42 +68-72,56-71 +13-85,16-84 +54-87,88-95 +26-29,32-35 +2-21,20-45 +18-18,19-48 +91-98,31-88 +5-59,41-60 +94-96,70-94 +8-85,86-89 +3-97,98-99 +89-90,16-92 +13-44,43-74 +6-87,25-99 +5-5,6-53 +3-85,1-84 +25-94,35-87 +17-95,17-64 +12-85,13-85 +2-4,4-75 +7-25,8-24 +47-96,24-96 +95-96,94-94 +94-94,93-93 +22-77,3-90 +17-77,78-83 +35-42,48-75 +12-12,13-97 +13-19,18-77 +32-83,26-83 +31-78,3-32 +3-17,17-95 +45-61,44-61 +73-81,13-80 +2-99,6-93 +80-88,33-74 +45-86,3-44 +39-75,39-93 +2-96,95-96 +10-64,9-65 +4-76,5-5 +72-96,72-73 +78-85,77-79 +20-94,19-98 +14-87,3-15 +21-35,35-53 +2-87,88-93 +15-90,15-87 +3-99,2-99 +9-95,9-96 +5-89,1-90 +6-73,3-74 +52-76,6-51 +5-52,66-69 +17-19,18-36 +8-43,2-9 +56-72,63-73 +73-91,66-92 +4-89,5-89 +95-99,9-93 +91-98,92-99 +18-78,6-7 +11-71,71-94 +1-99,3-97 +7-90,1-8 +5-87,5-88 +46-48,47-97 +3-92,7-91 +33-33,32-73 +39-95,38-98 +35-82,36-81 +41-90,86-95 +21-45,44-44 +5-5,6-49 +49-67,50-66 +8-76,8-77 +15-17,29-73 +35-95,20-34 +29-64,30-64 +11-45,11-46 +14-87,4-13 +38-69,37-37 +11-76,6-9 +70-98,62-97 +17-99,16-18 +2-82,5-81 +15-93,4-94 +56-57,56-57 +1-6,6-88 +48-93,48-49 +7-75,39-74 +1-3,2-90 +27-31,28-31 +10-10,9-63 +11-64,65-79 +57-57,56-69 +50-50,49-88 +43-43,2-44 +15-59,11-59 +28-44,7-28 +5-39,37-42 +88-95,95-95 +2-63,63-63 +5-91,14-98 +7-89,6-98 +16-36,36-56 +40-80,81-83 +4-99,2-98 +70-70,2-71 +6-45,7-46 +9-97,10-96 +34-79,33-34 +51-55,50-55 +27-72,58-79 +9-65,8-64 +3-5,4-99 +17-43,11-16 +9-29,10-28 +23-91,24-90 +13-80,10-14 +47-85,86-86 +9-25,4-8 +43-92,43-92 +89-90,76-89 +32-88,4-31 +33-52,32-51 +3-97,1-99 +39-91,40-51 +19-92,22-92 +4-89,23-92 +5-6,6-66 +6-99,7-78 +8-93,92-93 +5-95,58-97 +2-96,99-99 +34-39,35-35 +92-92,3-93 +38-54,11-53 +45-59,59-87 +55-78,54-54 +42-66,42-66 +19-91,22-92 +39-46,38-91 +42-89,41-41 +33-66,34-65 +7-71,6-70 +7-80,30-61 +58-91,57-90 +30-95,88-95 +4-97,96-99 +12-99,12-95 +39-41,40-50 +34-87,35-87 +14-86,2-12 +14-87,15-86 +7-97,96-96 +7-36,31-46 +6-75,7-49 +29-29,28-81 +58-67,68-68 +18-97,18-91 +17-31,27-30 +39-46,51-96 +68-89,69-69 +15-57,15-57 +24-24,16-77 +40-92,91-93 +43-61,41-76 +49-49,42-48 +34-76,15-75 +2-73,74-74 +16-98,16-97 +7-80,6-80 +23-66,24-65 +39-81,40-82 +74-99,33-37 +81-93,64-93 +19-86,86-95 +97-97,9-98 +45-70,62-71 +54-67,20-53 +85-85,18-85 +11-79,28-76 +40-96,12-40 +19-79,35-80 +3-91,1-92 +5-90,5-89 +42-93,43-92 +40-70,34-38 +12-43,11-12 +22-22,3-21 +53-90,7-65 +22-90,11-15 +24-24,24-36 +3-3,5-55 +53-54,53-53 +53-53,26-54 +3-9,9-97 +43-58,58-59 +31-64,17-64 +34-36,35-35 +4-11,10-48 +12-39,15-40 +44-44,43-92 +9-68,68-68 +20-95,20-81 +6-27,45-62 +7-91,7-91 +2-3,5-88 +11-77,22-61 +8-95,30-77 +85-97,86-97 +3-60,8-18 +14-70,13-69 +34-81,61-82 +42-82,43-82 +9-99,10-10 +2-75,19-53 +26-77,69-86 +82-97,27-81 +17-92,9-93 +5-6,5-5 +46-46,45-47 +21-67,21-68 +36-95,17-36 +41-88,41-89 +6-81,11-80 +26-45,45-46 +4-75,2-4 +27-36,24-35 +49-64,50-97 +86-86,40-85 +5-5,5-92 +81-82,6-82 +14-92,93-93 +28-36,35-65 +12-17,18-27 +28-68,6-68 +47-93,48-48 +20-99,11-97 +32-75,9-18 +53-96,96-96 +33-64,32-63 +79-83,3-78 +38-46,47-79 +3-88,4-98 +6-97,96-96 +68-68,42-69 +24-99,23-23 +27-98,65-99 +9-94,5-5 +22-30,23-23 +71-72,23-71 +2-97,2-96 +6-58,7-57 +44-88,45-74 +2-97,98-99 +27-30,9-27 +10-89,48-89 +19-99,18-88 +95-95,15-78 +10-30,10-31 +10-97,11-79 +5-97,1-98 +17-99,1-99 +27-29,28-95 +90-90,33-90 +64-65,3-64 +34-98,35-97 +23-62,22-63 +76-85,85-85 +56-97,57-98 +43-43,43-43 +17-83,16-18 +4-15,6-15 +18-70,66-70 +62-63,9-62 +81-85,32-80 +35-95,24-90 +6-62,7-62 +17-19,18-29 +24-38,37-37 +2-42,2-43 +11-50,10-12 +20-50,19-51 +22-22,2-22 +54-54,8-53 +27-47,46-46 +11-97,5-6 +47-99,1-99 +31-46,32-45 +8-56,2-39 +57-95,10-96 +17-17,25-75 +44-46,10-45 +30-33,29-32 +1-94,24-95 +31-32,8-32 +19-21,20-49 +34-34,19-35 +33-79,86-96 +12-98,12-97 +27-35,26-36 +37-89,90-90 +2-5,4-81 +29-38,38-39 +3-88,58-82 +5-8,7-65 +6-14,13-73 +57-98,90-99 +29-53,30-54 +1-78,59-60 +34-34,24-35 +4-12,11-11 +41-84,9-83 +5-88,6-6 +1-78,8-75 +80-80,19-81 +95-97,72-96 +13-85,84-84 +31-81,28-32 +53-58,37-45 +13-69,62-82 +11-69,10-69 +46-46,45-74 +60-93,77-98 +14-58,14-59 +73-73,11-72 +3-91,32-91 +4-6,5-87 +11-85,16-78 +2-99,89-97 +21-88,20-87 +4-52,51-51 +22-22,1-21 +21-76,8-94 +4-6,5-40 +97-97,5-93 +22-85,11-23 +6-74,5-5 +67-91,66-92 +24-99,16-98 +2-58,1-1 +21-52,20-52 +71-82,76-96 +5-65,5-64 +4-6,9-70 +73-75,68-88 +39-52,38-40 +29-32,29-31 +65-65,37-66 +3-69,2-68 +36-97,36-85 +52-68,15-69 +3-42,42-43 +19-25,25-58 +9-28,8-27 +23-99,24-99 +21-98,22-95 +6-12,12-13 +42-93,41-99 +57-83,58-84 +91-91,90-94 +71-72,71-88 +2-97,1-3 +9-12,11-49 +75-81,38-82 +38-75,16-52 +16-18,17-91 +29-72,30-71 +83-83,45-82 +17-56,19-57 +50-52,51-78 +17-67,66-66 +3-81,3-80 +20-48,49-65 +17-51,10-18 +1-9,2-10 +49-49,46-48 +95-96,55-96 +27-89,28-74 +47-76,28-82 +9-95,10-96 +87-88,5-88 +27-74,28-47 +74-93,46-92 +3-95,98-98 +49-50,26-50 +28-79,27-79 +15-53,14-93 +17-36,17-18 +7-72,64-75 +7-96,32-99 +87-99,21-77 +12-98,13-97 +14-79,2-79 +2-2,2-3 +38-73,73-74 +11-82,4-7 +67-67,68-71 +86-87,13-84 +52-80,51-52 +71-97,71-96 +4-5,5-87 +14-31,31-73 +28-28,27-55 +3-3,2-28 +37-67,65-73 +79-80,73-79 +16-95,17-94 +7-77,8-76 +16-82,18-82 +34-34,33-93 +13-84,88-88 +37-98,9-97 +16-40,7-59 +3-96,1-3 +3-95,30-99 +1-84,2-85 +2-3,4-56 +5-54,6-55 +69-93,36-93 +31-89,44-88 +5-88,23-87 +5-87,4-88 +85-90,42-84 +44-72,33-37 +7-11,21-99 +32-91,31-91 +99-99,61-99 +5-79,10-44 +59-94,58-84 +4-6,5-99 +24-29,28-82 +23-41,23-40 +6-95,95-96 +18-99,17-53 +87-95,32-85 +28-66,28-67 +4-94,99-99 +22-97,22-98 +30-96,14-31 +30-70,31-69 +56-74,3-89 +4-85,86-86 +57-97,58-97 +41-95,41-96 +78-79,37-78 +25-70,70-75 +92-92,4-93 +46-65,66-73 +18-20,19-23 +32-90,32-89 +38-73,38-95 +30-69,31-68 +49-68,1-78 +18-98,10-97 +25-65,14-22 +14-46,12-45 +19-48,20-32 +52-83,29-52 +57-95,57-94 +4-97,4-96 +35-91,90-92 +5-99,4-99 +4-26,4-27 +54-73,6-54 +6-98,7-99 +63-81,7-80 +58-85,59-59 +1-2,1-88 +71-85,51-93 +5-65,6-6 +3-49,33-93 +44-84,5-84 +49-62,48-61 +35-98,36-99 +2-3,10-64 +95-95,43-95 +2-55,3-56 +20-53,20-52 +15-97,11-13 +81-81,3-81 +40-45,1-44 +1-3,5-73 +4-97,97-98 +91-92,12-91 +31-64,30-63 +18-55,17-54 +35-40,34-35 +3-6,5-95 +26-70,79-94 +4-97,8-97 +6-63,28-63 +28-95,11-21 +5-81,1-6 +38-41,39-40 +49-96,48-88 +59-77,58-77 +29-40,28-40 +45-75,46-46 +3-87,4-67 +58-99,4-92 +47-57,46-47 +24-84,15-80 +85-92,38-85 +55-89,88-90 +32-68,67-67 +7-89,8-89 +14-92,13-92 +29-41,30-41 +5-92,4-92 +9-29,19-41 +65-89,90-99 +91-91,60-91 +5-70,21-68 +11-95,35-92 +25-65,14-26 +52-93,88-94 +52-89,51-90 +74-87,86-86 +32-96,99-99 +5-97,4-6 +19-91,20-91 +65-76,64-77 +36-90,37-90 +37-82,25-92 +76-78,77-84 +5-66,5-66 +4-9,12-50 +2-52,10-52 +15-99,14-98 +18-96,6-18 +3-81,4-33 +21-66,15-71 +49-49,27-67 +4-4,5-94 +50-50,9-51 +31-95,30-94 +82-91,87-93 +61-96,17-95 +2-95,17-95 +34-37,7-35 +2-94,7-85 +96-96,49-95 +41-41,42-59 +2-97,3-97 +22-97,22-98 +33-95,34-82 +33-47,47-72 +32-93,33-93 +36-58,35-35 +10-58,52-58 +77-89,60-67 +3-13,12-81 +14-98,40-98 +11-94,7-12 +51-63,43-63 +22-82,2-81 +31-34,35-60 +8-79,8-42 +67-67,66-88 +64-81,4-64 +16-96,15-97 +22-65,23-65 +59-97,60-96 +18-89,90-99 +2-2,3-97 +12-63,11-63 +12-42,41-59 +36-37,31-36 +45-91,2-59 +7-89,6-8 +21-49,21-50 +13-13,12-87 +48-89,47-90 +3-22,2-55 +19-19,20-41 +48-67,47-94 +11-13,12-83 +16-62,16-61 +11-35,12-41 +71-78,5-71 +66-67,67-87 +22-71,14-71 +19-72,15-72 +20-42,21-41 +8-94,7-93 +97-98,19-96 +3-98,2-98 +33-71,72-73 +33-35,34-81 +18-98,18-97 +85-85,24-86 +7-97,26-96 +47-47,46-49 +5-14,3-3 +1-83,14-83 +10-91,3-75 +62-62,32-63 +16-84,83-84 +52-53,52-70 +2-47,2-47 +8-93,8-24 +56-97,97-97 +8-84,27-84 +71-89,89-89 +96-98,30-96 +11-92,49-92 +66-66,19-67 +55-57,54-56 +3-69,3-70 +5-99,4-6 +1-40,1-39 +1-87,88-89 +11-98,20-96 +22-92,21-94 +5-88,5-86 +79-98,79-97 +34-88,82-88 +67-80,66-79 +16-87,9-17 +78-91,92-92 +46-57,35-57 +45-64,44-44 +77-82,12-81 +3-98,1-3 +42-62,62-89 +2-70,95-95 +62-63,61-63 +39-97,38-98 +3-99,6-98 +26-84,83-83 +18-27,17-28 +52-58,7-52 +25-82,1-82 +29-66,67-67 +43-72,21-71 +23-29,5-28 +43-90,43-44 +42-68,42-67 +67-69,66-70 +19-40,18-57 +1-1,8-9 +56-89,97-99 +87-98,25-86 +88-98,10-88 +2-93,2-96 +3-82,82-89 +7-14,8-14 +3-37,36-56 +51-52,4-51 +38-88,37-96 +74-81,22-81 +69-83,68-70 +2-91,38-91 +2-90,91-96 diff --git a/day_04/src/lib.rs b/day_04/src/lib.rs new file mode 100644 index 0000000..b29b21c --- /dev/null +++ b/day_04/src/lib.rs @@ -0,0 +1,225 @@ +use common::{Day, Part}; +use nom::character::complete::{char, digit1, line_ending}; +use nom::multi::separated_list1; +use nom::sequence::separated_pair; +use nom::IResult; +use std::ops::RangeInclusive; + +pub fn run_day_and_part(day: Day, part: Part, inp: &str) -> usize { + match (day, part) { + (Day::Four, Part::One) => { + part_01_do(inp) + .into_iter() + .fold(0, |acc, it| if it { acc + 1 } else { acc }) + } + (Day::Four, Part::Two) => { + part_02_do(inp) + .into_iter() + .fold(0, |acc, it| if it { acc + 1 } else { acc }) + } + (_, _) => unimplemented!(), + } +} + +fn elf_range(s: &str) -> IResult<&str, RangeInclusive> { + let (s, elf_range): (&str, (&str, &str)) = separated_pair(digit1, char('-'), digit1)(s)?; + + let left: usize = elf_range.0.parse::<_>().unwrap(); + + let right: usize = elf_range.1.parse::<_>().unwrap(); + Ok((s, RangeInclusive::new(left, right))) +} + +#[derive(Debug, Eq, PartialEq, Clone)] +struct ElfRangeLine { + first: RangeInclusive, + second: RangeInclusive, +} + +impl ElfRangeLine { + fn one_contained_in_other(&self) -> bool { + self.first.clone().all(|a| self.second.clone().contains(&a)) + || self.second.clone().all(|a| self.first.clone().contains(&a)) + } + fn any_overlap(&self) -> bool { + self.first.clone().any(|a| self.second.clone().contains(&a)) + || self.second.clone().any(|a| self.first.clone().contains(&a)) + } +} + +fn elf_range_line(s: &str) -> IResult<&str, ElfRangeLine> { + let (s, elf_ranges): (&str, (RangeInclusive, RangeInclusive)) = + separated_pair(elf_range, char(','), elf_range)(s)?; + + Ok(( + s, + ElfRangeLine { + first: elf_ranges.0, + second: elf_ranges.1, + }, + )) +} + +fn elf_range_sequence(s: &str) -> IResult<&str, Vec> { + separated_list1(line_ending, elf_range_line)(s) +} + +fn part_01_do(inp: &str) -> Vec { + let (_, ranges): (_, Vec) = elf_range_sequence(inp).unwrap(); + + ranges + .iter() + .map(|r: &ElfRangeLine| r.one_contained_in_other()) + .collect() +} + +fn part_02_do(inp: &str) -> Vec { + let (_, ranges): (_, Vec) = elf_range_sequence(inp).unwrap(); + + ranges + .iter() + .map(|r: &ElfRangeLine| r.any_overlap()) + .collect() +} + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn elf_range_creation() { + assert_eq!(Ok(("", (0..=4))), elf_range("0-4")) + } + + #[test] + fn elf_range_line_creation() { + assert_eq!( + Ok(( + "", + ElfRangeLine { + first: (0..=4), + second: (2..=5) + } + )), + elf_range_line("0-4,2-5") + ) + } + + #[test] + fn elf_range_contains_works_in_obvious_case() { + let expected = true; + + let under_test = ElfRangeLine { + first: (2..=8), + second: (3..=7), + }; + let res = under_test.one_contained_in_other(); + + assert_eq!(expected, res) + } + + #[test] + fn elf_range_contains_fails_correctly() { + let expected = false; + + let under_test = ElfRangeLine { + first: (2..=8), + second: (3..=9), + }; + let res = under_test.one_contained_in_other(); + + assert_eq!(expected, res) + } + + #[test] + fn elf_range_contains_reflexive() { + let expected = true; + + let under_test = ElfRangeLine { + first: (3..=7), + second: (2..=8), + }; + let res = under_test.one_contained_in_other(); + + assert_eq!(expected, res) + } + + #[test] + fn part_01_example_parsed_correctly() { + let expected = Ok(( + "", + vec![ + ElfRangeLine { + first: (2..=4), + second: (6..=8), + }, + ElfRangeLine { + first: (2..=3), + second: (4..=5), + }, + ElfRangeLine { + first: (5..=7), + second: (7..=9), + }, + ElfRangeLine { + first: (2..=8), + second: (3..=7), + }, + ElfRangeLine { + first: (6..=6), + second: (4..=6), + }, + ElfRangeLine { + first: (2..=6), + second: (4..=8), + }, + ], + )); + + assert_eq!( + expected, + elf_range_sequence( + r#"2-4,6-8 +2-3,4-5 +5-7,7-9 +2-8,3-7 +6-6,4-6 +2-6,4-8"# + ) + ) + } + + #[test] + fn part_01_example_score_is_correct() { + assert_eq!( + 2, + run_day_and_part( + Day::Four, + Part::One, + r#"2-4,6-8 +2-3,4-5 +5-7,7-9 +2-8,3-7 +6-6,4-6 +2-6,4-8"# + ) + ) + } + + #[test] + fn part_02_example_score_is_correct() { + assert_eq!( + 4, + run_day_and_part( + Day::Four, + Part::Two, + r#"2-4,6-8 +2-3,4-5 +5-7,7-9 +2-8,3-7 +6-6,4-6 +2-6,4-8"# + ) + ) + } +}