Episode · ADSP: Algorithms + Data Structures = Programs
Episode 267: Advent of Code 2025 (Day 2 & 3)
2 Jan 2026 · 35 min
Episode notes
In this episode, Conor and Ben chat about Advent of Code 2025 Day 2 and 3! Link to Episode 267 on WebsiteDiscuss this episode, leave a comment, or ask a question (on GitHub)Socials ADSP: The Podcast: TwitterConor Hoekstra: LinkTree / BioBen Deane: Twitter | BlueSkyShow Notes Date Recorded: 2025-12-22 Date Released: 2026-01-02 Advent of Code 2025Day 2 ProblemDay 3 ProblemC++23 std::views::chunkchunk Hoogle TranslateBQN fn.ChunkBQN ↕ (windows)Ben's Day 3 AoC 2025 in C++Ben's Day 6 AoC 2025 in P...
Transcript
Read the transcript · about 6,310 words, follows along as you listen
Conor:I definitely don't think about things in recursion, not even initially. And my my default way of thinking about things is like the collection-oriented. My collection happens to be an array. Yeah. But you know, if you're in Haskell, any other functional language, it's composing operations on these collections. I assume you did that with some kind of hash set or something like that.
Ben:Yeah, I just threw them in an audit set.
Conor:So I was doing these in BQN. You were doing these in C I said?
Ben:Originally in C. Although another aspect of Avent Code is that at some point, dynamic programming rears its head, which is to say memoization. And indeed, this year was no different to previous years, like sometime around I think of day five or six. In particular, there are graph problems which immediately become fairly trivial if you can just say memoize the function.max element begin end.
Conor:And why is this elegant? Because you are storing the iterator, aka essentially the index, and the value at the same time in this I. Welcome to ADSP the podcast, episode 267, recorded on December 22nd, 2025. My name is Connor. Today with my co-host Ben, we chat about Advent of Code 2025 in C and BQN days two and three. It is December. Today, uh, as we record, it's the December 22nd. Yes, Advent of Code. Have you been doing it? I have, yes.
Ben:And this year, uh have you have you looked at it this year? So this year it's a little different. Okay. Um, you know, it's a it's a lot of work for Eric every year. Eric spends, you know, he starts, what is it? He starts in spring or something, you know, like it's a it's a significant amount of work for Eric and and his team of testers and and you know that kind those folks who work on it. Anyway, he's been doing it, what, 10 years now? 2015 was the first one.
Ben:So 2025 now is the 11th one. I think. That's right. And fair play. It's just too much work for him to fit into a schedule, which means that this year it is only 12 days. It's still there, but it's cut down to 12.
Conor:Really? That explains a lot.
Ben:So it's it's over. It's uh you know, here we are 22nd of December, and and yes, Advent of Code is already over.
Conor:I did not know that. So, I mean, I I was not in Toronto uh at the beginning of December. I was in Australia, and there I think it drops at 3 p.m. or 4 p.m., depending on which city in Australia you're in. Okay. I did the first two days, and then the third day, I was how do I word this? Upset by the difficulty of part B. I algorithmically thought about it and knew how to solve it, and I just thought to myself, I did not want to implement this. And so I stopped.
Conor:Uh so I I got two and a half days into it, and uh for for uh the listener, if you've been following along, it was the question where you're given a sequence of digits and you need to find like the largest part A is find the largest two-digit number, which is pretty trivial. Um, and there's some criteria that like you know it's in from left to right or something. Uh it's it's not just extract the two greatest digits, I don't think. There's there's some extra criteria maybe.
Conor:And then part B is do the same thing but for nine digits, which is for day three. Oh, I was shocked. Interesting. Uh, because it's not algorithmically that difficult.
Ben:Yeah, I found day three easier than day two, actually. All right, well, here we go.
Conor:We're into it, folks. And I don't even remember what uh I don't think I was very happy about day one or day two either. I think day two, I think was easier than day one. I mean, I let's just uh pull it up. Or if you remember, you can what should we talk about though? Should we talk about day three first? Day one first, day two first?
Ben:Uh I don't know. I'm not sure I can claim to remember any one day in in particular, but um 2025.
Conor:Alright, I got day I got five stars, folks.
Ben:Alright, yeah, I've more or less stalled out at 21 stars. I haven't done which is so there are 24 total, but with event code you always get the last one for free, I think. So I've so I'm just missing part two of day nine and ten, which are the really difficult part twos.
Conor:And and I guess to follow up on my previous statement, when I said that makes a lot of sense. My reasoning was that because there's only 12 uh days, they ratchet up the difficulty more quickly. That being said, you said you found day three.
Ben:Yeah, and I don't think that's you know, I don't think the di difficulty ratchets up particularly. It it this year doesn't strike me as having so in some sense every year has one or two days that stand out in difficulty. So this year is no exception there. But I I didn't notice a particular steeper ramp of difficulty this year.
Conor:Okay.
Ben:Um but I can say, you know, at some point this the the harder ones tend to be significantly harder to the point where oftentimes folks use a library to solve it, like a linear algebra library or whatever it might be, or a graph library. Um when I come up against questions like that, I tend to that tends to put me off a bit. Oh, I see. And sometimes I can do them without a library, and sometimes that's where I just stall out. Um at some point my brain just says, well, you know, if there's a library, then the solution exists.
Ben:So the problem isn't interesting anymore. It's kind of that train of thought.
Conor:Right. All right, so what should we what should we or I also too, if you had a question in mind that you wanted to chat about, we can chat about that one. But uh, if not, we can chat about day three, day two.
Ben:Well, let's chat about one that you've tackled, I think. So I'm open to any of them.
Conor:I'm curious, uh I'm curious about hearing your day three solution if you think it was easier. But the question is is should we do day two first and then talk about day three, or do day three and then go back to day two?
Ben:Well, let's talk about day two.
Conor:So day two, if I refresh my memory, you're given these hyphen-separated numbers.
Ben:Right.
Conor:Representing ranges. That represent ranges, yeah. And then it asks you to find invalid IDs that I believe have the invalidness is that if they have repeated sequences, correct?
Ben:So for part one specifically, an invalid ID has a twice re well, one time repeat, it has has a repetition of a sequence of digits. So any two-digit number. But it is only a double repetition, it's not three repetitions, four repetitions. Right. That's important for part one.
Conor:Meaning that if you if you slice your digit or not digit, if you slice your number in half, you should have the same two halves or partitions of that of that string or a number.
Ben:So immediately it's only numbers with an even number of digits. Yeah.
Conor:And I think, doesn't it actually say that uh is is there only even numbers, or maybe not?
Ben:Well, you're given you're given ranges. The task is for you to figure out the sum of all of the invalid IDs. And valid ID is any number in any range which has the property of being in two halves identified. Right.
Conor:Well, I mean, I did nothing fancy for this. I just brute forced this uh for both parts. The first part, brute forcing it, takes no time at all. The second part, so the second part is invalid not just if you slice it in half, but if you slice it into any equally length partitions. So if you have a nine-digit number and you slice it into three parts of length three, if those all have the same equal value, uh that is also invalid. And you can brute force that with an algorithm that exists in many libraries.
Conor:And it does it exist? It doesn't, I guess it does exist in uh C 23 in the form of chunk. Um so if you Okay if you chunk your number in the form of a string by all potential lengths, you know, two to whatever I'm I think I might have just done half of the length. I don't even know. But uh, anyways, you do it from two to whatever length could possibly be, and then you just check if any one of those you know partitionings of your string is invalid. It takes a couple seconds.
Conor:I did this in BQN, but BQN has a primitive for kind of uh chunking up your window. Anyway, so I did nothing elegant for this. I'm not sure if you had a more elegant solution. Now I have to find my solution. Actually, I said that BQ BQN has a chunk function, but actually it has a Windows primitive that chunk can be built on top of. Anyways, I can link to the uh the solutions. They're not pretty because I just kind of hacked this in a few minutes.
Ben:It worked. Uh I did interestingly, it looks like I didn't do that. I rather than checking every number in the range, what I did was try to generate all the invalid numbers and then see if they were within the ranges. So I took a approach from the other way. I didn't enumerate the numbers and check to see if they were valid. I generated invalid numbers and checked if they were in the ranges.
Conor:You generated all invalid numbers. I mean, what's the limit of the number?
Ben:Well, no, well, I generated invalid numbers specifically within the ranges given. I see. But in doing that, I had to be a little careful because of course you can accidentally duplicate a number because the number 1111 is invalid in two different ways, right? It's invalid because it's a four-way repetition of ones, but it's also a two repetition of eleven. Right, right. And so you have to be sure to account for that kind of thing. You have to not double count numbers.
Conor:I assume you did that with some kind of hash set or something like that.
Ben:Yeah, I just threw them in an ordered set.
Conor:And I uh yeah, we we haven't talked about. So I I was doing these in BQN. You were doing these in CIC?
Ben:Originally in C. Although another aspect of Advent of Code is that at some point dynamic programming rears its head, which is to say memoization. And indeed, this year was no different to previous years, like sometime around I think of day five or six, there the in particular there are graph problems which immediately become fairly trivial if you can just say memoize the function. And so at that point, if you're in C you've got more work to do. But if you're in Python, it's trivial.
Conor:You can just add the cache decorator, yeah, exactly. Or cache, yeah, that's what it's called. I think we are.
Ben:Uh yeah, from functools, I think, yeah.
Conor:Yeah.
Ben:So I switched over to Python for the second half of Append of Code.
Conor:Okay. Interesting. So you generated the invalid numbers, which I guess uh it kind of at first it seems like it would be a lot of work, but it's not um not too bad.
Ben:Well, it should be less work than than enumerating all of the numbers, was my thought. And I was expecting that it would be too much work to just do brute force by enumerating all the numbers. Maybe I was wrong about that. I was certainly right, you know, as Advent the Code goes on, that is certainly something to bear in mind. Like brute force solutions don't cut it for part two in the later stages of Advent the Code.
Conor:Yeah, I mean, uh I also thought that potentially I knew for part one it would be fine because it's only linear, right? So it's fine. Part B, I was not convinced, but I thought, ah, it's easy enough to do a brute force, you know, just chunk my numbers up, check if it's invalid. The problem is that you're doing it from like, you know, uh chunk length of two to whatever length your uh integer could be. Right. And that means that you have a nonlinear solution.
Conor:What the complexity is, I don't actually know. And actually, more than the complexity is the fact that you're doing this like partitioning of your string uh or like number in the form of a string, and like that is uh you're gonna be allocating a bunch. And so, like I said, I wasn't convinced, but it ran in like I don't know, five or seven seconds or something. So I was like, oh well, it works for me. Not a pretty solution, but like uh as long as I'm not waiting five minutes for this thing to run.
Conor:Yeah, shout out to the speed of uh BQN's implementation. Anyway, so for this, even though it wasn't uh super pretty, I thought it was pretty straightforward. But but even I thought this was I don't know. I I wasn't in love with question two. I was already being like, yeah, you know, like I in years past, like I remember question one or two was like, I don't know, sum up the numbers that are like uh a new line separated. You'd have like a chunk of integers.
Conor:Right. You'd have to parse those into sublists and then you just add them up, and I was like, you know, that's what I had a nice little way to start off my 24-day journey, and uh by day two, I'm I'm already like reaching for library functions.
Ben:Um in previous years, actually in the early days, I tried to solve them without programming sometimes. Oh yeah, like in Excel or whatever. Well, even Excel could be viewed as a form of programming. I mean, I guess I'm solving them with programming, but for example, one of the early, maybe even day one of year one, 2015, one of the very early ones was um find the matching closed paren. Right? You're given a text file with an arbitrary jumble, well not jumble, they are matched, but an arbitrary nesting of different paren pairs, huge basically one huge s expression.
Ben:Right. Right? So it's like what character give give n where the nth character is the closing paren for the first character. So you just copy and paste it into an editor and uh well yeah, I load it up in Emacs, I type forward s expression followed by point. That's the answer.
Conor:Yeah, yeah, yeah. Then I guess you just delete the rest or or select and count the number of characters or whatever it is. Uh yeah, so anyways, this this problem definitely harder than that. Um But anyway, so let's m so day three.
Ben:Right, day three.
Conor:Whereas where I I lost it, um you're given a what does this look like, 15 or 20 digits in a row? And you're asked to find the largest possible joltage, aka number. And uh what are the criteria? You're choosing two numbers here, and you have to keep them stable, so in order. So if there's you know a nine and an eight, but the eight comes first, you're not allowed to make the number 98. You have to make the number 89. So that's that's basically the only criteria.
Conor:Correct, yeah.
Ben:They can be finding the subset two-digit number that that can be obtained by deleting some portion of the rest of the numbers, if you like.
Conor:Exactly. And so for for me in this one, it's just uh an outer product or a triangle product, which are um very easy to do in array languages, where you basically just create every single possible number and then just take the max. I mean, that's an inefficient way to do things, but it works. But then part B.
Ben:No, well, the way I did this the the the method that immediately suggested itself to me was um so you've got a range of numbers. You've got to pick the first number from n minus one of that range. Because you've got to leave yourself at least one number. You know, you're gonna find the max of the n minus one followed by the max of where you found the previous max to the end.
Conor:Right.
Ben:So that's your number. Um that's a trivial thing to code up. Um so that's what I did. And that and that generalizes to part two as well, right?
Conor:Wait, wait, wait.
Ben:Actually, we're play- So you said you gotta find the second number in n minus one where the the the most significant digit you can pick from elements 0 through n minus 1. Let's say there are let's say that it's gonna be n minus 2, right? Because n minus 1 is the last element, but that's confusing things a bit. So the first element through the n minus 1th element is your choice you've got to pick the max digit of those, and then where you found the max digit, you go from there to the end to pick your second digit.
Conor:Yes. Okay, I understand now. Sorry. And yes, that is what generalizes to the next solution.
Ben:Yeah.
Conor:Unfortunately, that how did you implement this? With recursion? Um or a for loop then. No, uh, a loop.
Ben:I mean Yeah, but I mean they're the same algorithm. It's I don't think of algorithms as being I I don't think of recursion versus iteration as a as a big difference in algorithms. Like the to me the right way to think about algorithms is recursively, how you implement them can be recursively or not. Right? So to me it's the same algorithm either way. Um but I happen to implement it with a with a for loop because it is trivially tail recursive, and so you can make a for loop.
Conor:So yeah, the the reason I didn't like so that was what I thought of basically is in if you kind of visualize this, you can visualize that like n minus one uh thing as this kind of like sliding trapezoid of where you get to select your numbers from, but then at each row you have to adjust the range based on the previous index of your number that you found.
Ben:So so we should have we meant have we said what part two actually is? So part one is five- you've got the string of what is it, 12 numbers, 15 numbers, let's say 15. Part one is find the largest two-digit number, which can be selected in the stable way we've we said. Part two is find the largest 12-digit number that can be selected in in that way where each digit is selected. Yes.
Conor:Yeah, yeah, 12. For some reason in my brain I had stored it as nine, but yeah, 12 is what the And the puzzle actually the puzzle input strings are like I don't know, 50, 60 digit long long strings.
Ben:The the the test input is only 15 or so. But the real input you get you get many more digits.
Conor:Yeah, so the the tr the reason I didn't want to implement it is because I wanted to do this in an array language. And I see.
Ben:Let me send you my I can link you my solution here.
Conor:Yeah, and I I am I am guessing that uh when I see this, there's gonna be an index that is used to do the truncation or you know, kind of limiting that range.
Ben:Yeah, so if you're selecting two digits, the first one comes from digits the the first through the n minus once, right? If you're selecting twelve digits, the first one comes from you know digit one through n minus uh eleven, and the next digit comes from where you found the first digit through n minus ten, and then the next digit through n minus nine, etc.
Conor:Right. So this uh I mean this is very elegant. Link in the show notes, folks, for it's not that elegant.
Ben:I mean it's it's it's hacked up. It happened to me, it happened to be the first thing I thought of, and it turned out to be not very much code.
Conor:Yeah, no, but it is elegant in the sense that on line 27 of this solution, it r on the first line inside the for loop is an auto i equals stdmax element begin end. And why is this elegant? Because you are storing the iterator, aka essentially the index and the value at the same time in this i, which is like essential for uh defining the actual range where you're looking for the next number. So two lines from the end of the loop, it says, let's reset the begin, which is defining your next range to be stood next of i.
Conor:So that's very elegant. Those two lines there, and the two lines in between are just uh doing the math to calculate the the number. So really line 27 and line 30 essential. And I mean, this is maybe the limits of my uh proficiency as an array programmer. Whenever you need the index of a value, depending on the problem type, it's not always trivial to get that, and you end up doing like a secondary like find and drop or take based on, or like you get the length of whatever.
Conor:Anyway, so it's unobvious to me how to elegantly do basically a reduction at the end of the day, because that's that's what's happening to based on the current step of your reduction, without having an algorithm like this that returns to you both the index and the value. In this case, it's in the form of an iterator, but you could imagine some other algorithm that returns you a tuple of you know the value. And the index, how do you then say, like, you know, drop drop n from this range so that you're not doing your search in the duplicate?
Conor:And so maybe it's maybe a part of the problem is that I should have just chosen a different language. Although I'm sure there are some listeners that are also listeners of array cast, and they're thinking that there is actually a pattern or an idiom that is just not in my tool chest of patterns. But so, anyways, did it make sense what I if it doesn't make sense to you, then it probably didn't make any sense to the listener.
Ben:The window. So what what makes this problem maybe interesting in an array language or indeed in the functional language or something. Even the functional language. Every iteration, the end of the window just gets bumped by one. Right. But the beginning of the window is from wherever you found the last thing. So that's the increasing thing. Yeah.
Conor:And in Haskell, I would imagine that the the idiomatic solution is just to use recursion because that's how you solve these kinds of recursive uh things. In an array language, you have access to recursion. I did not want to write a recursive. I think that's that's what my brain wants, is like I can do this recursively, or I could do it with like a while loop and some local state, but that would have just hurt my heart because I don't like while loops with local state.
Ben:Well, here's how you need to think of it, Color. Like I said five minutes ago, like the the elegant way to think of algorithms is to start with recursion. Right? If you and if you can solve it recursively, you can mechanically translate that to an efficient implementation. You can totally write a for loop, but but it doesn't change the essence of the algorithm. You can still think of the algorithm as being recursive, because many, if not most, algorithms are that kind of divide and conquer.
Ben:Even when you're working on a linear sequence, in the sense you are you're shrinking the input every time when you're working on the remaining linear sequence. So you can totally think of algorithms as recursive, and that is that is separate from your choice of how to implement them, right?
Conor:Yes. I mean, I definitely I definitely don't think about things in recursion. Not even initially, and not even I mean, obviously, you know, people say, oh, they get hung up on recursion. I don't get hung up on recursion. I just I my my my default way of thinking about things is like the collection-oriented my collection happens to be an array. Yeah, yeah. But you know, if you're in Haskell, any other functional language, it's composing operations on these collections.
Ben:Yeah, and I totally agree, to be fair. You know, like if you have for certain operations, we we uh can be used to thinking in those kind of high-level abstractions of the whole meal-oriented approach, uh working on collections. But oftentimes when an algorithm isn't doesn't immediately fit into that mold or you don't see how to do it, there are two ways you can go. You can and you can either go, oh, how can I you can carry on, and if and if you're really used to thinking about the whole meal programming approach, so maybe this is how you're thinking of things, you can carry on trying to say, well, how can I munge this data until it eventually gets into a form where I can reduce it, right?
Ben:Or I can think about maybe a scan, followed by, you know, and a transform, followed by a reduction, followed by a window, whatever it might be. You know, you can carry on down that row and you can get to an answer, I'm sure. Or you know, and maybe this dichotomy is not hard and fast, or you can think about how would I you know the for loop-based approach, if you like, or the you know the working on the indices, let's say the working on the indices approach, not the for loop, because that implies maybe iteration.
Ben:But yeah, how can I how can I divide and conquer? How would I work on the indices so that the range shrinks, that kind of way of thinking?
Conor:Yeah, yeah. That I completely agree with. And I guess when I'm doing advent of code or leak code problems or any kind of like, you know, for fun things, I I hope that I don't I hope I can just stay in my default way of thinking. Right. And even if I have to move from that, I still hope that the uh recursive or you know, while loop or for loop version, I can still use all of the primitives that I have. Like I don't have to write some bespoke thing that's an amalgamation of stuff.
Conor:And the problem is, is like not like it's not only can I not stay in my collection-oriented programming land or array program land, when I go to the recursive or for loop solution, I still I now need to create basically a function called like max with index.
Ben:Right. You need to enumerate the collection and carry that along.
Conor:Yeah, the way that you would do that is first you'd find the maximum, and then with that maximum you would go back, and like there's not even like an index of first function in array languages. You would have to like build a mask of all of the values equal to the maximum, and then take the first Boolean value that uh corresponds to that maximum and turn it into an index, and then take the first of those indices. So it's like you're already jumping through three different hoops just to get the first index of that max value.
Conor:And let's just like uh there's a scene from uh Zootopia where the little rabbit pretends to bleed.
Ben:Oh yeah, yeah, yeah.
Conor:It probably won't make any sense, but like that's what's happening in my brain when I'm just like, all right, I'm not solving this problem.
Judy Hopps (Clip):And death.
Ben:Well, let me let me say this to you. Um this sounds like you want to work inside like a putative monad, the enumerated monad, right? You wanting to work on values which are enriched with their index sounds to me like this is lifting into the enumerated monad, which I you know, I I don't know that it exists, but it sounds like a monad.
Conor:Right, yeah. I mean if if uh bundling anything in uh optional or whatever, like sure enough, bundling it with an index is a monad as well, right?
Ben:Um So maybe, you know, it what you're what you just said to me is it's kind of clunky and annoying to have to carry around the enumerated state and figure out where you are in the enumeration of the collection. Maybe the way to abstract that is to put to lift yourself into the enumerated monad. And I'm totally making that up, by the way, but it just sounds like the kind of thing that should be available.
Conor:Yeah, I mean, uh that is a it's a fantastic algorithmic idea. My my uh initial thought right away is that if you're bundling it with the uh original index sequence, each subsequent iteration, you're gonna now have a non-zero indexed index from like your new sequence. So like at first you go from zero to whatever, but then the second time you're at index six, but actually the beginning of your list was at index three, so now I need to back out what the what the current index is.
Ben:But wouldn't you be doing something like that manually anyway? Like you can you're having if if that's part of your your answer, you're having to carry along that state.
Conor:Well, so I mean the the the if you're not doing that kind of enumeration, you if you're just doing some kind of like if you build a primitive that returns you a tuple of the first max with index, you can then just apply that at every iteration where you don't need to do the like yes, you're you're do you're definitely doing the same work every time, but you're avoiding the now I need to subtract the sum of all my indices from the current index to get the correct offset.
Conor:But it is uh it is food for thought. But then also the other thing is even if you had this like enumerate monad thing, that's not really trivial either in an array language, because you can do like a zip width index pattern, but then I guess you are it probably does work. You could do a max on that two-element array.
Ben:Um the enumeration monad is very similar to the state monad or even the environment monad, right? Because it's not really writable. You're only ever reading it. So maybe it's just a a small variation on on that. Yeah.
Conor:I mean, maybe there's actually a nicer way to do this where like I'm thinking now in like Haskell brain, where it's like instead of getting the max, you just go, there's a bunch of yeah, it's been a while since I did any well, have I ever done any real Haskell programming? Probably not, but it's been a while since I've been working with the libraries. There was a data dot split.list or list.split at one point that had a bunch of like chunk before, chunk after.
Conor:If there was some like split at max or split at value, well, you'd still need the value. So I mean if you calculated the max and then you did a split, uh, I don't know. I don't know.
Ben:I'm sure there are things like that. And the great thing about advent code is that you know any route to the solution is fine as long as you learn something, right? So there's no it's not cheating to look at someone else's solution and learn a new technique. You can totally do that.
Conor:Yeah, yeah. Well, here's the challenge to the listener. If if you did advent a code listener in a functional or array and you've got this kind of and that's that's why I said, and and Ben, he was like, Well, is it elegant? I threw this together. But that's the thing that is very elegant. It's on line 27, is that you you for free with max element, you get the the index and the value in an elegant fashion. Yeah, it's right. Yeah, exactly. Um and it's stored all in one thing with a you know a dereference operator to get the value.
Conor:So it's not even like you're unbundling something into a two-tuple or a pair and then using each one. It's it's quite it's quite elegant, it's very nice. And in these in the instances where you need this index to do this kind of operation, this is a very, very nice way to solve it. And it's one of the things that I miss when I'm in array languages, is and that's why if if you ever live in NumPy, they have all these variations of like arg with max, or like they have they have all these like index versions of like these minimum and maximum reduction functions so that you can get the index because it is a common thing that you need to do, or it's not just the maximum value, you need some index for some subsequent operation.
Conor:And so they have all these duplicate operations basically, argmax and argmin and all that stuff, which is kind of uh, you know, there's some quote that says, you know, pat you know, design patterns are just addressing language deficiencies or something like that. It's you know, like argmax and argmin is one of these things for like an algorithmic deficiency. Like if you if you uh are are needing to do this kind of thing, it's because we don't actually have a good way to do it.
Conor:Um anyway, so should have done it in C folks, is the moral of this story. Well, I'm not sure that's the moral. Um and I'm actually curious how you do this in Python, too, right? Because you don't have iterators that you can back out the index from elegantly, right? You're probably doing some, you know, len on even if you use iterators. Uh actually, I don't I'm not familiar. Can you get just the index from an iterator if you're in iterator land? I don't actually know the answer to that question in Python.
Ben:Uh I've never written Python code that did that. I don't know.
Conor:Well, that was day two, day three of Advent of Code. Um any other highlights that that you want to mention? I mean, I like I said, I haven't done anything from uh day three uh onwards, but uh were there any favorite problems or and also two, have you have you been chatting with Michael about his Haskell experience? Because that was where this all the tr the segue uh came from. I have.
Ben:You know, for many of us, Advent of Code starts out with the best of intentions and we make it through two or three days, as you've experienced. So I don't think Michael has made it a lot further than you have. But but yes, uh he and I, you know, in the first uh you know, in the first few days we talked about our different solutions, we talked about how we'd solved it in Haskell. And I have to say that for a beginner in Haskell, his Haskell code is pretty nice, you know.
Ben:It's uh function composition and declarative style, of course. Um course Michael is well versed in that kind of thing. Uh but Haskell is new to him. But um he seems to have taken to it very well. Interesting.
Conor:Maybe we'll have to have uh Michael on and we can chat about his uh however many days of advent of code uh Haskell experience. Um because Haskell, I mean, people forget, but it used to be my favorite language before I discovered APL and friends. Um it was a short-lived favorite language period, but uh you should try day six. Be sure to check these show notes either in your podcast app or at adspthepodcast.com for links to anything we mentioned in today's episode, as well as a link to a GitHub discussion where you can leave thoughts, comments, and questions.
Conor:Thanks for listening. We hope you enjoyed and have a great day. I am the anti Bryce. Um
Transcript supplied by the publisher with the episode.
Podcast
ADSP: Algorithms + Data Structures = Programs
Conor Hoekstra, Bryce Adelstein Lelbach & Ben Deane · Tech & Science · English
Deep dives into algorithms, data structures and C++ — exploring the STL, functional programming and computer science fundamentals with three experienced engineers.
More from ADSP: Algorithms + Data Structures = Programs All episodes →
-
6 Feb 2026 · 27 min
Episode 272: Inverses, Monoids and ∞
In this episode, Conor and Ben chat about algorithms inverses, monoids, infinity and more! Link to Episode 272 on WebsiteDiscuss this episode, leave a comment, or ask a question (on GitHub)Socials ADSP: The Podcast: TwitterConor Hoekstra: LinkTree / BioBen Deane: Twitter | BlueSkyShow Notes Date Recorded: 2026-02-04 Date Released: 2026-02-06 ADSP Episode 271: Mastermind AlgorithmsHoogle Translate adjacent_transformHoogle Translate scanHoogle Translate whereBQN ⁼ (undo)Tacit Talk Episode 30:In...
-
30 Jan 2026 · 19 min
Episode 271: Mastermind Algorithms
In this episode, Conor talks about algorithms used to solve the Mastermind game and specifically a beautiful use of an inverse algorithm. Link to Episode 271 on WebsiteDiscuss this episode, leave a comment, or ask a question (on GitHub)Show Notes Date Recorded: 2026-01-29 Date Released: 2026-01-30 "Point-Free or Die: Tacit Programming in Haskell and Beyond" by Amar ShahC++98 std::transformC++23 std::views::zip_transformzip_transform Hoogle TranslateC++98 std::accumulateC++23 std::ranges::fold...
-
23 Jan 2026 · 44 min
Episode 270: 2026 Predictions - AI, The Future, Books & More!
In this episode, Conor and Bryce make their 2026 predictions and chat about the future! Link to Episode 270 on WebsiteDiscuss this episode, leave a comment, or ask a question (on GitHub)Socials ADSP: The Podcast: TwitterConor Hoekstra: LinkTree / BioBryce Adelstein Lelbach: TwitterShow Notes Date Recorded: 2026-01-13 Date Released: 2026-01-23 VOTE FOR YOUR FAVORITE ADSP EPISODES OF 2025ADSP Episode 111: C++23 Ranges, 2022 Retro & Star WarsADSP Episode 97: C++ vs Carbon vs Circle vs CppFro...
-
16 Jan 2026 · 38 min
Episode 269: 2025 Double Retro
In this episode, Conor and Bryce conduct the annual 2025 retro! Link to Episode 269 on WebsiteDiscuss this episode, leave a comment, or ask a question (on GitHub)Socials ADSP: The Podcast: TwitterConor Hoekstra: LinkTree / BioBryce Adelstein Lelbach: TwitterShow Notes Date Recorded: 2026-01-13 Date Released: 2026-01-16 VOTE FOR YOUR FAVORITE ADSP EPISODES OF 2025ADSP Episode 259: 🇳🇴 NDC TechTown 🇳🇴 Vittorio Romeo & JF BastienNDC TechTown 2025 PlaylistPrefix Sums and Their Applications by ...
-
9 Jan 2026 · 16 min
Episode 268: Advent of Code 2025 (Day 6)
In this episode, Conor and Ben chat about Advent of Code 2025 Day 6! Link to Episode 268 on WebsiteDiscuss this episode, leave a comment, or ask a question (on GitHub)Socials ADSP: The Podcast: TwitterConor Hoekstra: LinkTree / BioBen Deane: Twitter | BlueSkyShow Notes Date Recorded: 2025-12-22 Date Released: 2026-01-09 Advent of Code 2025Day 6 ProblemBen's Day 6 AoC 2025 in PythonConor's Day 6 AoC 2025 in BQNtranspose Hoogle TranslateIntro Song Info Miss You by Sarah Jansen https://soundclou...
-
26 Dec 2025 · 1 hr 10 min
Episode 266: Holiday Special 🎄 CppCon, NDC Toronto, C++Now, Teletext, Bamboozle & More!
In this episode, Conor and Ben chat about CppCon, NDC Toronto, C++Now, Teletext, Bamboozle & more! Link to Episode 266 on WebsiteDiscuss this episode, leave a comment, or ask a question (on GitHub)Socials ADSP: The Podcast: TwitterConor Hoekstra: LinkTree / BioBen Deane: Twitter | BlueSkyShow Notes Date Recorded: 2025-12-22 Date Released: 2025-12-26 Bamboozle!Bamboozle! QuizCeefaxTeletextNDC TorontoC++NowCppCon 2025 ScheduleAPI Structure and Technique: Learnings from Code Review - Ben Dea...
-
19 Dec 2025 · 28 min
Episode 265: 🇦🇺 YOW! Live 🇦🇺 Kevlin Henney & Damian Maclennan
In this episode, Conor chats with Kevlin Henney about the past, present and future of programming languages and with Damian Maclennan about YOW! 2025! Link to Episode 265 on WebsiteDiscuss this episode, leave a comment, or ask a question (on GitHub)Socials ADSP: The Podcast: TwitterConor Hoekstra: LinkTree / BioAbout the Guests: Kevlin Henney is an independent consultant, speaker, writer and trainer. His software development interests are in programming, practice and people. He has been a col...
-
12 Dec 2025 · 35 min
Episode 264: 🇦🇺 Aphantasia, Anendophasia & the Future with Kevlin Henney
In this episode, Conor interviews Kevlin Henney about aphantasia, anendophasia, synesthesia, future and more! Link to Episode 264 on WebsiteDiscuss this episode, leave a comment, or ask a question (on GitHub)Socials ADSP: The Podcast: TwitterConor Hoekstra: LinkTree / BioAbout the Guest: Kevlin Henney is an independent consultant, speaker, writer and trainer. His software development interests are in programming, practice and people. He has been a columnist for various magazines and websites....
-
5 Dec 2025 · 42 min
Episode 263: 🇳🇱 The Sean Parent Origin Story
In this episode, Conor and Bryce interview Sean Parent about the origin story of his career in software engineering! Link to Episode 263 on WebsiteDiscuss this episode, leave a comment, or ask a question (on GitHub)Socials ADSP: The Podcast: TwitterConor Hoekstra: Twitter | BlueSky | MastodonBryce Adelstein Lelbach: TwitterAbout the Guest: Sean Parent is a senior principal scientist and software architect managing Adobe's Software Technology Lab. Sean first joined Adobe in 1993 working on Pho...
-
28 Nov 2025 · 37 min
Episode 262: 🇳🇱 Chaos with Sean Parent! Bikes, Buses, Waffles & More!
In this episode, Conor and Bryce interview Sean Parent about generic programming and there is much chaos! Link to Episode 262 on WebsiteDiscuss this episode, leave a comment, or ask a question (on GitHub)Socials ADSP: The Podcast: TwitterConor Hoekstra: Twitter | BlueSky | MastodonBryce Adelstein Lelbach: TwitterAbout the Guest: Sean Parent is a senior principal scientist and software architect managing Adobe's Software Technology Lab. Sean first joined Adobe in 1993 working on Photoshop and ...
