summaryrefslogtreecommitdiff
path: root/2023/day3/src
diff options
context:
space:
mode:
Diffstat (limited to '2023/day3/src')
-rw-r--r--2023/day3/src/lib.rs184
1 files changed, 184 insertions, 0 deletions
diff --git a/2023/day3/src/lib.rs b/2023/day3/src/lib.rs
new file mode 100644
index 0000000..e70b994
--- /dev/null
+++ b/2023/day3/src/lib.rs
@@ -0,0 +1,184 @@
+#[derive(Debug)]
+struct Digit {
+ value: u32,
+ s: usize, // start index
+ f: usize, // start end
+}
+
+#[derive(Debug)]
+struct Symbol {
+ elem: char,
+ i: usize,
+}
+
+fn parse(s: &String, border: &i32) -> (Vec<Digit>, Vec<Symbol>) {
+ let n: i32 = s.len() as i32;
+ let chars = s.chars().rev();
+
+ let mut pos1: i32 = -1;
+ let mut pos2: i32 = -1;
+ let mut incr = 1;
+ let mut digit = 0;
+ let mut symbols: Vec<Symbol> = vec![];
+ let mut digits: Vec<Digit> = vec![];
+ let mut multiples: Vec<usize> = vec![];
+
+ for i in 0..150 {
+ multiples.push(*border as usize * i);
+ }
+
+ for (idx, ch) in chars.enumerate() {
+ if ch.is_digit(10) {
+ if pos2 == -1 {
+ pos2 = n - idx as i32;
+ } else if multiples.contains(&idx) && pos2 != -1 {
+ pos1 = n - idx as i32;
+ digits.push(Digit {
+ value: digit,
+ s: pos1 as usize,
+ f: pos2 as usize,
+ });
+ incr = 1;
+ digit = 0;
+ pos2 = n - idx as i32;
+ }
+ digit += ch.to_digit(10).unwrap() * incr;
+ incr *= 10;
+ }
+
+ if !ch.is_digit(10) {
+ if digit != 0 {
+ pos1 = n - idx as i32;
+ if pos1 == -1 || pos2 == -1 {
+ panic!("wtf is that?!");
+ }
+ digits.push(Digit {
+ value: digit,
+ s: pos1 as usize,
+ f: pos2 as usize,
+ })
+ }
+ pos2 = -1;
+ incr = 1;
+ digit = 0;
+
+ if ch != '.' {
+ symbols.push(Symbol {
+ elem: ch,
+ i: n as usize - idx,
+ })
+ }
+ }
+ }
+ if digit != 0 {
+ pos1 = 0;
+ if pos2 == -1 {
+ panic!("wtf is that?!");
+ }
+ digits.push(Digit {
+ value: digit,
+ s: pos1 as usize,
+ f: pos2 as usize,
+ })
+ }
+
+ digits.reverse();
+ symbols.reverse();
+
+ (digits, symbols)
+}
+
+pub fn part1(input: &str) -> u32 {
+ let mut res: u32 = 0;
+
+ let arr: String = input.split('\n').map(|c| c.chars()).flatten().collect();
+ let border = input.find('\n').unwrap() as i32;
+
+ let (digits, symbols) = parse(&arr, &border);
+
+ let mut valid_s: Vec<usize> = Vec::new();
+ for symbol in &symbols {
+ valid_s.push(symbol.i - 1);
+ }
+
+ for digit in digits {
+ // 13 with border=10
+ // --> 12, 14, 2, 3, 4, 22, 23, 24
+ let mut discover: Vec<usize> = vec![];
+ for i in digit.s..digit.f {
+ let mut js = vec![
+ i as i32 - 1,
+ i as i32 + 1,
+ i as i32 - border - 1,
+ i as i32 - border - 0,
+ i as i32 - border + 1,
+ // i as i32 + border - 1,
+ i as i32 + border - 0,
+ i as i32 + border + 1,
+ ];
+
+ if digit.f as i32 + 1 >= border {
+ js.push(i as i32 + border - 1);
+ }
+
+ for j in js {
+ if j >= 0
+ && !((digit.s..digit.f).contains(&(j as usize)))
+ && !(discover.contains(&(j as usize)))
+ {
+ discover.push(j as usize);
+ }
+ }
+ }
+
+ for d in &discover {
+ if valid_s.contains(&d) {
+ res += digit.value;
+ break;
+ }
+ }
+
+ discover.sort();
+ }
+
+ res
+}
+
+// pub fn part2(input: &str) -> u32 {
+// let mut res: u32 = 0;
+//
+// res
+// }
+
+#[cfg(test)]
+mod tests {
+ use super::*;
+
+ #[test]
+ fn example_part1() {
+ let input = include_str!("../example.txt");
+ let result = part1(input);
+ assert_eq!(result, 4361);
+ }
+
+ #[test]
+ fn input_part1() {
+ let input = include_str!("../input.txt");
+ let result = part1(input);
+ assert_eq!(result, 556367);
+ }
+ //
+ // #[test]
+ // fn example_part2() {
+ // let input = include_str!("../example.txt");
+ // let result = part2(input);
+ // assert_eq!(result, 2286);
+ // }
+ //
+ // #[test]
+ // fn input_part2() {
+ // let input = include_str!("../input.txt");
+ // let result = part2(input);
+ // assert_eq!(result, 71585);
+ // }
+}