• 1 Post
  • 206 Comments
Joined 2 years ago
cake
Cake day: August 6th, 2023

help-circle















  • Rust

    Finally having some fun with iters. I think part 2 came out nicely once I figured I can rotate the whole input to get numbers that look like ours.

    Q: Anyone have any tips how to reason about the intermediate types in a long iter chain? I’m currently placing dummy maps, and on occasion, even printing the values from them when I get too stuck.

    the code
    use std::fs::File;
    use std::io::{BufReader, Lines};
    
    #[allow(dead_code)]
    pub fn part1(input: Lines<BufReader<File>>) {
        let mut input = input
            .map_while(Result::ok)
            .map(|line| {
                line.split_ascii_whitespace()
                    .map(|s| s.to_string())
                    .collect::<Vec<String>>()
            })
            .collect::<Vec<Vec<String>>>();
    
        let ops = input.pop().unwrap();
        let values = input
            .iter()
            .map(|v| {
                v.iter()
                    .map(|v| v.parse::<i64>().unwrap())
                    .collect::<Vec<i64>>()
            })
            .collect::<Vec<Vec<i64>>>();
    
        let transposed: Vec<Vec<i64>> = (0..values[0].len())
            .map(|i| values.iter().map(|row| row[i]).collect())
            .collect();
    
        let mut sum = 0;
        for i in 0..ops.len() {
            let op: &str = &ops[i];
            match op {
                "+" => {
                    sum += transposed[i].iter().sum::<i64>();
                }
                "*" => {
                    sum += transposed[i].iter().product::<i64>();
                }
                _ => panic!("Invalid operation"),
            }
        }
    
        println!("sum = {}", sum)
    }
    
    #[allow(dead_code)]
    pub fn part2(input: Lines<BufReader<File>>) {
        let mut input = input
            .map_while(Result::ok)
            .map(|line| line.chars().collect::<Vec<char>>())
            .collect::<Vec<Vec<char>>>();
    
        let ops = input
            .pop()
            .unwrap()
            .iter()
            .map(|c| c.to_string())
            .filter(|s| s != " ")
            .collect::<Vec<String>>();
    
        let transposed: Vec<i64> = (0..input[0].len())
            .map(|i| input.iter().map(|row| row[i]).collect())
            .map(|vec: String| vec.trim().to_string())
            .map(|s| {
                if s.len() == 0 {
                    0
                } else {
                    s.parse::<i64>().unwrap()
                }
            })
            .collect();
    
        let groups = transposed
            .into_iter()
            .fold(Vec::new(), |mut acc: Vec<Vec<i64>>, num| {
                if num == 0 {
                    if let Some(last) = acc.last_mut() {
                        if !last.is_empty() {
                            acc.push(Vec::new());
                        }
                    } else {
                        acc.push(Vec::new());
                    }
                } else {
                    if acc.is_empty() {
                        acc.push(Vec::new());
                    }
    
                    acc.last_mut().unwrap().push(num);
                }
    
                acc
            });
    
        let mut sum = 0;
        for i in 0..ops.len() {
            let op: &str = &ops[i];
            match op {
                "+" => {
                    sum += groups[i].iter().sum::<i64>();
                }
                "*" => {
                    sum += groups[i].iter().product::<i64>();
                }
                _ => panic!("Invalid operation"),
            }
        }
    
        println!("sum = {}", sum)
    }
    
    



  • I’m still struggling to learn Rust, and also to figure out a good solution to these problems, but here’s mine anyway:

    #[allow(dead_code)]
    pub fn part1(input: Lines<BufReader<File>>) {
        let mut sum = 0;
        for line in input.map_while(Result::ok) {
            let total = find_joltage(line.as_bytes(), 2, false);
            let res = str::from_utf8(total.as_slice()).unwrap();
    
            sum += res.parse::<u32>().unwrap();
        }
    
        println!("{}", sum);
    }
    
    #[allow(dead_code)]
    pub fn part2(input: Lines<BufReader<File>>) {
        let mut sum = 0;
        for (_, line) in input.map_while(Result::ok).enumerate() {
            let total = find_joltage(line.as_bytes(), 12, false);
            let res = str::from_utf8(total.as_slice()).unwrap();
    
            sum += res.parse::<u64>().unwrap();
        }
    
        println!("{}", sum);
    }
    
    fn find_joltage(b: &[u8], size: usize, debug: bool) -> Vec<u8> {
        if size == 0 {
            return vec![];
        }
    
        let mut max: u8 = 0;
        let mut max_i = 0;
        for i in (0..=b.len() - size).rev() {
            if b[i] >= max {
                max = b[i];
                max_i = i;
            }
        }
    
        if debug {
            println!("max = {}, i = {}", max as char, max_i);
        }
        let mut rest = find_joltage(&b[max_i + 1..], size - 1, debug);
    
        rest.insert(0, max);
        rest
    }