day 06
This commit is contained in:
		
							parent
							
								
									f88c8db711
								
							
						
					
					
						commit
						7354c7f628
					
				| 
						 | 
					@ -77,12 +77,27 @@ dependencies = [
 | 
				
			||||||
 "rayon",
 | 
					 "rayon",
 | 
				
			||||||
]
 | 
					]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					[[package]]
 | 
				
			||||||
 | 
					name = "day-06"
 | 
				
			||||||
 | 
					version = "0.0.0"
 | 
				
			||||||
 | 
					dependencies = [
 | 
				
			||||||
 | 
					 "indoc",
 | 
				
			||||||
 | 
					 "nom",
 | 
				
			||||||
 | 
					 "rayon",
 | 
				
			||||||
 | 
					]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
[[package]]
 | 
					[[package]]
 | 
				
			||||||
name = "either"
 | 
					name = "either"
 | 
				
			||||||
version = "1.9.0"
 | 
					version = "1.9.0"
 | 
				
			||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
 | 
					source = "registry+https://github.com/rust-lang/crates.io-index"
 | 
				
			||||||
checksum = "a26ae43d7bcc3b814de94796a5e736d4029efb0ee900c12e2d54c993ad1a1e07"
 | 
					checksum = "a26ae43d7bcc3b814de94796a5e736d4029efb0ee900c12e2d54c993ad1a1e07"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					[[package]]
 | 
				
			||||||
 | 
					name = "indoc"
 | 
				
			||||||
 | 
					version = "2.0.4"
 | 
				
			||||||
 | 
					source = "registry+https://github.com/rust-lang/crates.io-index"
 | 
				
			||||||
 | 
					checksum = "1e186cfbae8084e513daff4240b4797e342f988cecda4fb6c939150f96315fd8"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
[[package]]
 | 
					[[package]]
 | 
				
			||||||
name = "itertools"
 | 
					name = "itertools"
 | 
				
			||||||
version = "0.12.0"
 | 
					version = "0.12.0"
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -4,10 +4,12 @@ members = [
 | 
				
			||||||
    "day-01",
 | 
					    "day-01",
 | 
				
			||||||
    "day-02",
 | 
					    "day-02",
 | 
				
			||||||
    "day-03",
 | 
					    "day-03",
 | 
				
			||||||
    "day-05"
 | 
					    "day-05",
 | 
				
			||||||
 | 
					    "day-06"
 | 
				
			||||||
]
 | 
					]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
[workspace.dependencies]
 | 
					[workspace.dependencies]
 | 
				
			||||||
 | 
					indoc = "2.0.4"
 | 
				
			||||||
itertools = "0.12.0"
 | 
					itertools = "0.12.0"
 | 
				
			||||||
nom = "7.1.3"
 | 
					nom = "7.1.3"
 | 
				
			||||||
rayon = "1.8.0"
 | 
					rayon = "1.8.0"
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -0,0 +1,11 @@
 | 
				
			||||||
 | 
					[package]
 | 
				
			||||||
 | 
					name = "day-06"
 | 
				
			||||||
 | 
					version = "0.0.0"
 | 
				
			||||||
 | 
					edition = "2021"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					[dependencies]
 | 
				
			||||||
 | 
					indoc.workspace = true
 | 
				
			||||||
 | 
					nom.workspace = true
 | 
				
			||||||
 | 
					rayon.workspace = true
 | 
				
			||||||
| 
						 | 
					@ -0,0 +1,2 @@
 | 
				
			||||||
 | 
					Time:        46     82     84     79
 | 
				
			||||||
 | 
					Distance:   347   1522   1406   1471
 | 
				
			||||||
| 
						 | 
					@ -0,0 +1,68 @@
 | 
				
			||||||
 | 
					use nom::{
 | 
				
			||||||
 | 
					    bytes::complete::tag,
 | 
				
			||||||
 | 
					    character::complete::{self, newline, space1},
 | 
				
			||||||
 | 
					    multi::separated_list1,
 | 
				
			||||||
 | 
					    sequence::{pair, preceded, separated_pair},
 | 
				
			||||||
 | 
					    IResult, Parser,
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					fn main() {
 | 
				
			||||||
 | 
					    println!("{}", part1(include_str!("./input.txt")));
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					fn part1(input: &str) -> u64 {
 | 
				
			||||||
 | 
					    separated_pair(time_parser, newline, distance_parser)
 | 
				
			||||||
 | 
					        .map(|(times, distances)| {
 | 
				
			||||||
 | 
					            times
 | 
				
			||||||
 | 
					                .into_iter()
 | 
				
			||||||
 | 
					                .zip(distances)
 | 
				
			||||||
 | 
					                .map(|(time, distance)| calc_game(time, distance) as u64)
 | 
				
			||||||
 | 
					                .product::<u64>()
 | 
				
			||||||
 | 
					        })
 | 
				
			||||||
 | 
					        .parse(input)
 | 
				
			||||||
 | 
					        .unwrap()
 | 
				
			||||||
 | 
					        .1
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					fn time_parser(i: &str) -> IResult<&str, Vec<u32>> {
 | 
				
			||||||
 | 
					    preceded(
 | 
				
			||||||
 | 
					        pair(tag("Time:"), space1),
 | 
				
			||||||
 | 
					        separated_list1(space1, complete::u32),
 | 
				
			||||||
 | 
					    )(i)
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					fn distance_parser(i: &str) -> IResult<&str, Vec<u32>> {
 | 
				
			||||||
 | 
					    preceded(
 | 
				
			||||||
 | 
					        pair(tag("Distance:"), space1),
 | 
				
			||||||
 | 
					        separated_list1(space1, complete::u32),
 | 
				
			||||||
 | 
					    )(i)
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					fn calc_game(time: u32, distance: u32) -> u32 {
 | 
				
			||||||
 | 
					    (1..time)
 | 
				
			||||||
 | 
					        .filter_map(|t| (calc_distance(t, time) > distance).then_some(()))
 | 
				
			||||||
 | 
					        .count() as u32
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					fn calc_distance(hold_time: u32, total_time: u32) -> u32 {
 | 
				
			||||||
 | 
					    hold_time * (total_time - hold_time)
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#[cfg(test)]
 | 
				
			||||||
 | 
					mod tests {
 | 
				
			||||||
 | 
					    use super::*;
 | 
				
			||||||
 | 
					    use indoc::indoc;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    #[test]
 | 
				
			||||||
 | 
					    fn test_part1() {
 | 
				
			||||||
 | 
					        assert_eq!(
 | 
				
			||||||
 | 
					            part1(indoc!(
 | 
				
			||||||
 | 
					                "
 | 
				
			||||||
 | 
					        Time:      7  15   30
 | 
				
			||||||
 | 
					        Distance:  9  40  200
 | 
				
			||||||
 | 
					        "
 | 
				
			||||||
 | 
					            )),
 | 
				
			||||||
 | 
					            288
 | 
				
			||||||
 | 
					        );
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
| 
						 | 
					@ -0,0 +1,65 @@
 | 
				
			||||||
 | 
					use nom::{
 | 
				
			||||||
 | 
					    bytes::complete::tag,
 | 
				
			||||||
 | 
					    character::complete::{digit1, newline, space1},
 | 
				
			||||||
 | 
					    multi::separated_list1,
 | 
				
			||||||
 | 
					    sequence::{pair, preceded, separated_pair},
 | 
				
			||||||
 | 
					    IResult, Parser,
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					use rayon::prelude::*;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					fn main() {
 | 
				
			||||||
 | 
					    println!("{}", part2(include_str!("./input.txt")));
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					fn part2(input: &str) -> u64 {
 | 
				
			||||||
 | 
					    separated_pair(time_parser, newline, distance_parser)
 | 
				
			||||||
 | 
					        .map(|(time, distance)| calc_game(time, distance))
 | 
				
			||||||
 | 
					        .parse(input)
 | 
				
			||||||
 | 
					        .unwrap()
 | 
				
			||||||
 | 
					        .1
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					fn time_parser(i: &str) -> IResult<&str, u64> {
 | 
				
			||||||
 | 
					    preceded(pair(tag("Time:"), space1), separated_list1(space1, digit1))
 | 
				
			||||||
 | 
					        .map(|strs| strs.join("").parse::<u64>().expect("Invalid digit"))
 | 
				
			||||||
 | 
					        .parse(i)
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					fn distance_parser(i: &str) -> IResult<&str, u64> {
 | 
				
			||||||
 | 
					    preceded(
 | 
				
			||||||
 | 
					        pair(tag("Distance:"), space1),
 | 
				
			||||||
 | 
					        separated_list1(space1, digit1),
 | 
				
			||||||
 | 
					    )
 | 
				
			||||||
 | 
					    .map(|strs| strs.join("").parse::<u64>().expect("Invalid digit"))
 | 
				
			||||||
 | 
					    .parse(i)
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					fn calc_game(time: u64, distance: u64) -> u64 {
 | 
				
			||||||
 | 
					    (1..time)
 | 
				
			||||||
 | 
					        .into_par_iter()
 | 
				
			||||||
 | 
					        .filter_map(|t| (calc_distance(t, time) > distance).then_some(()))
 | 
				
			||||||
 | 
					        .count() as u64
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					fn calc_distance(hold_time: u64, total_time: u64) -> u64 {
 | 
				
			||||||
 | 
					    hold_time * (total_time - hold_time)
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#[cfg(test)]
 | 
				
			||||||
 | 
					mod tests {
 | 
				
			||||||
 | 
					    use super::*;
 | 
				
			||||||
 | 
					    use indoc::indoc;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    #[test]
 | 
				
			||||||
 | 
					    fn test_part1() {
 | 
				
			||||||
 | 
					        assert_eq!(
 | 
				
			||||||
 | 
					            part2(indoc!(
 | 
				
			||||||
 | 
					                "
 | 
				
			||||||
 | 
					        Time:      7  15   30
 | 
				
			||||||
 | 
					        Distance:  9  40  200
 | 
				
			||||||
 | 
					        "
 | 
				
			||||||
 | 
					            )),
 | 
				
			||||||
 | 
					            288
 | 
				
			||||||
 | 
					        );
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
		Loading…
	
		Reference in New Issue