Algorithms + Data Structures = Programs - Episode 0: Our Favorite Algorithms
Episode Date: November 20, 2020In this episode, Bryce and Conor talk about each of their respective favorite algorithms.Date Recorded: 2020-11-14Date Released: 2020-11-20TLB Hit (our rival podcast)Magic Read Along PodcastC++Now 201...9 - Algorithm Intuitionstd::transform_reducestd::inner_productHaskell's outerProductboost::algorithm::splitSuperior String SplittingSean Parent's C++ SeasoningIntro Song InfoMiss You by Sarah Jansen https://soundcloud.com/sarahjansenmusic<br>Creative Commons — Attribution 3.0 Unported — CC BY 3.0<br>Free Download / Stream: http://bit.ly/l-miss-you<br>Music promoted by Audio Library https://youtu.be/iYYxnasvfx8<br>Twitter: https://twitter.com/adspthepodcastWebsite: https://adspthepodcast.com/
Transcript
Discussion (0)
if i'm going somewhere and there's ducks i will stop what i'm doing to go and like interact with
the ducks what like when we talk about transform reduce i'll be able to talk about how i met you
oh is this is this a pg rated podcast no no no we're allowed to say whatever we want
the most important thing and you gotta leave this part in the most important thing is that
our podcast has to be better than jf and ch podcast. That'll be the opening. That'll be the opening clip. Have you have you listened to their
podcast? No, I've not listened to their podcast. Welcome to episode zero of ADSP, the podcast recorded on November 14th, 2020.
My name is Connor and with my co-host Bryce, today we're going to be talking about what our favorite algorithms are.
Hey man, how's it going?
It's pretty good. I just woke up, had myself a bagel that I napped in my couch for half an hour.
Was that intentional, mentioning bagels in the first 30 seconds of our first inaugural episode of this podcast?
I mean mean it is
a meme with me but uh but yeah but yeah so uh what's this podcast about it's gonna be about
algorithms data structures and anything and everything we want to talk about so for those
of you that that don't know uh this podcast is going to be modeled after one of my favorite
podcasts called magic read-along which is just two guys, you know, hopping on what sounds like a phone call, chatting about some things programming related, some things not.
And hopefully it's entertaining for those that are listening.
Yeah, it's funny.
That term algorithms plus data structures equals programs.
It was actually one of the first things that my mentor,
Hartmut Kaiser, told me about. And I don't think he ever mentioned the book to me,
but he just said something to me in a moment of like, programming is just algorithms plus
data structures. And Hartmut was this East German guy with this... he had a real character to him so he just said it in such a way
as if it was just this fundamental truth of the universe and uh something i always really took to
heart when did you learn that it was a book so also for those that aren't aware uh that what
bryce just said is the title of a nicholas verth book that was published i don't even know what
year probably in the 70s which at some point both of us would read. Full disclosure, I don't think either of us have read
it yet. We just thought it was a great podcast name. Yeah, I think I first learned about it when
you told me about it. And I think prior to that, my only exposure to that title was Hurtment having
mentioned it to me. And I think I had no idea that it was a book. I just thought it was a wise saying that he told me.
Interesting. Yeah, that algorithms plus data structures equals programs.
Yeah. So what are we going to be talking about today? We've got a question in mind. What's that
question? That question is, what is your favorite algorithm? And I thought that the answer to this question was going to be
really easy because I thought both of us were going to say the same algorithm, the algorithm,
in fact, that brought us together, which is transform reduce or map reduce. And I should give the story of how I met Conor.
So it was, God, what year was it?
Was it 2018?
Technically, the first time that we talked was in 2018, yes.
But was that when you gave the talk at the user group?
The first time I spoke at the Bay Area C++ user group was in January of 2019.
But I moved to the Silicon Valley on August 5th of 2018.
And then I believe it was like August 8th or 9th I went to my first C++ Bay Area user group.
And yeah.
I'm going to say it was 2019 though, because that was when we really met.
That was when we really got to know each other, was when you gave that talk.
So for those who don't know, I live in the Bay Area and a few years ago I sort of became
one of the main organizers of the Bay Area's C++ user group, although I've since stepped
away from that role because I have no free time.
But at the time, I was still one of the main organizers. And we're always looking for people
from the community to give talks. And I don't remember if Connor approached me or I approached Connor. But Connor came to give this talk.
And I still think it is the best talk that Connor's ever given.
And he gave this talk about, I think it was at the time,
it was still called Algorithm Intuition.
And if you want to see a version of this talk um the best version
i think would be to go watch the uh the version that c++ now 2019 which won like best speaker
and best talk and it won a bunch of awards um and it's essentially it's a talk about um
uh some of the C++ algorithms.
I think primarily it's talk about a particular set of the C++ sequence algorithms
that are near and dear to my heart,
some of which are known as the numeric algorithms.
And during this talk,
one of the things that Connor was particularly excited about,
and Connor's a very excited speaker, one of the things he was particularly excited about was
TransformReduce.
TransformReduce is an algorithm that, if you're not a C++ person, you might know it better
under the name of MapReduce.
So the idea is that it's an algorithm where it takes an input sequence of items, and then it takes two operations that it applies to them.
One of those operations is a transformation, which takes some function and applies it to each one of the elements.
And then the result of that transformation gets fed into a reduction operation.
And a reduction operation is just an operation which takes two inputs
and it produces a single output from it.
So, for example, plus is a reduction operation.
Plus, you take two inputs, you know, the two things that you're going to add together,
and it produces a single value as the output. And it's very powerful it's used a lot in data science um and so i i had to say you know
the thing about connor's talk that really that really built our friendship was i just thought
it was like the best talk ever and this was at a point in my career where the bar for a talk to
impress me was really high um like you you know, sometimes there'd be talks
and I'd just be like, ah, this is good, but not, like, great.
But I'd come to have this intuition about, like,
what was truly a great talk.
And Connor was sitting there and giving this talk
and I just thought, boy, this was great.
And one of the reasons I thought it was great
was he was talking about all the things that I would talk about
when talking about these algorithms.
And Connor didn't know at the time,
but I had been the person who had written the, the like specification in the language for a bunch of these algorithms. And Connor was talking about a bunch of the problems
and the limitations with them. And I was like, oh my God, this dude gets it. And I was so excited.
And he mentioned at some point in that talk that transform reduces his favorite algorithm. And I
had given a talk a few years ago about how transform reduces my favorite algorithm because it's so powerful,
so versatile. There's so much stuff that you can do about it. But I think that we've determined that
neither of us actually think transform reduces our favorite algorithms. Is that right?
Well, I'm curious to hear what you're... I know when we spoke about this topic a while back,
that was your initial
thought and then i said oh well at the time inner product or transform reduce was my favorite
algorithm uh but i don't think it is anymore and that's not because i don't love it it's still
you know it's amazing algorithm it's still in my top whatever n um but yeah i think i have a new
one now and i guess maybe you have a new one too. So, uh, yeah, well, no, no, I want you to go first.
You go first.
I just,
I just said a bunch of words.
I want to hear,
I want to hear what your,
your new favorite algorithm.
Well,
so first I should say that even before,
uh,
you know,
so inner product for,
for those of you that,
um,
you know,
are less familiar with C plus plus,
cause I imagine we're going to have some non C plus plus developers listening in over time.
Um,
inner product is the C plus plus 11 name, sort of the precursor.
It's not identical because the constraints on the TransformReduce,
which is a parallel algorithm, are slightly different.
But I sort of first learned of TransformReduce by the name Interproduct,
and then I thought to myself, wow, this is a really bad name.
And then like a couple weeks later, discovered the C++17 version,
was like, oh my gosh, this is
way better name. And that's the case with most of the C++17 parallel algorithms.
But before Interproduct, probably my favorite algorithm was std partition,
which I don't think I've ever said in a talk or anything. I just loved it because it was a linear
runtime algorithm that had sort of the behavior of a sort. I think of partition as like a predicate
sort. You pass a predicate and then you sort everything
that adheres to it at the beginning
and doesn't adhere to it at the end.
But it's a linear runtime, which is super, super nice.
So I went from partition to inner product
to the renamed version, transform reduce,
to then a new algorithm,
which exists in very few languages,
called outer product.
And in fact, the product,-unquote family of algorithms,
I'm just a huge fan of.
So in that family exists inner product,
otherwise known as transform reduce,
Cartesian product, which is sometimes just known as product
in languages like Python and Ruby,
and outer product.
And I also wish that there was an algorithm
that I have yet to discover called triangle product,
which I mentioned in my CppCon 2020 talk,
but we're not going to talk about that here.
So outer product.
Whoa, whoa, whoa.
Why aren't we going to talk about that?
I want to know what triangle product is.
Well, these things are supposed to be like 20 to 30 minutes.
But yeah, so I'll explain outer product
and then triangle product is just a slight variation of it.
But so if you're familiar, so we've discussed inner product, a.k.a. transform reduce.
Cartesian product, for those of you that aren't familiar, is basically in the simple case you're taking two sequences or two ranges.
But in the more complicated, you can take up to n.
It's a variadic number of sequences.
And basically you create all possible combinations of each of the elements in that
list.
So if you have two lists, A, B, C, and then the second list is 1, 2, 3, you create the
pairs of elements A1, A2, A3, B1, B2, B3, and C1, C2, C3.
Pretty straightforward.
So you end up with like, if you have two different length lists, because they don't need to be
the same length, you end up with n times n pairs or tuples of elements if you have more
than two lists.
So a Cartesian product, if we think about it just in sort of the two list or sequence
or range case, you can actually visualize that as a two-dimensional data structure,
like a matrix.
So in the case where I had ABC and 1, 2, 3,
instead of just a Cartesian product gives you back all of the pairs in a single list,
outer product gives you back a list of lists or a range of ranges.
So you end up with basically a matrix that has each of these pairs,
except instead of getting back pairs,
similar to inner product or transform reduce, you specify a binary reduction operation that is applied to each of those pairs. So if you have an outer product, typically now the ABC123 case
doesn't make sense. But if you have the numbers, you know, one to five for each list, you can apply the multiplies binary operation, and then your resulting table is a multiplication
table. And this is extremely useful in the array oriented programming paradigm, which of course,
is where the first time on the ADSP, the podcast, I'll be mentioning APL.
We can start potentially a drinking game
for our listeners every time I mention APL,
which is my favorite programming language.
But outer product, it exists
in basically every array programming language,
APL, J, Julia is probably the most popular
array programming language that people have heard of.
Haskell also has an outer product.
But I think other than those, those are the only languages that I know that have outer product. But
you can do very, very cool things. And just to add, if you have Cartesian product and you don't
have outer product, you can do a Cartesian product and then call another algorithm called chunk,
where you just pass the length of the first sequence and then chunk your list, the resulting
list from your Cartesian product to get basically the equivalent of an outer product. But that's my
favorite algorithm. I absolutely love it. And maybe C++29 ranges will get it. We'll see.
What is your favorite algorithm now though, Bryce?
So my favorite algorithm, to understand it, my favorite algorithm actually though, Bryce? So my favorite algorithm to understand it,
my favorite algorithm actually tells the story of the start of my career. So it's actually like
perfect for our first podcast and my favorite algorithm. Um, uh, I will, I will say it's a
specific implementation of the algorithm because that leads into the story, which is boost algorithm split. And this, and the reason, well, one of the reasons that this is my
favorite is this was the first algorithm, the first time I was ever exposed to boost. So back
in 2010, I was a fresh college dropout okay technically speaking i didn't drop out of
college technically speaking i flunked out and they kicked me out for if we're if we're being
correct about things and um it was because i was bored with school and i um i played a lot of text
based games called muds when I was a kid.
And I started learning programming to create my own MUD engine.
And I didn't know anything about programming before I started this.
I was working with this guy who was a programmer.
And we were doing it in C++, which was sort of novel because a lot of MUDs were written in C.
But he was like, yeah, we should do C++. It's more of novel because a lot of MUDs were written in C, but he was like, yeah,
we should use C++. It's more modern. It's better. And so I first got exposed to the standard library in this project. And then there was one place in this MUD engine where he was using Boost and it
was, he was using Boost algorithm split. And what that split algorithm is,
is it's just a basic tokenization algorithm.
So you give it an input sequence
and then you give it some set of tokens.
And it takes the input sequence
and it chops it up using those tokens.
So like, you know, if you had an IP address
and you wanted to split it out into
the individual numeric components, your token would be a period. And then what, you know,
if I had the IP address 127.0.0.1 and I fed it into this tokenization algorithm,
it would give me back four components the first component would be one two
seven then second one would be zero the third one would be zero the last one would be one
um and i don't remember exactly what we were using it for in this little mud engine i think we were
using it to perhaps we were using it to like um uh separate out um commands entered into the mud into into their constituent components but
it was my first exposure to boost and i seem to recall i found some sort of bug in the algorithm
and so i went to the boost people and i was like hey here's this bug i had this fix for it
um and then i very rapidly got completely sidelined from my little game project into contributing to Boost.
And if I recall correctly, what happened was my use case got more and more advanced.
And somebody was like, you should use Boost Spirit.
And then I started talking with the Boost Spirit guys and I started contributing to Boost Spirit. And at the time,
you know, one of the main contributors
to Boost Spirit was one of its creators,
Hartmut Kaiser.
And so I got to know Hartmut.
And after, you know, some period of time,
Hartmut and I got talking about,
well, I basically approached him on IRC
and was like, hey, I
need a job because I was like a 19-year-old college dropout.
And he's like, why don't you buy a one-way plane ticket to Louisiana, come down here
and work for me.
My parents, of course, absolutely loved this idea of me getting on a plane and going off
to some stranger that they'd never met.
My mother thought he was going to be an axe murderer.
And that was the start of my career. Is your mom going to listen to this podcast?
Oh, she'll probably listen to this podcast. Yes. Yeah. But I think it's a very cool algorithm.
And one of the reasons why it's a very cool algorithm is it's a very common thing that comes up for a lot of programmers.
Even if you're not doing anything like that complex,
I think tokenization is a fairly common thing to come up.
I mean, even if you're just writing some command line scripts,
it's a very common thing that you do where you're like,
hey, I have this input sequence
and I need to divide it up in some way.
And it also, it sort of leads into some interesting
discussions about efficiency.
You know, one of the reasons that we introduced
StringView into C++17 was to allow you
to write an algorithm like this more efficiently.
So let's go back to that example of parsing an IP address. Let's say that I've got a string that stores some IP address, a std string specifically. And I want to split that std string up into its
constituent components. So a std string is an
owning string. You know, it owns the memory for the string that it points to. So if my API for
split is that it takes a std string in and it returns a vector of std strings, well, boy,
that is not efficient at all, is it? Because then what I'm doing is I'm taking this one initial input string, and for each one of the constituent components, I have to make a copy of that piece of the string and stick it into the vector that I'm going to return.
And so one of the canonical examples for why C++17 string view is useful is split.
Because if I have a string view,
what a string view is,
is it's a non-owning view into some other string.
So if I have one string that's my input string,
and I want to split it up into the constituent components,
string view is perfect for this
because the string view is non-owning.
It can just refer to the piece of the string
that it refers to.
And the storage for that string
is owned by the original input.
And so instead of returning a string view,
you can return a vector of string views
or perhaps even something better than a vector.
And it's actually even more interesting
because just coincidentally, this week, one of my other jobs is I'm the chair of the C++ Committee's Library Design Group.
And we got a paper this week talking about improving string splitting in C++. So C++20 introduced ranges, which is a more powerful
idiom for composing algorithms than our previous idiom, which was iterator-based.
And one of the things that's introduced in C++20 is a ranges view called split view.
But there's kind of a little bit of a problem with split view.
And this paper tries to address it.
The problem is split view in C++20, you give it some sequence and it gives you back a sequence of sequences.
The issue is what type of iterators that sequence of
sequence gives you. So my understanding from the proposal is that today the iterators that
you get back from split view only provide the forward iterator guarantee.
And this is problematic because almost all of
the string API's expect contiguous iterator.
So suppose that you're taking C++20 split
and you wanna do something like parse an IP address
and then you wanna call the C library function A2I,
or the more modern version from cars, to convert each one of those IP constituent components to
an actual integer type. But you can't do that because the iterators that split gives you
are not the correct type of iterators to feed into from cars, and they're not the correct type of iterators to feed into from cars and
and they're not the correct type of iterators to turn into to give to a to I
because a to I expects actual you know pointers so there's this proposal oh god
I'm not gonna remember the proposal number I'm sure I'm sure sure we can add
it in we'll put it in the show post. We'll put it in the show notes.
Yeah, we'll put it in the show notes.
Superior String Splitting is the
name of the paper. Here, I'll see if I can find it.
But
this proposal essentially aims
to fix this problem.
Here, I got the paper
number. It's P2210
by Barry Rebson. And that IP example is like the first example in the paper. So if you go and look at that paper, you'll see immediately what I mean.
And this proposal attempts to remedy that in C++ to make the split view a lot more useful when working with strings.
And the other algorithm, which is, I think, sort of combined with this,
is the algorithm for joining a set of strings with a delimiter.
We've all probably written this at some point.
You know, you have a vector of strings, and you want to insert a comma in between them. And I'm sure
we've all written the naive form of this where you've just got some for loop and it just does
like, you know, if I'm the first one, then don't insert it, et cetera. But you could probably tell
me if there's like what the name of that algorithm is. I don't even actually know what the name of that algorithm is in like, you know, all the cool kid algorithm languages.
What's the variant that you just described?
It's like where it inserts a comma in between every element, but like not, it doesn't insert one before the first element or after the last element uh that depends on the language but like typically that is called um it's doing the concatenation as
well right right right it's also doing so typically that is like there's several different names but
yeah join uh concat or flatten typically don't take a delimiter i know in haskell there's an
algorithm called intersperse which is the same thing as join, but like minus the concatenation.
So like if you have a list of elements, it will just insert in between every element the new element that you want there, but like doesn't join them.
So you still end up with a list of elements.
But I think typically...
What's it called? It's called intersperse?
Intersperse, yeah.
There's two different inter algorithms. One is intersperse? Intersperse, yeah. There's two different
inter-algorithms. One is
intersperse, and one is interleave.
And a little C++
trivia fact, if you've watched
Eric Niebler,
who is the author behind the
RangeV3 library, which was the work that
was sort of done to show
what C++ ranges could look like,
in his calendar talk, i believe it was cpp
con 2015 but i plus or minus one uh he shows an algorithm for transposing which is just a
composition of chunk and interleave interleave being where basically you have n different
sequences and then you take one element at a time from each one uh so that you reorder them that way
um and then you go and take the second element from each one so that you reorder them that way.
And then you go and take the second element from each algorithm, so on and so forth.
But yeah, join, I think it's a classic name for it.
Interestingly, the join that we got in ranges C++20 doesn't take a delimiter.
So in the current C++23 proposal for sort of extending the range algorithms and adapters,
I should say, and views we've had to propose join with, because unfortunately the way we design join doesn't enable us to extend the
interface such that it can take a delimiter.
So we now need two different algorithms for that, which.
Is this going to be another example that you're going to show in a talk where
you're going to have a list of what every programming language calls it, and it's going to be the same for every programming language, andly referring to is the fact that c++ calls uh
what every language calls map um stood transform uh because we accidentally already chose map for
our uh ordered associative containers and ordered um yeah so that that and this this is a real
problem like like people think that names might not matter, but I bet you, you know, the first half of this talk, we talked about transform reduce.
And I bet you that a lot of our audience would have not really known what transform reduce is.
But if we said, you know, we did say map reduce.
You know, if you say map reduce, a lot more people know that because that's what it's called in every other language.
And, like, it's not only that. It's not only that Transform is called Map in every other language, it's that MapReduce is a specific paradigm.
So our mistake of calling MapTransform then led to this other mistake of the common paradigm of MapReduce not being called MapReduce in C++.
And the problem also exists in reverse.
So I had heard of MapReduce and the whole Hadoop,
you know, at scale doing this kind of computation.
And I think MapReduce, you know,
became very popular at Google for a while,
or maybe still is.
And I thought it was different than what,
like I learned TransformReduce and like never made the connection until i started learning functional programming
um and so like yeah it's it's both a problem for c++ developers uh relating things to you know in
other languages or paradigms um and also for you know software developers coming to c++
um but yeah naming naming is hard well and that sort of gets to, you know,
one of the reasons why, I didn't explain really why I like Transform Reduce so much, but the reason
is, you know, you're much more an algorithms guy than me. I'm more of a system software sort of
guy, but really my expertise and specialty is in parallel programming and concurrent programming.
And one of my jobs at NVIDIA is I'm the team lead for Thrust, which is our parallel algorithms library, our implementation of C++17 parallel algorithms.
And I think transform-reduce is the most useful of the parallel algorithms. I'll temper that a little bit.
I'll say that reduce is one of the most useful. And I say that because in our implementation,
we implement many algorithms in terms of other algorithms. And the algorithm that the most number of algorithms are implemented in terms of is reduce and transform reduce.
You know, there's things like the extrema functions, you know, min element, max element, count if, et cetera.
All of those are implemented in terms of reductions and transform reduce in our parallel algorithms library.
And in general, it's just a very useful parallel algorithm.
Yep, there was a talk given by, you know,
moving outside the parallel world,
a talk that Ben Dean gave,
I believe it was at 2016 CPPCon,
called Stood Accumulate, an Alg an algorithmic empire where he showed that
of the 90 algorithms across a couple
headers 77 of
them with a little bit of sort of
bending and twisting were implementable
in terms of std accumulate which is what the
C++11
standard calls basically std
reduce once again slight differences on
restrictions due to the parallel nature
of the reduce algorithm but yeah you start to see reductions everywhere. I remember when I listened to the first LambdaCast podcast where they were talking about sort of maps, reduces, and filters. And they were talking about how like there's catamorphic functions and anamorphic functions. Catamorphic functions are the ones that do reductions.
Anamorphic is exactly split.
So it's when taking a list and you end up with a list of lists. So like chunk, split, group by, they're all versions of anamorphic ones.
But like these categories are just everywhere.
And that like once you learn them, everything starts to look like a reduction.
I think there's a paper called Beautiful Folds where they show that like basically
everything is implementable in terms of a reduction. I think there's a paper called Beautiful Folds where they show that basically everything is implementable in terms of a reduction. Yeah, I have this great diagram
that I made that shows the dependencies between which algorithms are implemented in terms of other
algorithms in our parallel algorithms layer. And I just shared it with you on my screen,
although it's not great for the podcast audience. I was going to say now, now you know what this
means. We're going to have to start screen capturing and putting these on YouTube as well,
because now our listeners are going to feel left out that we're staring at their screens and
they're not. Plus you need, you need, you need the pictures, like the video evidence of how excitable we get.
But yeah, it's really fascinating some of the things that are implemented with reductions in thrust.
So findif is one whole family of algorithms that we implement in terms of reductions. In parallel algorithms, oftentimes short-circuiting algorithms or algorithms where you can give up early, it doesn't make sense to do those in our implementation.
Well, give up is a bit of a misnomer.
You've already found your results, so you can stop iterating.
Right, right. You can stop iterating, but in the case of something that you're going to GPU accelerate,
it's actually more expensive to make an algorithm that's going to stop,
that's going to be efficient, than an algorithm that's going to be fast.
So making an algorithm that's going to stop as soon as it finds the result
is going to potentially be slower than an algorithm that just exhaustively searches the entire
input sequence. So we implement find if in terms of reduce, and then we implement find if not
in terms of find if. And interestingly, we implement partition point in terms of find if not,
and we implement mismatch in terms of find if not um uh so so essentially we implement
mismatch and then equal uh in terms of reduce and mismatch is an interesting one because i know
that's one of your that's one that's an algorithm that's also near and dear to your heart so maybe
you can talk a little bit about mismatch well so we're we're getting close to when we got to wrap
this up but definitely i'll say a little bit about mismatch but first partition point i recently so in the follow-up to the talk that bryce mentioned at the beginning
algorithm intuition was a another talk with a very similar title but they're completely
different talks better algorithm intuition i point out that there are five uh binary searches
in uh the algorithm header most people are familiar with at least least three. I would say at least one,
the one is being binary search. And then there's two other flavors, lower bound and upper bound.
And then there's a fourth one called equal range, which is basically a combination of lower bound
and upper bound. But there's a fifth one that very few people have heard of, or have heard of,
but don't realize that it's a binary search. And that's partition point.
And this has come up recently twice in like code reviews of people asking,
I need like a binary search, but that looks at two elements at a time.
So it takes a binary predicate and finds the place where the element on the left returns true and the element on the right returns false for like some unary predicate,
which you can then sort of fold into a binary predicate.
I recently, the reason I'm going on this little tangent here is I recently discovered that
we actually have a section in the C++ ISO standard for binary algorithms, binary search
algorithms, and partition point isn't in it.
It's in the section next to partition because there's partition is partitioned and partition
point. So even in our standard,
we don't acknowledge that partition point is the fifth binary search algorithm. But anyways,
yes, and mismatch, mismatch is the generic version of adjacent find and adjacent find is the generic
version of is sorted until and is sorted until can be used to program or to code is sorted. So that was like a relationship
that I found. And interestingly, in the same talk that I just mentioned, better algorithm intuition,
I thought that this was amazing. I'm not sure actually, Bryce, if you recall,
we had, you know, non-alcoholic beverages and what is that bar called? Shannon's at the top of NVIDIA.
And that was the time when I had made this discovery that adjacent find was implementable
in terms of what I had then called the most, you know, the worst named or the most poorly
named algorithm in the C++ algorithm header. And I was scared to tell anybody because I wanted to be the first person in a talk to say,
oh my goodness, look at, what do you think?
And so I did this game where I said, what is is sorted implementable in terms of?
And you said is sorted until.
And then I asked what's is sorted until implementable in terms of.
And then I think you got adjacent fine.
Then I said, and there's one more.
And you couldn't get it.
But no one got it. And so then I told you stood mism fine. Then I said, and there's one more. And you couldn't get it. But no one got it.
And so then I told you it was stood mismatch.
And I was super excited.
I asked Sean Parent this.
And when I asked him what is is sorted until implementable in terms of,
he skipped over adjacent fine and went straight to stood mismatch.
So in my talk, I call it the sean parent game because um everyone should
aspire to be as knowledgeable about your algorithms as he is um because he he just knew it off the
back of his hand so what one one of these episodes we will talk about you and your fanboy love for
sean parent that's that's fine we can do that i mean that's an appropriate topic uh
everyone should be a fan boy of sean parent um i mean he he single-handedly can like him and kate
gregory basically uh he started sort of the the road to my public speaking um and then kate gregory
i stole the title of my talk um from from her cpp cast episode i think it was 30 um but yeah like when i when i see sean's talks
like they they are so inspiring um and they just make they make me want to like inspire i hope that
like someday i can inspire people like the way that like sean inspired me um yeah his c++
seasoning talk his generic programming talk when he talks about how reading alexander stepanov's
code was just like mind-blowing for him like that's that's just like so my favorite of his
talks was i think his c++ now 2014 uh keynote where he talked about um he talked about um
essentially porting uh porting some adobe app to run on the ipad and talked about um
sort of the fundamentals of where you can get performance on modern processors and how you
have to turn to parallelism and how you have to turn to accelerators to get performance and
uh as somebody who's in that field i just thought just thought it was just a super inspiring talk.
And I mean, at the time,
I was really in the HPC world.
And Sean is not somebody who's an HPC programmer.
And I was really awestruck
with how many of the things that he was talking about.
Like he was talking about getting performance on an iPad.
An iPad is not an HPC platform. But the way in which he was talking about. Like he was talking about getting performance on an iPad. An iPad is not an HPC platform,
but the way in which he was talking about it
was just as applicable to how you get performance
on the world's largest supercomputers.
And I was just like, wow, this guy knows his stuff.
Yep, Sean is an inspiration.
Yeah.
And maybe with that, maybe we should call it right there.
Yeah, I think that's it.
The final line of our first episode is Sean is an inspiration.
And, yeah, I think with that, we'll just say thanks to everyone that's listening.
And anything else you want to say, Bryce?
No, I'm good. If you have a favorite algorithm and you want to share it with us,
go follow us on Twitter at ADSP The Podcast and let us know what's your favorite algorithm.