@CameronDev - eviltoast
  • 61 Posts
  • 2.17K Comments
Joined 2 years ago
cake
Cake day: June 18th, 2023

help-circle



  • Rust

    pt2: 71ms.

    Wow. What a step up in difficulty. Using the geo library got me the right answer, and quickly in terms of code, but run time was terrible (2m+). Switching back to simply checking if a wall is entirely outside the rectangle got me a much faster win, and the code isn’t too bad either.

    Code and algorithm description

    (A wall is outside if its entirely to the left OR entirely to the right of the rect) OR (entirely above OR entirely below).

       fn check_wall_outside(
            c: &(&Coord, &Coord),
            top: usize,
            bottom: usize,
            left: usize,
            right: usize,
        ) -> bool {
            if (c.0.x <= left && c.1.x <= left) || (c.0.x >= right && c.1.x >= right) {
                return true;
            }
            if (c.0.y <= top && c.1.y <= top) || (c.0.y >= bottom && c.1.y >= bottom) {
                return true;
            }
            false
        }
    
       #[test]
        fn test_y2025_day9_part2_mine1() {
            let input = include_str!("../../input/2025/day_9.txt");
            let coords = input
                .lines()
                .map(|l| {
                    let halfs = l.split_once(',').unwrap();
                    Coord {
                        x: halfs.0.parse::<usize>().unwrap(),
                        y: halfs.1.parse::<usize>().unwrap(),
                    }
                })
                .collect::<Vec<Coord>>();
    
            let mut walls = vec![];
    
            for i in 0..coords.len() {
                let first = &coords[i];
                let second = coords.get(i + 1).unwrap_or(coords.first().unwrap());
    
                walls.push((first, second));
            }
    
            let mut max_area = 0;
            for i in 0..coords.len() {
                let first = &coords[i];
                'next_rect: for j in i..coords.len() {
                    let second = &coords[j];
                    if first == second {
                        continue 'next_rect;
                    }
                    let area = (first.x.abs_diff(second.x) + 1) * (first.y.abs_diff(second.y) + 1);
                    if area < max_area {
                        continue 'next_rect;
                    }
    
                    let (top, bottom) = if first.y > second.y {
                        (second.y, first.y)
                    } else {
                        (first.y, second.y)
                    };
    
                    let (left, right) = if first.x > second.x {
                        (second.x, first.x)
                    } else {
                        (first.x, second.x)
                    };
    
                    for wall in &walls {
                        if !check_wall_outside(wall, top, bottom, left, right) {
                            continue 'next_rect;
                        }
                    }
    
                    max_area = area;
                }
            }
            assert_eq!(max_area, 1542119040);
            println!("Part 2: {}", max_area);
        }
    












  • Proof of work means that your client has to do some “work” in order to gain access. It typically means a challenge that can’t be trivially solved, but can be trivially verified.

    For example, the challenge may be something to the effect of:

    “Give me a string, that when hashed by md5, results in a hash that ends in 1234”.

    Your browser can then start bruteforcing until it finds a string (should take a few seconds max), and then it can pass the string back to the server. The server can verify with a single hash, and you’re in.

    Its not wildly different to crypto mining, but the difficulty is much lower for antibot, as it needs to be solveable in seconds by even low end devices.




  • Rust

    Not an easy one, mostly because I messed up my merge circuits function (Pop/remove first circuit, load into second, but the pop/remove messed up the indexes, so I was merging the wrong thing).

    After getting that it was all good. Pt2 was trivial once pt1 was solved.

    spoiler
        #[derive(Debug)]
        struct Circuits {
            circuits: Vec<Vec<usize>>,
        }
    
        impl Circuits {
            fn find_circuit(&mut self, i: usize) -> Option<usize> {
                for (j, c) in &mut self.circuits.iter().enumerate() {
                    if c.contains(&i) {
                        return Some(j);
                    }
                }
                None
            }
    
            fn new_circuit(&mut self, i: usize, j: usize) {
                self.circuits.push(vec![i, j]);
            }
    
            fn join_circuits(&mut self, i: usize, j: usize) {
                let mut other = self.circuits.get(j).unwrap().clone();
                self.circuits.get_mut(i).unwrap().append(&mut other);
                self.circuits.remove(j);
            }
    
            fn append_circuit(&mut self, c: usize, x: usize) {
                self.circuits.get_mut(c).unwrap().push(x);
            }
    
            fn top_three(&mut self) -> Vec<usize> {
                let mut sizes = self
                    .circuits
                    .iter()
                    .map(|c| c.len())
                    .collect::<Vec<usize>>();
                sizes.sort();
                sizes.reverse();
                sizes[0..3].to_vec()
            }
        }
    
        type Pole = (isize, isize, isize);
    
        fn dist_poles(p1: &Pole, p2: &Pole) -> f32 {
            sqrt(
                ((p1.0 - p2.0) * (p1.0 - p2.0)) as f32
                    + ((p1.1 - p2.1) * (p1.1 - p2.1)) as f32
                    + ((p1.2 - p2.2) * (p1.2 - p2.2)) as f32,
            )
        }
    
        #[test]
        fn test_y2025_day8_part1() {
            let input = include_str!("../../input/2025/day_8.txt");
            let poles = input
                .lines()
                .map(|l| {
                    let [x, y, z] = l
                        .splitn(3, ",")
                        .map(|c| c.parse::<isize>().unwrap())
                        .collect::<Vec<isize>>()[..]
                    else {
                        panic!();
                    };
                    (x, y, z)
                })
                .collect::<Vec<Pole>>();
            let len = poles.len();
    
            let mut circuits: Circuits = Circuits { circuits: vec![] };
    
            let mut pairs = vec![];
    
            for i in 0..len {
                let first = poles.get(i).unwrap();
                for j in i + 1..len {
                    if i == j {
                        continue;
                    }
                    let second = poles.get(j).unwrap();
                    let dist = dist_poles(first, second);
                    pairs.push((dist, i, j));
                }
            }
    
            pairs.sort_by(|a, b| {
                if a.0 < b.0 {
                    Ordering::Less
                } else {
                    Ordering::Greater
                }
            });
    
            for (dist, a, b) in pairs[0..1000].iter() {
                let first_circuit = circuits.find_circuit(*a);
                let second_circuit = circuits.find_circuit(*b);
    
                match (first_circuit, second_circuit) {
                    (None, None) => {
                        circuits.new_circuit(*a, *b);
                    }
                    (Some(c), None) => {
                        circuits.append_circuit(c, *b);
                    }
                    (None, Some(c)) => {
                        circuits.append_circuit(c, *a);
                    }
                    (Some(c1), Some(c2)) => {
                        if c1 != c2 {
                            circuits.join_circuits(c1, c2);
                        }
                    }
                }
            }
    
            assert_eq!(circuits.top_three().iter().product::<usize>(), 66640)
        }