Gobbel2000

joined 10 months ago
[–] Gobbel2000 7 points 17 hours ago (1 children)

Lemmy is open source, so you can easily download its source code and open it in neovim :)

[–] Gobbel2000 59 points 2 days ago (3 children)

The article only summarizes it shortly, but the parallels to the Munich Agreement from 1938 are really scary.

Hitler's aim was to take over all of Czechoslovakia by breaking it apart. The subject of the Munich Agreement was the Sudetenland, the region bordering Germany. Before there were some votes and local political forces expressing the wish of the German minority in the Sudetenland to create an independent state (See the parallels with DNR, LNR and Crimea). This was used by Hitler to justify taking over the region. Suddenly it wasn't about independence anymore, but about inclusion into Germany.

The Czechoslovakian government in Prague obviously hated the idea, but they were not invited to the talks in Munich. Only afterwards were they made aware of the decision that would be imposed on their nation. Who was invited was fellow fascist Mussolini from Italy, as well as France and UK, who gave in and signed this agreement, giving international support to Germany just taking over parts of neighboring nations.

Their reasoning was, if they were to disagree, Hitler would assert his will by force and take Czechoslovakia militarily, starting a large European war (that is also the reason Prague was forced to accept the decision: the alternative was a war they could never win, they could not count on any outside help). This was the so-called appeasement policy by the UK. They bought "peace" in exchange for territories they didn't own but felt the right to decide over. We all know how this heavily-priced peace turned out. At most it gave the allied forces one more year to prepare for WWII.

[–] Gobbel2000 15 points 3 days ago

Reminds me of the beginning of Zelenskys presidency in 2020 when he refused the deal with Trump to investigate Hunter Biden. Trump really believes he can get Ukraine to do anything for him.

[–] Gobbel2000 6 points 4 days ago (7 children)

Just wait until they figure out how much carbon is captured by planting a tree.

[–] Gobbel2000 16 points 1 week ago (3 children)

Only if you convert rubles by "purchase power parity" as opposed to the market rate, which seems like a weird way to manipulate data to fit some narrative.

[–] Gobbel2000 6 points 1 week ago (1 children)

Funny idea, but good luck getting this leaky bucket from the Baltic sea all the way via Gibraltar to the Black sea.

[–] Gobbel2000 2 points 1 month ago

Nah, this photo is definitely not from this year.

[–] Gobbel2000 5 points 1 month ago

Pretty sure that's correct. You can also see the elevated U2 in the background.

[–] Gobbel2000 7 points 1 month ago (1 children)

"Fraunce" is my favorite part of this map.

 

Now that Advent of Code 2024 has concluded, I wanted to get people's opinion on what puzzles they especially liked looking back. This could be because of the puzzle mechanics, the description, because you are especially proud of your solution that day, or for any other reason.

Feel free to answer even if you only saw part of the puzzles.

My picks would be:

  • 14 (Restroom Redoubt, robots moving into christmas tree shape). Even though it caught me off-guard in the moment, I did like that part 2 had this very imprecise requirement for once. Definitely made for varied, creative solutions.
  • 15 (Warehouse Woes, robots pushing boxes) The second part was a fairly big complexity spike with just a minor change in the tasks. Basically a form of simulation where the hard part is finding a good data representation for the setup. I liked this one because debugging was such a visual process for me, by printing the grids.
  • 17 (Chronospatial Computer, running a machine code) For me the first really tricky one, but still doable. These assembly puzzles are just neat. A lot of computation is started with a pretty small input, and the task is basically to really understand how this "computer" works.

What have been your favorites?

[–] Gobbel2000 2 points 1 month ago

Rust

Nice ending for this year. Lock and key arrays are just added together and all elements must be <= 5. Merry Christmas!

Solution

fn flatten_block(block: Vec<Vec<bool>>) -> [u8; 5] {
    let mut flat = [0; 5];
    for row in &block[1..=5] {
        for x in 0..5 {
            if row[x] {
                flat[x] += 1;
            }
        }
    }
    flat
}

fn parse(input: &str) -> (Vec<[u8; 5]>, Vec<[u8; 5]>) {
    let mut locks = Vec::new();
    let mut keys = Vec::new();
    for block_s in input.split("\n\n") {
        let block: Vec<Vec<bool>> = block_s
            .lines()
            .map(|l| l.bytes().map(|b| b == b'#').collect::<Vec<bool>>())
            .collect();
        assert_eq!(block.len(), 7);
        // Lock
        if block[0].iter().all(|e| *e) {
            locks.push(flatten_block(block));
        } else {
            keys.push(flatten_block(block));
        }
    }
    (locks, keys)
}

fn part1(input: String) {
    let (locks, keys) = parse(&input);
    let mut count = 0u32;
    for l in locks {
        for k in &keys {
            if l.iter().zip(k).map(|(li, ki)| li + ki).all(|sum| sum <= 5) {
                count += 1;
            }
        }
    }
    println!("{count}");
}

fn part2(_input: String) {
    println!("⭐");
}

util::aoc_main!();

Also on github

[–] Gobbel2000 2 points 1 month ago

Rust + Pen and Paper

Yikers. Part 2 took a while, staring at this diagram for hours. Eventually I noticed that each of these blocks has two pairs of (XOR, AND) gates sharing the same inputs (and inputs aren't changed). So I matched up these pairs based on a distance metric of how much needs to be swapped to fit together. This helped me identify 4 blocks with errors, the rest was solved using pen and paper (one block is missing as it became apparent at that point):

shaky diagrams for full adder with wrong outputs

There is also some code, but do yourself and me a favor and don't look at it. While it does turn up the correct solution, it probably won't with any other input, especially not the examples.

[–] Gobbel2000 2 points 2 months ago* (last edited 2 months ago)

Rust

Finding cliques in a graph, which is actually NP-comlete. For part two I did look up how to do it and implemented the Bron-Kerbosch algorithm. Adding the pivoting optimization improved the runtime from 134ms to 7.4ms, so that is definitely worth it (in some sense, of course I already had the correct answer without pivoting).

Solution

use rustc_hash::{FxHashMap, FxHashSet};

fn parse(input: &str) -> (Vec<Vec<usize>>, FxHashMap<&str, usize>) {
    let mut graph = Vec::new();
    let mut names: FxHashMap<&str, usize> = FxHashMap::default();
    for l in input.lines() {
        let (vs, ws) = l.split_once('-').unwrap();
        let v = *names.entry(vs).or_insert_with(|| {
            graph.push(vec![]);
            graph.len() - 1
        });
        let w = *names.entry(ws).or_insert_with(|| {
            graph.push(vec![]);
            graph.len() - 1
        });
        graph[v].push(w);
        graph[w].push(v);
    }
    (graph, names)
}

fn part1(input: String) {
    let (graph, names) = parse(&input);
    let mut triples: FxHashSet<[usize; 3]> = FxHashSet::default();
    for (_, &v) in names.iter().filter(|(name, _)| name.starts_with('t')) {
        for (i, &u) in graph[v].iter().enumerate().skip(1) {
            for w in graph[v].iter().take(i) {
                if graph[u].contains(w) {
                    let mut triple = [u, v, *w];
                    triple.sort();
                    triples.insert(triple);
                }
            }
        }
    }
    println!("{}", triples.len());
}

// Bron-Kerbosch algorithm for finding all maximal cliques in a graph
fn bron_kerbosch(
    graph: &[Vec<usize>],
    r: &mut Vec<usize>,
    mut p: FxHashSet<usize>,
    mut x: FxHashSet<usize>,
) -> Vec<Vec<usize>> {
    if p.is_empty() && x.is_empty() {
        return vec![r.to_vec()];
    }
    let mut maximal_cliques = Vec::new();
    let Some(&u) = p.iter().next() else {
        return maximal_cliques;
    };
    let mut p_pivot = p.clone();
    for w in &graph[u] {
        p_pivot.remove(w);
    }
    for v in p_pivot {
        let pn = graph[v].iter().filter(|w| p.contains(w)).copied().collect();
        let xn = graph[v].iter().filter(|w| x.contains(w)).copied().collect();
        r.push(v);
        let new_cliques = bron_kerbosch(graph, r, pn, xn);
        r.pop();
        maximal_cliques.extend(new_cliques);
        p.remove(&v);
        x.insert(v);
    }
    maximal_cliques
}

fn part2(input: String) {
    let (graph, names) = parse(&input);
    let p = (0..graph.len()).collect();
    let mut r = Vec::new();
    let maximal_cliques = bron_kerbosch(&graph, &mut r, p, FxHashSet::default());
    let maximum_clique = maximal_cliques
        .iter()
        .max_by_key(|clique| clique.len())
        .unwrap();
    let mut lan_names: Vec<&str> = names
        .iter()
        .filter(|(_, v)| maximum_clique.contains(v))
        .map(|(name, _)| *name)
        .collect();
    lan_names.sort_unstable();
    println!("{}", lan_names.join(","));
}

util::aoc_main!();

Also on github

 

linked from: https://programming.dev/post/19267200

In its current plan, the EU commission intends to cut €27 million in funding for Free Software. The article has a link to a questionnaire that you can fill out and express your opinion about the plan. I believe non-EU citizens can participate as well.

 

In its current plan, the EU commission intends to cut €27 million in funding for Free Software. The article has a link to a questionnaire that you can fill out and express your opinion about the plan. I believe non-EU citizens can participate as well.

 

While the exact details of this vulnerability are still investigated (see here if you want to catch up on the topic), I wanted to share some of the thoughts I had regarding to what this incident means for the wider open source ecosystem.

TL;DR: To summarize, these are the main points I found remarkable in this entire development:

  • A backdoor was snuck relatively openly into an open source project
  • It was done by a somewhat trusted maintainer
  • The target was not even xz itself, but rather sshd through an obscure chain of dependencies
  • Luckily, it was discovered within a few weeks before the backdoored version was widely adopted

Obviously, there are many examples of security vulnerabilities occurring in open source software. But these are usually due to oversights or mistakes of most likely well-meaning developers that end up enabling the possibility for critical exploits. In the case of the xz backdoor however, it was obviously constructed with malicious intent and high effort towards a precise target. Does anybody know of another vulnerability ending up in a high-profile open source project that is similar in that sense?

This was only possible because the malicious actor under the pseudonym Jia Tan had direct write access to the xz repository as a maintainer. I don't think it is too unreasonable that with enough time and effort, anyone can get maintenance access to openly developed projects like xz. That is part of the beauty of the democratic process in open source. But what this incident shows is that for projects that are as widely used as xz, even changes coming from seemingly trusted maintainers should be properly reviewed. I don't mean to say that the original maintainer Lasse Collin has any fault in this matter, or that he should have prevented it, this is too much of a burden to expect from a single person. Instead I think the large tech corporations should put more resources into vetting these kind of open source projects that much of their infrastructure so heavily relies on (in fact, this backdoor seems to mainly target servers).

Even just looking at the source code, the backdoor was very cleverly hidden in testing binaries for the compression algorithm. These things are always easy to say in hindsight, but I do believe that a closer review of the build system shenanigans used to install the backdoor would have at least raised some questions. There was just too much luck involved in the discovery of the backdoor with someone noticing ssh access taking 0.5 seconds longer than usual.

This isn't really news, but this incident again shows that just like a chain is only as strong as its weakest link, a program is only as strong as its weakest dependency. The fact that the backdoor just hooks into the dynamic library loading process and completely hijacks authorization functions of ssh from inside xz is pretty scary. Maybe this will encourage developers to be more careful and sparing with adding dependencies. However to be honest, up until recently I would have pretty blindly trusted xz to be a very safe dependency due to its popularity and relatively simple use-case.

By opening a backdoor into ssh servers, this is a very critical issue, and there was clearly a lot of time and effort put into making it seem innocuous and hard to detect. I'm very glad that it got found and patched by the time it did, but it does leave me wondering what else is out there. It would be illusionary to think that such attack vectors always get found out eventually.

view more: next ›