I found this channel several months ago and it's quickly become one of my favorite programming channels. I do wonder about this: > Can you find the intersecting elements of two lists without sorting them first? The first thing in the solution is a call to Order on both lists. That's sorting both lists first. Syntactically it may not look similar to the original deleted code, but I'd argue that it's essentially the same and doesn't answer the question.
This is why I became a Patreon. Thank you for taking the time to show us how you solve these tasks. I already did these tasks in a similar way, but still I learned from this.
Oh man im too old for this, @Zoran Horvat, how you finding willing and motivation to attend code challenges ? Leverage Linq is brilliant as usual i love it.
Amazingly succinct, though one more improvement would be to add a concise code comment before each expression summarizing the requirement that it attempts to satisfy. That way future developers and debuggers know exactly what they are working with. Though always good practice, I say this especially in reference to the requirement for similarityScore, which is calculated by "adding up each number in the left list after multiplying it by the number of times that number appears in the right list". Your first rendition of the expression made that multiplication explicit, but I simply do not find it in your final version after 4:11. Where is that required multiplication in your final version?
@@kenbrady119 It is implemented through repeated addition this time. GroupBy was entirely wasteful. However, there is the bug in the video, as I have ignored how many times the number appears in the left list. Please read the solution from the GitHub repo for the fix.
Yes, it would be. It's because he's passing a _method group_ to the `Where` function. The method group is `Contains`, so what's happening is only a single instance of HashSet is created, but that instance's `Contains` method group is bound to the `Where` function's delegate parameter. In other words, it's the same as if he had declared a variable before the LINQ query, `HashSet hashSet = new(left)`, along with `.Where(hashSet.Contains)`. Only the `Contains` function is being passed around. It would be different if he had done `Where(x => new HashSet(left).Contains(x))` because the lambda is bound to the delegate parameter, and so each time it is invoked, it would create a new instance. How he has written it, only the code in the `Contains` method will be executed each time.
You solved it just like I did! The first part, anyway. I knew using a HashSet for the second part would scale better, but the input was small enough that it hardly mattered. Later days won't be so kind.
Nice serie Zoran! Keep them coming :). Wouldn´t it be enough to calculate total distance: int totalDistance = Math.Abs(leftList.Sum() - rightList.Sum())? Do we really need to Sort() anything here?
Great example of using FP to solve what feels like an inherently imperative problem. In general, iteration is expensive, so if you must iterate do it to set up the data structures that avoid future iterations. In practice this is a `Set` `Map` `Tree` or `Trie`. Java is lacking a `zip` function, which makes this far less elegant when you have to implement that as well (rolling your own `Gatherer` is such a java answer). Maybe in java 26 or something 😢
@@zoran-horvat "Calculate a total similarity score by adding up each number in the left list after multiplying it by the number of times that number appears in the right list." Your part 2 is missing the multiplication part the number appears in the right list.
@@zoran-horvat interesting reading your comment it should work yes. But when I replaced my own implementation with yours it failed. I’ll try again when I’m home. Probably made a copy from TH-cam video to code editor error … 😅
@ryan-heath I suppose it must be some typing mistake. The solution I have shown is producing the expected result on Advent of Code. P.S. The code is available on GitHub, so you can fetch it from there.
@@belongstomyself Behind the scenes, it would use a hash table again, but with an added pressure of constructing a new object for every join. You would need to perform Distinct on the left before applying Join.
@@zoran-horvat but if I apply distinct on the left side, it would return wrong results, since the requirement is every number in the left side is multiplied by how many time it is repeated in the right side, even if repeated in the left side, its score would be added as many times as it appears on the left side
@belongstomyself Oh, you are right! I misread the last point and my code passed by pure chance! It appears that in my input no number appeared twice on the left. I will have to fix this ASAP. Thank you for pointing that out.
Excellent solution and thought process. That's an instant subscribe!
Wish I could be half that good with LINQ someday.
Please, please, please continue the Advent of Code challenges
Watching your videos is a salve for sour minds 💐
I found this channel several months ago and it's quickly become one of my favorite programming channels.
I do wonder about this:
> Can you find the intersecting elements of two lists without sorting them first?
The first thing in the solution is a call to Order on both lists. That's sorting both lists first. Syntactically it may not look similar to the original deleted code, but I'd argue that it's essentially the same and doesn't answer the question.
Very helpful! Thank you Zoran!
Elegant as usual 🤌
FC# language in its power.
please keep this series going, its nice to see it be done in your typical style.
Nice solutions!
This is why I became a Patreon. Thank you for taking the time to show us how you solve these tasks. I already did these tasks in a similar way, but still I learned from this.
Would love to see you doing all days of the event. I'm currently on Day 5 finished and love seeing other's approaches.
@@drewfyre7693 I'm posting each day on GitHub, so you can compare solutions even prior the video.
Oh man im too old for this, @Zoran Horvat, how you finding willing and motivation to attend code challenges ? Leverage Linq is brilliant as usual i love it.
@@eugene5096 People asked for it on my Discord server. It is also interesting to see how that relates to queries we use in business applications.
Amazingly succinct, though one more improvement would be to add a concise code comment before each expression summarizing the requirement that it attempts to satisfy. That way future developers and debuggers know exactly what they are working with.
Though always good practice, I say this especially in reference to the requirement for similarityScore, which is calculated by "adding up each number in the left list after multiplying it by the number of times that number appears in the right list". Your first rendition of the expression made that multiplication explicit, but I simply do not find it in your final version after 4:11.
Where is that required multiplication in your final version?
@@kenbrady119 It is implemented through repeated addition this time. GroupBy was entirely wasteful.
However, there is the bug in the video, as I have ignored how many times the number appears in the left list. Please read the solution from the GitHub repo for the fix.
How come HashSet is created once? Would it be different it was in a anonymous function (x=> …)
Yes, it would be. It's because he's passing a _method group_ to the `Where` function. The method group is `Contains`, so what's happening is only a single instance of HashSet is created, but that instance's `Contains` method group is bound to the `Where` function's delegate parameter.
In other words, it's the same as if he had declared a variable before the LINQ query, `HashSet hashSet = new(left)`, along with `.Where(hashSet.Contains)`. Only the `Contains` function is being passed around.
It would be different if he had done `Where(x => new HashSet(left).Contains(x))` because the lambda is bound to the delegate parameter, and so each time it is invoked, it would create a new instance. How he has written it, only the code in the `Contains` method will be executed each time.
@@d2pgoon86 That is the correct answer.
@ Gotcha makes 100% sense if you think about it a bit.
Where takes a reference to a method which is the Contains from the newed HashSet
You solved it just like I did! The first part, anyway. I knew using a HashSet for the second part would scale better, but the input was small enough that it hardly mattered. Later days won't be so kind.
@@nickcorrado5105 Day 6 has already shown some teeth.
3:40 Why is the HashSet only created once??
Never mind, i found the answer in the comments
We in here!
Nice serie Zoran! Keep them coming :). Wouldn´t it be enough to calculate total distance: int totalDistance = Math.Abs(leftList.Sum() - rightList.Sum())? Do we really need to Sort() anything here?
@@camlcase That is a very interesting idea, but I think not correct because of the sign-changing effect of individual abs calls.
@@zoran-horvat Tried it for real now and you where right :)
Great example of using FP to solve what feels like an inherently imperative problem.
In general, iteration is expensive, so if you must iterate do it to set up the data structures that avoid future iterations. In practice this is a `Set` `Map` `Tree` or `Trie`.
Java is lacking a `zip` function, which makes this far less elegant when you have to implement that as well (rolling your own `Gatherer` is such a java answer). Maybe in java 26 or something 😢
Part 2 seems wrong ...
@@ryan-heath What makes it wrong?
@@zoran-horvat "Calculate a total similarity score by adding up each number in the left list after multiplying it by the number of times that number appears in the right list."
Your part 2 is missing the multiplication part the number appears in the right list.
@ryan-heath Actually, it doesn't miss it. Every number in the right list is added to the sum as many times as it appears. That is multiplication.
@@zoran-horvat interesting reading your comment it should work yes.
But when I replaced my own implementation with yours it failed.
I’ll try again when I’m home.
Probably made a copy from TH-cam video to code editor error … 😅
@ryan-heath I suppose it must be some typing mistake. The solution I have shown is producing the expected result on Advent of Code.
P.S. The code is available on GitHub, so you can fetch it from there.
what about joins for the second part ? is it a good option?
@@belongstomyself Behind the scenes, it would use a hash table again, but with an added pressure of constructing a new object for every join. You would need to perform Distinct on the left before applying Join.
@@zoran-horvat but if I apply distinct on the left side, it would return wrong results, since the requirement is every number in the left side is multiplied by how many time it is repeated in the right side, even if repeated in the left side, its score would be added as many times as it appears on the left side
@belongstomyself Oh, you are right! I misread the last point and my code passed by pure chance! It appears that in my input no number appeared twice on the left. I will have to fix this ASAP. Thank you for pointing that out.
just wow