 All right Good evening everyone Welcome to today's episode of Advertisement of Code in Haskell It's day seven. I've been streaming it for seven consecutive days now that is Enough to be affiliate Hey, Lil Annie. She is the only VIP on this stream If you want to be VIPs You got to know me, you know All right Let's Start of the day off make their day seven day seven touch day seven not just Touch just input that just create all the files That we need And let's open it up Day seven So what's today's problem? I guess some of you Already solved it seen someone already saw it but Hey down right criminal. Thanks for subscribing or following I think like I you can't get subscribers unless you're affiliate but We're getting there. I'm actually I think I Think I have to stream for an hour 20 minutes More and then I fulfill all our requirements. It's gonna be great. Oh Shit so much tech so you need to fix All right, you land at the regional airport in time for next flight. In fact, oh No, there's luggage processing issues Like I said yesterday They're they're covering all the aspects of travel you got passport you got customs You got the luggage issues It's not a good trip for For Santa, okay, so There's so many rules about bags Bags must be color-coded and must contain specific quantities of other color What It's very strict regulations. Is it like hey you don't have bags in your bag, so We're gonna throw it away Okay, apparently if nobody do something for this regulations considering how long they would take to enforce, okay So light red bags contain one bright white bag two muted yellow bags Dark orange bags contain one two, okay, so I think each line Every faded blue bag is empty every white and plump bag has in things 11 bags and so on You have a shiny gold bag if wanted to carry it in at least one other bag. How many different back colors? Would be valid for the outermost bag In other words, how many colors can eventually contain at least one shiny gold bag? Okay, yeah, so okay, so bright white bags Muted yellow bag because they can contain shiny okay, so I'm gonna contain gold bag. Yeah, okay, okay Dark orange bag, which can hold bright white and muted yellow bags Either way, yeah, okay a light red bag, okay So we're gonna be calculating Transitivity great. I just implemented transitivity stuff For my plug-in I think so there's like a So I mean so we're essentially finding you know transitive closure of sets So let's see Let's take the test input we need to We need to Paste it in and now we need to parse it Now that's that's oh, no, this is the This is not this is the test input This is the test input save it this is gonna be not our test input is actually Okay, so let's look at this we need to parse it Let's write a parser There's a lot of options for writing parses in Askel Parsec, he's just just so use You know actually I don't think we're gonna write like a full like this is like proper stuff like Daniel Asian He is a legend and this is really good. It's a really good parser, but you know we are We're not that desperate. Okay Let's just split it So we're gonna say here main main equals get input test input into Oh my god Oh, I pressed caps lock into print Get input is gonna take a file path as usual gonna give us List of strings and then get input Is going to be fmap lines I'll read line Uh, I'll read file, right? Let's compile it and run it day seven oh day seven and time Running it This one's gonna be a bit hard actually I think so let's let's copy paste from day six. We have this nice split when function already To split and we're gonna split so we're gonna split on these keywords, right? Let me see fmap split when contains dot lines And the problem with this is Oh, yeah Now this will not work because it only works for for one string, right? So We need to Okay, we can't split it like this Uh, yeah, so we need to do We need to do map This so we took the lines and we are gonna take the Words also, right? So then we want a What is this return? Okay, so this is this returns all right. So this one should So this one takes a list Do a list of strings. What? Yeah, yeah, so it takes a list and so list of strings, but this is not the type of that So let's see So let's Oh, we need to map Like this Okay, let's see what this returns All right Light red bags contain one White bag dark red Okay, this says contain Okay, light red bags one bright right bag Two muted yellow bags Okay so So we have a list of list of strings Now, okay, we're gonna have here We're gonna map over that right this is gonna take in get uh two two bag So the first one so we're gonna take in a list of lists We're gonna take a list of list of strings. Okay And then we're gonna return I don't know yet to bag We are going to take in so this is the Uh Container and this is the contained right So this is we're gonna take the container and the contained Um Okay, and then we we want we want to have light red Okay, uh, let us So let's let's like create a compound key, right? So we want the map So all of them have two right so it's gonna be map of string comma string to list of strings So this is gonna be Uh, okay, so these are always gonna be you know, uh light light lighter dark, right? Uh light More dark and then color And then it's gonna be So and then the rest here is gonna be the contained Okay, and we're gonna say this This is a list of list of strings. So this is for each one Uh, so So we're just gonna say here map dot single Singleton So we're gonna import data dot map Import data dot Qualified data dot map As map And then this is gonna be map dot singleton Uh, so we're gonna say here Light or dark comma Color Contained Let's see So we are going to Map to bag Oh, no non-accessive patterns What contains here? Okay, fade it contain faded blue bags. Yeah, that's the first one Okay, let's Instead we will map So let's let's so we got the input so Imp Uh do okay, we're just gonna get the input And then Should be commented out, right? Yeah map m A print We're just gonna we want to print every line in the input There's some there's some pattern error here. They were not seeing So let's red back dark light or dark Like your dark color and then yeah here. This is just gonna say bags So If we map Two bag here Okay, now we have dotted black no other bags Okay, so so we really just need to find the transitive one But uh, I I assume I assume we're gonna have to be using these numbers And so So let's encode those somehow Okay, let's let's just wait until task. Let's just see if we need to encode them right away Um and then So can Tamed bags So this is gonna be contained bags Okay, and they when it's gonna be it's gonna be So we're just gonna split let's split it on So now we're looking at one of these lists, right? Let's spit it on something that starts with bag I don't think there's any color that starts with bag baggering bag baggering No doesn't exist. Um Where All right, I have plenty of viewers How you guys all find me? Y'all coming here from I mean, so this time I made like a post on the Haskell subreddit and Admitive code because I think I think people I want to see how we how we do it in the programming world Um, let's see So These are going to be contained bags equals split when Uh, so I think there's a function called starts with But oh no, it's in the missing Yeah, it's this is like, you know There's so many things in ghc felt like in the list which you might want But it's all in this data list split or in like One of the sub libraries or like, you know missing missing base or something like that So missing h, you know, it's like this this function should be there But I don't want to import cabal, right? So let's just say Uh, let's just define starts with like here's our these are utils It starts with Uh, it's going to take an eq a So it takes a list of a's So it takes an a and a Now it takes a list of a's And an a It turns bull, okay Starts with Yeah, so string starts with all right, so yeah, so this is going to be a list of Um Is this how we do it We start with What was the type here? Starts with eqa splitter Starts with eqa eqa pool Yeah, okay, so we're essentially going to say So here is some going to be some uh s So Com so this is one more paper and then the string and then we're going to say Take length comp from string Is equal to comp that is The definition of starts with right Don't I think a parser would have been easier? I mean, yes But I don't want to use cabal to download one of the nice parsing libraries, right? So that's the that's the thing, right? Is there any parser like built into gsc that I that I could just import directly? Because I I don't I don't recall there one being one Okay, this is This one did not work. Um Yeah, sorry contained And this is going to be akin to split when It's going to be a list of list of strings All right one bright white two muted yellow three bright white muted yellow sunny gold nine fighting No other Okay Now let's turn these into A map of screen comma string to Okay contained bags and now Mapify So we take a list of strings And we will return a map of string comma string to An integer Yeah, I mean, I know I I have used the read thing but it's just It's like if if this was like a production thing, right and I was going to be using it again and again I would But Yeah, I should really yeah, I'll probably do that But I need to get familiar with it first, right? It would be a very good thing to have in your repertoire like a you could just whip out a parser like that, but This is going to be fine. Okay mapify if it is, you know a If it is a number So this is light dark bright muted What is what did we call this descriptor? adjective uh color No, this is gonna be uh, this will overwrite this will probably shadow this color, right? Uh, so let's call it c color This is gonna be a map dot singleton of a Adjective comma color and then a read Of the number Mapify anything else is going to be mapped off empty So instead of returning a list a list of strings So we we got the contain bags Uh, so this is going to be we're going to have a map of string or string the strings and then we're going to We're going to combine those data.map a Into no, okay, we're gonna have the we're gonna union, right? Yeah, so this just takes two maps um So we get all these maps So we are going to say uh All contained equals Hold l We're gonna just say Union dot map if I So this is gonna be map dot union of map if I What is it complaining about? Yeah, I mean Couldn't expect type map string into this I'm just gonna finish writing this function, right? Okay, that's probably because it's gonna be a fold or map dot empty and then it's going to be No Okay, I don't want to I don't want to So I think it's going to be like this and then I want to map it over Overcontained bags Yeah, this works So this is gonna change all of them into These maps so I'm just going to join all of them So this will be a Map of map of strings to a map String comma string Int Um All contained see All right now we've figured out this This this kind of So now we can go from a Light red to the map which contains This the the things that can contain right And now we want to so okay, so Okay, so Let's see here Okay, and we want to you have a we want to carry it in at least one other bag How many different bag colors will be valid for the outermost bag? So now we have to compute the transitive closure And we have to figure out Whether shiny gold is a member of the transitive closure Okay, so how do we write? Transitive closures Um Of maps A first of all, let's let's drop the map. Oh, no, we don't want to drop the map Um So transitive closure Uh So and we have to start with all of them, right? So we kind of want to We kind of want to flip flip them, right? Kind of want to flip the maps um some way Okay, let me let me I I don't quite remember how we did transitive closures I did do it for my plugin Let's just open plugin code This is Uh Yeah, I don't think you supposed to be I mean, I think I could figure it out Like if it wasn't an interview And I would have to figure out how to write a transitive closure, but I will not in an interview, right? So And like if you're at actual work You are expected to use code you used before So here's my writ plugin and This Uh This fix fit scope. It's like Fixing the scope of stuff And In one of these I have to do Uh transitive closure This code looks way harder When it isn't Smaller Okay, um I think it's Yeah, here we go. So full dvar set And then This is This is exactly where we compute the transitive closure Oh no We use the trans closed dvar set function Let's just see if data.set Has transitive closures data data.set Uh data.set Like this Oh, I thought google knew me, you know But unfortunately it doesn't Doesn't know me well enough Thanks for the subscription snake on your child That is not a good thing to have closure set transitive closure Hey data.set Okay, so here's where I would write it down. So, okay, let's let's just think How do we compute the transitive closure? So one step So we take All the things in the map We look those up in the map and then we we We put so for for every element in the map We we look up the closure and then we do it again Until we never add anything else So let's just do that Let's just let's just do it live Uh Trans close Of uh map Key a Map key B Uh to map K map FKD Trans close. Okay. So we have the map We are going to Switch a map of things, right? Uh So where what's the values in a map? Values A map with key Foldable folder filter That's just a function that's just called values, right? How do I how do I get? let let Let's use a Let's use let's just type tools Because I don't remember what the function here should be. So we're just gonna say f is supposed to be a function from map A B to a list of B's What is it? See I added this function because I am lazy like this A Valutal fits ellums Good thing we have type tools suggestions in Haskell, huh? Yeah anyway, so else Is gonna be ellums of f Map dot ellums of the map So that is a A else is gonna be a list of map kb Okay, so the keys of those are going to be So now I want a So now I want to I want to list the list of I want I want a list of list of keys So I go map something Uh Over this else Okay, and this type tool is empty. No, that's not what I want Um Okay keys equals So map kb Let's take this out Uh Map kb to a list of keys keys equals So it would actually be a set of keys, but that's fine keys. Okay. It's just called keys So map And why didn't it want to do this for us here? because Oh map dot keys not in scope. Okay But the problem with this is Couldn't match expected type k1 What No It's because I want I'm saying k and it's like not realizing that I actually want the same k As as is in the definition. So I have to add this scoped type variables to there and This is gonna give me the keys. It's just it's just If I do here for all k We have to use explicit for alls to get the k into scope and then this works Okay, now let's just get the keys So for each key So now I have a map of no wait I actually I don't want it like this right? I want I want the map I want a key and then I want the set of keys that key goes to um Which is just gonna be you know, like this like so I just want to turn this into a set of keys Um, so I just want to say F map Uh What how can I can if I map over the elements? Yeah, so So I want I want here a map of k Set k Let's import data dot set data dot set Set I think we're of way over complicating this but I want to do it the cool way, you know and Uh, I've been complaining that these are too easy, but this is actually This is fun. You know transitive closures. It's not so often. I mean You use transitive closures surprisingly often like that is something when I learned about them. I was like, wow I won't use this that often but Now here I am Okay, so we're gonna f map Uh, so for each So for the elements So over uh So we're gonna map map something over the The map, right? So this one is gonna have type map kb to set k, right? Key set nice. I really like typed whole completions Uh I mean, I don't have to control f on hugel or hackage It's the best. Okay. So map k. So now we have Now we have for each of them Let's just say here Let's just say that this goes to map k Okay, let's just let's just say else here. I just want to see the I just want to see the I just want to see what the value is currently trans close For all of these Okay, so your light red from list bright red Oh right So I mapped the string over to the I mapped the two bags But then I never actually I should unify the two bags, right? So Uh Let's let's do let's just do that. So here in the input I get a list of strings And then I map two bag Uh Let Big map equals a Fold our Union dot two bag Map dot union Of Input Oh, no What is the problem here aren't big map That input here is map Two bag, okay, so Oh I need map dot empty here, right? Right. Now we have one Big map and then we want to Print the transitive closure of big map Okay. Now This is not easy to read so From list bright white Okay, so this so this one goes to We I would like It would be nice if we had like a Nice syntax in Haskell for for sets um Like set like you know like python has You just you just write Brackets, you know one comma two and it's just set One comma two. That's that's nice syntax Um Let's just write it pp pretty print set Takes in a show a of set eight string pp set s set uh lm set set dot lms So this is gonna be Set dot lms that's gonna be a is complaining now that it's So this returns those And then we are going to map Show show This is just gonna be this plus Map show over the list So we're just actually going to say We're just gonna be very dirty We're gonna say show set dot set dot lms of set um So and then we're gonna replace The the first and last one with this like so it's not a so it's not a list um Let are So we're gonna show this so now we have an r that's gonna be without the first one uh It's gonna be the last one Over yours are and then we're just gonna write Okay, so now we're pretty pretty to set Um, how do we pretty print the map? um, well to pp map Show a I'm gonna show V so map kv To string Let's actually Let's actually not say show. Well, we need show v but let's Uh, let's let's have this be, you know v to string pp map equal so this is pp val's Of and then we have the map So Here we are going to do So for each of the keys Oh, yeah, good point. We need to reverse this again um Actually, I mean, I think the map the map is not gonna be that difficult. Let's just Because I kind of like I just want to like print it print it Um, so let's let's just key come a key evaluate Okay, now I have a map If I wanted a I want to function That goes I want to function that I want to import data dot map I want to function That goes map kv To a list of k comma v a two list Assocks, right? Let's just use assocks So I'm going to right here Um map m I want to do four four m Is four m even by default there Okay, well, I just want to Flip So what's the type of flip map m? Yeah, so flip map m of the assocks Of the trans clause of big map do so k comma v k comma v a do put stir ln Uh, I'm just gonna put Show k plus plus plus pp set We should work with Oh, no, I think this is because We need like explicit Yeah, okay. No, yeah So the key valve should be here and then this should be do, right? What is it complaining about? Don't I I I have too many Let's see here. Oh, it's just This entire thing this one Okay, somewhere something somewhere something somewhere else Uh, okay, so it's some error somewhere here So it's not this one Uh, oh, yeah, shoot. This is supposed to be where Like this. Okay. Good. I don't know. This is supposed to be k comma. Well Let's see if this works all right bright white shiny white park olive dawn and olive faded olive Okay, so now we have to take the map and we have to do this fix point And the fix point just means that We kind of run it again and again until the map doesn't change So transitive closure Of a set Um, so here we have the map. So here we have the initial set Um And then to do the transitive closure we need to use the fix function You know what you see I fix We have the fix function, right? Yeah, I mean we can just write our own fix function Which takes in Fix eq aq a a to a to a So fix eq Uh f a equals So if F a equals a then a else fix eq f f a Let's say here where apple equals f a we only want to Apply it once And what the what's the problem here? Oh, no Fix eq is applied to two arguments, but its type only has one What's you what's you talking about? Oh Like this Okay, so now we're gonna fix until it it's the same but We're gonna fix it until it's the same Uh We're gonna fix it until it's the same and then so and then we keep going. Okay, so How how do we so so now we're gonna say so the update It's gonna take a map k set k Uh, it's gonna take, you know, I think we need the the equality of the keys Uh And to a map k set k Update a and it doesn't have an update so how do we update the map? Uh So we simply okay, we simply do this We We so okay, so let we do it for for each key Uh map keys Yeah, I think we can map keys over data dot map, right data map Cool Let me let's see how well google knows me. Okay map Damn it. I used to when I was working on this the most I used to be I could just google map And google would know me so well. It would be like yeah matty Matty is probably meaning data dot map. He's not He's not talking about google maps that guy goes nowhere But now I travel too much In 2020, I'm not sure Okay, let's say here update a value add a specific key with the result of the provided function So adjust with key that's good I think we want to I think we want to adjust with key For all of the keys, right? So we're gonna say Uh map So, okay, so it's gonna be so if you flip adjust with key, what do we get then? import data dot map flip adjust with key it's just that uh What's the type of that? Yeah, so then we flip it Okay, it's because we would want to flip all of it. We want to We want it to take the map. Oh wait So we want the so I think so we want the function the function is always going to be the same And then we're gonna have We're gonna we're gonna take a key and the current Updated map and then we're gonna look up the key in the map and then yeah, okay So we're gonna we're gonna be folding fold l. I think and okay, so Kerr map So fold fold l takes in the function and the initial value, right? So here you're gonna have some fun And then we're gonna have um And then we're gonna have the keys in the current map Is the map ever gonna Add it's never gonna add I don't think it's ever gonna add stuff to the current It's never gonna add keys to the map, right? We're only gonna be updating Updating the values so it's gonna be this is gonna be fine map dot keys Uh Fold fun and then this is gonna be the kerr map And now I have to define where fun What's the type of fun? Can't spell functional programming without fun. You know Anyway What's the type of fold l I keep forgetting So we can fold l over the maps But that's uh, that's not per key, right? Adjust the value at a specific key. Yeah, okay So the fun here Okay, so the current so a here is going to be kerr map. So fun is going to take in a map K set K It's going to take in a key And it's going to return a map K Set K Okay, that is that is so we got the type there, correct Now, let's see. We're gonna do we're gonna be doing adjust with key Adjust with key And then fun K Okay, let's fold let's fold or actually And then we will get it No We want to take the map Well, let's fold our I think I fold our fold l is like better Map K set. I think it's like more efficient, but For these problems. It's usually usually doesn't matter too much So adjust with key Uh And here we need some function, right and after uh, if that That should be yeah, this would be mapped at a just key Uh, what is wrong here? So that takes in So if we if we give this a function some value, right, it's going to Uh This should be the right type, right? Why isn't this the right type? So if I give adjust with key Oh, okay We need word We need word here. So, okay. So, okay. So for the given key Uh, we're gonna apply update key Now update key is going to take in, um Yeah, exactly that is going to take in our K And a map K set K And return a map K Set K, right? This is just the same thing again, right? Oh, we're getting rated again I got rated like two days ago Um It's always a lot of fun. You got a lot of new people Hey, I'll Hope you enjoy some programmatic Haskell programming. Um programmatic programming I'm trying to do like this very algebraically. So we're doing transitive closures now Uh And I said earlier Wait, what is supposed to be the type of? Update key here Oh, this is gonna be This is gonna be like this Now, what's what is it? What is the type of update key here? Let's see. Whoops Uh K set K set K right Is this what I want though Okay, so No, okay. Let's let's just do this directly. So, okay, so here we have a K here. We have the current map Okay, and then we are going We're going to do the following So we're going to look up We're gonna look up K First of all Look up Yeah, we're gonna look up. Okay, so let's So now we we have the K Key K Okay, and this is always going to be In the map, right? It's always going to be there Uh the key right because we're we're iterating We're editing over over the list of Keys in the map. So we don't have to worry about it being there So we can do actually we can do this right we can just say We can say L's equals Where L's is going to be it's going to be curve map Bang K So L's Is going to be of type set K right? Uh, what is wrong here? And you find Yeah, if you like this content, uh, don't forget to subscribe. This is uh of our milo keyboard um These va 69 special edition Uh, but it only comes in like Blue and no it comes in so the original layout is like it's essentially this except these were all red um And I didn't quite like that because so the thing is I'm Icelandic right Uh, let me so I have another one. So this is the blue blue keys one I use for programming This is the one other one I have So and it looks it looks a bit more like this, right? But this is like a the Danish flag Okay, and December 1st when we first started the the advent of code we I was we were celebrating Uh 102 years of independence or like sovereignty from Denmark So I got one of those key cap sets which had blue keys And I replaced a lot of the red keys with blue keys And turned my keyboard into the Icelandic flag You gotta represent, you know, there's there is I think literally Five or six people in all of Iceland But they're like really into functional programming. They're like You know, maybe at less than 10. I think you know, we have a we have a meet-up We have a meet-up every Every Christmas because everyone comes owns for Christmas, right? And it's just like 10 people and that's it That's all of them And we all know each other, uh, and we have some pretty cool people But uh Yeah, another varmillo keyboard those are they're pretty good like and also I tried buying another key cap set And it just it didn't feel right It was like the oh the feel of the keys is so good I I really like these But yeah, you gotta if you're if you're from a small country, you got our represent, you know anyway, so Where were we we were updating the elements here, uh, this is going to be map dot bang So we found the set of elements for that map Okay, and now for each of those elements we want to look up So let's say here that's going to be cat maybes, right? Import data dot maybe we're gonna cat the maybes Uh, so for the elements here, we're gonna say Uh In map is going to be a list of keys No, it's gonna be less of sets, okay, so in map is going to be That is going to be the The we're gonna map We are no yeah, we are going to map maybe bang map dot bang question mark of uh So this is going to be we're going to map or the curl map over the else And this is wrong Because this is a set and map. Maybe it doesn't work over a set So we have to say ellens Okay, right set dot ellens Now this is going to be what is what is occurs cannot construct the infinite type. Yeah, okay, huh No, okay, we want the sets actually here, uh, so can we just Set dot map Uh I would I don't think there's a map maybe for sets actually Let's see Um So like these are the ones in the map this is going to be a maybe A list of maybe set case. Let's just say here. What is why what do you want? What do you want from me? Couldn't match exact bit type Map map maybe Um, okay Okay, this this should be c map We want to be looking up in the c map Hmm Let me see here Okay, so This is going to be a set of k. Let's let's see what we can do with data dot set Google data dot set Um, we're going to be set mapping over No, wait So these are the ones in the map. Okay, we want to do tool list here Yeah, that's going to be okay Because we're going to be mapping over them. We don't actually need the sets. So this is going to be set dot tool list Of the current map Okay, cannot construct the infinite type Expected type map map map That is this is haskell Uh functional programming language is lazy so and the trick there is You basically write something and it's all going to be expressions and then like the the It combines piles to something called a spineless spineless tagless machine Or tagless spine machine or something like that and it just optimizes the shit Out of it. It's crazy stuff Um, so, you know, I write all of this code super algebraically and then It uses all the algebra to just just make it fast because it knows that it's allowed to do all these things uh, but Yeah, you can't it take can take take a bit of work because now we're now we're like writing Transitive closures because you have to express it in algebraic. I mean, you don't have to I could do this With uh with like variables and stuff, but that wouldn't be good content. Now would it? Okay, um in map map, maybe So what do I want here? So the the c map is a map of k to set of k So map k set of k Well, maybe maybe it's because oh, yeah, I think that's the thing. I think that's the issue here So we want to be looking at it like this, right? Couldn't match maybe maybe set k um So, okay All right, this has to be the question mark Cool, we mapped maybe so So these are all the sets for the current key So this is gonna be the list of sets For which the sets are in the Keys are in the map. So these these we're gonna add these to the key So we are going to say here Uh, so Okay, so okay now we have a a set list of sets. So we're gonna we just want a one big set set dot union Hey, where is it going? getting set dot union set unions, okay, this is gonna be set k and then we want to and then we want to She will we want to adjust I just So we want to adjust the key we want to adjust k with the union of Map So this is going to be map dot adjust of the set dot union Uh, what is wrong here? Map so map to the chip. Okay. Yeah, okay. It's going to take k like this Mm-hmm Okay, wait Like this But I was referring to the k here. So I need yeah k c map It's gonna be k c map This is one update step Yeah, it's the Moomin mug. It's the Sherlock It's one of my favorite bugs So this is one step of the update So let's see here So let's Let's do this And then let's apply the update once to the transfer closure But let's print something out in between putster lm after Okay, so Okay, so here we had okay bright white Contains shiny white And shiny white is not In the list. Okay. So dark olive contains dotted olive A dotted okay. There's no dotted. Um Faded olive There's no faded olive Dark orange contains. Okay. So we're trying to figure out here So, okay Which which one of these do we are we trying to update even? There's none of them in here faded Huh Let's see, um Faded blue bags dotted black buttons faded blue bags contain no other bags our black bags contain no other bags Yeah Okay, let's see Hmm Every vibrant plum bag contain five blue dark olive Bags must be color-coded and must contain specific lunges of other color-coded bags I see. Okay A bright white bag Which could hold your shiny gold bag directly Bright white shiny gold. Yeah. Okay. So shiny. So so bright white here White is bright white say shiny white Bright white should be saying shiny gold, right? Okay. I think there's an issue with our Our parsing that is inconvenient. Okay Uh, what did we say for our parsing? Is it because yes, this should be cc color Okay, now it makes more sense. We were always referring to the original color that was That was too much. All right, let's see. Um Yeah Also, if you're enjoying this, hey Yeah, I would appreciate a follow because like if you get enough followers you get like twitch affiliate and then And then they they pay me money For sitting here and coding Uh I mean, I could make money from coding, but This is just for fun. So, okay, right. This should be good. So shiny gold Uh Has dark olives And vibrant plum. No wait, the bright white has shiny gold Yeah, so after one update bright white should have shiny gold and bright white and muted yellow Bright white has dark olive What just shiny gold? Huh, I thought we were only doing Oh, are we like doing the entire update? Because we Because we fold our trans clothes is going to be the fixed eq Update of the map. Okay, so let's let's say here. Uh, no, yeah, it's just going to be fixed eq I want update Of the oh shit Yeah, but they pay me to do research Which uh Yeah That's not too bad, right? um Oh, no instance for okay. Yeah, I want to say I need the eq here or I actually need the horde key here Yeah, okay, so we already did the fix. I think it was because we were Why people burning me? I'm just trying to make my living roll Uh Yeah, okay, so these are the All right, so shiny gold Dark olive dotted black fatty blue vibrant plum so Shiny we shouldn't hold your shiny gold bag directly And I then I need to invert this Oh, we have a we have a new raid It's a lot of raiders today If this was the lost arc, we would have raiders of the lost arc Okay. No, that was a terrible That didn't even make sense. What arc are you talking about? um Okay, so now we've now we've We've found all the things and now Now we need to find which one of these contain shiny gold, right? let's see Oh, it's called member. It's called member Yeah, so now we so now we we found a transitive transitive closure so now We don't need to update here. Okay, uh Because we did the transitive closure and now we want to see Okay, so uh Let TC equal Trans close of the big map Okay, and now we want to say How many how many how many Can hold the shiny gold that is exactly those um So that is so we do We will say okay map Let's say it's going to be map Uh can hold shiny gold That is going to be so we're going to take the map doc as ox of the TC Of the big of the big one big map The big transitive closure. Let's say here Try TTC Uh I'm gonna actually use underscore here. I kind of like that convention where Variables are called with underscore and then and then like functions are snake camel case Okay, so map doc as ox Okay, now we're going to filter k comma v Uh Yeah, okay We're going to filter k comma v Based so we're going to filter filter it Based on A you know shiny Gold If shiny gold is a is a Oh should No, like this member Set dot member Of the value What is wrong here? Oh So let's say print Can hold shiny gold And then we're just going to get the first ones of these Let's see Uh, what is uh, can I what are the what are the associations here map dot? map dot map dot as ox Of of the TC Oh, it's this one. That's uh Okay, yeah map dot as ox That's the one that's wrong This should be okay Okay, uh Bright white dark orange light red minority yellow Those are the ones which Contain shiny gold as a transitive closure So bright white bright white community yellow. Yes Dark orange. Yes, and light red So we just print the length of this Of can hold shiny gold All right, that's four Now, let's do this again with the actual input So we get the input, uh input And we will print the length of the Of filtering shiny gold Let's do this in a one-liner, right? Because we have all the functions set dot member Of oh no My code is so big. I need to I need to My head is getting in the way That is too much Okay, thank plant set member of a Yeah, this is gonna be a big one on her So such a big one on her. We're not even gonna have it in one line a Is that even legal? Print the length of the filter of shiny gold is a member in a map dot ellums Of the Trans close trans claws Of The Folder Geez Look at look at this data data stream func programming. This is It's good stuff so So you first fold it and turn it into this union thing then we find a transducer closure And then we take the elements of the transducer closure because we don't care about the keys at that point We only care about the sets and then we filter those who contain shiny gold And then we print the length of that. So if we test this with a test input Uh, it will print for again So let's test it with the input Uh, but then we need the actual input. So let's see Get your puzzle input Oh, wow, that is a lot of input Let's see 192 Seems like a reasonable number. Are you ready? Did we do the transducer closure correct? Yes All right, that was Yeah, it's cool. I think it's cool. I think it's cool that we could like write a transducer closure Just to write out the bet All right, now let's hope that all the work we did actually pays off Uh in part two Okay, he's getting principally fly these days not because of ticket prices because of the ridiculous number of bags you need to buy Consider again, your shiny gold bag and most of it was simple Fatal blue dotted black, vibrant plum dark olive So he contains seven free fatal blue bags and four A single shiny gold bag must contain one dark olive bag And a seven bag within it plus two vibrant plum bags And the 11 bags within each of those Okay So now we're going to be using the integer values here Okay, um The actual have small trends are going several levels deeper than this example We should account all the bags even if nesting becomes topologically impractical So when we were finding the transducer closure, we were always like updating and just merging the sets now When we merge the set we actually need to look at the integer value and we have to be Multiplying the value for the current key with the total amount of the bags in there, right? So now we essentially have to write The transducer closure again except the update function Will be a bit bit bit worse actually can we Can we just Can we use the information we already have How many individual bags are required inside your single shiny gold bag? Okay The darker bags contain two two dark violet bags two Do we uh, so here I don't think we need to find the transducer closure. I think So the shiny gold bag contained two dark red bags and then we just look that up and do two times whatever this contains Well, that would be a power of two Right and this is not a 126 is not a power of two Okay, so let's see a shiny gold bag one dark olive bags So and the dark so let's see here So one shiny gold bag contains a one dark olive bag and two vibrant plum bags And the dark olive bag three favorable bags four daughter black bags and that was one time seven This was a one dark olive by sound back when there was two vibrant plum bags Yeah, and then those two five plum bags Contain 11 bags within them and then you contain. Okay. So here we just need to go and go go into the map and then look up recursively Okay, that should be way easier than writing transitive closures damn it But I was fun. I think I I like writing transitive closures I think it need to be a bit special To like writing transitive closures. I don't think it's a common trade, but you know, they are kind of they're they're so nice. They're so clean They do they're they're mmm. It's always like It's such a such a nice way to go about things Okay, so solution Two let's just copy this and say So solution It's going to take a listless list of strings To an int Oh, no Oh, shit Yeah, the editor does this sometimes it like If I paste too much Like it will just stop Doing vin key bindings For a while I actually might have to restart it Because it like it so now what it's doing now is that it's trying to parse like the all the file all the lines. Okay, let me just yeah, there we go Yeah, exactly get line length whatever. Yeah, okay p And then this should just be print solution Okay, now solution two That is going to take this map here string string to int map solution to That is going to take the map a string comma string of int And it's going to take a key And it's going to return an int What are we going to do with it? Well solution to bags so This is going to be okay First we're going to say We are going to Take the bag. We're going to look up Ah, wait. No, this is this is not a it's we want to take the the actual map this map of string this one It's a big one and Okay, so here we want to say so this is going to be the big thing It's going to be a map string comma string To these things and then it's going to take in a string a string. Okay So, okay Okay, so first of all, we're going to say So case We are going to look up map dot look up We're going to look up. Um We're actually just going to say we're going to look up this String here, right? key we're going to say key Look up the key in the map, right? key map Bags of okay, so if Um, if there is no entry for that bag It's actually an invalid bag, right? But uh, so But then then we will just return zero, right? That was I don't think that can happen, but it's okay We will say case key bags of Nothing, we're going to return zero Just Okay, so if we if we get if we have a result then We are going to say And here we're very much hoping there's not going to be like a loop in the thing, right? So if it's just a map just mp then Then what we're going to do We are going to say So for that map, we are going to say map dot assox of the mp. So this is going to be a list So that's going to be the list of key comma values in that map um So we are looking up. So this is going to be a Where so this is going to be a a list of string comma string mpa This is going to be string comma string comma int That's what this is going to be a list of a mpa equals map dot assox of mp Okay, uh So and for each of those so let's see So we're going to use a curry function here, which essentially takes a function of two parameters and transforms it into a function of Of a pair Yeah, so it's we're going to use uncurry So we are going to So we have a list of strings of int, right? Okay. We don't need to uncurry stuff um So for for each In that map So f okay key v. We are going to return K so F zero v is just going to be zero We don't want to loop if there's zero thing. We don't have to count what's in there if that's zero. So f k v. So this is going to be non-zero It's going to be k times solution two Of the bags uh of the Of the No, yeah, so it's going to be k zero It's going to be k k val. So it's going to be value times solution bags key So then we're just going to recursively look up for each one and we we we calculate that So f here it's going to take a string comma string And an int and it's going to return int um So we are going to say So we're going to the values Vals It's going to be a list of integers and valves is going to be map So yeah, now he uses uncurry function, right? So we take this and turn it into a List of operates on this pair uncurry f On a mpa And then we take the sum of those so Yeah, so we're going to take the sum of the valves And the problem here Solu solution Sol two in Could match expected type. Okay, wait map. Oh This is again this thing eggs key Okay, let's try solution two on the testing put but we first have to Create the big map. So let's just let's just print the print solution two on the big map Uh, so this is going to be Of shiny gold. Yeah shiny Gold Let's see here. What happens? Well, we got zero It's not good um How about What happens what is happening? Let's print the big map first We already printed the big map, right? We don't have to print these So this is like we said zero somewhere and that's That's wrong, right? okay, uh so For the first one so shiny gold And let's let's not let's just show we're Let's not not the let's let's do this for the big map Let's let's look at the big map in this kind of More regular format from shiny gold one. Okay, so shiny gold dark olive one wyburn plum two Okay, and then we look up dark olive one um So solution for the big map. Okay, so look up We look up the key shiny gold Uh, let me see print Big map Map dot What if I look up look up that right? Yeah, I get from all dark olive one wyburn plum two Oh, I think I think if they contain nothing it should be It should be one Because they contain those bags plus the bags within them So this here is not just the sum vowels. It's also so it's One plus the length Val no one plus the So I think this will be V plus I think it's like this actually um, what do we get then here for Here we get 32 For this one. Yeah, and then let's see here for the test input two So we got it right for the for the previous test input now. Let's see Now let's see what happens here new file test Let's see this was Way easier than the than the first part of this If we got it right that is Uh big map So how do we so solution two Should really okay, um Let's see So two big map. Let's just let's just Call this here function two big map And this is gonna be This the list the list of strings No, so we just want to have it like this And this is gonna have a two big map So this is a string to a map of string comma string map string comma string int Okay, and then this a This this will just be Big map is just gonna be f map two big map over Get input. No, it doesn't doesn't like that Why not Ish f map to big map. Oh, let's see a big map In okay Let big map equals two big map in but Shouldn't that isn't it the same as two big map F map or the test input? Yeah, okay. That's what I thought I was writing. Anyway, um So big map t2 is going to be two big map over get input test input two And then let's print Uh, these are all These are all for the second one. So big map t2 splint solution two for a big t2 Okay, compiling one or two 32 126. Okay. Now we got it right for the both of the two inputs So it's I'm pretty certain It's gonna work for the test input So let's see big map input. All right, this is still test input since the input 12 128 that sounds like a reasonable number, right? Let's check it out. All right We got part two We didn't have to write any transitive closures, but you know, I hope you guys learned how to write Transitive closures. The second part was just easy. That's just looking up in a map But I think I think we might have done this a little bit too generally I think I think because we were only like checking the elements We didn't actually need to compute the complete Transitive closure. We we could have gotten away with just um Just checking for elements like we could probably have gotten away with the same thing we did here Um, which is to say, you know, we could have just checked for the element instead of Instead of saying Yeah, so I think I you know, we could have We could have said one here If it was too shiny gold or shiny gold and then zero otherwise and then just summed it up Let's let's try that actually Solution one redo redo Okay, so this is gonna be So this is gonna be if it's shiny Gold Yeah, you think these guys might work? Let me see Here we got zero Let's see. Oh, but is it because we didn't do plus one or something like that Let's see Okay, I don't think yeah, so here we don't iterate Thanks I like this you got to see the keyboard and I get away with having super clicky keys Because you can see it. Otherwise you would just be like, oh, that's such a annoying sound but Let's see here if it's if shiny if it is shiny gold Then it is one plus If it's not shiny gold Okay, then it is Solution one redo of the bags of Okay, now, I think we would have had to do We would have had to do something different for solution one redo Maybe we did have to do the transitive closure. I like I I don't I don't think so I feel us because we kind of generated the entire transitive closure We could have taken a shortcut somewhere So instead of computing this entire set And then and then, you know, we just check if it's a member which one's which one of them it says member in We could probably have like started at each key and then kind of recursively gone through the thing And if you end up seeing shiny gold, then we add one. Otherwise No, let's do that. Actually, I want to see if we had to do this, right? So solution one redo That's going to be this might miss type big map It's going to be this thing And then it says big map Okay, so let's take the big map and it returns an integer Okay, so here we're going to say Okay, so here we're going to say solution one one redo A map so let's just hard code it right so So for all the keys Okay, so let's see here Where case equals keys so map dot keys of the map So for all the keys in the map We want to we want to go through we want to check if we can end up with shiny gold Okay, so That's going to say Okay, so for all the keys So check if check if the Okay, so I want to do like a nice recursive solution here So for all the keys in the map We have to check if Shiny gold is a member of the transitive closure, right? and So let's say Has shiny gold So this is going to be key comma value. So shiny own Crew Okay, wait, so no, so okay, so we we we we took take it to the set So we want the the the set here, right? So the the one we've got with F map a map dot keys set So we take the map we say a ks equals F map Key s So this is going to be mp mp k I'm not naming these things very well. I think map k set k mp k equals the f map of the keys set of map So now we turn it into just this key set So now we want to see Okay, so has shiny gold So this will take in a set k and it will return true So has shiny gold Set case So let's if this is set dot empty That's false, right Has shiny gold Uh, that's actually let's not do it into the key set So let's let's let's do Yeah, we want the key set. We want the set dot two list of the key set Uh, I'm behind And we want this to be a list of keys Hmm, right This should be Come on stream Okay, this needs to be mapped our key set, right? Okay, so has shiny gold A list of case list of string Oh to boom Has shiny gold For empty list equals false Has shiny gold of shiny gold This Prepanded to rest equals true Okay, and has shiny gold Something else That is going to say Uh, no, this this is gonna. Okay, this is not gonna be an inch. This is gonna be an It's gonna be boom So if it is shiny gold, it is true and we we've finished we found it, right? If it isn't shiny gold Then we want to check Then we want to check Uh Has shiny gold So we then we want to check if if has shiny So then we want to check. Okay case x Map dot this operator Uh mpk of So if we find if it if we find if we look up the list and we have some elements, then we're just gonna say just so Nothing is false Nothing is false is that What is this? Uh, what are you complaining about now? Uh, if it's I think I I am there's some indentation error here, right? just else Then we want to say Any Has shiny gold else but Yeah Yeah, okay. This is I I I always screw up this operator map mpk x Okay, so What is what is this? Okay, so If I look it up in the map, I will get a list of strings, right? Yeah, I should get a list of strings, no And if it has And then I want to map over the strings, right map has shiny gold else but it's complaining because A Couldn't actually package. Yeah, and then okay. Well, how's the oh, yeah, sorry This is not supposed to be any this supposed to be or Dollar map Couldn't match that just list of list of else X here is This is a list of list of strings. Okay the return value here is a maybe list of strings Okay Is this Something like this. What is this el here is list of string comma string Okay And then I I map this Okay, and I want to Apply some function here Oh sheet I just apply the function recursively Uh, yeah, and then this is going to be the length Of filtering has shiny gold on keys MPK It's going to be a list of list of strings. Why is There is something very weird going on. Okay, there's something. He's not clicking here Uh data dot map. Yeah, so I want a list of string elements, right? Okay This is what if I just do MP Uh, so ks equals map dot keys of mp ks is type Oh, okay. Yeah, so it's Okay, right So this one takes in a list of list of strings So Okay So I really so I want to I want to create the list of Uh strings Let's see what solution root one redo does now bring What was it supposed to say what is solution one say for us? Okay. Um What does what does this say here? Let's see Is that yeah, I feel like I'm feeling just the simplest thing here I mean I managed to do the like overly complex version but but but yeah I mean because like I've wrote the transit of closure thing but now yeah because now it's just saying that all of them have contain it right which isn't like so because it's it's saying that the empty list is like actually not containing it right this is for the input so let's see it on a test input so it is giving four on the test input but on the actual input it's saying it's saying only 13 I think I think it's because I only go one level deep in this one so these are all like the top level ones that contain them but I don't have I don't have all the possible values of bags here I think that's the issue anyway I think we spent too much time on this solution one where you do I'm just gonna be happy with my my my transit of closure solution probably overkill but you know at least cuz I cuz I I'd rather write a big general solution that works than one that doesn't write so let's go over it a bit what we did here so we just parse it into these maps all right so we parse it into like a map that said you know this is the one white and then it contains a list of values so essentially we parsed it you know we parse this into something we could operate on you can see it a faded blue here has nothing so it has a nothing empty map right and then we wrote some pretty printing functions and then we wrote the transitive closure so what did that do I mean that kind of goes into the map and it finds the transitive closure of that key so it takes that key it takes all the sub keys of that key and it adds to that those sets of keys all all the sets that can be reached from those right so and then the trick was okay then we went into all the all the bags and we found out all the bags that could be reached starting from that bag saved that in the map and then we just figured out which ones had shiny gold as a like a reachable thing at the end and it and it worked and like that's this is not a lot of code to do that right and it's like so this we can even you know this is you know we do the transitive closure that's like the general way to do it right and then we just yeah we we built the transitive closure when we found out which ones had the shiny gold as a final member like which like if starting from these you could reach shiny gold right solution two is way simpler then we just had to kind of recursively look things up and add them together and I'm like I just usually solution like part one is easy and then part two is a bit harder and like you can usually use your solution for part one for part two so I'm thinking like we could replace some of this with like one somehow and just get the final final solution right for the thing but that was that was not to be I couldn't I couldn't figure it out and you know I would have to like sit down and think about it a bit before I did it but you know we already solved it so and that's like you know I'm not so not so excited about just trying to write in a different way I think because I think this transitive closure it's just such a like a generally nice way to do it and you know it doesn't take too long 320 seconds for for all of it oh this is like twice the same no yeah so how how long did we do if we just take off everything except the thing we need the complete solution without any printing or anything takes 360 milliseconds I mean that's that's not super fast but that's not too bad for doing the transitive closure all right I hope you guys and gals learn something how to write Haskell code and you know don't be afraid of just doing the transitive closure because it is it works and then you know you're not gonna spend a bunch of time trying to figure out why your kind of hard-coded solution doesn't work like this will always work for all of all of all maps like this would just find the transitive closure of them and hopefully we can use it later all right that's all I have for you tonight thanks for staying so long we were like two hours today we're usually like 40 minutes but you know these are getting harder and that's what's fun I just hope they don't get too hard I don't want to not solve these on stream anyway thanks a lot for today and yeah see you again tomorrow at five o'clock UTC which is six o'clock in Europe I guess it's noon 11 ish in East Coast US I am not quite sure what the time is there but anyway thanks a lot and see you tomorrow all right