7 Ways to Solve Minesweeper

Sdílet
Vložit
  • čas přidán 2. 06. 2024
  • We look at 7 different solutions to Exercism's Minesweeper exercise - exploring solutions using nested loops, clever use of min/max to simplify bounds checking, functional pipelines and using two-dimensional matrices in Julia, C++, F#, Rust, Ruby, Crystal, and Java.
    Kick back and enjoy 30mins of learning with Jeremy and Erik, then go solve the exercise in your favourite way on Exercism.
    Solve the exercise at: exercism.org/exercises/minesw...
    Join #48in24 at: exercism.org/challenges/48in24
    Featured solutions:
    - exercism.org/tracks/cpp/exerc...
    - exercism.org/tracks/java/exer...
    - exercism.org/tracks/rust/exer...
    - exercism.org/tracks/crystal/e...
    - exercism.org/tracks/julia/exe...
    - exercism.org/tracks/fsharp/ex...
    - exercism.org/tracks/ruby/exer...
    Timestamps:
    00:00:00 Introduction
    00:00:45 C++: for loops and indexing
    00:06:25 Java: for loops with StringBuilder and min/max for simplified bounds checking
    00:10:31 Rust: functional pipeline using map, filter and neighbor deltas
    00:15:51 Crystal: function pipeline and string translate method to replace chars
    00:20:07 Ruby: Starting with the mines
    00:24:46 Julia: convert to 2D matrix and iterate over mines and update neighbors
    00:31:07 F#: use Array2D type and extra padding for easy bounds checking
    00:39:26 Conclusion
  • Věda a technologie

Komentáře • 20

  • @robinheyer708
    @robinheyer708 Před 14 dny +3

    I like these grid navigation style exercises and I love that Crystal implementation! But it does sound a bit weird when someone talks about a Crystal method... which I just checked is what they are referred to officially. Maybe they want to change that to function.
    I half expected a more pure OOP version with a Point class that has its own Neighbours array.
    I used a Span in C# (which is sort of like a slice in Rust, I think) that I pre-allocate with the size of the first string and then, since there is an action on each character, you can keep using the same span in every row loop, and create a string in the result array based on the span at the end of the loop.

  • @computersciencestudentriverbat

    I learn so much from these conversations meets tech-talks. Also love the chemistry too, just two dudes hanging out and talking about something they care about, nothing beats that sincerity. I would love to see more developer talk plainly about how/why they do X or Y. Really glad y'all are doing what you do!

    • @ErikSchierboom
      @ErikSchierboom Před 16 dny

      Thanks so much! What a lovely comment

    • @exercism_org
      @exercism_org  Před 13 dny +1

      Love to read. Thanks for all your comments and support - really always appreciate them! :)

  • @ganderston
    @ganderston Před 16 dny +3

    thank you!

  • @benitoe.4878
    @benitoe.4878 Před 17 dny +4

    Great video, thank guys. "Minesweeper" should be re-classified to "medium". It's above the level of other "easy" exercises on exercism.

    • @exercism_org
      @exercism_org  Před 16 dny +1

      Thanks! Exercises are rated differently per track as they can vary wildly in difficulty. If there's a specific track that you found it misclassified in, please do open an issue in the forum (forum.exercism.org) and the maintainers of that track can take a look! :)

  • @rodolfo_carvalho
    @rodolfo_carvalho Před 16 dny +3

    At 34:56 Erik's comment that "the author had to use mutable" in F# made me intrigued! So much so that I went to install dotnet and run the F# interactive shell. After reading the docs and a few attempts, @Exercism turns out there is a short and readable way to sum items in a 2D array:
    > let a = array2D [[' '; '*'; ' ']; [' '; ' '; '*']; ['*'; '*'; '*']];;
    val a: char[,] = [[' '; '*'; ' ']
    [' '; ' '; '*']
    ['*'; '*'; '*']]
    > a.[0..2, 0..2] |> Seq.cast |> Seq.map (fun x -> if x = '*' then 1 else 0) |> Seq.sum;;
    val it: int = 5
    > a.[0..2, 0..2] |> Seq.cast |> Seq.filter ((=) '*') |> Seq.length;;

    • @rodolfo_carvalho
      @rodolfo_carvalho Před 16 dny +1

      Oh, and the whole "board" can be removed too. Indexing out of bounds is apparently ok, so not need to do explicit bounds check either :)

    • @ErikSchierboom
      @ErikSchierboom Před 16 dny +1

      That's really cool. What I meant to say was that the author tried to use Array2D functions primarily, and that they don't lend themselves well to the summing

    • @rodolfo_carvalho
      @rodolfo_carvalho Před 16 dny +2

      @@ErikSchierboom Yeah, I love your commentary and how you and Jeremy interact. You're always very insightful! When I saw "mutable" on the screen I almost immediately paused the video and went "there must be a better way to do it", only later did I listen to the rest and realized the nuance you added to it. Spot on!

  • @phix3471
    @phix3471 Před 17 dny +3

    This is what it looks like in Phix (no such track yet, but soon)
    global function annotate(sequence board)
    integer h = length(board)
    sequence res = repeat(0,h)
    if h then
    integer w = length(board[1])
    for y,line in board do
    string outline = ""
    for x,ch in line do
    if ch!='*' then
    integer m = 0
    for i=y-(y>1) to y+(y1) to x+(x

    • @exercism_org
      @exercism_org  Před 11 dny

      Nice! Phix is similar to our Euphoria, I think? Have you played with the OpenEuphoria track yet? exercism.org/tracks/openeuphoria

    • @phix3471
      @phix3471 Před 10 dny

      @@exercism_org yes, and yes!

  • @AbdulrahmanSheikho
    @AbdulrahmanSheikho Před 10 dny +2

    I was planning to solve this exercise before the video came up using Elm, which I started my journey on exercism this year primarily with it, (plus some Go & Python "haven't solved it in either of them yet") and I refrained from watching the video until I solve it.
    I found that when I try to solve an exercise, I over complicate the problem if there is no obvious guidelines to solve it. Should I go for the mines '*' or clear '.'? Should I find the number of mines and then turn it to character 'n' in place for each character at a time, or should I go and scan for mines and then start counting?! Can my solution be generalized??
    And different languages has different "flavours" of programming.
    For example Elm and Go are both simple and minimalistic languages, but the way I would solve it in Go would be dramatically different from the way I solved it in Elm. (And I got 250-ish lines to solve it, while the rest of the community is under 150) and this makes me go backwards and look for ways to optimise my solution which is more intuitive for me. (I'm not an optimization-first guy)
    Watching these videos is quite helpful, because unlike scrolling through communities' solutions, each exercise is getting a deep explanation and understanding for its different ways of solving it and optimise it. For example, I would never tried any bitwise solutions from the first try.
    Great work have been put into these videos, website, exercises, and communities.
    Thanks a lot for your and everyone's efforts.
    Maybe at the end of this year's challenge you can make a bounce video about how to tackle a problem and different optimisation technics.
    And next year the challenge could be 3-level project for each month similar to last year's theme "appy, analytic, system, ..."