Untitled
unknown
rust
2 years ago
8.4 kB
6
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