Day 6: Trash Compactor

Megathread guidelines

  • Keep top level comments as only solutions, if you want to say something other than a solution put it in a new post. (replies to comments can be whatever)
  • You can send code in code blocks by using three backticks, the code, and then three backticks or use something such as https://topaz.github.io/paste/ if you prefer sending it through a URL

FAQ

you are viewing a single comment's thread
view the rest of the comments
[โ€“] 1 point 10 months ago*

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)
}

  • source