1
0
Fork 0

Compare commits

...

6 Commits

Author SHA1 Message Date
chylex 63f86596b2
Add 2020 - Day 3 - Part 2 2022-02-23 05:46:21 +01:00
chylex 4cb654dd2f
Add 2020 - Day 3 - Part 1 2022-02-23 03:43:42 +01:00
chylex 7eef7e4ae3
Refactor Rust error utility 2022-02-23 03:11:22 +01:00
chylex f8bc38182f
Add 2020 - Day 2 - Part 2 2022-02-23 02:15:13 +01:00
chylex cb2c6becbf
Add 2020 - Day 2 - Part 1 2022-02-23 02:15:13 +01:00
chylex ef3703949e
Add 2020 - Day 1 - Part 2 2022-02-23 00:36:11 +01:00
10 changed files with 1596 additions and 3 deletions

View File

@ -0,0 +1,18 @@
<component name="ProjectRunConfigurationManager">
<configuration default="false" name="2020 - Day 02" type="CargoCommandRunConfiguration" factoryName="Cargo Command">
<option name="command" value="run --bin 02" />
<option name="workingDirectory" value="file://$PROJECT_DIR$/2020/02" />
<option name="channel" value="DEFAULT" />
<option name="requiredFeatures" value="true" />
<option name="allFeatures" value="false" />
<option name="emulateTerminal" value="false" />
<option name="withSudo" value="false" />
<option name="backtrace" value="SHORT" />
<envs />
<option name="isRedirectInput" value="false" />
<option name="redirectInputPath" value="" />
<method v="2">
<option name="CARGO.BUILD_TASK_PROVIDER" enabled="true" />
</method>
</configuration>
</component>

View File

@ -0,0 +1,18 @@
<component name="ProjectRunConfigurationManager">
<configuration default="false" name="2020 - Day 03" type="CargoCommandRunConfiguration" factoryName="Cargo Command">
<option name="command" value="run --bin 03" />
<option name="workingDirectory" value="file://$PROJECT_DIR$/2020/03" />
<option name="channel" value="DEFAULT" />
<option name="requiredFeatures" value="true" />
<option name="allFeatures" value="false" />
<option name="emulateTerminal" value="false" />
<option name="withSudo" value="false" />
<option name="backtrace" value="SHORT" />
<envs />
<option name="isRedirectInput" value="false" />
<option name="redirectInputPath" value="" />
<method v="2">
<option name="CARGO.BUILD_TASK_PROVIDER" enabled="true" />
</method>
</configuration>
</component>

View File

@ -6,6 +6,13 @@ mod utils;
fn main() -> Result<(), Box<dyn Error>> {
let lines = utils::parse_input_lines::<u32>()?;
part1(&lines);
part2(&lines);
Ok(())
}
fn part1(lines: &Vec<u32>) {
'outer: for i in 0..lines.len() {
let value1 = lines.get(i).unwrap();
@ -14,10 +21,27 @@ fn main() -> Result<(), Box<dyn Error>> {
if value1 + value2 == 2020 {
println!("Result: {} x {} = {}", value1, value2, value1 * value2);
break 'outer
break 'outer;
}
}
}
}
fn part2(lines: &Vec<u32>) {
'outer: for i in 0..lines.len() {
let value1 = lines.get(i).unwrap();
for j in (i + 1)..lines.len() {
let value2 = lines.get(j).unwrap();
for k in (j + 1)..lines.len() {
let value3 = lines.get(k).unwrap();
if value1 + value2 + value3 == 2020 {
println!("Result: {} x {} x {} = {}", value1, value2, value3, value1 * value2 * value3);
break 'outer;
}
}
}
}
Ok(())
}

1000
2020/02/input/1.txt Normal file

File diff suppressed because it is too large Load Diff

55
2020/02/main.rs Normal file
View File

@ -0,0 +1,55 @@
use std::collections::HashSet;
use std::error::Error;
use std::str::FromStr;
use utils::GenericError;
#[path = "../utils/mod.rs"]
mod utils;
fn main() -> Result<(), Box<dyn Error>> {
let lines = utils::parse_input_lines::<PasswordRule>()?;
println!("Valid passwords according to part 1 rules: {}", lines.iter().filter(|x| x.is_valid_part1()).count());
println!("Valid passwords according to part 2 rules: {}", lines.iter().filter(|x| x.is_valid_part2()).count());
Ok(())
}
struct PasswordRule {
left_value: usize,
right_value: usize,
required_char: String,
actual_password: String
}
impl PasswordRule {
fn is_valid_part1(&self) -> bool {
let count = self.actual_password.matches(self.required_char.as_str()).count();
return count >= self.left_value && count <= self.right_value;
}
fn is_valid_part2(&self) -> bool {
let positions = self.actual_password.match_indices(self.required_char.as_str()).map(|(index, _)| index + 1).collect::<HashSet<usize>>();
let is_in_first_position = positions.contains(&self.left_value);
let is_in_second_position = positions.contains(&self.right_value);
return (is_in_first_position && !is_in_second_position) || (!is_in_first_position && is_in_second_position);
}
}
impl FromStr for PasswordRule {
type Err = GenericError;
fn from_str(s: &str) -> Result<Self, Self::Err> {
let (s_range, s_rest) = s.split_once(' ').ok_or(GenericError::new("Missing space."))?;
let (s_min, s_max) = s_range.split_once('-').ok_or(GenericError::new("Missing dash in the left part of the input."))?;
let (s_char, s_password) = s_rest.split_once(": ").ok_or(GenericError::new("Missing colon followed by space in the right part of the input."))?;
Ok(PasswordRule {
left_value: s_min.parse::<usize>().map_err(|_| GenericError::new("Cannot parse first number."))?,
right_value: s_max.parse::<usize>().map_err(|_| GenericError::new("Cannot parse second number."))?,
required_char: s_char.to_string(),
actual_password: s_password.to_string()
})
}
}

323
2020/03/input/1.txt Normal file
View File

@ -0,0 +1,323 @@
.##......#.##..#..#..##....#...
...##.....#...###........###...
#....##....#.....#.....#..##.##
.......#.###.#......#..#..#..#.
##..........#....#.#...#.......
###.#.#.#......##...#..........
.#.##........#..............#..
..#..........#...##..#.......##
.........##...#...#....###.#...
#.......#.....#.#.#...###.##.#.
...#...#...#......#........#.##
....#..........#.....#..#....##
.#.#.##....#.#...#.............
#....#..#.....#.#..............
........#....#....#..#........#
..#.......#...#....##.#........
......#.........##.......#.#...
............#.......#..........
.....#..#.#..#........##...#...
....#.....................###..
..#.......#.........#..##....##
..#........#..#...#........#...
..............#....##..##....#.
....#..#.#.......#....#..#...##
.#........##......#.#..#.#.....
............#.##...##...#...##.
.......#........#.........##...
...#...........#.#...#..#......
#...#............#..####.......
..#..#..#..#.....#...#.#.#.....
....#.#..............#.....##..
#.....##........#......#.......
.....#..#................##.#..
.###.#...................#.....
....#....#...#.##..........#...
.#.....#....#.......#...#......
.....#...#.##.##............#..
..........#..#....#...#.#..#...
#...#..#..............###.#...#
......#....#.#....##....#......
............#......#......##...
.#....#...#........#.#.#..#....
..#.....#.......#.....#.#......
#....#......#.......#......#...
....#..##.....#...#........#...
.#..#......#..#................
.#...#...#....#.#...#.....#...#
......#..#...#...#..#.......##.
...#..#...#.#.......#.......#..
..#...#.........#......#......#
......#...#..#..........#......
.#..#......#....#.#.#...#....#.
.#.#....#.#.#..#..#..#........#
....###.#...##..#.#..#....#....
...#.#.#................#......
.#.....#..#..........##..#....#
..........#..#......#.........#
.....#....#...#.#..##....#.#.#.
........#.##......###..........
##......#.#..#.....#..##.#.....
.#.......#..#....##.....##.....
.....##....#...................
##......#....##........#.....#.
..##...#...........##........#.
...#....#..##.#....#......##...
#....#...##....#..........#....
......##....#...............#..
...#.#.#...#...#...#...........
....#..#...#.#....#.#......#...
.......#...#...............#...
.##..#....#...#....#.#........#
.....#..##............#......#.
...##...#.....#..........#.#..#
..#..##.............#....#.....
.....#.#.....#.........#......#
........#..........#.#.#...#..#
#........#.#...................
......#......##..............#.
......#..#.#.....#...#.#...#...
.#..##.....#...##.......#......
#.......#....#..##....#..#.#...
#..#..#....#...........#.##....
..##....#....##.....#...#...##.
.#.......#.......#....#.......#
.#..#..#...#...#...............
.#..............#.....#........
..........##...#....#.#......##
..........#..........#.......#.
..#..##....##...#.......#......
.#......#.#........##.#........
...#......#..#....#...#....#...
...............#....#..#.##...#
....#.......................#..
#....##.#......#....#..........
.......#.#......#........#..##.
..#.....#...#...........##..#..
#........#.#....#............#.
.........##..................#.
........#...#..#...#......#...#
...#.......#...####.#...#......
....#..###......###..#.........
.....#...........#......#......
.#.....#......#.....#.....##.##
.#.#...##..........#........#.#
..#....#.....##...............#
.....##.....#...##..#..........
.#......##.......#..##.##.#...#
.#..#...#.##.....#.#...........
.........#....##...#.....##....
#..........#.............#..#.#
...........#........#.#...#....
........#..###...#...........#.
#.........#...#....#..##.##....
........#....##.......#.#....#.
..........#..............#.....
....##...#...##..........#.....
...#..##.#...###..#............
...##..#####....#.............#
.#..#.......##.......#........#
....##..........#.......#.#....
......#.........####.......#...
...............#......#..#.....
...#...##...#.#.#.....##.#.#...
..#....#..#..............#....#
#..............#............#..
.#.#..#....#.....#.#.#...#.....
......#......#..#..#.....#.....
.#.#..#.##.#........#..........
..##.#......#..#.......#.......
.##...##....#..#.#.........#.##
.........#........#.#..###....#
.....#...............#.........
......##..........#.....#......
.#.....#.#.#..#.#.....#..#.####
.......###.##......#.....#.#..#
..#.....#....#.#.##......#....#
.....##..#................#..##
.#......#.....#..#.....#..#####
.........#.#.......#..##...#...
.#.#..#.......##.....#....#....
.....#...###.#...#......#....#.
.#....#....#...#..#.#........#.
......##........##.#...#..#..#.
.##.##.###..#.....#........###.
.....#..#.#.......#..#.#.......
##.#.#..............#..##......
....#.........#.......#.#......
.....#..#.....#...#.#....#.#...
...#..#.#.#..................#.
........##.#.###...............
..#...#.#.......#......#.......
.......#.##....#...#....#......
......#.#.............#........
........#......#........##.##..
.....#...#......##.............
...#.#..#.....#.#...#..........
.#.#..#.....#............#.....
.#.#..#.#.##.#...#.##..##...#..
.........##........#.##..#.....
##.#.#......###..#.##.#........
.##...#..#...#.#..#....##.....#
#......#..........#.#...#.....#
..........#......#...#.......#.
.............#..........#......
#.#....#.......##..#.....#.#...
##......#..#......#.#..#.#....#
..#.#..#.....#.#......#....#..#
...#......#......##.....#..#.#.
....#......#.....#....#.#.#..#.
.....#..#..#.....#...........##
....#.....#...#........##.#.#.#
..#......#.......#........#....
#.......##..##......#...####..#
#..........#......#.#..#..#....
.................##............
...#..#..#.#.....#.##.#.....#.#
...#....###....................
....#.......#..#.#.............
#......#................#......
..........#........#..#........
.....#......##..#......#..###..
...#....#.......#..............
.#....#.#.#........#.....#...#.
.......#.....##.#.....#....#...
.........#.#.........##..#...#.
......#......#....#.....##.#.#.
####...#.........#.....#......#
...#.#..#..#.............#.....
......#.........#....#.#..##..#
.........#.....#.#..##..##..#..
.#......##.............#.......
....#...#......#...#.....#.#.##
......#..##....#..#.....#......
......#..............#....##...
.........#.###..........#.##...
#....#..........#..#.......#...
...........#...#.....#.......#.
..#..#........#................
...###.........#...............
.....#.##...#.................#
..#.#..#...###......#........#.
#......#......#.#.............#
.........#.#.....#..#........#.
........#..#......#......##....
.....#......#...#.....##...#.##
.##...#..#....##..........###..
.......#............#........##
.##.....#.......#...#..........
..###..........#.............##
#....#....#.#....#............#
#...#......................#...
....#..#..#..#.......###....#..
#..###.#..#.....#.............#
..........#.##.....#.........##
...#.............#....#....##..
#........................#..#..
........#...#.....#.....#..##..
#........#......#....#..#....#.
.....#.#.#....#.#..#....#......
.....#....#....................
.........#..#..#....#......#...
..........#.#.#.......#........
.......#.#.....#..#.....##.....
.....#....#.#.....#.......#..#.
.#..###.......#......#..#..#...
..##.#.....#.........##.#......
.....#.......###.......##......
#...#.......##.#.#......#.....#
.##........##.#...#...#........
....#.......#....#..#.......#..
.#..#.......#..####..##........
..#..#..#..#..#..#.............
...#......#...#...#.#......##.#
........#.#..#.#.#......#...#..
#.......#..##.......##........#
..##...#...............#.#....#
.####........##..........#..#..
..#........#...##...#........#.
.#.#..........#...#...#........
....###..........#....#........
.#.#.#.###.#.##..#.#........#..
..........#....##.#..##........
.......#..#..##.......#........
..#........#....#..####.#..#...
....#.......#..##..#..........#
.....#...........#....#....#...
.#.##..#......##.........#.#...
...#......##..##......#.....#..
#........#..........#.#...#....
.#.#........###........#..#....
....#####.................##...
.........##...#......#.........
.......#....#....#.#....#...#..
......#................#...#.#.
....#.....#.....#.#.....#.....#
#.........#..#........#.....#..
....#...........#.....#.#......
##..#....................#.#...
#.#.##....#.....##....#.......#
..#..#....###.......#..##......
......##.....#.##...#....#..#..
........#..#.#..#..#.#.........
#...#.....##..........##.......
....#.....#...#.###.......#....
..........#..#...#........##..#
##..#...#.#.####.#..#..#...#...
................#......#..#....
.......#...###...#........#....
....#..##..#.#......#...#.#..##
.##......#...........#.......##
....#.#...#..#.#.......##......
....#..##..#.....#........##...
...#...#..#.#.#....#.........#.
#....##.#....#..##.............
.#......##......#.#.##.......#.
.......#...#....#.##......#....
..##..........#.....#.#......#.
#..##.....#..........##..#.#...
....#.#.......#.#.....#.....#..
##.....#..#.....##...#.....#..#
...#.#..#...#..............#...
...............#..#............
.#.......#......#........##....
..#......#..##..####.....#...#.
.#.##.#.#..#..##..##...........
...##.............#.....#..#...
.##.....#..#.#......##........#
##....#.............#...#......
......#.....###...........##...
.#.#...#.............##..#..###
..#.##.##...#.....#...........#
.....#.....##...#...#........#.
........#..##.......##.....#...
.#........####.......#.#...#...
...#..........#......##........
.......#......#..##..#...#.....
..#...........#.#.#..#.#.#.....
#..........#....#....###.#.....
....#.................#...##...
#....#.###......#..#.....#...##
.#.......##.....###.....#...#..
....##............#...........#
...#.#.#.........#...#..#..#..#
.....#..###.................#..
.#.....#.....#....###.#..#...#.
................#...#..........
..#....#..##....#.##........#..
....##....#...........#..#.....
...##......###.......#...#.....
.......##............#......#.#
#####.....#..#.###..#.#........
#.##.##..#.......#....#........
....###..#.#.#......###.#......
....#....#.....##.#..#....#...#
....#.....#.#...##.##.#.#....#.
.........#.#.###.#.....#.......
.#....#.......#..##...#....#...
...####...##.#.....#...........
#.....#.....#..........##..#...
................#.#.#......#...
.#...#.......#..#............#.
.##.#.......#..#....#.....#....
.#...#..#.....#..............#.

120
2020/03/main.rs Normal file
View File

@ -0,0 +1,120 @@
use std::error::Error;
use grid::{Grid, GridLine};
#[path = "../utils/mod.rs"]
mod utils;
fn main() -> Result<(), Box<dyn Error>> {
let lines = utils::parse_input_lines::<GridLine>()?;
let grid = Grid::from(lines)?;
println!("Total trees on slope going 3 right 1 down: {}", grid.count_trees_on_slope(3, 1));
let mut product = 1u32;
let slopes = vec![
(1, 1),
(3, 1),
(5, 1),
(7, 1),
(1, 2)
];
for (down, right) in slopes {
product *= grid.count_trees_on_slope(down, right);
}
println!("Product of all attempted slopes: {}", product);
Ok(())
}
mod grid {
use std::ops::Rem;
use std::str::FromStr;
use crate::utils::GenericError;
pub struct Grid {
data: Vec<GridLine>,
}
impl Grid {
pub fn from(data: Vec<GridLine>) -> Result<Self, GenericError> {
let expected_length = data.first().ok_or(GenericError::new("There are no lines."))?.data.len();
if data.iter().any(|line| line.data.len() != expected_length) {
return Err(GenericError::new("Every line must be the same length."));
}
Ok(Grid { data })
}
pub fn get_at(&self, x: i32, y: i32) -> Option<Cell> {
let line = self.data.get(y as usize)?;
Some(line.get_at(x))
}
pub fn count_trees_on_slope(&self, step_x: i32, step_y: i32) -> u32 {
let mut x = 0;
let mut y = 0;
let mut trees = 0u32;
loop {
match self.get_at(x, y) {
None => break,
Some(Cell::Open) => {}
Some(Cell::Tree) => {
trees += 1;
}
}
x += step_x;
y += step_y;
}
return trees;
}
}
pub struct GridLine {
data: Vec<Cell>,
}
impl GridLine {
fn new(data: Vec<Cell>) -> Self {
GridLine { data }
}
fn get_at(&self, x: i32) -> Cell {
let len = self.data.len() as i32;
let x = x.rem(len);
let x = if x < 0 { len + x } else { x };
return *self.data.get(x as usize).unwrap();
}
}
#[derive(Copy, Clone)]
pub enum Cell {
Open,
Tree,
}
impl Cell {
fn from(c: char) -> Result<Self, GenericError> {
match c {
'.' => Ok(Cell::Open),
'#' => Ok(Cell::Tree),
_ => Err(GenericError::new(format!("Invalid character: {}", c).as_str()))
}
}
}
impl FromStr for GridLine {
type Err = GenericError;
fn from_str(s: &str) -> Result<Self, Self::Err> {
s.chars().map(Cell::from).collect::<Result<Vec<Cell>, GenericError>>().map(GridLine::new)
}
}
}

View File

@ -6,3 +6,11 @@ edition = "2021"
[[bin]]
name = "01"
path = "01/main.rs"
[[bin]]
name = "02"
path = "02/main.rs"
[[bin]]
name = "03"
path = "03/main.rs"

View File

@ -1,4 +1,5 @@
use std::error::Error;
use std::fmt::{Debug, Display, Formatter};
use std::fs::File;
use std::io;
use std::io::{BufRead, BufReader};
@ -12,3 +13,27 @@ pub fn read_input_lines() -> Result<Vec<String>, io::Error> {
pub fn parse_input_lines<T : FromStr>() -> Result<Vec<T>, Box<dyn Error>> where <T as FromStr>::Err : Into<Box<dyn Error>> {
return read_input_lines()?.iter().map(|line| line.parse::<T>()).collect::<Result<Vec<T>, T::Err>>().map_err(Into::into);
}
pub struct GenericError {
pub message: String
}
impl GenericError {
pub fn new(message: impl Into<String>) -> GenericError {
GenericError { message: message.into() }
}
}
impl Display for GenericError {
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
write!(f, "Parse error: {}", self.message)
}
}
impl Debug for GenericError {
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
Display::fmt(self, f)
}
}
impl Error for GenericError {}

View File

@ -38,6 +38,8 @@ The versions should not matter, but I used Visual Studio 2019 with `MSVC v142 (1
| 2015 | 01 | NASM x64 |
| 2015 | 02 | NASM x64 |
| 2020 | 01 | Rust |
| 2020 | 02 | Rust |
| 2020 | 03 | Rust |
| 2021 | 01 | Kotlin |
| 2021 | 02 | Kotlin |
| 2021 | 03 | Kotlin |