• 1 Post
  • 18 Comments
Joined 1 year ago
cake
Cake day: June 6th, 2023

help-circle








  • Rust

    github codeberg gitlab

    First tried a really slow brute force, but after waiting many minutes heard others talk of Karger's Algorithm, so I implemented that.

    use rand::prelude::*;
    use std::collections::HashSet;
    
    type Graph = (V, E);
    
    type V = HashSet<String>;
    type E = Vec<(String, String)>;
    
    fn parse_input(input: &str) -> Graph {
        let mut vertices = HashSet::new();
        let mut edges = Vec::new();
    
        for line in input.trim().lines() {
            let mut it = line.split(':');
    
            let left = it.next().unwrap();
            vertices.insert(left.to_owned());
    
            for right in it.next().unwrap().trim().split_whitespace() {
                vertices.insert(right.to_owned());
                edges.push((left.to_owned(), right.to_owned()));
            }
        }
    
        (vertices, edges)
    }
    
    fn part1(input: &str) -> usize {
        let (vertices, edges) = parse_input(input);
    
        let mut rng = rand::thread_rng();
    
        // Karger's Algorithm
        loop {
            let mut vertices = vertices.clone();
            let mut edges = edges.clone();
            while vertices.len() > 2 {
                let i = rng.gen_range(0..edges.len());
                let (v1, v2) = edges[i].clone();
    
                // contract the edge
                edges.swap_remove(i);
                vertices.remove(&v1);
                vertices.remove(&v2);
    
                let new_v = format!("{}:{}", v1, v2);
                vertices.insert(new_v.clone());
    
                for (e1, e2) in edges.iter_mut() {
                    if *e1 == v1 || *e1 == v2 {
                        *e1 = new_v.clone()
                    }
                    if *e2 == v1 || *e2 == v2 {
                        *e2 = new_v.clone()
                    }
                }
    
                // remove loops
                let mut j = 0;
                while j < edges.len() {
                    let (e1, e2) = &edges[j];
                    if e1 == e2 {
                        edges.swap_remove(j);
                    } else {
                        j += 1;
                    }
                }
            }
    
            if edges.len() == 3 {
                break vertices
                    .iter()
                    .map(|s| s.split(':').count())
                    .product::<usize>();
            }
        }
    }
    

  • Rust

    github: https://github.com/Treeniks/advent-of-code/blob/master/2023/day24/rust/src/main.rs

    codeberg: https://codeberg.org/Treeniks/advent-of-code/src/branch/master/2023/day24/rust/src/main.rs

    gitlab: https://gitlab.com/Treeniks/advent-of-code/-/blob/master/2023/day24/rust/src/main.rs

    Had to look on reddit for how to solve part 2. Wasn't happy with the idea of using something like Z3, so I ended up brute force guessing the velocity, solving for the position and time and seeing if those are correct.

    Lots of unintelligible calculations for solving the equation systems in the code that I just prepared on paper and transferred over.


  • Zig

    https://github.com/Treeniks/advent-of-code/blob/master/2023/day22/zig/src/main.zig

    (or on codeberg if you don't like to use github: https://codeberg.org/Treeniks/advent-of-code/src/branch/master/2023/day22/zig/src/main.zig )

    Every time I use Zig, I love the result, but I hate writing it. The language is just a little too inflexible for quick and dirty solutions to quickly try out an idea or debug print something useful, but once you're done and have a result, it feels quite complete.


  • Rust

    https://github.com/Treeniks/advent-of-code/blob/master/2023/day21/rust/src/main.rs

    I reused my Grid struct from day 17 for part 1, just to realize that I'll need to expand the grid for part 2 so I awkwardly hacked it to be a Vec> instead of a linear Vec.

    I solved task 2 by reading through the reddit thread and trying to puzzle together what I was supposed to do. Took me a while to figure it out, even with literally looking at other people's solutions. I wrote a lengthy comment about it for anyone that's still struggling, but I honestly still don't really understand why it works. I think I wouldn't have solved it if I didn't end up looking at other solutions. Not a fan of the "analyze the input and notice patterns in them" puzzles.







  • I love wezterm, primarily because it is cross platform. The most important factor to me is being able to use the same one on Windows, Mac and Linux, because I use all three on a regular basis and don't want to maintain multiple configs. However, wezterm currently has a bug that prevents it from opening on Wayland+Nvidia which forces me to use something else on Linux. None of the other ones get close imo.


  • This talk is technically not about Zig, but he still shows many of Zig's strengts: https://youtu.be/aPWFLkHRIAQ?si=b-rf_oMremovedIvAdq

    To me, Zig is a language that tries to be like C, but with all the decades of mistakes removed, or rather with modern knowledge of good language design in mind, while keeping as much compatibility as possible, as to not require a lot of work for the transition as Rust did. Thus, if you're working in a C codebase, you'll be good to go to integrate Zig in as little as an hour. They also have by far the cleanest solution to macros and generics that I have seen yet (although I miss my type classes).