Untitled
unknown
rust
2 years ago
8.4 kB
10
Indexable
use std::str::Split;
const ROW_LENGTH: usize = 140;
const ROW_COUNT: usize = 140;
pub fn day3(data: String){
let mut lines = data.split("\n");
let mut slots = get_slots(lines);
let mut num_finished: bool = false;
let mut current_num: Vec<Slot> = Vec::new();
let mut gears: Vec<GearConnection> = Vec::new();
let mut result = 0;
let mut gear_score: i32 = 0;
for y in 0..ROW_COUNT{
for x in 0..ROW_LENGTH{
let slot = slots[get_idx(x, y)];
// Not currently building a number
if !slot.is_num && num_finished {
continue;
}
else if !slot.is_num && !num_finished{
num_finished = true;
let connected = is_connected_number(¤t_num, &slots);
let gear_connection = is_connected_gear(¤t_num, &slots);
let mut number = 0;
if connected{
let mut count = current_num.len();
for s in current_num.clone(){
match count {
3 => {
number += s.number * 100;
}
2 => {
number += s.number * 10;
}
1 => {
number += s.number;
}
_ => {}
}
count -= 1;
}
result += number;
}
if gear_connection.0 {
let mut found = false;
for mut g in &mut gears{
if g.gear.x == gear_connection.1 && g.gear.y == gear_connection.2{
g.connected_nums.push(number);
found = true;
}
}
if !found{
let mut g = GearConnection { gear: slots[get_idx(gear_connection.1, gear_connection.2)], connected_nums: Vec::new(), ratio: 0 };
g.connected_nums.push(number);
gears.push(g);
}
}
current_num.clear();
}
else{
current_num.push(slot.clone());
num_finished = false;
}
}
}
println!("Part 1 Result: {result}");
for mut gear in gears{
if gear.connected_nums.len() == 2{
gear.ratio = gear.connected_nums[0] * gear.connected_nums[1];
gear_score += gear.ratio;
}
}
println!("Part 2 Result: {gear_score}");
}
struct GearConnection{
gear: Slot,
connected_nums: Vec<i32>,
ratio: i32,
}
fn is_connected_gear(number: &Vec<Slot>, slots: &Vec<Slot>) -> (bool, usize, usize){
for n in number{
if n.x != 0{
// Left
if slots[get_idx(n.x - 1, n.y)].is_gear{
return (true, n.x - 1, n.y);
}
// Top left
if n.y != 0 {
if slots[get_idx(n.x - 1, n.y - 1)].is_gear{
return (true, n.x - 1, n.y - 1);
}
}
// Bot left
if n.y != ROW_LENGTH-1 {
if slots[get_idx(n.x - 1, n.y + 1)].is_gear{
return (true, n.x - 1, n.y + 1);
}
}
}
if n.x != ROW_LENGTH {
// Right
if slots[get_idx(n.x + 1, n.y)].is_gear{
return (true, n.x + 1, n.y);
}
// Top right
if n.y != 0 {
if slots[get_idx(n.x + 1, n.y - 1)].is_gear{
return (true, n.x + 1, n.y - 1);
}
}
// Bot right
if n.y != ROW_LENGTH-1 {
if slots[get_idx(n.x + 1, n.y + 1)].is_gear{
return (true, n.x + 1, n.y + 1);
}
}
}
if n.y != 0 {
// Top
if slots[get_idx(n.x, n.y - 1)].is_gear{
return (true, n.x, n.y - 1);
}
}
if n.y != ROW_COUNT-1 {
// Bot
if slots[get_idx(n.x, n.y + 1)].is_gear{
return (true, n.x, n.y + 1);
}
}
}
return (false, 0, 0);
}
fn is_connected_number(number: &Vec<Slot>, slots: &Vec<Slot>) -> bool{
let mut connected = false;
for n in number{
if n.x != 0{
// Left
if !slots[get_idx(n.x - 1, n.y)].is_num && !slots[get_idx(n.x - 1, n.y)].is_blank{
connected = true;
}
// Top left
if n.y != 0 {
if !slots[get_idx(n.x - 1, n.y - 1)].is_num && !slots[get_idx(n.x - 1, n.y - 1)].is_blank{
connected = true;
}
}
// Bot left
if n.y != ROW_LENGTH-1 {
if !slots[get_idx(n.x - 1, n.y + 1)].is_num && !slots[get_idx(n.x - 1, n.y + 1)].is_blank{
connected = true;
}
}
}
if n.x != ROW_LENGTH {
// Right
if !slots[get_idx(n.x + 1, n.y)].is_num && !slots[get_idx(n.x + 1, n.y)].is_blank{
connected = true;
}
// Top right
if n.y != 0 {
if !slots[get_idx(n.x + 1, n.y - 1)].is_num && !slots[get_idx(n.x + 1, n.y - 1)].is_blank{
connected = true;
}
}
// Bot right
if n.y != ROW_LENGTH-1 {
if !slots[get_idx(n.x + 1, n.y + 1)].is_num && !slots[get_idx(n.x + 1, n.y + 1)].is_blank{
connected = true;
}
}
}
if n.y != 0 {
// Top
if !slots[get_idx(n.x, n.y - 1)].is_num && !slots[get_idx(n.x, n.y - 1)].is_blank{
connected = true;
}
}
if n.y != ROW_COUNT-1 {
// Bot
if !slots[get_idx(n.x, n.y + 1)].is_num && !slots[get_idx(n.x, n.y + 1)].is_blank{
connected = true;
}
}
}
return connected;
}
fn get_slots(lines: Split<&str>) -> Vec<Slot>{
let mut slots: Vec<Slot> = Vec::new();
for (y, line) in lines.enumerate(){
for (x, symbol) in line.chars().enumerate(){
if symbol.is_ascii_digit() {
let slot = Slot{
x,
y,
is_num: true,
is_blank: false,
number: symbol.to_digit(10).unwrap() as i32,
is_gear: false,
};
slots.push(slot);
continue;
}
else if symbol != '.' {
let mut gear = false;
if symbol == '*' {
gear = true;
}
let slot = Slot{
x,
y,
is_num: false,
is_blank: false,
number: -1,
is_gear: gear,
};
slots.push(slot);
continue;
}
else{
let slot = Slot{
x,
y,
is_num: false,
is_blank: true,
number: -1,
is_gear: false,
};
slots.push(slot);
continue;
}
}
}
return slots;
}
fn get_idx(x: usize, y: usize) -> usize{
return (y * ROW_LENGTH) + x;
}
#[derive(Clone)]
#[derive(Debug, Copy)]
struct Slot {
x: usize,
y: usize,
is_num: bool,
is_blank: bool,
number: i32,
is_gear: bool,
}Editor is loading...
Leave a Comment