Skip Navigation

InitialsDiceBearhttps://github.com/dicebear/dicebearhttps://creativecommons.org/publicdomain/zero/1.0/„Initials” (https://github.com/dicebear/dicebear) by „DiceBear”, licensed under „CC0 1.0” (https://creativecommons.org/publicdomain/zero/1.0/)CA
Posts
23
Comments
76
Joined
2 yr. ago

Cooking @lemmy.world

Cutting Board Recommendations (Machine Washable, No Microplastics)

DACH - Deutschsprachige Community für Deutschland, Österreich, Schweiz @feddit.org

Grammatikfrage: Das Wort "Junges"

  • I'm with you on Clair Obscur (I need to check tbe spelling literally every time I write that). I usually don't risk the money on new games or things not-on-sale, but after all the positivity, I decided to go for it. And what a game! I'm still in Act 2, and I am loving it so far.

  • I'm playing Wylde Flowers. It's a farm sim game with witchcraft, but I mostly like it because it is extremely low-stress. No inventory management, no time pressure to do things, just building a farm and talking to / romancing people.

    I picked it up after I got to the point in Subnautica where you have too much contact with leviathans, and I need something calm and relaxing. Maybe I'll make more Subnautica progress soon, though :).

    Edit: Spelling

  • I finally tried resocketting the cable, and I've only seen the issue a little bit since, but not as extreme. But I'm not sure if it's real or just my perception ;). I'll keep an eye on it. Thanks for the idea!

  • München/Munich @discuss.tchncs.de

    Sauna Kleidung in München?

    Fairphone @lemmy.ml

    Phantom touches on FP4?

  • When I toured the concentration camp at Dachau some years ago, the tour guide was very clear on this point: people did elect the Nazis.

    In 1932, the Nazi party became the largest party in the German parliament, with 37.3% of the vote. It is true that it was not mandatory to make Hitler chancellor, but as the head of the largest party, it would have been expected.

    The Nazi party received massive support in democratic elections, where the expectation of the voters would have been that if the Nazi party gained enough seats, Hitler would become chancellor.

    This is an important point to me, as it shows that it is possible for democratic elections to result in a fascist government that dismantles democracy. Ignoring this historical example prevents us from applying the lesson to new situations.

  • Hah. I tried doing some research about what this kind of drain is called, but I have no idea. I've never had a drain like this before, but I guess it must not be too rare?

    In my case, the issue is that it starts to stink a lot. We had a plumber out a few years ago, and he opened that thing up and used a plunger to remove a ton of hair. He then suggested we wash it out every now and again, but I haven't been able to do it for a while now, since I can't get that thing open.

  • Not at all a silly question! I have tried, yes. Also, I've been able to remove it before, but the last time I put it in, I really jammed it in, I guess. There are no threads, so the turning is really just about generating force.

  • No Stupid Questions @lemmy.world

    Is there a device to help turn stoppers with an o-ring?

    CSCareerQuestions @programming.dev

    Advice on going self-employed / contractor in Germany?

  • Rust

    I was stuck for a while, even after getting a few hints, until I read the problem more closely and realized: there is only one non-cheating path, and every free space is on it. This means that the target of any shortcut is guaranteed to be on the shortest path to the end.

    This made things relatively simple. I used Dijkstra to calculate the distance from the start to each space. I then looked at every pair of points: if they are a valid distance away from each other, check how much time I would save jumping from one to the next. If that amount of time is in the range we want, then this is a valid cheat.

    https://gitlab.com/bricka/advent-of-code-2024-rust/-/blob/main/src/days/day20.rs?ref_type=heads

  • Rust

    I essentially used flood fill to collect each region. Part 1 was then relatively easy: for each point, check how many neighbors are outside of the region.

    Part 2 took me forever, and I ended up looking for hints online, where I discovered that an easy way to count the number of sides is to instead count the number of corners. Doing this for "normal" corners (e.g. in a square) was relatively easy, but "reverse corners" took me a long time. Corners like here what we see in the NE corner of the first C in the third row here:

     
        
    ....
    ..C.
    ..CC
    ...C
    
      

    I'm more or less happy with my solution, but my brain is now totally fried.

    https://gitlab.com/bricka/advent-of-code-2024-rust/-/blob/main/src/days/day12.rs?ref_type=heads

     rust
        
    use std::collections::HashSet;
    
    use crate::grid::{Coordinate, Direction, Grid};
    use crate::solver::DaySolver;
    
    fn perimeter_score(c: Coordinate, grid: &MyGrid) -> usize {
        let plant_type = grid[c];
    
        Direction::orthogonal_iter()
            .map(|d| grid.neighbor_in_direction(c, d))
            .map(|c_opt| match c_opt {
                None => 1,
                Some(c) => if grid[c] == plant_type {
                    0
                } else {
                    1
                }
            })
            .sum()
    }
    
    type MyGrid = Grid<char>;
    
    struct Region {
        #[allow(dead_code)]
        plant_type: char,
        coordinates: HashSet<Coordinate>,
    }
    
    impl Region {
        fn new(plant_type: char, coordinates: HashSet<Coordinate>) -> Region {
            Region { plant_type, coordinates }
        }
    
        fn iter(&self) -> impl Iterator<Item = &Coordinate> {
            self.coordinates.iter()
        }
    
        fn part1_score(&self, grid: &MyGrid) -> usize {
            self.coordinates.len() * self.coordinates.iter().map(|c| perimeter_score(*c, grid)).sum::<usize>()
        }
    
        fn part2_score(&self, grid: &MyGrid) -> usize {
            let area = self.coordinates.len();
            let sides = self.number_of_corners(grid);
    
            area * sides
        }
    
        fn number_of_corners(&self, grid: &MyGrid) -> usize {
            self.coordinates.iter().cloned()
                .map(|coordinate| {
                    // How many corners do we have from here?
                    // println!("Checking {}", border_coordinate);
    
                    let corner_count = Direction::diagonal_iter()
                        .filter(|corner_direction| {
                            // Either:
                            // 1) Both neighbor directions are not 100% in the region
                            // 2) Both neighbors are in the region, but the corner itself isn't
    
                            let corner_in_region = match grid.neighbor_in_direction(coordinate, *corner_direction) {
                                None => false,
                                Some(c) => self.coordinates.contains(&c),
                            };
    
                            let both_neighbors_not_in_region = corner_direction.neighbor_directions().iter()
                                .all(|direction| match grid.neighbor_in_direction(coordinate, *direction) {
                                    None => true,
                                    Some(c) => !self.coordinates.contains(&c),
                                });
    
                            let both_neighbors_in_region = corner_direction.neighbor_directions().iter()
                                .all(|direction| match grid.neighbor_in_direction(coordinate, *direction) {
                                    None => false,
                                    Some(c) => self.coordinates.contains(&c),
                                });
    
                            both_neighbors_not_in_region || (both_neighbors_in_region && !corner_in_region)
                        })
                        .count();
                    // println!("Corner count = {}", corner_count);
                    corner_count
                })
                .sum()
        }
    }
    
    fn parse_input(input: String) -> MyGrid {
        input.lines()
            .map(|line| line.chars().collect())
            .collect::<Vec<Vec<char>>>()
            .into()
    }
    
    fn find_region_at(grid: &MyGrid, start: Coordinate) -> Region {
        let plant_type = grid[start];
        let mut coordinates = HashSet::new();
        let mut frontier = vec![start];
    
        while let Some(coordinate) = frontier.pop() {
            if grid[coordinate] == plant_type  && !coordinates.contains(&coordinate) {
                coordinates.insert(coordinate);
                frontier.extend(grid.orthogonal_neighbors_iter(coordinate));
            }
        }
    
        Region::new(plant_type, coordinates)
    }
    
    fn find_regions(grid: &MyGrid) -> Vec<Region> {
        let mut visited_coordinates: HashSet<Coordinate> = HashSet::new();
        let mut regions = vec![];
    
        for coordinate in grid.coordinates_iter() {
            if !visited_coordinates.contains(&coordinate) {
                let region = find_region_at(grid, coordinate);
                visited_coordinates.extend(region.iter().cloned());
                regions.push(region);
            }
        }
    
        regions
    }
    
    pub struct Day12Solver;
    
    impl DaySolver for Day12Solver {
        fn part1(&self, input: String) -> usize {
            let grid = parse_input(input);
            let regions = find_regions(&grid);
    
            regions.into_iter()
                .map(|region| region.part1_score(&grid))
                .sum()
        }
    
        fn part2(&self, input: String) -> usize {
            let grid = parse_input(input);
            let regions = find_regions(&grid);
    
            regions.into_iter()
                .map(|region| region.part2_score(&grid))
                .sum()
        }
    }
    
      
  • Rust

     rust
        
    use std::collections::{HashMap, HashSet};
    
    use crate::solver::DaySolver;
    use crate::grid::{Coordinate, Grid};
    
    fn add_distance(coordinate: Coordinate, distance: (i64, i64)) -> Option<Coordinate> {
        coordinate.try_add(distance)
    }
    
    fn sub_distance(coordinate: Coordinate, distance: (i64, i64)) -> Option<Coordinate> {
        coordinate.try_sub(distance)
    }
    
    fn part2_possible_antinodes<F>(
        grid: &Grid<Option<char>>,
        coordinate: Coordinate,
        distance: (i64, i64),
        op: F,
        mut accumulator: Vec<Coordinate>
    ) -> Vec<Coordinate>
    where F: Fn(Coordinate, (i64, i64)) -> Option<Coordinate> {
        match op(coordinate, distance).filter(|c| grid.get(*c).is_some()) {
            None => accumulator,
            Some(next_coord) => {
                accumulator.push(next_coord);
                part2_possible_antinodes(grid, next_coord, distance, op, accumulator)
            }
        }
    }
    
    trait Pairable<T> {
        fn pairs(&self) -> Vec<(&T, &T)>;
    }
    
    impl<T> Pairable<T> for HashSet<T> {
        fn pairs(&self) -> Vec<(&T, &T)> {
            let v: Vec<&T> = self.iter().collect();
    
            let mut p = vec![];
    
            for i in 0..v.len() {
                let thing1 = v[i];
    
                for thing2 in &v[i+1..] {
                    p.push((thing1, *thing2));
                }
            }
    
            p
        }
    }
    
    fn parse_input(input: String) -> (Grid<Option<char>>, HashMap<char, HashSet<Coordinate>>) {
        let g: Grid<Option<char>> =
            input.lines()
            .map(|line| line.chars()
                 .map(|c| if c == '.' {
                     None
                 } else {
                     Some(c)
                 }).collect::<Vec<Option<char>>>()
            )
            .collect::<Vec<Vec<Option<char>>>>()
            .into();
    
        let mut freq_to_coords: HashMap<char, HashSet<Coordinate>> = HashMap::new();
    
        for (coord, freq_opt) in g.iter() {
            match freq_opt {
                None => (),
                Some(freq) => {
                    freq_to_coords.entry(*freq)
                        .and_modify(|coords| {
                            coords.insert(coord);
                        })
                        .or_insert(HashSet::from([coord]));
                }
            }
        }
    
        (g, freq_to_coords)
    }
    
    pub struct Day08Solver;
    
    impl DaySolver for Day08Solver {
        fn part1(&self, input: String) -> usize {
            let (g, freq_to_coords) = parse_input(input);
    
            let mut antinodes: HashSet<Coordinate> = HashSet::new();
    
            for (_, coords) in freq_to_coords {
                // println!("Freq = {}", freq);
                for (c1, c2) in coords.pairs() {
                    let distance = c1.xy_distance_to(c2);
                    let possible_antinodes: Vec<Coordinate> = [c1.try_sub(distance), c2.try_add(distance)].into_iter()
                        .flat_map(|co| co.filter(|c| g.get(*c).is_some()))
                        .collect();
    
                    // println!("Pair = ({},{}), antinodes = {:?}", c1, c2, possible_antinodes);
    
                    for antinode in possible_antinodes {
                        antinodes.insert(antinode);
                    }
                }
            }
    
            antinodes.len()
        }
    
        fn part2(&self, input: String) -> usize {
            let (g, freq_to_coords) = parse_input(input);
    
            let mut antinodes: HashSet<Coordinate> = HashSet::new();
    
            for (freq, coords) in freq_to_coords {
                println!("Freq = {}", freq);
                for (c1, c2) in coords.pairs() {
                    let distance = c1.xy_distance_to(c2);
    
                    let possible_antinodes: Vec<Coordinate> = [
                        part2_possible_antinodes(&g, *c1, distance, add_distance, vec![*c1]),
                        part2_possible_antinodes(&g, *c1, distance, sub_distance, vec![*c1]),
                        part2_possible_antinodes(&g, *c2, distance, add_distance, vec![*c2]),
                        part2_possible_antinodes(&g, *c2, distance, sub_distance, vec![*c2]),
                    ].into_iter().flatten().collect();
    
                    println!("Pair = ({},{}), antinodes = {:?}", c1, c2, possible_antinodes);
    
                    for antinode in possible_antinodes {
                        antinodes.insert(antinode);
                    }
                }
            }
    
            antinodes.len()
        }
    }
    
      

    https://gitlab.com/bricka/advent-of-code-2024-rust/-/blob/main/src/days/day08.rs?ref_type=heads

  • No Stupid Questions @lemmy.world

    How modern is it to have "sympathetic" portrayals of Hell?

    Garmin @lemmy.world

    Is it worth getting a Fenix 7 now?

    Garmin @lemmy.world

    The Fenix 8 is now available

    boardgames @feddit.de

    How to make Machi Koro more "fair"?

    Garmin @lemmy.world

    When are new smartwatches announced?

    No Stupid Questions @lemmy.world

    Why do passports need to be signed to be valid?

    No Stupid Questions @lemmy.world

    Why can animals eat grass that they have pooped on, but humans would get sick?

    München/Munich @discuss.tchncs.de

    Empfehlung für Steuerberater:in für Freiberufler/Nebenjob?

    Germany @feddit.de

    Vote on new citizenship law tomorrow?

    Emacs @lemmy.ml

    Emacs Meetup at CCC

    München/Munich @discuss.tchncs.de

    Schottischer Ceilidh am 18.11 im Hirschgarten

    Emacs @lemmy.ml

    Changelog when I update with straight.el?

    No Stupid Questions @lemmy.world

    What does it mean to "get low" or "drop it down"?

    DeGoogle Yourself @lemmy.ml

    Calling and SMS via Data (Google Voice Alternative?)