Compare commits
	
		
			2 Commits
		
	
	
		
			cde23745ef
			...
			cf1fb4c792
		
	
	| Author | SHA1 | Date | |
|---|---|---|---|
| 
						 | 
					cf1fb4c792 | ||
| 
						 | 
					161e5f7a5f | 
							
								
								
									
										86
									
								
								2021/src/day2.rs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										86
									
								
								2021/src/day2.rs
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,86 @@
 | 
				
			|||||||
 | 
					use std::str::FromStr;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					use color_eyre::eyre;
 | 
				
			||||||
 | 
					use eyre::{eyre, ensure};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					use crate::lib::ParseLines;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					enum Direction {
 | 
				
			||||||
 | 
					    Forward,
 | 
				
			||||||
 | 
					    Up,
 | 
				
			||||||
 | 
					    Down,
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					struct MoveCmd {
 | 
				
			||||||
 | 
					    dir: Direction,
 | 
				
			||||||
 | 
					    value: i32,
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					impl<'a> FromStr for MoveCmd {
 | 
				
			||||||
 | 
					    type Err = eyre::Report;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    fn from_str(s: &str) -> Result<Self, Self::Err> {
 | 
				
			||||||
 | 
					        let parts: Vec<&str> = s.split_whitespace().collect();
 | 
				
			||||||
 | 
					        ensure!(parts.len() == 2, "Could not parse: \"{}\" (Wrong number of words)", s);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        let dir = match parts[0] {
 | 
				
			||||||
 | 
					            "forward" => Direction::Forward,
 | 
				
			||||||
 | 
					            "up" => Direction::Up,
 | 
				
			||||||
 | 
					            "down" => Direction::Down,
 | 
				
			||||||
 | 
					            _ => return Err(eyre!("Could not parse: \"{}\" (invalid axis)", s)),
 | 
				
			||||||
 | 
					        };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        let value = parts[1].parse::<i32>()?;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        Ok(MoveCmd{dir, value})
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					fn part1(commands: &Vec<MoveCmd>) -> i32 {
 | 
				
			||||||
 | 
					    let mut horiz = 0; // how many units forward
 | 
				
			||||||
 | 
					    let mut vert = 0; // how many units DOWN (so flipped)
 | 
				
			||||||
 | 
					    for cmd in commands {
 | 
				
			||||||
 | 
					        match cmd.dir {
 | 
				
			||||||
 | 
					            Direction::Forward => horiz += cmd.value,
 | 
				
			||||||
 | 
					            Direction::Up => vert -= cmd.value,
 | 
				
			||||||
 | 
					            Direction::Down => vert += cmd.value,
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    horiz * vert
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					fn part2(commands: &Vec<MoveCmd>) -> i32 {
 | 
				
			||||||
 | 
					    let mut horiz = 0;
 | 
				
			||||||
 | 
					    let mut vert = 0;
 | 
				
			||||||
 | 
					    let mut aim = 0;
 | 
				
			||||||
 | 
					    for cmd in commands {
 | 
				
			||||||
 | 
					        match cmd.dir {
 | 
				
			||||||
 | 
					            Direction::Down => aim += cmd.value, // flipped again
 | 
				
			||||||
 | 
					            Direction::Up => aim -= cmd.value,
 | 
				
			||||||
 | 
					            Direction::Forward => {
 | 
				
			||||||
 | 
					                horiz += cmd.value;
 | 
				
			||||||
 | 
					                vert +=  cmd.value * aim;
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    horiz * vert
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					pub fn run(data: &str) -> eyre::Result<()> {
 | 
				
			||||||
 | 
					    let mut commands = Vec::new();
 | 
				
			||||||
 | 
					    for res in data.parse_lines::<MoveCmd>() {
 | 
				
			||||||
 | 
					        commands.push(res?);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    println!("One: {}", part1(&commands));
 | 
				
			||||||
 | 
					    println!("Two: {}", part2(&commands));
 | 
				
			||||||
 | 
					    Ok(())
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
@@ -36,7 +36,7 @@ pub trait ParseLines {
 | 
				
			|||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
impl ParseLines for String {
 | 
					impl ParseLines for str {
 | 
				
			||||||
    fn parse_lines<T: FromStr>(&self) -> LineParser<'_, T> {
 | 
					    fn parse_lines<T: FromStr>(&self) -> LineParser<'_, T> {
 | 
				
			||||||
        LineParser {
 | 
					        LineParser {
 | 
				
			||||||
            it: self.lines(),
 | 
					            it: self.lines(),
 | 
				
			||||||
@@ -45,3 +45,10 @@ impl ParseLines for String {
 | 
				
			|||||||
    }
 | 
					    }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					impl ParseLines for String {
 | 
				
			||||||
 | 
					    fn parse_lines<T: FromStr>(&self) -> LineParser<'_, T> {
 | 
				
			||||||
 | 
					        self[..].parse_lines::<T>()
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1,45 +1,14 @@
 | 
				
			|||||||
use color_eyre::eyre;
 | 
					use color_eyre::eyre;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
mod lib;
 | 
					mod lib;
 | 
				
			||||||
use lib::{load, ParseLines};
 | 
					use lib::load;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					mod day2;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
fn main() -> eyre::Result<()> {
 | 
					fn main() -> eyre::Result<()> {
 | 
				
			||||||
    day_one()
 | 
					    let data = load("data/02.txt")?;
 | 
				
			||||||
 | 
					    day2::run(&data)
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
fn day_one() -> eyre::Result<()> {
 | 
					 | 
				
			||||||
    let data = load("data/01.txt")?;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    let mut single_increases = 0;
 | 
					 | 
				
			||||||
    let mut window_increases = 0;
 | 
					 | 
				
			||||||
    let mut prev = (None, None, None);
 | 
					 | 
				
			||||||
    for res in data.parse_lines::<i32>() {
 | 
					 | 
				
			||||||
        let n = res?;
 | 
					 | 
				
			||||||
        if let Some(p) = prev.2 {
 | 
					 | 
				
			||||||
            // apparently we can't combine "if let" and regular boolean conditions
 | 
					 | 
				
			||||||
            if n > p {
 | 
					 | 
				
			||||||
                single_increases += 1;
 | 
					 | 
				
			||||||
            }
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        if let (Some(first), Some(second), Some(third)) = prev {
 | 
					 | 
				
			||||||
            if (n + second + third) > (first + second + third) {
 | 
					 | 
				
			||||||
                window_increases += 1;
 | 
					 | 
				
			||||||
            }
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
        // would have forgotten this if not for the warning triggered by "let mut" without mutation
 | 
					 | 
				
			||||||
        prev = (prev.1, prev.2, Some(n));
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    println!("One: {}", single_increases);
 | 
					 | 
				
			||||||
    println!("Two: {}", window_increases);
 | 
					 | 
				
			||||||
    Ok(())
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
// fn day_two() -> eyre::Result<()> {
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
// }
 | 
					 | 
				
			||||||
 
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user