day6: problem 1 solution
This commit is contained in:
parent
077f4ff8ee
commit
de6e826c31
7
6/Cargo.lock
generated
Normal file
7
6/Cargo.lock
generated
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
# This file is automatically @generated by Cargo.
|
||||||
|
# It is not intended for manual editing.
|
||||||
|
version = 3
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "day6"
|
||||||
|
version = "0.1.0"
|
8
6/Cargo.toml
Normal file
8
6/Cargo.toml
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
[package]
|
||||||
|
name = "day6"
|
||||||
|
version = "0.1.0"
|
||||||
|
edition = "2021"
|
||||||
|
|
||||||
|
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
||||||
|
|
||||||
|
[dependencies]
|
199
6/src/main.rs
Normal file
199
6/src/main.rs
Normal file
@ -0,0 +1,199 @@
|
|||||||
|
use std::fs::File;
|
||||||
|
use std::io::{BufRead, BufReader, Lines};
|
||||||
|
|
||||||
|
// --- Day 6: Wait For It ---
|
||||||
|
|
||||||
|
// The ferry quickly brings you across Island Island. After asking around, you discover
|
||||||
|
// that there is indeed normally a large pile of sand somewhere near here, but you don't
|
||||||
|
// see anything besides lots of water and the small island where the ferry has docked.
|
||||||
|
|
||||||
|
// As you try to figure out what to do next, you notice a poster on a wall near the
|
||||||
|
// ferry dock. "Boat races! Open to the public! Grand prize is an all-expenses-paid trip
|
||||||
|
// to Desert Island!" That must be where the sand comes from! Best of all, the boat
|
||||||
|
// races are starting in just a few minutes.
|
||||||
|
|
||||||
|
// You manage to sign up as a competitor in the boat races just in time. The organizer
|
||||||
|
// explains that it's not really a traditional race - instead, you will get a fixed
|
||||||
|
// amount of time during which your boat has to travel as far as it can, and you win if
|
||||||
|
// your boat goes the farthest.
|
||||||
|
|
||||||
|
// As part of signing up, you get a sheet of paper (your puzzle input) that lists the
|
||||||
|
// time allowed for each race and also the best distance ever recorded in that race. To
|
||||||
|
// guarantee you win the grand prize, you need to make sure you go farther in each race
|
||||||
|
// than the current record holder.
|
||||||
|
|
||||||
|
// The organizer brings you over to the area where the boat races are held. The boats
|
||||||
|
// are much smaller than you expected - they're actually toy boats, each with a big
|
||||||
|
// button on top. Holding down the button charges the boat, and releasing the button
|
||||||
|
// allows the boat to move. Boats move faster if their button was held longer, but time
|
||||||
|
// spent holding the button counts against the total race time. You can only hold the
|
||||||
|
// button at the start of the race, and boats don't move until the button is released.
|
||||||
|
|
||||||
|
// For example:
|
||||||
|
|
||||||
|
// Time: 7 15 30
|
||||||
|
// Distance: 9 40 200
|
||||||
|
|
||||||
|
// This document describes three races:
|
||||||
|
|
||||||
|
// The first race lasts 7 milliseconds. The record distance in this race is 9 millimeters.
|
||||||
|
// The second race lasts 15 milliseconds. The record distance in this race is 40 millimeters.
|
||||||
|
// The third race lasts 30 milliseconds. The record distance in this race is 200 millimeters.
|
||||||
|
|
||||||
|
// Your toy boat has a starting speed of zero millimeters per millisecond. For each
|
||||||
|
// whole millisecond you spend at the beginning of the race holding down the button, the
|
||||||
|
// boat's speed increases by one millimeter per millisecond.
|
||||||
|
|
||||||
|
// So, because the first race lasts 7 milliseconds, you only have a few options:
|
||||||
|
|
||||||
|
// Don't hold the button at all (that is, hold it for 0 milliseconds) at the start
|
||||||
|
// of the race. The boat won't move; it will have traveled 0 millimeters by the end
|
||||||
|
// of the race.
|
||||||
|
|
||||||
|
// Hold the button for 1 millisecond at the start of the race. Then, the boat will
|
||||||
|
// travel at a speed of 1 millimeter per millisecond for 6 milliseconds, reaching a
|
||||||
|
// total distance traveled of 6 millimeters.
|
||||||
|
|
||||||
|
// Hold the button for 2 milliseconds, giving the boat a speed of 2 millimeters per
|
||||||
|
// millisecond. It will then get 5 milliseconds to move, reaching a total distance
|
||||||
|
// of 10 millimeters.
|
||||||
|
|
||||||
|
// Hold the button for 3 milliseconds. After its remaining 4 milliseconds of travel
|
||||||
|
// time, the boat will have gone 12 millimeters.
|
||||||
|
|
||||||
|
// Hold the button for 4 milliseconds. After its remaining 3 milliseconds of travel
|
||||||
|
// time, the boat will have gone 12 millimeters.
|
||||||
|
|
||||||
|
// Hold the button for 5 milliseconds, causing the boat to travel a total of 10
|
||||||
|
// millimeters.
|
||||||
|
|
||||||
|
// Hold the button for 6 milliseconds, causing the boat to travel a total of 6
|
||||||
|
// millimeters.
|
||||||
|
|
||||||
|
// Hold the button for 7 milliseconds. That's the entire duration of the race. You
|
||||||
|
// never let go of the button. The boat can't move until you let go of the button.
|
||||||
|
// Please make sure you let go of the button so the boat gets to move. 0
|
||||||
|
// millimeters.
|
||||||
|
|
||||||
|
// Since the current record for this race is 9 millimeters, there are actually 4
|
||||||
|
// different ways you could win: you could hold the button for 2, 3, 4, or 5
|
||||||
|
// milliseconds at the start of the race.
|
||||||
|
|
||||||
|
// In the second race, you could hold the button for at least 4 milliseconds and at most
|
||||||
|
// 11 milliseconds and beat the record, a total of 8 different ways to win.
|
||||||
|
|
||||||
|
// In the third race, you could hold the button for at least 11 milliseconds and no more
|
||||||
|
// than 19 milliseconds and still beat the record, a total of 9 ways you could win.
|
||||||
|
|
||||||
|
// BOILERPLATE
|
||||||
|
type InputIter = Lines<BufReader<File>>;
|
||||||
|
|
||||||
|
fn get_input() -> InputIter {
|
||||||
|
let f = File::open("input").unwrap();
|
||||||
|
let br = BufReader::new(f);
|
||||||
|
br.lines()
|
||||||
|
}
|
||||||
|
|
||||||
|
fn main() {
|
||||||
|
println!("Problem 1 solution: {}", problem1(get_input()));
|
||||||
|
println!("Problem 2 solution: {}", problem2(get_input()));
|
||||||
|
}
|
||||||
|
|
||||||
|
// PARSER
|
||||||
|
|
||||||
|
#[derive(Debug)]
|
||||||
|
struct Races(Vec<(u64, u64)>);
|
||||||
|
|
||||||
|
impl<T: BufRead> From<Lines<T>> for Races {
|
||||||
|
fn from(mut input: Lines<T>) -> Self {
|
||||||
|
let timeline = input.next().unwrap().unwrap();
|
||||||
|
let distline = input.next().unwrap().unwrap();
|
||||||
|
|
||||||
|
let times = timeline
|
||||||
|
.split_whitespace()
|
||||||
|
.skip(1)
|
||||||
|
.map(|s| s.parse().unwrap());
|
||||||
|
let distances = distline
|
||||||
|
.split_whitespace()
|
||||||
|
.skip(1)
|
||||||
|
.map(|s| s.parse().unwrap());
|
||||||
|
|
||||||
|
Races(times.zip(distances).collect())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// PROBLEM 1 solution
|
||||||
|
|
||||||
|
// To see how much margin of error you have, determine the number of ways you can beat
|
||||||
|
// the record in each race; in this example, if you multiply these values together, you
|
||||||
|
// get 288 (4 * 8 * 9).
|
||||||
|
|
||||||
|
// Determine the number of ways you could beat the record in each race. What do you get
|
||||||
|
// if you multiply these numbers together?
|
||||||
|
|
||||||
|
/// Calculate the 'score' of a race. Speed will equal button duration, and runtime
|
||||||
|
/// equals the remaining time
|
||||||
|
fn race_distance(button_duration: u64, race_duration: u64) -> u64 {
|
||||||
|
assert!(button_duration <= race_duration);
|
||||||
|
|
||||||
|
let running_time = race_duration - button_duration;
|
||||||
|
|
||||||
|
running_time * button_duration
|
||||||
|
}
|
||||||
|
|
||||||
|
fn problem1_possible_wins(race: (u64, u64)) -> u64 {
|
||||||
|
let (duration, record) = race;
|
||||||
|
|
||||||
|
(1..duration)
|
||||||
|
.map(|button_duration| race_distance(button_duration, duration))
|
||||||
|
.filter(|achieved_distance| *achieved_distance > record)
|
||||||
|
.count() as u64
|
||||||
|
}
|
||||||
|
|
||||||
|
fn problem1<T: BufRead>(input: Lines<T>) -> u64 {
|
||||||
|
let races = Races::from(input);
|
||||||
|
races.0.iter().map(|race| problem1_possible_wins(*race)).fold(1, |accum, elem| accum * elem)
|
||||||
|
}
|
||||||
|
|
||||||
|
// PROBLEM 2 solution
|
||||||
|
fn problem2<T: BufRead>(input: Lines<T>) -> u64 {
|
||||||
|
0
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(test)]
|
||||||
|
mod tests {
|
||||||
|
use crate::*;
|
||||||
|
use std::io::Cursor;
|
||||||
|
|
||||||
|
const EXAMPLE: &str = &"Time: 7 15 30
|
||||||
|
Distance: 9 40 200";
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_races_parser() {
|
||||||
|
let c = Cursor::new(EXAMPLE);
|
||||||
|
let races = Races::from(c.lines());
|
||||||
|
assert_eq!(races.0, vec![(7, 9), (15, 40), (30, 200)]);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_race_distance() {
|
||||||
|
assert_eq!(race_distance(0, 7), 0);
|
||||||
|
assert_eq!(race_distance(1, 7), 6);
|
||||||
|
assert_eq!(race_distance(2, 7), 10);
|
||||||
|
assert_eq!(race_distance(3, 7), 12);
|
||||||
|
assert_eq!(race_distance(7, 7), 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_possible_wins() {
|
||||||
|
assert_eq!(problem1_possible_wins((7,9)), 4);
|
||||||
|
assert_eq!(problem1_possible_wins((15,40)), 8);
|
||||||
|
assert_eq!(problem1_possible_wins((30,200)), 9);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_problem1_example() {
|
||||||
|
let c = Cursor::new(EXAMPLE);
|
||||||
|
assert_eq!(problem1(c.lines()), 288);
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user