Thanks for this. I enjoy reviewing your videos each year. I notice you mention that a Map is just a .net Dictionary. This isn't actually true, as it has Log n lookup time instead of constant lookup time. This is because Set and Map are both tree data structures, which helps with immutability and persistence. I've been using Sets and Maps to speed up my code, but I might have to think again about this!
@JamesBData18 күн бұрын
Glad to see you're back for 2024!
@matthewjackson9288Ай бұрын
I got pretty good time processing the list forward using binary recursion (or I guess ternary for part 2) at 0.15s for part2. At each step you can check if the sum or the product would be greater than the target and stop checking down that branch. However, it seems processing backwards allows for pruning the branches better. Glad I checked your video out. (code example is below in read more) let isEquationSatisfiableWithConcat (lhs, calibrations) = let rec loop runningTotal calibrations = match calibrations with | [] -> runningTotal = lhs | c :: remainingCalibrations -> let runningTotalProduct = runningTotal * c let runningTotalSum = runningTotal + c let runningTotalConcat = concat runningTotal c let productSatisfies = if runningTotalProduct > lhs then false else loop runningTotalProduct remainingCalibrations let sumSatisfies = if runningTotalSum > lhs || productSatisfies then false else loop runningTotalSum remainingCalibrations let concatSatisfies = if runningTotalConcat > lhs || productSatisfies || sumSatisfies then false else loop runningTotalConcat remainingCalibrations productSatisfies || sumSatisfies || concatSatisfies match calibrations with | c :: cs -> loop c cs | _ -> failwith "Expected at least one calibration component"
@jhjl1Ай бұрын
Thanks for posting, I am new to F# and I learn so much from your videos. I solved this puzzle by using a quicksort using a rule checker function to portition the update list. If the sorted list matches the initial list then it is valid. For part 2 the sorted list is the one we want. Not very efficient but my head was scrambled by over complicating things!
@JoVanEyckАй бұрын
That's awesome, welcome to the F# community! It's tough combining both solving these puzzles and learning a new language like F#, good job! 💪 It's great to hear you're getting value out of the videos.
@screechpicassoАй бұрын
On part2 couldn't you keep the parser from part1 and insert a mutually recursive function before the regex from part1. Something like `let rec splitOnDont enabled remainder = if remainder = "" then enabled else let [|e;r|] = lines.Split("don't()", 2) splitOnDo (enabled + e) remainder and splitOnDo enabled remainder = if remainder = "" then enabled else let [|_;r|] = lines.Split("do()", 2) splitOnDont enabled remainder`
@JoVanEyckАй бұрын
That sounds doable, yes! I'm waiting on a more complex parsing puzzle so I can play around with parser combinator libraries again, those do a lot of that recursive "remainder" and backtracking heavy lifting for you. Have you played around with FParsec? It's got a bit of a learning curve but it's worth the effort if you have to do non-trivial parsing: www.quanttec.com/fparsec/
@skyswimsky1994Ай бұрын
Learning more F# and trying to be idiomatic as I go along and check those videos out at the end of the day. I thought I was being really smart using fold and keeping state of 2 digits+the current one, but the second part really screwed me over with a bunch of edge-casing and all.
@JoVanEyckАй бұрын
That's cool! Do let me know if you come up with different solutions! I tend to do the simplest thing that could possibly work for these adventofcode puzzles. But most often I hit a wall somewhere because the simplest thing is wildly inefficient and solving it within a reasonable amount of time requires a full rewrite 😅
@Akronymus_Ай бұрын
For part 1 I did 1 pairwise with substraction to get the delta between entries, then another pairwise where I multiplied both values and checked if the result was > 0 to check for monotocity. For part 2 I did a mapi over the array and returned the array, except the one at the current idx position. Then fed that into the first parts code, but with the condition that one of those generated arrays or the original array must produce a valid result. Brute forced but fast enough
@GetrektinpeaceАй бұрын
Loving the videos. Will you be continuing with your Web Api series? im invested!
@JoVanEyckАй бұрын
Thank you! Yes, I'm planning to do that in 2025 once I've recovered from #adventofcode 😂
@Michal_PeterkaАй бұрын
Rider seems nice. I installed it after the licencing change to free for non-commercial use. But I still spend more time in VS Code because I am lazy to set it properly and I am missing some hints provided by Ionide. BTW: do you prefer in part1 List.zip |> List map over just List.map2 because of readability or some other reason?
@JoVanEyckАй бұрын
For me personally rider is a step up from visualstudio, although I did not try F# in vscode all that much. RE map2: Not at all, I simply haven't used map2 enough to have it readily available in my head. Thanks for the tip!
@000dr0gАй бұрын
Thanks for doing these! Unlike previous years, I've forced myself to do the puzzle first, which makes watching your version even more valuable. List.transpose is cool!
@JoVanEyckАй бұрын
That's smart! Please do let me know if you come up with different solutions, I'm always interested in how other people tackle these problems.
@TimSchraepenАй бұрын
First time I saw a non-responsive AoC page! Good on you for livecoding this! <3
@donarnold8811Ай бұрын
I had totally forgotten that List.transpose exists and messily coded it by hand. Thank you for the reminder!
@JoVanEyckАй бұрын
Nice! I've seen people use List.unzip, that's another alternative for you!
@Michal_PeterkaАй бұрын
Same here. I used transpose many times but this had only two colums so it did not get to my mind and I was maping it to int * int and then unziping.
@MrJimGiantАй бұрын
Good to see you back here on KZbin. I really enjoy your F# live coding.
@JoVanEyckАй бұрын
Good to have you back! Are you solving the puzzles this year?
@MrJimGiantАй бұрын
@@JoVanEyckI'm too busy at work, so your videos are my way to follow the event. No pressure ;-)
@JoVanEyckАй бұрын
No pressure 😅
@Isti1153 ай бұрын
Thanks for doing these videos! It's interesting to see the though process of someone who's more familiar with the language. Probably I will do this year in Scala instead of F#, but still, it's really great to see that there's content available for both languages! Are you planning on uploading this year too? :)
@JoVanEyckАй бұрын
Good luck with your Scala adventure! Day 1 is up now: kzbin.info/www/bejne/rYqVmGV_g6mqask
@Zainjerr5 ай бұрын
YES YES YES! This is exactly what I needed! This series is a gem I hope this helps further the adoption of F# by mainstream developers
@davidgrant58876 ай бұрын
Would love to see episode 3!!
@TreeLuvBurdpu8 ай бұрын
You know what would probably be more interesting instead of googling "how do i create a record?"? Ask codeium right there in your IDE.
@AnythingGodamnit8 ай бұрын
I switched from VS to Rider not too long ago. Once I got over the initial Who Moved My Cheese friction, I simply could not believe the quality of life improvement I was getting. It's embarrassing at this point how much better the F# experience is within a JB product than within a MS one. That said, my employer paid for the license and I have no idea of the cost because I never looked into it. I do think I'd struggle to go back to VS at this point, and this recording has reminded me of the day-to-day struggles with doing F# in it.
@KurtMueller9 ай бұрын
Will this series cover authentication and authorization?
@Pretence019 ай бұрын
Besides from demonstrating some cool F# features, thanks Jo for confirming VS is still the lesser IDE 😀
@JoVanEyckАй бұрын
You were right all along! I switched to Rider for this year's advent of code and haven't regretted it yet 💪
@mattgreer69729 ай бұрын
Thank you for keeping your stuff-ups in the video--it's so reassuring to see someone making the same mistakes I do--installing Nuget packages into the wrong project (and fix by copying and pasting project config) or getting backslashes and forward slashes muddled up. I suppose that almost everyone does this kind of thing, but it's so rare to actually see it--made me feel much better about myself! Will definitely be following along--looking forward to more (especially persistence and data-validation). :)
@JoVanEyckАй бұрын
Thanks for the feedback! That's exactly what I'm trying to showcase with my current advent of code live-coding series. Even the most experienced engineers struggle from time to time, most content createos just cut those bits out out in post 😀
@pino67829 ай бұрын
I think Giraffe got new maintainer(s) so it should be ok. You're making some great content! Thanks!
@gp53819 ай бұрын
keep going, really nice content!
@robhunt83789 ай бұрын
I've tried Rider and in many places seems to be more friendly to F# than Visual Studio. It will autocomplete record fields for you for example, which to this day VS still won't do. It has had this nasty bug for a long time where indent guides are not correctly aligned, which is a big problem when working with whitespace-sensitive languages :D. There's also the issue of licensing so ... By the way, how do you get code autoformatting in Visual Studio? 🙂 Oh, I see there's a VS extension for Fantomas, it's probably that.
@JoVanEyckАй бұрын
Correct, I use fantomas. Your comment pushed me over the edge to give rider another try and I haven't looked back since. Thanks for the suggestion!
@NielsNuyttens9 ай бұрын
Good stuff! Funny how you start on the "outside" of the application, I always begin at the domain side :-)
@JoVanEyck9 ай бұрын
I think both approaches are equally valid, it might just come down to personal taste 🍧 Outside-in works best for me personally: it trims all the fat and just-in-case bells and whistles I tend to add otherwise and it allows me to focus on the public API/devex/usability of everything I built. But outside-in requires a ton of discipline to nudge the design incrementally or you end-up with a seperate transaction script copy-paste for each different api call. I used to think outside-in designs always ended up in mocking-hell, but I've picked up some tricks that make mocking unnecessary (like injecting data retrieval functions here, that stuff is super easy to test without mocks).
@johnprincipes80589 ай бұрын
Finally! Something real world style in F#.
@olavre9 ай бұрын
Good stuff! Funny to see (or maybe not) that VS is still acting strangely with the red squiggly lines - I remember that from your AoC videos! Must be frustrating as it slows down the coding. Do you have the same problem in VS Code?
@JoVanEyck9 ай бұрын
Oomph yes. I have not tried F# alternative IDE's like VS code or rider for a while now as they always seem to lag a bit when a new F# version releases, but that does not seem to be a valid argument anymore now that VS also fumbles the ball 😅 Do you have experience with F# in vscode? Do you like it?
@olavre9 ай бұрын
@@JoVanEyck Hehe true! I've used F# in vscode for AoC in 2022 and 2023, and it worked fine with Ionide extension! However at some point it would'nt send selected lines to the FSI terminal with Alt + Enter, so I switched to Visual Studio heh. Which worked fine by the way, no lag with squiggly lines.
@strumjedi9 ай бұрын
Keep making these videos, they are a lot of fun.
@JoVanEyck9 ай бұрын
Thank you! More on the way 🚂
@JustSomeAussie19 ай бұрын
I’ve been looking forward to this
@JoVanEyck9 ай бұрын
Thanks for tuning in, good to have you!
@robhunt83789 ай бұрын
Looking forward to the next episode. Any thoughts on Giraffe's current status and its most recent fork, Oxpecker?
@JoVanEyck9 ай бұрын
I did a liiiiittle bit of research before I picked giraffe. It's not maintained anymore and missing some crucial things I need when writing production apps (openAPI integration for one) which it currently lacks. Suave.io looked promising but the hello world docs did not even compile with the latest version which made me not dive too deeply. Oxpecker looks very interesting! I won't be migrating away from Giraffe in this series (yet?), but that's definitely one I would take into account next time I build an F# backend!
@davecook18059 ай бұрын
Perfect timing! Planning on spiking out this exact thing with a few of the team this week!
@JoVanEyck9 ай бұрын
Oh that's awesome! How did it turn out?
@donarnold88119 ай бұрын
Thanks for introducing me to Unquote! I'm really looking forward to further installments in this series!
@JoVanEyck9 ай бұрын
You're welcome, thanks for tuning in!
@codewithkv9 ай бұрын
This is awesome! Excited to build with F#
@JoVanEyck9 ай бұрын
Thanks! Are you building something yourself?
@codewithkv9 ай бұрын
@@JoVanEyck I'm using Giraffe to build a simple dashboard to display market data for stocks and crypto. Trying to apply the knowledge gained from your video and other sources.
@OrdridOfficial9 ай бұрын
This is just the foothold I need to get started making projects in F#. Thank you so much for this.
@JoVanEyck9 ай бұрын
That's awesome! Do let me know if you end up building something in F#, it's amazing to see more and more people build real stuff with it!
@guillaumedechambre91389 ай бұрын
Pretty cool. More F#!
@JoVanEyck9 ай бұрын
Thanks :) More on the way!
@nickbarton319110 ай бұрын
Just stumbled on property testing today, I've written a lot of algorithmic code that would have benefited from it. If the random data causes a test failure, we'd still need TDD developed tests to find the problem as the next run may pass. You were also doing manual mutation testing to prove that your property tests were valid. Could be a powerful combination where it matters. For day-to-day testing, I'd never get anything done with this as the test turnaround would be so slow. Maybe, segregated tests would work. Very interesting topic, thanks for the demo.
@JoVanEyck9 ай бұрын
Thanks for your feedback! That's a really good point about non-determinism of these property based tests. Most pbt frameworks, fs-check included, show you the random seed that was used to generate the random data in a specific test run. You can use this seed to reproduce the exact same scenario locally. You're right, it makes a lot of sense to copy paste the shrunken failing case in an example-based unit test!
@GaryChike Жыл бұрын
Very cool using ray casting to help solve this problem - makes me think of Wolfenstein and Doom tech.
@boxacuva Жыл бұрын
Very nice i liked it a lot. I got a question on how do u execute a specific Method and execute it?
@JoVanEyck Жыл бұрын
Hi @boxacuva, that depends on your editor/IDE/installed plugins. For visual studio and vscode the default shortcut is "alt+enter" aka "execute in interactive" learn.microsoft.com/en-us/dotnet/fsharp/get-started/get-started-vscode#write-your-first-script I have an older video on how you can do the same with C# code: kzbin.info/www/bejne/qJyuqJ-kl56bors
@josephmargaryan Жыл бұрын
is it possible to pay you to help me with a simple fsharp programming assignment? Estimated time is maybe 1 hour
@zdabka Жыл бұрын
First part of this day is really simple and clear, especially if compared to a few previous days. Thanks for the video!
@Baan616 Жыл бұрын
I've been learning F# for the past month and found working on AoC alongside you very productive. First I do my best at the problem, then look at your vids to see what language features I could use to have a cleaner solution. Thanks for putting them out!
@mat5ch Жыл бұрын
I really liked this series so far. Your videos made me want to give F# another spin after only dabbling with it in the past.
@andreasmewald2439 Жыл бұрын
What kind of extension are you using for auto-formating?
@JoVanEyck Жыл бұрын
Fantomas is built into visual studio, you can use it in other IDE's as well: github.com/fsprojects/fantomas
@FDominicus Жыл бұрын
Your idea with Lenth was good, it should work if you used length-1 because afaikt there can Veblen just one overlap
@NKCSS Жыл бұрын
It’s good that you found the bug 😊 they do have an example in The test, eightwosometving with the t overlapping. It’s how I spotted it myself.
@WalrusPug1 Жыл бұрын
In handType you could have counted the Js and enrich the pattern match tuple. Then a (IsFourOfKind, 0) is still a FourOfKind but a (IsFourOfKind, 1) becomes a FiveOfKind for example. :)
@JoVanEyck Жыл бұрын
That sounds correct and way less troublesome than expanding Jokers into all different possibilities
@MrJimGiant Жыл бұрын
If I understood your call for help on remembering compare results, then I remember the compare function as subtraction. So compare a b is like a - b. If the result is positive then a is greater than b. Negative means that a is less than b. Zero then they are equal.
@JoVanEyck Жыл бұрын
That's substraction metaphor just might stick in my head, thanks! learn.microsoft.com/en-us/dotnet/api/system.icomparable-1?view=net-8.0
@oysteinhaga Жыл бұрын
I used groupby on list of cards in a hand. In addition I kept the max count of cards in the groups. This way it was easy to match with hit count. Like this let toQuality1 hand = let hitCount, maxEqualCardsCount = groupCards hand match hitCount with | 1 -> Five | 2 -> //Four, House match maxEqualCardsCount with | 4 -> Four | _ -> House | 3 -> // Three, TwoPair match maxEqualCardsCount with | 3 -> Three | _ -> TwoPairs | 4 -> Pair | _ -> Highest With jokers, it was slightly more options to match with. let toQuality2 hand = let jokerCount = getJokerCount hand let hitCount, maxEqualCardsCount = groupCards hand match hitCount with | 1 -> Five | 2 when jokerCount >= 1 -> Five //Five with joker | 2 -> //Four, House match maxEqualCardsCount with | 4 -> Four | _ -> House | 3 when jokerCount = 3 -> Four //Four with joker .... and more...
@chewbaccarampage Жыл бұрын
Great walk through. I tried using a masking technique in F# after seeing people in the APL community use that. It's worth a try, but I'm not familiar with the technique enough, so it was really painful. I saw some solutions in Python that used masking libraries as well and their solutions were only 20 lines and extremely elegant.
@JoVanEyck Жыл бұрын
Do you have an example somewhere? I can't find any reference to masking on the adventofcode subreddit
@chewbaccarampage Жыл бұрын
@@JoVanEyck Unfortunately, I couldn't find the post. It was on the Advent of Code Day 3 solutions thread, but there's too many posts there now. The general idea I came up with was: 1. Create a matrix with only the symbols as booleans. 2. Union this matrix with a version shifted up and shifted down. 3. Create a matrix with only numbers. 4. Flatten the both arrays 5. Zip the arrays 6. Read all the data and keep any numbers that start with a symbol, contains a symbol or ends with a symbol. Otherwise, I saw this idea from one of the videos from "code_report" on youtube. I think he solved the sum of squares problem with a data mask and using boolean algebra to apply it to the data matrix. To do this properly, I think I need to fix step 6 and effectively apply the boolean mask on the data... but I'm not sure how to do that. The python solution used a 3x3 matrix as a boolean mask and used some library to perform to mask around the symbols.
@olavre Жыл бұрын
Todays puzzle was a breath of fresh air! Nice tip about enriching the types when piping 👍
@zdabka Жыл бұрын
Very cool idea of using the range. I actually was running into a tiny bit of a problem because initially I tried to fit everything into a map. while it worked for the test input, real data proved my decision very wrong xD thanks for the video!