Skip to content

Commit

Permalink
Solve Rust for 17/1,2 and 16/1
Browse files Browse the repository at this point in the history
  • Loading branch information
code-shoily committed Aug 17, 2024
1 parent f7b8a1e commit b8094b4
Show file tree
Hide file tree
Showing 8 changed files with 256 additions and 8 deletions.
7 changes: 5 additions & 2 deletions native/aoc/src/lib.rs
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
pub mod util {
pub mod io_helpers;
pub mod parsers;
pub mod runner;
pub mod result;
pub mod runner;
}

// All modules for year 2015
Expand All @@ -15,13 +15,16 @@ pub mod year_2015 {

// All modules for year 2016
pub mod year_2016 {
mod day_16_01;
mod day_16_02;
mod day_16_04;
pub mod solver;
}

// All modules for year 2017
pub mod year_2017 {
mod day_17_01;
mod day_17_02;
mod day_17_04;
pub mod solver;
}
Expand Down Expand Up @@ -64,10 +67,10 @@ pub mod year_2023 {
pub mod solver;
}

use rustler::Error;
use util::io_helpers::read_input_from_resources;
use util::result::Solution;
use util::runner::Runner;
use rustler::Error;

#[rustler::nif]
fn solve(year: i16, day: i8) -> Result<Solution, Error> {
Expand Down
2 changes: 1 addition & 1 deletion native/aoc/src/util/io_helpers.rs
Original file line number Diff line number Diff line change
Expand Up @@ -28,4 +28,4 @@ pub fn validate_input(year: i16, day: i8) -> (bool, bool) {
}

(year_ok, day_ok)
}
}
9 changes: 4 additions & 5 deletions native/aoc/src/util/result.rs
Original file line number Diff line number Diff line change
@@ -1,9 +1,8 @@
use rustler::NifTaggedEnum;


#[derive(NifTaggedEnum)]
pub enum Solution {
BothString((String, String)),
BothInt32((i32, i32)),
BothUSize((usize, usize)),
}
BothString((String, String)),
BothInt32((i32, i32)),
BothUSize((usize, usize)),
}
140 changes: 140 additions & 0 deletions native/aoc/src/year_2016/day_16_01.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,140 @@
use std::collections::HashSet;

pub fn solve_16_01(raw_input: String) -> (i32, i32) {
let input = process_input(&raw_input);

let mut position = Position::new();
input.iter().for_each(|instruction| {
position.step(instruction);
});

let part_1 = position.location.manhattan_distance();
let part_2 = position.repeat.unwrap().manhattan_distance();

(part_1, part_2)
}

fn process_input(raw_input: &str) -> Vec<(Direction, i32)> {
raw_input
.trim()
.split(", ")
.map(|i| {
let direction = match &i[0..=0] {
"R" => Direction::Right,
"L" => Direction::Left,
value => panic!("Invalid instruction {value}"),
};
let steps: i32 = i[1..].parse::<i32>().unwrap();

(direction, steps)
})
.collect()
}

enum Facing {
North,
East,
South,
West,
}

enum Direction {
Left,
Right,
}

#[derive(Debug)]
struct Point {
pub x: i32,
pub y: i32,
}

impl Point {
pub fn manhattan_distance(&self) -> i32 {
self.x.abs() + self.y.abs()
}
}

struct Position {
facing: Facing,
location: Point,
visits: HashSet<(i32, i32)>,
repeat: Option<Point>,
}

impl Position {
pub fn new() -> Position {
Position {
facing: Facing::North,
location: Point { x: 0, y: 0 },
visits: vec![(0, 0)].into_iter().collect(),
repeat: Option::None,
}
}

pub fn step(&mut self, instruction: &(Direction, i32)) {
let (direction, steps) = instruction;

match (direction, &self.facing) {
(Direction::Left, Facing::North) => self.move_to((-1, 0), *steps),
(Direction::Left, Facing::East) => self.move_to((0, 1), *steps),
(Direction::Left, Facing::South) => self.move_to((1, 0), *steps),
(Direction::Left, Facing::West) => self.move_to((0, -1), *steps),
(Direction::Right, Facing::North) => self.move_to((1, 0), *steps),
(Direction::Right, Facing::East) => self.move_to((0, -1), *steps),
(Direction::Right, Facing::South) => self.move_to((-1, 0), *steps),
(Direction::Right, Facing::West) => self.move_to((0, 1), *steps),
}
}

fn move_to(&mut self, delta: (i32, i32), steps: i32) {
let (x_diff, y_diff) = delta;

self.facing = Self::facing_for_delta(delta);

for _ in 0..steps {
let Point { x, y } = self.location;
self.location = match x_diff {
0 => Point { x, y: y + y_diff },
_ => Point { x: x + x_diff, y },
};

self.update_visits();
}
}

fn facing_for_delta(delta: (i32, i32)) -> Facing {
match delta {
(-1, 0) => Facing::West,
(0, 1) => Facing::North,
(1, 0) => Facing::East,
(0, -1) => Facing::South,
_ => unreachable!(),
}
}

fn update_visits(&mut self) {
if self.repeat.is_none() {
let Point { x, y } = self.location;
if self.visits.contains(&(x, y)) {
self.repeat = Some(Point { x, y });
}
self.visits.insert((x, y));
}
}
}

#[cfg(test)]
mod tests {
use super::*;
use crate::util::io_helpers::read_input_from_resources;

#[test]
fn test_result_16_01() {
let (year, day) = (2016, 1);
let expected_result = (253, 126);

let raw_input = read_input_from_resources(year, day, false);
assert_eq!(solve_16_01(raw_input), expected_result);
}
}
2 changes: 2 additions & 0 deletions native/aoc/src/year_2016/solver.rs
Original file line number Diff line number Diff line change
@@ -1,12 +1,14 @@
use crate::util::result::Solution;

use super::day_16_01::solve_16_01;
use super::day_16_02::solve_16_02;
use super::day_16_04::solve_16_04;

const YEAR: i16 = 2016;

pub fn run(day: i8, input_data: String) -> Solution {
match day {
1 => Solution::BothInt32(solve_16_01(input_data)),
2 => Solution::BothString(solve_16_02(input_data)),
4 => Solution::BothUSize(solve_16_04(input_data)),
_ => panic!("Year {YEAR} day {day} has not been solved."),
Expand Down
46 changes: 46 additions & 0 deletions native/aoc/src/year_2017/day_17_01.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
pub fn solve_17_01(raw_input: String) -> (i32, i32) {
let processed_input = process(raw_input);

(part_1(&processed_input), part_2(&processed_input))
}

fn process(raw_input: String) -> Vec<i32> {
raw_input
.trim()
.chars()
.map(|c| (c as i32) - 0x30)
.collect()
}

fn part_1(input: &[i32]) -> i32 {
captcha(input, 1)
}

fn part_2(input: &[i32]) -> i32 {
captcha(input, input.len() / 2)
}

fn captcha(input: &[i32], by: usize) -> i32 {
let mut rotated = input.to_owned();
rotated.rotate_left(by);
input
.iter()
.zip(rotated.iter())
.filter_map(|(a, b)| (a == b).then_some(*a))
.sum()
}

#[cfg(test)]
mod tests {
use super::*;
use crate::util::io_helpers::read_input_from_resources;

#[test]
fn test_result_17_01() {
let (year, day) = (2017, 1);
let expected_result = (1089, 1156);

let raw_input = read_input_from_resources(year, day, false);
assert_eq!(solve_17_01(raw_input), expected_result);
}
}
54 changes: 54 additions & 0 deletions native/aoc/src/year_2017/day_17_02.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
use itertools::Itertools;

pub fn solve_17_02(raw_input: String) -> (i32, i32) {
let input = process(&raw_input);
(part_1(&input), part_2(&input))
}

fn process(input_data: &str) -> Vec<Vec<i32>> {
input_data.trim().split('\n').map(parse_row).collect()
}

fn parse_row(line: &str) -> Vec<i32> {
line.split('\t')
.map(|cell| cell.parse::<i32>().unwrap())
.sorted()
.collect()
}

fn part_1(input_data: &[Vec<i32>]) -> i32 {
input_data
.iter()
.map(|row| row.last().unwrap() - row.first().unwrap())
.sum()
}

fn part_2(input_data: &[Vec<i32>]) -> i32 {
input_data
.iter()
.map(|values| {
for i in 0..values.len() {
for j in i + 1..values.len() {
if values[j] % values[i] == 0 {
return values[j] / values[i];
}
}
}
unreachable!()
})
.sum()
}

#[cfg(test)]
mod tests {
use super::*;
use crate::util::io_helpers::read_input_from_resources;

#[test]
fn test_result_17_02() {
let raw_input = read_input_from_resources(2017, 2, false);
let expected_result = (32020, 236);

assert_eq!(solve_17_02(raw_input), expected_result);
}
}
4 changes: 4 additions & 0 deletions native/aoc/src/year_2017/solver.rs
Original file line number Diff line number Diff line change
@@ -1,11 +1,15 @@
use crate::util::result::Solution;

use super::day_17_01::solve_17_01;
use super::day_17_02::solve_17_02;
use super::day_17_04::solve_17_04;

const YEAR: i16 = 2017;

pub fn run(day: i8, input_data: String) -> Solution {
match day {
1 => Solution::BothInt32(solve_17_01(input_data)),
2 => Solution::BothInt32(solve_17_02(input_data)),
4 => Solution::BothUSize(solve_17_04(input_data)),
_ => panic!("Year {YEAR} day {day} has not been solved."),
}
Expand Down

0 comments on commit b8094b4

Please sign in to comment.