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"#
+ )
+ )
+ }
+}