jonah's recent activity
-
Comment on Day 9: Disk Fragmenter in ~comp.advent_of_code
-
Comment on Day 8: Resonant Collinearity in ~comp.advent_of_code
jonah The last two days have been annoyingly challenging for me. I only obtained one star in the last two days :( So it was nice to get an easy one today. Part 1 | Part 2 Hopefully I'll have some time... -
Comment on Day 5: Print Queue in ~comp.advent_of_code
jonah Incredible, I will remember this for next time. Thanks!Incredible, I will remember this for next time. Thanks!
-
Comment on Day 5: Print Queue in ~comp.advent_of_code
jonah Y'all, I way over engineered my solution and even after cutting back on a lot of it, it's still much longer than some of the other solutions here. I think my brain hurts from a long day at work... -
Comment on Day 4: Ceres Search in ~comp.advent_of_code
jonah Today's solution felt gross, but it's probably because I felt like I was hacking this one instead of coming up with a good solution. I still feel like I'm abusing Python instead of letting it work...Today's solution felt gross, but it's probably because I felt like I was hacking this one instead of coming up with a good solution. I still feel like I'm abusing Python instead of letting it work for me.
I got tired of copy/pasting code and I've been publishing my solutions on GitHub anyways so shrug
-
Comment on Day 2: Red-Nosed Reports in ~comp.advent_of_code
-
Comment on Day 2: Red-Nosed Reports in ~comp.advent_of_code
jonah Now that I'm off work I can post my solutions: Part 1 from common import load_input input = load_input() def get_direction(first, second): return 1 if second - first > 0 else -1 def...Now that I'm off work I can post my solutions:
Part 1
from common import load_input input = load_input() def get_direction(first, second): return 1 if second - first > 0 else -1 def validate_report(levels): dir = get_direction(levels[0], levels[1]) for i in range(0, len(levels) - 1): diff = levels[i + 1] - levels[i] adiff = abs(diff) if adiff > 3 or adiff < 1 or get_direction(levels[i], levels[i + 1]) != dir: return False return True score = 0 reports = input.split("\n") for report in reports: levels = list(map(lambda x: int(x), report.split(" "))) if validate_report(levels): score += 1 else: for i in range(0, len(levels)): copy = levels.copy() copy.pop(i) if validate_report(copy): score += 1 break print(score)
Part 2
from common import load_input input = load_input() def get_direction(first, second): return 1 if second - first > 0 else -1 def validate_report(levels): dir = get_direction(levels[0], levels[1]) for i in range(0, len(levels) - 1): diff = levels[i + 1] - levels[i] adiff = abs(diff) if adiff > 3 or adiff < 1 or get_direction(levels[i], levels[i + 1]) != dir: return False return True score = 0 reports = input.split("\n") for report in reports: levels = list(map(lambda x: int(x), report.split(" "))) if validate_report(levels): score += 1 else: for i in range(0, len(levels)): copy = levels.copy() copy.pop(i) if validate_report(copy): score += 1 break print(score)
Part 2 took me a while because I was trying to be cute. I gave up and just brute forced it which seemed to work well enough. I'm still trying to get used to Python. For those who know, is there a cleaner way for me to convert my list of strings to a list of ints? I'm still stuck in functional Javascript world and want to use maps everywhere, but maybe there's an easier or more idiomatic way to do it.
-
Comment on Day 1: Historian Hysteria in ~comp.advent_of_code
jonah Hey folks, I didn't know how many of us were planning to (try to) keep up with Advent of Code this year. I see last year there ended up being a scheduled topic, but I wanted to just post here and...Hey folks, I didn't know how many of us were planning to (try to) keep up with Advent of Code this year. I see last year there ended up being a scheduled topic, but I wanted to just post here and remind anyone who's interested that today is the first day of December, which means it's the first day of Advent of Code! Last year was a lot of fun even when I couldn't keep up. I really enjoyed seeing everyone's solutions and discussions around the puzzles every day. I'm hoping that will continue this year :)
Happy holidays!
-
Day 1: Historian Hysteria
29 votes -
Comment on 1 bug, $50,000+ in bounties, how Zendesk intentionally left a backdoor in hundreds of Fortune 500 companies in ~tech
jonah Zendesk wrote a small retrospective with respect to this article: https://support.zendesk.com/hc/en-us/articles/8187090244506-Email-user-verification-bug-bounty-report-retrospective It’s worth...Zendesk wrote a small retrospective with respect to this article: https://support.zendesk.com/hc/en-us/articles/8187090244506-Email-user-verification-bug-bounty-report-retrospective
It’s worth noting in their response that they leave out their original response which effectively ignores the first report. Their justification for not paying the bug bounty is that the bounty hunter did not wait for remediation before talking to third parties, but from the bounty hunter’s article, it looked like Zendesk themselves were not interested in remediation.
I’m curious about any thoughts here, because I don’t think Zendesk should pay someone who caused them to allegedly lose business, but they also ignored the bug.
-
Comment on AI is here. What now? in ~tech
jonah I don’t really disagree with any of this. I think the examples you listed here are far better than a pretty standard tech startup mindset about iterating quickly on a product. I agree with your...I don’t really disagree with any of this. I think the examples you listed here are far better than a pretty standard tech startup mindset about iterating quickly on a product. I agree with your characterization of Zuckerberg’s lack of accountability, I just wouldn’t use that quote as evidence of it. I don’t mean to be pedantic, I think it’s an important distinction.
-
Comment on AI is here. What now? in ~tech
jonah Is there more context to that Zuckerberg quote? In my personal experience, this saying usually applies to breaking the things you’re building, not all the stuff around you. Another way of putting...Is there more context to that Zuckerberg quote? In my personal experience, this saying usually applies to breaking the things you’re building, not all the stuff around you. Another way of putting it would be that it’s worth breaking the product we’re building for a little bit every once in a while if it means we’re developing the product quickly. I don’t think it means if we’re not destroying things around us, we’re not going hard enough.
It’s also possible that I’ve been interpreting this phrase incorrectly for my entire professional life
-
Comment on Chevrolet Malibu heads for the junkyard as GM shifts focus to electric vehicles in ~transport
jonah Also x.com. All the old TLDs probably have no more two letter domain names left, and it's possible that when new TLDs are registered they reserve two letter domains for more established...Also x.com. All the old TLDs probably have no more two letter domain names left, and it's possible that when new TLDs are registered they reserve two letter domains for more established businesses. Just a guess, I actually have no idea.
-
Comment on Chevrolet Malibu heads for the junkyard as GM shifts focus to electric vehicles in ~transport
jonah Another step in the direction towards having more EV's on the road. As a Malibu driver, I'm a little sad to see them go, but I'm all for increasing production of electric vehicles.Another step in the direction towards having more EV's on the road. As a Malibu driver, I'm a little sad to see them go, but I'm all for increasing production of electric vehicles.
-
Chevrolet Malibu heads for the junkyard as GM shifts focus to electric vehicles
17 votes -
Comment on Kansas City Chiefs score game-winning touchdown to beat San Francisco 49ers in overtime in ~sports.american_football
jonah 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!
-
Comment on Day 9: Mirage Maintenance in ~comp.advent_of_code
jonah 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.
-
Comment on Day 8: Haunted Wasteland in ~comp.advent_of_code
jonah 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 :DParsing 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.
-
Comment on Introducing Beeper Mini - get blue bubbles on Android in ~tech
jonah 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.
-
Comment on Day 6: Wait For It in ~comp.advent_of_code
jonah 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); })();
My solution for part 1 basically followed the way AoC walked through the solution so it was suuuuuuper slow but it got me the right answer. I ended up going with a pretty different approach for part 2 that was significantly faster, and if I feel like it maybe I'll refactor my part 1 solution based on part 2.
I'm feeling more comfortable with Python. I started using type hints to help me out with this one. I'm sure there's still some Python-y things I'm not doing or doing the "wrong way" but it's a process. Baby steps.
Part 1 | Part 2