jonah's recent activity

  1. Comment on Kansas City Chiefs score game-winning touchdown to beat San Francisco 49ers in overtime in ~sports.american_football

    jonah
    Link
    As a Chiefs fan myself, I always hated that last year’s SB ended on a questionably timed pass interference call. And it gave all the haters an asterisk next to the win like we didn’t ruin the...

    As a Chiefs fan myself, I always hated that last year’s SB ended on a questionably timed pass interference call. And it gave all the haters an asterisk next to the win like we didn’t ruin the Eagles the entire second half of the game.

    So I wanted to say that I’m just so glad that this game was officiated so cleanly so that there’s less room for excuses from the doubters. And also because it’s just nice to see a game officiated well after a season rife with bad calls and no calls.

    There was a moment in the game, I think close to the two minute warning in the final quarter when I had accepted that the Chiefs were going to lose and then to have the COMEBACK IN OT!! The basement exploded with roars and cheers and all that good stuff. What a fun game it turned out to be!

    5 votes
  2. Comment on Day 9: Mirage Maintenance in ~comp.advent_of_code

    jonah
    Link
    This was a fun one! I tried to apply my shortcut from part 1 to part 2, but since I got a little lucky with my part 1, I had to actually try to understand math for part 2. Part 1 import { getInput...

    This was a fun one! I tried to apply my shortcut from part 1 to part 2, but since I got a little lucky with my part 1, I had to actually try to understand math for part 2.

    Part 1
    import { getInput } from "./input";
    import * as utils from "./utils";
    
    const input = getInput();
    const sequences = input
      .split("\n")
      .filter((s) => !!s)
      .map((s) => utils.ints(s));
    
    let sum = 0;
    sequences.forEach((seq) => {
      const stack = [];
    
      let arr = seq;
      let next = [];
    
      stack.push(seq);
      while (!arr.every((s) => s === 0)) {
        for (let i = 0; i < arr.length - 1; i++) {
          const v = arr[i + 1] - arr[i];
          next.push(v);
        }
        stack.push(next);
        arr = next;
        next = []; // forgot this line and had to chase a crazy Node crash
      }
    
      // here's my fun one-liner calculation to find the next value in the sequence
      const val = stack.map((s) => s[s.length - 1]).reduce((a, c) => a + c, 0);
      sum += val;
    });
    
    console.log(sum);
    
    Part 2
    import { getInput } from "./input";
    import * as utils from "./utils";
    
    const input = getInput();
    const sequences = input
      .split("\n")
      .filter((s) => !!s)
      .map((s) => utils.ints(s));
    
    let sum = 0;
    sequences.forEach((seq) => {
      const stack = [];
    
      let arr = seq;
      let next = [];
    
      stack.push(seq);
      while (!arr.every((s) => s === 0)) {
        for (let i = 0; i < arr.length - 1; i++) {
          const v = arr[i + 1] - arr[i];
          next.push(v);
        }
        stack.push(next);
        arr = next;
        next = [];
      }
    
      const vals = stack.slice(0, -1).map((x) => x[0]);
      // Stack math!
      while (vals.length > 1) {
        const right = vals.pop()!;
        const left = vals.pop()!;
        vals.push(left - right);
      }
      sum += vals[0];
    });
    
    console.log(sum);
    

    I'm very happy with today's problem. With how some of the first few days went I was afraid this year would be really hard.

    2 votes
  3. Comment on Day 8: Haunted Wasteland in ~comp.advent_of_code

    jonah
    Link
    I finally got around to day 8 tonight. I'm only posting part 2 since it's really similar to part 1 and I'm really happy that I figured out... Spoilers that it was an LCM problem. I'm usually very...

    I finally got around to day 8 tonight. I'm only posting part 2 since it's really similar to part 1 and I'm really happy that I figured out...

    Spoilers that it was an LCM problem. I'm usually very bad at figuring these types of things out. And on the plus side I can add the `gcd` and `lcm` code to my utils :D

    Parsing was also pretty easy with some simple regex today, which is very welcome. Okay, here's my code

    Part 2
    import { getInput } from "./input";
    import * as utils from "./utils";
    
    const gcd = (a: number, b: number): number => {
      return !b ? a : gcd(b, a % b);
    };
    
    const lcm = (a: number, b: number): number => {
      return (a * b) / gcd(a, b);
    };
    
    const alcm = (nums: number[]): number => {
      nums.sort((a, b) => a - b);
      while (nums.length > 1) {
        const x = lcm(nums[0], nums[1]);
        nums.splice(0, 2, x);
      }
      return nums[0];
    };
    
    (async () => {
      const input = getInput();
      const lines = input.split("\n").filter((l) => !!l);
    
      const dirs = lines[0].split("");
      const nodes: Map<string, [string, string]> = new Map();
      const regex = /(\w+) = \((\w+), (\w+)\)/;
    
      for (let i = 1; i < lines.length; i++) {
        const args = lines[i].match(regex)!;
        nodes.set(args[1], [args[2], args[3]]);
      }
    
      const keys = [...nodes.keys()].filter((x) => x.endsWith("A"));
      console.log(`Going through ${keys.length} paths`);
      const steps = keys.map((key, i) => {
        let count = 0;
        let currNode = key;
        while (currNode != "ZZZ") {
          const lr = nodes.get(currNode)!;
          const dir = dirs[count % dirs.length] === "L" ? 0 : 1;
          currNode = lr[dir];
          count++;
          if (currNode.endsWith("Z")) {
            break;
          }
        }
        console.log(`Finished ${i + 1}`);
        return count;
      });
    
      console.log(alcm(steps));
    })();
    

    Because I didn't brute force the problem I was able to get the solution in less than a second which was like an early Christmas for me! Reading through some of the comments here it seems like today's part 2 is maybe controversial. Personally I thought it was fun, but I also lucked out a little bit with some assumptions and figuring out the secret earlier than usual.

    1 vote
  4. Comment on Introducing Beeper Mini - get blue bubbles on Android in ~tech

    jonah
    Link Parent
    Pretty much everyone in my life does this with the exception of large quantities of images or a video longer than a few minutes. I would imagine this is pretty common with how well messaging apps...

    Pretty much everyone in my life does this with the exception of large quantities of images or a video longer than a few minutes. I would imagine this is pretty common with how well messaging apps like iMessage handle photos and videos. Maybe nobody in your circle does this, but I see it all the time.

    8 votes
  5. Comment on Day 6: Wait For It in ~comp.advent_of_code

    jonah
    Link
    We have been blessed with an easy day. My code is a little more verbose than necessary, but I have some brain fog today so it was helpful to lay everything out more explicitly. Part 1 import {...

    We have been blessed with an easy day. My code is a little more verbose than necessary, but I have some brain fog today so it was helpful to lay everything out more explicitly.

    Part 1
    import { getInput } from "./input";
    import * as utils from "./utils";
    
    (async () => {
      const input = getInput();
      const lines = input.split("\n");
    
      const times = utils.ints(lines[0]);
      const distance = utils.ints(lines[1]);
    
      let total = 1;
    
      for (let i = 0; i < times.length; i++) {
        const time = times[i];
        const dist = distance[i];
        let wins = 0;
    
        for (let charge = 1; charge < time; charge++) {
          const rem = time - charge;
          if (charge * rem > dist) {
            wins++;
          }
        }
    
        total *= wins;
      }
    
      console.log(total);
    })();
    

    I kinda cheesed part two by doing a little bit of dumb processing to keep my previous solution exactly the same, so here's what that looks like:

    Part 2
    import { getInput } from "./input";
    import * as utils from "./utils";
    
    (async () => {
      const input = getInput();
      const lines = input.split("\n");
    
      const times = [
        parseInt(
          utils
            .ints(lines[0])
            .map((x) => x.toString())
            .join(""),
        ),
      ];
      const distance = [
        parseInt(
          utils
            .ints(lines[1])
            .map((x) => x.toString())
            .join(""),
        ),
      ];
    
      let total = 1;
    
      for (let i = 0; i < times.length; i++) {
        const time = times[i];
        const dist = distance[i];
        let wins = 0;
    
        for (let charge = 1; charge < time; charge++) {
          const rem = time - charge;
          if (charge * rem > dist) {
            wins++;
          }
        }
    
        total *= wins;
      }
    
      console.log(total);
    })();
    
    1 vote
  6. Comment on Day 5: If You Give A Seed A Fertilizer in ~comp.advent_of_code

    jonah
    Link
    Today, my choice of using TypeScript is biting me. Part 1 was not very difficult. I made the naive mistake of using actual hashmaps in my first implementation, and then I saw the actual puzzle...

    Today, my choice of using TypeScript is biting me.

    Part 1 was not very difficult. I made the naive mistake of using actual hashmaps in my first implementation, and then I saw the actual puzzle input, and realized I needed to rework it.

    Part 1
    import { getInput } from "./input";
    import * as utils from "./utils";
    
    interface Record {
      dst: number;
      src: number;
      len: number;
    }
    
    (async () => {
      const input = getInput();
      const lines = input.split("\n");
    
      const seeds = utils.ints(lines[0]);
      const records: Record[][] = [];
    
      let currRecords: Record[] = [];
      for (let i = 2; i < lines.length; i++) {
        const line = lines[i];
        if (!line) {
          records.push(currRecords);
          continue;
        }
    
        if (line.includes("map")) {
          currRecords = [];
        } else {
          const nums = utils.ints(line);
          currRecords!.push({ dst: nums[0], src: nums[1], len: nums[2] });
        }
      }
    
      let lowest = Number.MAX_VALUE;
      seeds.forEach((seed) => {
        let num = seed;
        for (let i = 0; i < records.length; i++) {
          const record = records[i].find(
            (r) => r.src <= num && r.src + r.len > num,
          );
          if (record) {
            num = record.dst + (num - record.src);
          }
        }
        if (num < lowest) {
          lowest = num;
        }
      });
    
      console.log(lowest);
    })();
    

    Part 2 was not a very big change for me, because like many others, I just brute forced this one. I would like to figure out a more efficient solution, but I have to start work soon, so I will leave that for another time (which is probably never)

    Part 2
    import { getInput } from "./input";
    import * as utils from "./utils";
    
    interface Record {
      dst: number;
      src: number;
      len: number;
    }
    
    (async () => {
      const input = getInput();
      const lines = input.split("\n");
    
      const seeds = utils.ints(lines[0]);
      const records: Record[][] = [];
    
      let currRecords: Record[] = [];
      for (let i = 2; i < lines.length; i++) {
        const line = lines[i];
        if (!line) {
          records.push(currRecords);
          continue;
        }
    
        if (line.includes("map")) {
          currRecords = [];
        } else {
          const nums = utils.ints(line);
          currRecords!.push({ dst: nums[0], src: nums[1], len: nums[2] });
        }
      }
    
      let lowest = Number.MAX_VALUE;
      for (let n = 0; n < seeds.length; n += 2) {
        const seedStart = seeds[n];
        const seedLength = seeds[n + 1];
    
        for (let k = seedStart; k < seedStart + seedLength; k++) {
          let num = k;
          for (let i = 0; i < records.length; i++) {
            const record = records[i].find(
              (r) => r.src <= num && r.src + r.len > num,
            );
            if (record) {
              num = record.dst + (num - record.src);
            }
          }
          if (num < lowest) {
            lowest = num;
          }
        }
      }
    
      console.log(lowest);
    })();
    

    Had I used C++ or Rust, I don't think it would've taken as long to brute force. My machine clocked in 285s of runtime for this method. Oh well. Another day, another two stars.

    1 vote
  7. Comment on The weirdest bug I've seen yet in ~comp

    jonah
    Link
    Here's a quick read from the Gusto engineering team about a doozy of a bug they discovered in their internal tooling which was causing crashes in Google Chrome. I always enjoy reading these types...

    Here's a quick read from the Gusto engineering team about a doozy of a bug they discovered in their internal tooling which was causing crashes in Google Chrome. I always enjoy reading these types of write-ups because the answer is usually something silly like it was in this case.

    4 votes
  8. Comment on Join the Tildes Advent of Code leaderboard! in ~comp.advent_of_code

    jonah
    Link Parent
    I probably won't get many points either. The puzzles open at 11pm for me which is way past my bedtime :-) and I'm really slow so it wouldn't matter if I did start at 11. Like @first-must-burn...

    I probably won't get many points either. The puzzles open at 11pm for me which is way past my bedtime :-) and I'm really slow so it wouldn't matter if I did start at 11. Like @first-must-burn said, I'm here to see how everyone else is doing!

    2 votes
  9. Comment on Advent of Code starts tonight! in ~comp

    jonah
    Link Parent
    But they said not to do that this year. Surely that will be enough!

    But they said not to do that this year. Surely that will be enough!

    3 votes
  10. Comment on Advent of Code starts tonight! in ~comp

    jonah
    Link
    Every year I start, and I never finish. Maybe this year I can finally complete every challenge! I typically use these as an opportunity to learn a new language, but I may just go with something in...

    Every year I start, and I never finish. Maybe this year I can finally complete every challenge! I typically use these as an opportunity to learn a new language, but I may just go with something in familiar with this time around.

    As a question for those who do the same thing, what’s your favorite language you started learning with advent of code? Maybe not started learning but using a language you weren’t as familiar with? Last year I did Rust which was super fun!

    11 votes
  11. Comment on Routing around a VPN connection in Linux in ~comp

    jonah
    Link Parent
    Hi there! Thank you for the feedback! Regarding mangle, if you are curious, it seems that the mangle table is for modifying various pieces of the packet, particularly the IP headers. In other...

    Hi there! Thank you for the feedback!

    Regarding mangle, if you are curious, it seems that the mangle table is for modifying various pieces of the packet, particularly the IP headers. In other words, you are mangling the packet! I’m not super great at networking so that’s about where the wheels fall off for me.

    As far as VPNs go, I’ll see what I can do with our fire stick. If I can figure out a clean and easy way to connect to my home network from the stick, I’ll start working on a (new) networking solution.

    Thanks again for your feedback, I really appreciate it!

    2 votes
  12. Comment on Routing around a VPN connection in Linux in ~comp

    jonah
    Link Parent
    Hello! Yes I do have it exposed directly over the internet. However I was very careful to not reveal the domain ;) Jellyfin also has a login system which I understand is not saying much, but it’s...

    Hello! Yes I do have it exposed directly over the internet. However I was very careful to not reveal the domain ;) Jellyfin also has a login system which I understand is not saying much, but it’s better than being completely open on the port.

    That being said, I really would like to move to a VPN system sooner rather than later, but the convenience of an open port is easy for me and more importantly, my less technically minded wife.

    movies.byjonah.net does sound cool though :P

    2 votes
  13. Comment on Routing around a VPN connection in Linux in ~comp

    jonah
    Link Parent
    Thank you for the feedback! I'm glad it was easy to follow.

    Thank you for the feedback! I'm glad it was easy to follow.

    2 votes
  14. Comment on Routing around a VPN connection in Linux in ~comp

    jonah
    Link Parent
    Sounds good, thank you! It's been a while since I've read the docs. I should probably go through those again.

    Sounds good, thank you! It's been a while since I've read the docs. I should probably go through those again.

    2 votes
  15. Comment on Routing around a VPN connection in Linux in ~comp

    jonah
    Link
    Hello! Here is an article I wrote about how I was able to port forward some services from my home media server around the VPN it is connected to. This was a nice challenge for me, especially...

    Hello! Here is an article I wrote about how I was able to port forward some services from my home media server around the VPN it is connected to. This was a nice challenge for me, especially because my networking knowledge is more limited than it should be, and I had a hard time finding any articles or forum posts that had the same problem as me. I was able to find people with similar problems and piece together my own solution for my own problem.

    I am trying to get better at writing, so I'm trying to create some technical articles to improve that skill. I hope self-promo here is alright and that you find the article interesting and/or helpful. Thanks for reading!

    7 votes
  16. Comment on What programming/technical projects have you been working on? in ~comp

    jonah
    Link
    I’ve always had a deep respect for LISP and other LISP-y languages because of their simplicity and power. The syntax is super easy to parse which is fun for me because I’m not any good at writing...

    I’ve always had a deep respect for LISP and other LISP-y languages because of their simplicity and power. The syntax is super easy to parse which is fun for me because I’m not any good at writing parsers.

    Which is what I’m doing: I’ve been having fun writing my own LISP language. I just want to see how far I can take it before I either stop having fun or I start encountering serious friction.

    As an aside, I had a more experienced coworker encourage me on trying to work on my brand which I’ve dabbled with for the last several years but never really took super seriously. At some point I’d like to write one or two articles about this project.

    1 vote
  17. Comment on Morning routines and getting ready for the day in ~life

    jonah
    Link
    I don't have any kids yet (not until next year anyways) so I don't have as much going on, but I'll throw in my routine anyways since I've enjoyed how it's recently changed. I wake up around 5:30am...

    I don't have any kids yet (not until next year anyways) so I don't have as much going on, but I'll throw in my routine anyways since I've enjoyed how it's recently changed.

    I wake up around 5:30am so I can get changed and go to the gym with a friend. I'm trying to get into shape, but the added benefit of running and lifting every morning is that by the time I get back home around 7am, I feel much more ready for my day. It's also a huge plus mentally for me. My wife leaves for work a little after I get back, so we get to enjoy a little bit of time together before she goes. I usually work from home, so I spend the next hour of my morning showering, getting dressed, and eating breakfast. I log into work around 8am. If I'm going into the office, it's about the same since I live about ten minutes from there. On the weekends I will naturally wake up around 7am or so, and I'll typically read a book until my wife wakes up.

    Once she has our kid, I'm sure my routine will change, but for now, this is what I do every morning and I really like how it's been going!

  18. Comment on What programming/technical projects have you been working on? in ~comp

    jonah
    Link Parent
    I am not implementing the DNS level parts myself. That's a little out of scope for what I wanted to try and do. It does sound super interesting, so I might end up separately looking into playing...

    I am not implementing the DNS level parts myself. That's a little out of scope for what I wanted to try and do. It does sound super interesting, so I might end up separately looking into playing around with that!

    2 votes