Skip Navigation

Posts
53
Comments
877
Joined
2 yr. ago

New account since lemmyrs.org went down, other @Deebsters are available.

  • What to do with people who jump the queue?

    How do you turn a pig into a sausage?

  • Yeah, it's quite a mean trick really - kinda a big middle finger to anyone who does TDD

  • Are words in a poem lyrics?

  • Mild spoilers ahead, but you're reading the solutions thread.

    I was just doing some preliminary checking of the data on my phone with Nushell (to see how much my ageing laptop would suffer) when I discovered there weren't any non trivial cases.

    Normally I get the test data working before trying the input data, this is definitely teaching me the value of investigating the data before heading down into the code mines.

    Unfortunately I can't get the second star yet because I missed a few days.

  • Sounds like perhaps unified codes would be the answer to that problem!

  • Interesting stuff, thanks for writing it up.

    I did know that US codes weren't standardised, partially because the video covers it - perhaps I should have phrased it as "a police code" to be more technically correct. Edit: or bothered to check the video so could have written "Philadelphia police code" - but then I would have missed out on your reply.

  • If you read the article, you learn that the authorities never properly searched any of these freighters - that's probably a more sensible place to start.

  • Ask vague questions, get oddly specific answers, I guess.

  • https://www.youtube.com/watch?v=laZpTO7IFtA is worth the 15 minutes, but the TL;DW is that the kids are just using it as an in-joke marker (i.e. the phrase is a shibboleth), but its origin is in lyrics* by the rapper Skrilla referring to police codes for a dead body.

    * are rapped words lyrics?

  • nushell

    I'm still travelling, so another phone attempt. Jet lag says sleep, so just part 1 for now:

     nu
        
    def part1 [filename: string] {
      mut input = open $filename | lines |
        each { parse '{index}: {children}' | update children { split row " " } | first } |
        insert paths { null }
      print $"Data loaded, ($input | length) devices"
    
      $input = explore-path $input you
      $input | where index == you | get 0.paths
    }
    
    def explore-path [devices, start: string] {
      print $"Exploring ($start)"
      let dev = $devices | where index == $start | first
      if ($dev | get paths) != null {
        print "Already explored"
        return $devices
      }
    
      # Shadow with mutable version
      mut devices = $devices
      mut paths = 0
      let is_out = $dev | get children | where ($it == out) | is-not-empty
      if $is_out {
        print $"Found an out device: ($start)"
        $paths = 1
      } else {
        for child in ($dev | get children ) {
          $devices = explore-path $devices $child
          $paths += $devices | where index == $child | get 0.paths
        }
      }
    
      # Shadow with immutable... wtf
      let paths = $paths
      print $"Setting paths for ($start) to ($paths)"
      $devices = $devices | update paths { |row| if $row.index == $start {  
    $paths } else {} }
       $devices
    }
    
      
  • Firefox does seem to be clearing out their old bugs (another example is MKV support) but perhaps it's buses arriving together and not due to some policy.

  • I can't code today because of travel, just as the one that might run slow enough to geek out on benchmarking the various options. Does seem like it's a bit of a jump in difficulty from previous days.

  • We’re still preparing the notes for this release, and will post them here when they are ready. Please check back later.

    Oh come on guys

    edit: they're up now

  • That is surprising about Firefox - you'd have thought something that literally just runs JavaScript would be able to beat Firefox with all the UI, sandboxing, etc. 30% is a huge margin.

  • For part one and likely part 2 you don't need to do all 499500 comparisons, you could split the grid into boxes and only search adjacent ones. E.g. z / 10 = which decile and look at z, z-1, z+1 (and the same for x and y). Less work for the processor, more work for you, and of course, sqrt (which you can also probably skip) is so efficient on modern chips that the overhead of this eats a chunk of the benefits (depending on how low-level your language is).

  • Rust

    Part 1 took a decent while, partly life getting in the way, partly as I was struggling with some Rust things like floats not being sortable without mucking around, plus some weird bugs trying to get collect to do everything that I eventually just rewrote to avoid.

    I found the noisy_float crate which let me wrap f64 as a "real" r64 which meant no NaN which meant Ord which meant sort_by_cached_key() and the rest worked.

    I'd planned how to partition the closest neighbour search, but the whole thing runs in 24ms so I didn't bother.

     rust
        
    type Id = usize;
    type Connection = (Id, Id);
    type Circuit = HashSet<Id>;
    
    #[derive(PartialEq)]
    struct Point {
        x: usize,
        y: usize,
        z: usize,
    }
    
    impl FromStr for Point {
        type Err = Report;
    
        fn from_str(s: &str) -> Result<Self> {
            let mut parts = s.split(',');
            Ok(Point {
                x: parts.next().ok_or_eyre("missing x")?.parse()?,
                y: parts.next().ok_or_eyre("missing y")?.parse()?,
                z: parts.next().ok_or_eyre("missing z")?.parse()?,
            })
        }
    }
    
    impl Point {
        fn distance(&self, other: &Point) -> R64 {
            let dist = ((
                self.x.abs_diff(other.x).pow(2) +
                self.y.abs_diff(other.y).pow(2) +
                self.z.abs_diff(other.z).pow(2)) as f64)
                .sqrt();
            r64(dist)
        }
    }
    
      
     rust
        
    struct Boxes(Vec<Point>);
    
    impl Boxes {
        fn closest(&self) -> Vec<Connection> {
            let mut closest = (0..self.0.len())
                .flat_map(|a| ((a + 1)..self.0.len()).map(move |b| (a, b)))
                .collect::<Vec<_>>();
    
            closest.sort_by_cached_key(|&(a, b)| self.0[a].distance(&self.0[b]));
            closest
        }
    
        fn connect_all(&self, p1_threshold: usize) -> Result<(usize, usize)> {
            let mut circuits: Vec<Circuit> = (0..self.0.len())
                .map(|id| HashSet::from_iter(iter::once(id)))
                .collect();
    
            let mut closest = self.closest().into_iter();
            let mut p1 = 0;
            let mut n = 0;
            loop {
                n += 1;
                let (a, b) = closest.next().ok_or_eyre("All connected already")?;
                let a_circ = circuits.iter().position(|c| c.contains(&a));
                let b_circ = circuits.iter().position(|c| c.contains(&b));
                match (a_circ, b_circ) {
                    (None, None) => {
                        circuits.push(vec![a, b].into_iter().collect());
                    }
                    (None, Some(idx)) => {
                        circuits[idx].insert(a);
                    }
                    (Some(idx), None) => {
                        circuits[idx].insert(b);
                    }
                    (Some(a_idx), Some(b_idx)) if a_idx != b_idx => {
                        let keep_idx = a_idx.min(b_idx);
                        let rem_idx = a_idx.max(b_idx);
    
                        let drained = circuits.swap_remove(rem_idx);
                        // this position is still valid since we removed the later set
                        circuits[keep_idx].extend(drained);
                    }
                    _ => { /* already connected to same circuit */ }
                };
    
                if n == p1_threshold {
                    circuits.sort_by_key(|set| set.len());
                    circuits.reverse();
                    p1 = circuits.iter().take(3).map(|set| set.len()).product();
                }
                if circuits.len() == 1 {
                    let p2 = self.0[a].x * self.0[b].x;
                    return Ok((p1, p2));
                }
            }
        }
    }
    
      
  • I normally use the "most appropriate" size, but this year I'm just using usize everywhere and it's a lot more fun. So far I haven't found any problem where it ran too slow and the problem was in my implementation and not my algorithm choice.

  • Ah, it took me looking at your updated Codeberg version to understand this - you looked at part two in the opposite way than I did but it comes out the same in the end (and yours is much more efficient).

  • Home Automation @lemmyonline.com

    Haier hits Home Assistant plugin dev with takedown notice

    www.bleepingcomputer.com /news/security/haier-hits-home-assistant-plugin-dev-with-takedown-notice/
  • Taskmaster @feddit.uk

    Taskmaster Champion of Champions 3 is on tonight!

    www.scotsman.com /arts-and-culture/film-and-tv/taskmaster-champion-of-champions-3-watch-contestants-winners-4474924
  • Gentoo @lemmy.cafe

    Bard does Gentoo dirty

  • Gentoo Linux @reddthat.com

    Bard does Gentoo dirty

  • Taskmaster @feddit.uk

    Taskmaster's New Year Treat 2024

  • Taskmaster @feddit.uk

    Other countries' Taskmaster shows?

  • Fake History Porn @lemmy.world

    Muhammad Ali uses his “Ali shuffle” to beat Cleveland Williams in this historic snow angel match (1966)

  • datahoarder @lemmy.ml

    Lost Doctor Who episodes found – but owner is reluctant to hand them to BBC

    www.theguardian.com /tv-and-radio/2023/nov/11/lost-doctor-who-episodes-found-owner-reluctant-to-hand-them-to-bbc
  • Taskmaster @feddit.uk

    Taskmaster S16 E8 I’ve Never Packed a Boot

  • Programmer Humor @programming.dev

    Bingo

  • Navidrome Music Server (Unofficial) @discuss.tchncs.de

  • AbandonedPorn @reddthat.com

    Abandoned Wooden Windmill in Belogradchik, Bulgaria

  • EAC and foobar2000 @lemm.ee

    Foobar2000 2.0 worth updating to?