Python Sudoku Solver - Computerphile

แชร์
ฝัง
  • เผยแพร่เมื่อ 21 พ.ย. 2024

ความคิดเห็น • 1.3K

  • @dickjohnson4447
    @dickjohnson4447 4 ปีที่แล้ว +1219

    It must ba a joy having him as teacher, he is so chill and methodical.

  • @MatheusLeston
    @MatheusLeston 4 ปีที่แล้ว +2992

    1:38 wow he was able to say "recursion" without even moving his mouth, that's the real trick

    • @jojosoni6355
      @jojosoni6355 4 ปีที่แล้ว +96

      It's easy if you try it.

    • @DarshanSenTheComposer
      @DarshanSenTheComposer 4 ปีที่แล้ว +280

      now everyone is trying it out

    • @qcdiamond8292
      @qcdiamond8292 4 ปีที่แล้ว +67

      I've literally watched it 10 times now and I'm still amazed.

    • @vadiimt
      @vadiimt 4 ปีที่แล้ว +253

      His lips utilize a very efficient algorithm

    • @NicosLeben
      @NicosLeben 4 ปีที่แล้ว +33

      That comment made me laugh so hard. xD

  • @etienneschramm83
    @etienneschramm83 4 ปีที่แล้ว +42

    The Dancing Links algorithm, by Knuth, is one of the most beautiful algos I have ever seen. It works by abstracting away from the sudoku itself, and translating all the constraints into a matrix form, on witch you can apply a backtracking algorithm, in order to find a subset of lines with exactly one non-zero value in each column. The advantage is that it treats all constraints as equal.
    You should absolutely do a video on solving Sudoku with Dancing Links. Moreover, you can show that by generalizing a problem, you can use exactly the same algorithm for Sudoku, Pentominos, Soma cube and many others.

  • @songzh2911
    @songzh2911 4 ปีที่แล้ว +13

    Dear Thorsten, I was your student and enjoy this video. As a Chinese, I want to tell that the later game is called Huarongdao. (华容道), The story is about a general of a kingdom escaping from a losing battle. I have some fun when I was a child with it.

  • @jordanolson11
    @jordanolson11 4 ปีที่แล้ว +501

    I really like Thorsten, he seems like a good guy.

    • @Gooberpatrol66
      @Gooberpatrol66 4 ปีที่แล้ว +15

      eh kills sodukus and doesnt afraid of anything

    • @stoneskull
      @stoneskull 4 ปีที่แล้ว +19

      he's awesome. he has that excitement for maths like a young person, and explains in a way to help others.

    • @ASCENDANTGAMERSAGE
      @ASCENDANTGAMERSAGE 4 ปีที่แล้ว +5

      Yeah I love this guy.

    • @user-zu6ts5fb6g
      @user-zu6ts5fb6g 4 ปีที่แล้ว +24

      he ist verry deutsch

    • @bryphi77
      @bryphi77 4 ปีที่แล้ว +7

      Kinda reminds me of a bond villain.

  • @garethevans9789
    @garethevans9789 4 ปีที่แล้ว +870

    It's more fun to write a solver/ generator than it is to do the puzzles by hand

    • @recklessroges
      @recklessroges 4 ปีที่แล้ว +15

      A+ (now write it in Rust ;-) )

    • @garethevans9789
      @garethevans9789 4 ปีที่แล้ว +32

      @@recklessroges Now Brainf*ck 😉
      (It's is a real programming language)

    • @quintrankid8045
      @quintrankid8045 4 ปีที่แล้ว +1

      @@garethevans9789 Piet?

    • @sabouma
      @sabouma 4 ปีที่แล้ว +20

      Making a solver is also kind of a puzzle :p

    • @imveryangryitsnotbutter
      @imveryangryitsnotbutter 4 ปีที่แล้ว +13

      @@garethevans9789 I refuse to believe anyone is so masochistic as to write a program for extensively handling a two-dimension array in Brainfuck. Like, I'm sure one exists somewhere, but it was almost certainly written in C and then run through a converter.

  • @ThePolaroidPicture
    @ThePolaroidPicture 4 ปีที่แล้ว +70

    Does he have his own TH-cam channel? I really enjoy the way he talks about problems. Makes them seem much easier than they really are.

  • @edhofiko7624
    @edhofiko7624 3 ปีที่แล้ว +42

    For those who wanted to learn more about this. The problem of solving sudoku can be generalized to a problem called Constraint Satisfaction Problem (CSP), CSP includes things from puzzle solving to real world problem like planning and scheduling.

    • @codemaster1768
      @codemaster1768 3 ปีที่แล้ว

      True. It mostly uses AllDiff constraints to solve the problem.Which states that all the variables must have different values.

  • @tomw0815
    @tomw0815 4 ปีที่แล้ว +4

    This is really a clever little algorith for the problem. It's a bit too simple for my taste because it only prints out the solution while the solve() recursion is still running. After solve() is completed, the grid is in the state from the beginning again and the solution is lost. I slightly modified it by adding a returnvalue to solve() and some evaluation to keep the final result in the variable grid[ ][ ]. A while back I began programming a sudoku solver that should replicate the exact way I solve a sudoku on paper. It's still not finished because it struggles with the extra hard Sudokus. I like these Computerphile videos.

  • @johantitulaer1052
    @johantitulaer1052 3 ปีที่แล้ว +9

    I was actually contemplating on making a sudoku solver myself as practice or not, but then seeing how it's done is just way too fun.

  • @ZimoNitrome
    @ZimoNitrome 4 ปีที่แล้ว +611

    aaaaa the spaces before the colons

    • @ekrem_dincel
      @ekrem_dincel 4 ปีที่แล้ว +6

      And this nested loops...

    • @OrgBrent
      @OrgBrent 4 ปีที่แล้ว +8

      It hurts

    • @seftondepledge3658
      @seftondepledge3658 4 ปีที่แล้ว +34

      @@OrgBrent And not having a space after commas. Not very pythonic

    • @rudyorre
      @rudyorre 4 ปีที่แล้ว +9

      @@ekrem_dincel I get the spaces thing, but how else would you write the nested loops?

    • @ekrem_dincel
      @ekrem_dincel 4 ปีที่แล้ว +1

      @@rudyorre you should find a better algorithm if possible.

  • @user-zu1ix3yq2w
    @user-zu1ix3yq2w 4 ปีที่แล้ว +5

    I remember i made my own sudoku solver in my late teens. I don't remember much but i remember part of it would track POSSIBLE numbers for each square. This video brought back a bit of my memory when i saw "possible" in the code.

  • @igorperfeitovivo
    @igorperfeitovivo 3 ปีที่แล้ว +7

    I’ve tried to code it myself using my own logic on solving sudokus. It is far more complicated and frustrating to code, and this is where the beauty of his method resides.

    • @ziga1122
      @ziga1122 2 ปีที่แล้ว

      I feel you, after 5 attempts i finally succeeded using logic, i spent way too much time on it though

  • @kchannel5317
    @kchannel5317 3 ปีที่แล้ว +3

    As someone who's learning Python I'm excited to try this project. I've learned to build my first LogisticRegression model, so I'm excited to to continue making progress.

  • @ekrem_dincel
    @ekrem_dincel 4 ปีที่แล้ว +1891

    This is O(scary)

    • @nikolasscholz7983
      @nikolasscholz7983 4 ปีที่แล้ว +199

      I'm literally crying from seeing this approach

    • @aevus
      @aevus 4 ปีที่แล้ว +238

      i mean this aproach is almost brute force

    • @SimonTiger
      @SimonTiger 4 ปีที่แล้ว +60

      Not for a normal 9x9 sudoku. NP-hard means it gets way harder once you _increase_ the size. For example, 16x16 sudoku would probably take longer to solve, but a 9x9 should be doable in just a few milliseconds.

    • @TaylorLopez412
      @TaylorLopez412 4 ปีที่แล้ว +59

      How did this not hit the recursion depth limit?

    • @incription
      @incription 4 ปีที่แล้ว +7

      @@TaylorLopez412 you can set the recursion limit iirc

  • @cody5535
    @cody5535 4 ปีที่แล้ว +35

    For my final project in pic10C (programming in computing) at Uni, I tried to finally write a program in c++ to generate Sudokus using specified seeds. I had tried to write this program three times previously: once in c++, then in python, then again in c++ and of course the last attempt in c++. It's amazing just how complicated it becomes trying to generate Sudokus.
    You'd think the logic would be simple enough: put a number there if it can go there; but the issue is the framework you have to move in: columns, rows, and blocks. You find that numbers being in cells is only a suffucient condition to block a number from potentially going in a cell. In fact, potential numbers in potential cells can affect OTHER cells potential numbers, and the issue just compounds from there!

    • @Henrix1998
      @Henrix1998 4 ปีที่แล้ว +2

      I have couple ideas, I'll try to remember to test them

    • @cody5535
      @cody5535 4 ปีที่แล้ว +1

      @@Henrix1998 One of the ideas I came up with (which was ultimately insufficient but which might be improvable though I've not worked on this project for about a year) to surmount this problem was this concept of cell "families" which were empty cells in a block, row, or column whose mutual potentials were the source of the exclusion of those numbers outside the family in that block, row, or column. I remember getting the first layer of this idea working but it needed to "shrink" as cells in families were assigned numbers which I never solved in time. Typing this out it reads like a non-issue but for whatever reason the difficulty of doing what I was doing shot up.

    • @aevus
      @aevus 4 ปีที่แล้ว +15

      i also wrote a sudoku generator. my approach was to first: generate a list of the most "primitive" sudokus possible and store that list, then use that list to create the sudokus.
      with "primitive" sudoku i mean a special set of sudokus with which i can create any legal sudoku. i create a new sudoku out of a primitive by several transformations like:
      flipping,
      rotating,
      switching numbers with each other (like switching all 1s to 2s, all 2s to 5s and all 5s to 1s)
      switching rows within blocks
      switching rows of blocks
      and more.
      the important thing is doing any of the transformations on a valid sudoku will give a new valid sudoku.
      and to get that list of the most primitive sudoku i basically just brute-forced all sudokus, checked if they were legal, then check if i already stored this sudoku or any of its transformations, if not then store this as a new primitive sudoku.
      you only have to generate that list once on your computer, then you can use that to generate new sudokus really fast on any machine.

    • @vandelayindustries2971
      @vandelayindustries2971 4 ปีที่แล้ว +9

      Wouldn't it be exactly the same as solving a sudoku, with the only two key differences being that
      1) you start with an empty board, and
      2) you don't check whether 1-9 can fit in a cell in numerical order, but random

    • @philrod1
      @philrod1 4 ปีที่แล้ว +4

      How about this for generation:
      Create a complete and legal board
      Remove a number and solve()
      Keep repeating until the board has more than one solution
      Put back the last removed number
      I'm not sure if this would make for nice puzzles, though. It will probably _depend_ on backtracking, which humans don't really like. I prefer to deduce or infer solutions.

  • @armsymusic3926
    @armsymusic3926 4 ปีที่แล้ว +436

    1:12 - "vot do vee do?"

  • @NomenNescio99
    @NomenNescio99 4 ปีที่แล้ว +5

    At one time I wanted to learn java, so I wrote a sudoku solver in Java, with a gui to input the puzzle.
    The principles of solving were basically the same as the python version, but Thorstens version were more elegantly written.

  • @ylyassun
    @ylyassun 4 ปีที่แล้ว +126

    The time when Targaryens not using Dragons anymore, They are using Python..

  • @TerjeMathisen
    @TerjeMathisen 4 ปีที่แล้ว +1

    Many years ago now, i.e. very shortly after Sudoku arrived in Norway, I wrote a solver for it. For a quick & dirty program like this I used Perl. The obvious method was to use recursion with pruning and backtracking since a brute force approach would be far too slow. My solver sorts all the open cells by the number of possible numbers to put there, this means that I always enter any forced values first, then when I can't see any more of these I will try the cells with two possible values, then 3, 4 etc.
    The key to make it fast was to have a compact grid representation so that I could pass it along on the recursive calls, I used a 9-bit bitmap for each cell, so each time I place a digit I also cross out that bit from cells in the same column or row. The alternative is to clean up during backtracking but in that case the bitmap updates take a lot of time so it is better to simply make a local copy for each call.
    The obvious next stage was to use the solver to evaluate the difficulty of randomly generated sudokus, I gave this program to my parents for Christmas so that they could print out a pair of new puzzles each time they wanted to have a solving race. I used the number and size of the N-way splits needed in the solver as a proxy for difficulty and this worked very well.

  • @okiseeyou
    @okiseeyou 4 ปีที่แล้ว +341

    6:45 that keyboard has seen war

    • @NoHandleToSpeakOf
      @NoHandleToSpeakOf 4 ปีที่แล้ว +6

      Space bar certainly did

    • @choOz
      @choOz 4 ปีที่แล้ว +8

      what about his whiteboard
      shits scarred for life

  • @maxxg7
    @maxxg7 4 ปีที่แล้ว +732

    I would smoke weed with this guy

    • @francescodiniccolo
      @francescodiniccolo 4 ปีที่แล้ว +21

      Teo Ionut me too, and I don’t even smoke

    • @evolutionsimplified
      @evolutionsimplified 4 ปีที่แล้ว

      Teo where do you find weed in Bucharest?

    • @uwu-zl6tq
      @uwu-zl6tq 4 ปีที่แล้ว +1

      @@evolutionsimplified noapte buna

    • @mayursaroj4360
      @mayursaroj4360 4 ปีที่แล้ว +22

      He lowkey looks like a gangsta or a drug lord turned programmer 😂

    • @johnjacobjinglehimerschmid3555
      @johnjacobjinglehimerschmid3555 4 ปีที่แล้ว +4

      I think I'd have to have smoked weed to understand this guy!

  • @NanakiPL
    @NanakiPL 4 ปีที่แล้ว +3

    Some time ago I was making a sudoku solver for fun. But I did the "like human" approach. Specifically, I made it try various techniques. This also nicely doubled as a puzzle difficulty checker. Instead of just looking at how many cells were pre-filled (most of publications I checked do that), it checked what techniques were required to progress.
    But I got bored before I could finish it so it would solve the "hardest sudoku puzzle" without guessing.

  • @what-uc
    @what-uc 4 ปีที่แล้ว +3

    I did one years ago, I made a 3 dimesional array, 10 values for each square (10th value holds the solved value). The user could enter numbers interactively. When a number was inserted it registered the number across the row, column and block, thus reducing the possibilities in each square. Then it checked the whole grid, and if there was only one possibility in a particular square, it got filled in. Then it recursed. If it failed to fill in another square, it went back to waiting for the user to fill in another number. It would normally reach a tipping point where all the numbers got filled in.

  • @TonyBestOfficial
    @TonyBestOfficial 4 ปีที่แล้ว +35

    You can use the built-in pprint function (from pprint import pprint) to pretty print data

    • @rucker69
      @rucker69 4 ปีที่แล้ว +3

      That is a separate library in the deployments I'm familiar with.

    • @Kuchenrolle
      @Kuchenrolle 4 ปีที่แล้ว +2

      @@rucker69 I guess he means it's part of the standard library.

    • @rucker69
      @rucker69 4 ปีที่แล้ว

      @@Kuchenrolle it looks like the original was edited

  • @GroockG
    @GroockG 3 ปีที่แล้ว +1

    I tried copying this with a blank starting grid with all zeros and thought it wasn't working, but then realized it was just taking forever to loop through everything! Great video, got me thinking.

  • @velkidekho0
    @velkidekho0 4 ปีที่แล้ว +3

    Wow, it's not teaching, it's gossiping, motivating, soothing, relaxing.

  • @liqo12
    @liqo12 4 ปีที่แล้ว +2

    Worth mentioning is that sudoku is part of a family of problems called 'exact cover' problems which are NP hard. In the family are problems such as nonograms and the eight queens problem. Would be cool to see sudoku generalized as an exact cover problem and solved that way.

  • @avi2578
    @avi2578 4 ปีที่แล้ว +14

    He has so much more enthusiasm for computer science than 90% of my professors in the department. Lol.

  • @daviddwyer6824
    @daviddwyer6824 4 ปีที่แล้ว +4

    I built a sudoku solver in PowerShell, python and C++. But it couldn't solve the harder problems. Awesome video.

  • @Taterzz
    @Taterzz 4 ปีที่แล้ว +13

    a function that calls itself? THIS CHANGES EVERYTHING

  • @BangsarRia
    @BangsarRia 4 ปีที่แล้ว

    Am I the only viewer who can't get enough of the Professor's videos but quickly gets bored or irritated at other Computerphile presenters - and stops watching them? Why? Because the Professor is the antidote to the computer science lectures I attended in College where the lecturers took themselves and/or the subject matter too seriously.

  • @rishabhmalhotra9762
    @rishabhmalhotra9762 4 ปีที่แล้ว +92

    4:02 smooth af

  • @roninpawn
    @roninpawn 4 ปีที่แล้ว +107

    Got to say, this wasn't very well taught here. I didn't have a pre-existing understanding of recursion, and by the end of the video I had to pause on the function code and reverse engineer it to come to understanding. (In fact, I'm still looking back at it as I write this comment to make sure I get it)
    If the goal was to inspire study: okay. But if the goal was to teach: I don't think that happened.
    Anyone else who was left wanting, I'll try my hand: When there's a 0 in the list and the possible() test returns true, that 'possible' value is shoved in where the zero was, and the entire cycle starts again with this nested call to solve(). But now /that/ space in the grid is no longer a zero, so the first unknown value that this new call to solve() will find and try to populate is for the next zero in the list. The whole loop can have as many successful populations as it can get, all the way to the very last zero... But if that last zero can't be ANY of the possible values, then these nested calls to solve() start to unravel.
    If none of the values are possible in the current field that solve() is trying to solve for, then we return to the previous solve() call -- the one that was operating on the zero before the test that just failed. Having just fallen back out of it's call to solve(), the next line it processes is to set the value it had previously populated back to a zero. It then carries on trying the remaining possibilities in the range() for that empty space -- picking up from wherever it had left off. So if it had tried a 3, found success, called solve... but then solve() ultimately failed on some other space and return'd all the way back to it, it'll carry on trying a 4, then a 5, and so on.
    If 4-9 all fail, this call to solve() returns back to the preceding call -- aka: the previous unknown value. If it finds another possible match in the remaining range (4-9), it populates it and calls to solve() again. So it ends up moving forward and back, and forward and back, until it can get a successful match for the very last zero / the very last call to solve().
    On that last call to solve(), all the numbers in the list will now be populated with non-zero values. So on this call, solve() will never try any possibles, and instead it will just cycle through all its for loops, and end by printing the grid() and asking for "More?" input.
    When you hit enter to tell it to continue, the entire umpteen-deep calls to solve() will all pick up from where they left off. The last zero will try any remaining possible values; if none found, return to the last zero; try remaining values; if found, call solve() again; etc.
    In this way, literally every possibility of every value ends up being checked, without wasting a single iteration repeating something that's already been tried. And if there's multiple possible solutions, all of them will be printed. So, when you hit Enter on the "More?" request... even though you may not get any other printed results, the program carries on testing every single possibility it hadn't already tried.
    --
    The fact that this video was made, got me to understand recursion by studying this sample function on my own, in the absence of a through explanation. And often that's more valuable to a student in learning and retention. But the video didn't REALLY explain what was going on, and why, to the unfamiliar like I've just tried to here. And that means there's a barrier of entry placed on a potential student. They have to /want/ to understand enough to teach themselves. This is just my opinion, but I think computerphile should aim to use this space to teach, rather than to inspire learning.

    • @qyrghyz
      @qyrghyz 4 ปีที่แล้ว +6

      Thank you; this was the elaboration I was looking for.

    • @ea9702
      @ea9702 4 ปีที่แล้ว +2

      Thanks a lot mate...really helpful!

    • @TheJuava
      @TheJuava 4 ปีที่แล้ว

      Thank you! This was very helpful to me.

    • @glitchy_weasel
      @glitchy_weasel 4 ปีที่แล้ว

      Thank you, I got it now :)

    • @narinpratap8790
      @narinpratap8790 4 ปีที่แล้ว +1

      Thanks. I still don't think that I entirely comprehend the idea, but it's definitely starting to make more sense now.

  • @4pThorpy
    @4pThorpy 4 ปีที่แล้ว +15

    The homework is to create a python script using that solver and "back tracking" to generate new "1 possibility" sudoku grids.

  • @thoughtpolease7183
    @thoughtpolease7183 4 ปีที่แล้ว +1

    For anyone interested: If you want an easy way to go the constraint solving route, for example because you want to solve this for larger N where the running time becomes restrictive, you can model your sudoku problem in a constraint programming language such as MiniZinc and solve it using a constraint solver. Sudoku is actually part of the MiniZinc tutorial

    • @es68951
      @es68951 2 ปีที่แล้ว

      Constraint programming is the way to solve this without reinventing the wheel 😄

  • @sadiqabbaszade4789
    @sadiqabbaszade4789 4 ปีที่แล้ว +12

    He explains everything well, except for the part "grid [y] [x] = 0". I had to take some time to realize that this part is actually connected to the input part where the program stops and not just sets the cell value back to zero right after finding the answer)

    • @weejohntee
      @weejohntee 3 ปีที่แล้ว +2

      I still struggle to understand that part

    • @Anaximander29A
      @Anaximander29A 3 ปีที่แล้ว +8

      @@weejohntee this took me a while. Thing is solve() has 3 different outcomes: 1. No empty cell found (the sudoku is solved) -> before the function finishes (and leads to grid[y][x] = 0) it prints the array. 2. The possible() function returns false and not all numbers (1-9) were tried already OR the possible() function returns false and no number fits in the cell. In the first case it checks possible() with the next number, in the second case (3) it returns the solve() function before the the whole sudoku was finished and sets no number for this cell. The previous solve() call in the recursion now finishes its own solve call, and sets the cell before also 0. BUT in this case maybe not all numbers(1-9) were tried so it could try again with another. Only when all numbers were tried, the solve() returns and then checks the previous solve() call (bottom up in the recursion). But maybe in the end the solve() function can't find an empty cell anymore. Then the whole thing gets printed before all the recursions collapse and go bottom up (--> clear the array) again.

    • @niranjanshankaran3493
      @niranjanshankaran3493 3 ปีที่แล้ว

      @@Anaximander29A thanks for the explanation

  • @Ianoxen
    @Ianoxen 4 ปีที่แล้ว +1

    My job is in the health industry and I have very little idea about other domains. I've recently just been looking at computer science online. This is insane for me. There are universes of things in life I have no idea existed.

  • @madsteeez
    @madsteeez 4 ปีที่แล้ว +4

    If anyone is confused how the resetting to 0 isn't called everytime: note where the print statement is! It gets called only in the case, that on some recursion level deep down, there is no more empty cell! After the full algorithm has finished, all the initially empty cells are indeed back to 0.

    • @ua6919
      @ua6919 4 ปีที่แล้ว

      Nice! Thank you

  • @okawashingo2079
    @okawashingo2079 4 ปีที่แล้ว +11

    I would like to watch your follow-up video about Knuth’s algorithm x and dancing links, considering a sudoku solver as a constraint satisfaction problem :)

  • @sukanyabaliarsingh204
    @sukanyabaliarsingh204 4 ปีที่แล้ว +3

    Wow. I really want to learn more under him. Beautifully explained everything. ❤️

  • @megamindblue1732
    @megamindblue1732 4 ปีที่แล้ว

    I implemented this in C++ and found out that the easier sudoku problems are solved within seconds. But seeing that my code could solve sudoku in a matter of seconds, I became confident and googled the hardest sudoku problem and gave that for my computer to solve. It took my computer 55 minutes to solve that problem and I quickly became reminded of the limitations of my code. PS: My approach is a bit different from professor Thorsten's but it is backtracking nonetheless. I built that before watching this. My processor is an Intel Celeron R and I have 4 GB of memory, if any one is wondering.

  • @motorheadbanger90
    @motorheadbanger90 4 ปีที่แล้ว +4

    "Once you understand it, it's quite simple"....That is the beauty of computer science

  • @deveshm7900
    @deveshm7900 4 ปีที่แล้ว +93

    I can just imagine this guy as Hitchhiker's Guide to the Galaxy character.

    • @Nilslos
      @Nilslos 4 ปีที่แล้ว +3

      I like your comment, but at this moment it has 42 likes, so I won't put another one there, it would ruin the "answer".

    • @deveshm7900
      @deveshm7900 4 ปีที่แล้ว +1

      @@Nilslos can't help it now

    • @naommalotane7444
      @naommalotane7444 4 ปีที่แล้ว +1

      President Zaphod

  • @steelpanther88
    @steelpanther88 4 ปีที่แล้ว +7

    I was reading Steven Skiena's "Algorithm Design Manual" and according to him, this kind of sudoku solution for backtracking suffers from choosing the empty squares suboptimally. It seems like the best way would be to try the most-constrained-empty-squares first, rather than simply looping empty squares from top left corner to the bottom right corner. Most constrained empty square is those squares on the board which have the least possible (guessable) values in them. So instead of recursing from a square which has [1,2,4,6] as possible guessses, focus on starting from a square which has only two possible if that is available on the board. It makes it a bit tricky to code the backtracking but it seems in principle it should prune the search tree quite a bit.

    • @QContinuuum
      @QContinuuum 4 ปีที่แล้ว +1

      Of course the purpose of this video was not to present an efficient algorithm, but to explain recursion/backtracking on an example. I doubt an efficient algorithm would use recursion or backtracking... I guess it would solve the constraint problem. But on topic: The tricky part in the code comes after you invoke solve()... when you return ,where are you in the tree of all possibilities? What to do next? That's what makes this video so valuable. Thanks a lot....

    • @steelpanther88
      @steelpanther88 4 ปีที่แล้ว

      @@QContinuuum I'm not disagreeing in principle but I just wanted to point it out for benefit of all viewers. I reckon that DFS brute force with backtrack would still be effective for regular sudokus. Assuming properly formed sudokus with 17 or more clues (with singular answer). There are allegedly some other type of methods like simulated annnealing which use random guessing somehow to solve the sudoku fast. But in principle DFS brute force with backtracking will always succeed in solving sudoku given enough time. In terms of other known sudoku algorithms there is dancing links/algorithm X by Donald Knuth, but I'm not too familiar with its time complexity or how efficient it supposedly is.

  • @puellanivis
    @puellanivis 4 ปีที่แล้ว +3

    When I originally wrote one of these, I looped through and filled in values that I knew had to be correct, because I was counting the numbers in rows, columns, and boxes and if there was only one solution, put it in. It ended up solving about 90~99% of sudoku puzzles on its own, with no further complicated logic. Just counting up what it couldn’t be, and if there is only one could be left, it knew what had to go there.
    This solution is pretty interesting and elegant in that it does not actually need any special constraint logic to do the solving, which is neat, but I think filling in the table with “MUST BE” values first might speed up the amount of backtracking necessary. But then, as mentioned, this way solves nearly all the puzzles I came across. But at least this would be an interesting combination solver, that only deferred this backtracking logic to get around complicated constraint heuristics.

    • @FADGhost70
      @FADGhost70 4 ปีที่แล้ว

      puellanivis definitely a way to optimise the solving progess but i don’t think it’s necessary here. We don’t have so many combinations that the backtracking would need to go through. Any modern cpu can solve it in fractions of a second or whatever. However if we look at chess we definitely need more than plain backtracking and with example of Go to even be applicable in real time we need deep learning

  • @JAM0LO
    @JAM0LO 4 ปีที่แล้ว +18

    Really liked this one, the solution is so elegant

    • @bugodi327
      @bugodi327 4 ปีที่แล้ว +10

      not really its about as brute force as it gets

    • @mayursaroj4360
      @mayursaroj4360 4 ปีที่แล้ว

      why does it continue to print other solutions, even after its out of loop? plz help

    • @lesa251
      @lesa251 4 ปีที่แล้ว

      @@bugodi327 No it's not as brute force as it gets. The as brute force as it gets would be to generate all the possible sudokus and check for each one if it was vaild.

  • @letsgocamping88
    @letsgocamping88 4 ปีที่แล้ว

    I wrote a sudoku solver that ran on an arduino spitting each new addition to the grid as a load of serial prints. I didn’t use the brute force recursive approach but instead tried to replicate the methods I found on a website devoted to solving sudoku. I think it taught me allot

    • @nunoricardoserafim3187
      @nunoricardoserafim3187 4 ปีที่แล้ว

      Why did you run on an arduino? I'm just curious

    • @letsgocamping88
      @letsgocamping88 4 ปีที่แล้ว

      Nuno Ricardo Serafim because at the time it was the only programming language / environment that I was familiar with!

  • @lastmaj
    @lastmaj 4 ปีที่แล้ว +3

    i'm so intimidated by the ease he's talking about those hellish loops.

  • @anatolbeck1992
    @anatolbeck1992 3 ปีที่แล้ว

    One of ze best vizeos!
    Further to clearify the input('More?') thing:
    When he prints the matrix we just end one of those recursion steps. The others a still to come.
    If we get a solution let's say in the n-th step we still have not evaluated N-n steps. The input('More?') just halts the process till someone presses enter. Then it is possible that none or more times in the last N-n steps we get further solutions.
    So the answers is, we do not initiate something when pressing 'Enter' to the question 'More?', we just proceed.

  • @Multigor96
    @Multigor96 4 ปีที่แล้ว +524

    _cries in PEP8_

    • @ekrem_dincel
      @ekrem_dincel 4 ปีที่แล้ว +3

      Lol

    • @SSJ3Tim
      @SSJ3Tim 4 ปีที่แล้ว +29

      Every video with this guy

    • @pitrk
      @pitrk 4 ปีที่แล้ว +16

      Searched through the comments for this before starting the video.

    • @proud22beme
      @proud22beme 4 ปีที่แล้ว +16

      the think that hurts me the most is not using numpy's nicer features, for ex, the possible() function could have been this:
      def possible(x, y, value):
      return np.all((grid[y, ...] != value) + (grid[..., x] != value))

    • @JNCressey
      @JNCressey 4 ปีที่แล้ว +23

      @@proud22beme, looks like that's only the column and row rules, you missed the 3x3 square rule.

  • @brtkl_
    @brtkl_ 4 ปีที่แล้ว

    Great video! Worth mentioning that after all solutions are found grid will return to its original form as a side effect of grid[y][x]=0 (which can also be a feature).

    • @elhartzer1639
      @elhartzer1639 2 ปีที่แล้ว

      If i dont want this, how can i prevent it? An idea was to put it in an if statement, that checks if all rows sum to 45 and then not execute grid[x][y] = 0. Or maybe use numpy to check if there are any zeroes left? Would there be a more elegant solution?

  • @douglaslawrie3449
    @douglaslawrie3449 4 ปีที่แล้ว +6

    I wrote a similar solver in MATLAB using recursion but I searched through the puzzle to find the element with the least number of possible values which minimises the number of calls to the function.

  • @ZapOKill
    @ZapOKill 4 ปีที่แล้ว +2

    there is one little trick to improve the the solver by magnitudes, iterate over all fields and find the one with the least possible values according to the 3 constraints (row, colom, box)
    if you feel fance only try those values (but it just reduces runtime costs by some small amount)
    that way you have much less guessing and the search tree almost collapses to a list

    • @jan861
      @jan861 ปีที่แล้ว

      could you elaborate, please?

  • @ianmoore5502
    @ianmoore5502 4 ปีที่แล้ว +4

    This is the kind of guy who teaches by doing
    My favorite kind of teacher

  • @austinhruska7473
    @austinhruska7473 4 ปีที่แล้ว +7

    hay everyone 2d list output easy mode -> print(*listvar, sep='
    ') !!!best thing EVER changed my life

    • @rishavmitra5732
      @rishavmitra5732 3 ปีที่แล้ว

      Another one
      from pprint import pprint
      pprint (grid)

  • @leooel4650
    @leooel4650 4 ปีที่แล้ว +9

    LEGEND!
    10 minutes on this and was able to understand backtracking...

    • @akywongster
      @akywongster 4 ปีที่แล้ว +3

      Dude ur profile pic made me throw my phone against the wall

  • @roberteaster6655
    @roberteaster6655 4 ปีที่แล้ว +16

    I really like the, "and my challenge to you is to write...".

    • @runrickyrun157
      @runrickyrun157 4 ปีที่แล้ว +4

      "The proof is left as an exercise to the reader"

  • @goranjosic
    @goranjosic 4 ปีที่แล้ว +1

    I'm hobby Python programer and Sudoku solver was my first "real" project fee months ago. I really love Python!!! :)

  • @maciejbrzeski9740
    @maciejbrzeski9740 4 ปีที่แล้ว +5

    Is it possible for you to enable automatically generated captions? They work perfectly on Numberphile channel!
    I am convinced I am not the only one who would appreciate this. I often watch your videos at night and I cannot enable sound because that would disturb my roommates :(
    btw. I love your videos. Great content as always!

  • @trevorreynafarje9395
    @trevorreynafarje9395 4 ปีที่แล้ว

    I did something similar in python last year (as a college freshman). It's really cool seeing how my sloppy self taught code/sudoku logic (not using brute force/guess and check) compares to a legitimate build.

  • @ThisIsFez
    @ThisIsFez 4 ปีที่แล้ว +10

    He makes coding on light mode less weird

  • @artursz1993
    @artursz1993 4 ปีที่แล้ว +36

    I dig this speaker. Pretty chill one. And interesting topics too :)

  • @andranikmuradian1321
    @andranikmuradian1321 4 ปีที่แล้ว +49

    From the notes on his whiteboard it seems he is taking the MIT Programming with Categories course :)))

    • @Evan490BC
      @Evan490BC 4 ปีที่แล้ว +23

      Are you kidding me? Altenkirch does research on Homotopy Type Theory, he doesn't need to take any course. He eats Category Theory for breakfast.

    • @carlosarchable
      @carlosarchable 4 ปีที่แล้ว +11

      In any case he'd be giving the course...

  • @JimmyXOR
    @JimmyXOR 4 ปีที่แล้ว +1

    It was fun to do the Klotski challenge, but it's more efficient to just brute force Klotski. It took me less than half a second to find all 25955 possible positions (counting every similar block as equal). The shortest solution has 116 single steps and every configuration can be reached in 137 steps.
    With recursion and backtracking, I got my solution in 2 seconds, but it required 3873 single steps (or 20928 steps when I forgot counting every similar block as equal).

    • @5_Sigma
      @5_Sigma 4 ปีที่แล้ว

      Hey, I just did the challange aswell and found that every configuration can be reached in 167 steps, instead of 137

  • @e1nste1in
    @e1nste1in 4 ปีที่แล้ว +14

    The cooking animation was amazing ... and made me laugh^^

  • @MM-td9oe
    @MM-td9oe 4 ปีที่แล้ว +1

    Love yt recommendations. I have been watching for 1 min and was subscribed already.

  • @tzkelley
    @tzkelley 4 ปีที่แล้ว +7

    Realizing the topic is just back-tracking here, this algorithm is inefficient for difficult puzzles. I found it more efficient when I wrote similar code to work the most obvious cells first (the ones with fewer potential solutions). I greatly reduced the time to solve the most complicated puzzles.

    • @kristypolymath1359
      @kristypolymath1359 4 ปีที่แล้ว

      On my smart phone I play on the EXPERT mode, 1-3 games just before I go to sleep. It usually takes me 10-12 minutes to complete a game without any errors.

    • @aiyadalreshidi3289
      @aiyadalreshidi3289 2 ปีที่แล้ว

      I totally agree with you. That what came in my mind first. I thought it was not the perfect one for expert sudoku puzzles, because it will take more time .

  • @okaro6595
    @okaro6595 4 ปีที่แล้ว +1

    Recursion is easy to understand at high level but hard if you actually think in detail. When I wrote a Sudoku solver I used a more human approach. I first added those that were certain and used recursion only when there were alternatives,

  • @dukestt
    @dukestt 4 ปีที่แล้ว +11

    That puzzle is called The Setting Sun, its on my list for VB

  • @austinwoodall5423
    @austinwoodall5423 2 ปีที่แล้ว

    I have written a deterministic sudoku solver. I am one step closer to proving all polynomial complexity problems, even nondeterministic ones, are solvable in polynomial time if they have finite states and are not iterative such as chess where the order of the moves is important.

  • @peterlohmann
    @peterlohmann 4 ปีที่แล้ว +29

    REALLY be wanting to fix that phone cord.

    • @Diachron
      @Diachron 4 ปีที่แล้ว

      Glad I'm not the only one. 👍

    • @lisatorres2377
      @lisatorres2377 3 ปีที่แล้ว

      Ur so funny guy

  • @arthurlevitsky3347
    @arthurlevitsky3347 3 ปีที่แล้ว +2

    I didnt do it this. But I did a sudoku verifier in C instead. It was quite interesting because you can use threads to check the puzzle from rows, columns, and each individual square.

  • @geoffcunningham6823
    @geoffcunningham6823 4 ปีที่แล้ว +35

    far more efficient to find all possibles, fill in any square with only one possible number. Do that as much as you can, and if there are no one-possibles, then do this guessing algorithm.

    • @darkdudironaji
      @darkdudironaji 4 ปีที่แล้ว +12

      Yeah, but with modern computers that's negligible on a 9x9 grid.

    • @JohnR31415
      @JohnR31415 4 ปีที่แล้ว +9

      Efficient? I doubt it. Coding time far exceeds running time, even if he didn’t take us through line by line. After a few million sudoku you might draw even...

    • @feha92
      @feha92 4 ปีที่แล้ว +1

      You could eliminate candidates using clever tricks too, such as one of my favs (because its cheating) is to use the meta-knowledge that you fed it a puzzle that only had one solution to eliminate any candidates that results in a "unique rectangle".

  • @kirillvourlakidis6796
    @kirillvourlakidis6796 ปีที่แล้ว

    The intuition (at least for me) is that the complexity of this solution is going to be off the scale even for a 9x9 problem, so it's quite surprising that it solves the puzzles quite successfully.

  • @7cmhg840
    @7cmhg840 4 ปีที่แล้ว +22

    So this is what Steve Wozniak do after leaving Apple

  • @mikelipsey8837
    @mikelipsey8837 4 ปีที่แล้ว +2

    This is a classic Finite State Machine approach to solving problems! Takes me way back to early classes in computer science.

  • @Yobleck
    @Yobleck 4 ปีที่แล้ว +139

    I spent a week on a sudoku solver then this video comes along and makes my code look like it was written by a 5y year old :(
    Edit: my program does solve the problem within a similar amount of time so at least its not too bad.

    • @user-zu1ix3yq2w
      @user-zu1ix3yq2w 4 ปีที่แล้ว +6

      Keep going though?

    • @chixulub
      @chixulub 4 ปีที่แล้ว +24

      That's amazing! You got to solve it for yourself, spoiler-free :)
      And then you got to see how someone else did it, so you could compare notes!
      Did you solve it the same way?
      Don't worry about your code looking like a kid wrote it. It will improve if you keep at it. You never really notice it though, before you go back and look at some code you wrote a couple of years ago. Fun!
      So make sure you put copy of your code in its current state in a durable place. You may thank yourself in the future :)

    • @Yobleck
      @Yobleck 4 ปีที่แล้ว +8

      @@chixulub The main difference in our programs is that I generated an entire possible solution filling in all the squares and then went through it row/column/3x3 and then tossed out the result if an inconsistency was found. rather than his approach of going through each square one by one. I think its called breadth first vs. depth first.
      I also tried to implement some logic that uses human tricks to solve sudokus like the hidden/naked pairs trick, but its kind of difficult to program it efficiently. I got stuck trying to avoid quadruple for loops with tons of if statements. Maybe I'll go back to it later.
      for the last point I've been using github for offsite storage. Not really the sites intended use since no one will ever see or use the code, but its a really nice place to keep things organized.

    • @clifffraser7433
      @clifffraser7433 4 ปีที่แล้ว +13

      This is elegantly simple and effectively illustrates backtracking. However, it is still a brute-force solution and back in my day, when computers were orders of magnitude slower, we would have lost marks for a solution like this. Glad he reflected on this near the end.

    • @Schmidtelpunkt
      @Schmidtelpunkt 4 ปีที่แล้ว +2

      Same over here - I completely thought through the rules of the game and had an intermediate step before the recursion which would solve the field according to those rules. Which makes it a lot more complicated.

  • @E450AMD
    @E450AMD 4 ปีที่แล้ว

    I have written Sudoku solver in CPP in my 2 year of university ... more than 10 years ago. And it it solve Sudoku in less than second on Pentium 3 @1.2Ghz notebook. I used brute force with recursion and 3 simple rules.

  • @band-o-lear
    @band-o-lear 4 ปีที่แล้ว +3

    Interesting solution.
    I wrote a Solver a few years ago that replicated the way that humans would attempt to solve it. It would be interesting to see a speed comparison between this method (recursion) compared to my solution. I suspect that with a simple puzzle as presented here that the recursion method would be comparable, but it would be interesting to see how it would deal with a harder puzzle.

    • @massimookissed1023
      @massimookissed1023 4 ปีที่แล้ว +1

      Yeah, this one looks like a brute-force try 9^81~ish possibilities until one of them doesn't fail.

    • @ekrem_dincel
      @ekrem_dincel 4 ปีที่แล้ว +1

      Bro the code in this video is O(scary)

    • @band-o-lear
      @band-o-lear 4 ปีที่แล้ว +6

      Because I didn't have anything better to do (read avoiding responsibilities), I copied the code presented here and wrapped the same timing method around the solve function. For the puzzle presented here, on the same hardware, my solver completed it in 0.003 seconds (I'm aware that there will be slop in python timing) and this recursive solution took 0.09 seconds.
      I then fed them both a hard puzzle (as pulled from an Australian Newspaper which had 24 values entered - compared to 29 in the video). Mine took 0.005 seconds (so not much slower compared to the easier puzzle), but the recursive solver took 0.8 seconds, so significantly slower.

    • @vladalgov1770
      @vladalgov1770 4 ปีที่แล้ว

      @@band-o-lear Code from this video can be significantly improved: when an empty cell is found Code start from the very beginning to looking for another empty cell. But if continue from the "current" position (there are no empty cells before) - it will be much faster.

    • @qzdl
      @qzdl 4 ปีที่แล้ว

      who can golf the fastest solver

  • @neo1510
    @neo1510 2 ปีที่แล้ว

    I dun understand why comment section ppl like this video. This professor might be the best/chillest person in the world however I think the explanation can be done way better with more details provided (e.g. probably walk through a sudoku to show how this algorithm works). There are a lot of important details which are not explained or briefly touched in this video.

  • @vaughanmuller
    @vaughanmuller 4 ปีที่แล้ว +7

    Please do a follow up on Knuth's dancing links algo.

  • @sunilprajapati6377
    @sunilprajapati6377 4 ปีที่แล้ว +1

    I programmed my own sudoku solver last week, was fun.

  • @HocExcelOnline
    @HocExcelOnline 4 ปีที่แล้ว +74

    3:08, shouldn't it be x = 2, y = 0?

    • @FranciscoPereira-gc5xu
      @FranciscoPereira-gc5xu 4 ปีที่แล้ว +12

      in python, matrixs works the other way around. when you assing a X value to smth, you get it in a vertical line, not in a horizontal line. python has some tricks x)

    • @caseykawamura8718
      @caseykawamura8718 4 ปีที่แล้ว +2

      @@FranciscoPereira-gc5xu in any grid, an x gives you a vertical line. OP is correct.

    • @sazid2637
      @sazid2637 4 ปีที่แล้ว +3

      he used y to represents columns and x to represent rows. you could do vice versa. it doesn't really matter

    • @bricewoodlock
      @bricewoodlock 3 ปีที่แล้ว +2

      y=2 and x=2 is correct, the grid is mislabeled.

    • @mvrjane
      @mvrjane 3 ปีที่แล้ว +1

      The function is actually def possible (y,x,n), that's why they seem reversed

  • @alessandrochiri6315
    @alessandrochiri6315 3 หลายเดือนก่อน

    The most beautiful computer scientist.

  • @pnachtwey
    @pnachtwey 4 ปีที่แล้ว +3

    The next trick is to make the search more efficient. Minimize recursion and time.

    • @etopowertwon
      @etopowertwon 4 ปีที่แล้ว

      If you are lazy and don't want to optimize it by hand(which is fun), you can cheat with "from z3 import *" (or other SMT solver)
      then translate grid to format with solver understands and call it. SMT solvers are fast.

    • @pnachtwey
      @pnachtwey 4 ปีที่แล้ว

      I already have a solver. Even the most difficult problems are solved in a fraction of a second but it is inefficient. It use a 54 char string of characters 0 through 9.. an array of bit sets would be more efficient using np.arrays. Also, making lists of offsets for each square would speed up indexing. When making the initial table of what numbers are still available the always seem to be squares with one option so do those first so the width of the recursive search is narrower.

  • @zerozeronine5461
    @zerozeronine5461 3 ปีที่แล้ว

    I use backtracking in C to find out all solutions. Each unfilled cell is a set created by the intersection sets of possible numbers in that column, in that row, and in that sub square. This can highly reduce the possibility of choice of numbers.

  • @juliussoldan4016
    @juliussoldan4016 4 ปีที่แล้ว +25

    Instead of importing numpy, how about :
    for row in grid:
    print(row)

    • @whuzzzup
      @whuzzzup 4 ปีที่แล้ว +3

      " ".join(row)
      Otherwise you'd print "[1, 2, 0, 3, ...]"

    • @paulmaccormick
      @paulmaccormick 4 ปีที่แล้ว +3

      Or just use pprint

    • @rensaito9009
      @rensaito9009 4 ปีที่แล้ว +1

      ????
      For r, row in enumerate(grid):
      For c, cell in enumerate(row):
      Print(cell)

    • @whuzzzup
      @whuzzzup 4 ปีที่แล้ว +3

      @@rensaito9009 Why are you wasting CPU-cycles for `enumerate`?

    • @Rotem_S
      @Rotem_S 4 ปีที่แล้ว +1

      use print("
      ".join(" ".join(str(x) for x in y) for y in grid)) for efficiency, printing many lines wastes more time than joining them beforehand

  • @upthebuffer1921
    @upthebuffer1921 4 ปีที่แล้ว +1

    My brain melted when the function calls its self. I think I understand why it works but oh it hurts so much trying to get my head around it.

    • @alexanderschiendorfer2203
      @alexanderschiendorfer2203 4 ปีที่แล้ว +1

      Keep in mind what the state of the global variable looks like at all times. Maybe even draw it on a piece of paper for a few function calls

  • @GZXC993
    @GZXC993 4 ปีที่แล้ว +6

    I don't think I'd be able to come up with this solution. My first CS professor instilled an urge to always write efficient code, so I'd never even consider trying this approach lol

    • @lacascadaobregon
      @lacascadaobregon 2 ปีที่แล้ว

      what? why not. what would you have tried?

  • @mikekerry7989
    @mikekerry7989 2 ปีที่แล้ว +1

    The problem with this script seems to be that it doesn't know when to stop. After printing the result, the script actually carries on gradually unravelling back to the original source grid. Try printing the grid back in mainline code, after the call to solve() !!
    If you add 1 to a global counter each time solve() is entered, this counter reaches 1919 when the solution is found.
    However solve() is then entered a further 798 times, so that the counter reaches 2717 before getting back to mainline code.

    • @elhartzer1639
      @elhartzer1639 2 ปีที่แล้ว

      Yes, you're right! I've tried it with several sudokus and after printing the result, the solve function is called many times more. Could you explain, how to exactly change the code to stop, after printing/getting the result? :)

    • @mikekerry7989
      @mikekerry7989 2 ปีที่แล้ว +1

      The easiest way is a bit brute-force, but it works :)
      At the top of the script add:
      import sys
      and when the solution has been found and printed, do this:--
      sys.exit()

    • @elhartzer1639
      @elhartzer1639 2 ปีที่แล้ว

      @@mikekerry7989 Haha yes of course! Here i was thinking about convoluted solution, but thats definitly better :D

  • @JohnHollowell
    @JohnHollowell 4 ปีที่แล้ว +7

    "you just have to understand the recursion" was basically an entire course in my uni

    • @lacascadaobregon
      @lacascadaobregon 2 ปีที่แล้ว

      Recursion techniques have a lot of depth, that's for sure. Consider yourself lucky for that education

  • @diegolainfiesta
    @diegolainfiesta 4 ปีที่แล้ว +1

    Pure brute force 🙂 never stops to amaze me, how far brute force can get you.

  • @YBXtreminal
    @YBXtreminal 4 ปีที่แล้ว +4

    I didn't understand what for the line after the call for the recursion func?
    the line grid[y][x] = 0?
    because, if i call the function, it will start over, and if i finished, i will not enter the if statement..

    • @entivreality
      @entivreality 4 ปีที่แล้ว +11

      as i understand it, it goes like this:
      find a number that is possible in the next empty position (on the first call, this will be the first empty position).
      now taking the position as filled with that chosen number, again find a number that is possible in the next empty position. repeat this process until all positions are filled.
      if we can’t find a possible number for a given position we made a mistake somewhere and the lowest recursive call returns.
      this return within the lowest recursive call will lead the next higher call to reset its position as empty and loop to the next value between 1 and 9, repeating the process.
      if the loop can’t find a possible value for the empty position, it too will return, leading the next higher call to reset its position as empty. repeat for each layer.

  • @d4m4s74
    @d4m4s74 4 ปีที่แล้ว

    I just wrote a honest sudoku solver instead of a brute forcer. It can solve easy, intermediate or hard puzzles in under tenth of a second, but it currently fails with expert puzzles, if it doesn't solve it it uses a backtracker as a backup.
    First trying to solve "honestly" lowers the brute force time from several minutes to 5 seconds on the expert puzzles, and lowers the solve time from 5 seconds to 0.5 seconds for hard puzzles.

  • @DebanjanKarmakar
    @DebanjanKarmakar 4 ปีที่แล้ว +7

    solve() didn't return anything for me, I have tried to write the same program with one of the puzzle I've found online. But this is not working for me. Can anybody plese help me solve this problem?

    • @yapyeeqiang9217
      @yapyeeqiang9217 4 ปีที่แล้ว

      same

    • @jennyh7591
      @jennyh7591 3 ปีที่แล้ว

      It’s not meant to do you mean it doesn’t print anything??

  • @ryanthompson591
    @ryanthompson591 4 ปีที่แล้ว +1

    Took me a few minutes to really figure out what that code is doing. Normally with recursion, you'll do something like this
    if baseCase:
    return something
    else:
    change something
    call recursive function
    his code is
    run through a bunch of loops
    if the problem is not solved (ie. one of the values is 0)
    modify global variable with new guess
    recursively call the function
    revert the state of the global variable ( note: this works because the recursive calls have also reverted)
    return (note: this skips the later part of code that prints the solution
    else (note: he doesn't write else here, it just works - because we don't hit return in the previous code)
    print the solution
    It is cool in how concise the code is though. Edited: removed my wrong analysis.

    • @lacascadaobregon
      @lacascadaobregon 2 ปีที่แล้ว

      There's not a lot of industry applications for a Sudoku Solver. Is that why you say "Most industry would not allow it"?

    • @ryanthompson591
      @ryanthompson591 2 ปีที่แล้ว

      @@lacascadaobregon Nope I was just wrong in my original comment. Using these type of passed through variables is totally fine.

  • @skullkidn64
    @skullkidn64 4 ปีที่แล้ว +40

    Python Beginner: print("Hello World!")
    Beginner: AYE
    Thorsten: Let's make a Python Sudoku Solver, not a problem
    Beginner: ...

    • @dylan-j-gerrits
      @dylan-j-gerrits 4 ปีที่แล้ว

      I started to learn python 3 days ago and I just finished a to create a sudoku solver yesterday, with just some basic loop and conditions.
      Using no import.

    • @skullkidn64
      @skullkidn64 4 ปีที่แล้ว

      I can fluently program in python and starting to move into python but i made that joke because i have a friend who only knows the print function

    • @FreedomOfTħought
      @FreedomOfTħought 4 ปีที่แล้ว +1

      @@dylan-j-gerrits If you are a somewhat experienced software dev, which it sounds like you are, then moving from language to language is merely a change in syntax and operation. Object oriented principles don't care about your language as long as OOP is natively supported, neither does the concept of recursion for that matter, as long as your language supports nested method calls.
      So yeah, I believe the OP was referring to a beginner software developer rather than just python haha.

    • @dylan-j-gerrits
      @dylan-j-gerrits 4 ปีที่แล้ว

      @@FreedomOfTħought : I am a beginner, not only in Python but overall. I've started to learn just a month ago, more or less, and doing a sudoku solver was the first thing I've created.

    • @abdullahsaid8561
      @abdullahsaid8561 4 ปีที่แล้ว

      @@dylan-j-gerrits then you're a prodigy I guess. i have 4 years experience and yet can't do this sh*t

  • @Syncromatic
    @Syncromatic 4 ปีที่แล้ว +1

    This kind of sudoku solver is sort of my version of a Hello world program. I write it in every (or at least most) programming language I learn since it’s nice practice that covers the simple syntax and passing by reference (note my disdain for the global variable used here).
    So far done in C++, Python, Rust and I even used it for a test assembly program for an assembler/emulator we made in a system software course.

    • @maestbobo
      @maestbobo 4 ปีที่แล้ว +2

      Rest assured, your disdain has been noted.

  • @freshmilk980
    @freshmilk980 4 ปีที่แล้ว +4

    I put the exact same code into Python so I could mess around with it but it doesn't seem to work ... it is calling the function recursively (if I put a print statement as the first line after def it will print many, many times) but it never seems to reach the print(np.matrix(grid)) statement at the very end.
    Also, why does the grid variable not seem to get changed by the solve() function? If grid is global, shouldn't it be different after solve() runs? If I say print(np.matrix(grid)) after running solve I just get the original.

    • @jhwheeler7
      @jhwheeler7 4 ปีที่แล้ว +1

      I haven't checked, but maybe because it's all made in Jupyter and not run in the normal Python terminal. Did you try it in Jupyter?

    • @Sirjosephcharles
      @Sirjosephcharles 4 ปีที่แล้ว

      Its hard to understand with his accent, but he has a few DIY functions he built and added to his library & to @Alacritas' point, he's using Jupyter. He mentions this whole Soduku solver is a section in his book. Look him up and see if you can pick it up & walk through the process. Thats what I'm about to do.

    • @freshmilk980
      @freshmilk980 4 ปีที่แล้ว

      @Theo van der Sluijs For me it was actually just because I inputted the original matrix incorrectly, seems that it was unsolvable. After I fixed that it worked as it should. I could send you the Jupyter notebook if you're really curious!

    • @adamwenicki6252
      @adamwenicki6252 4 ปีที่แล้ว

      @@freshmilk980 Hey could you give link to this notebook, that be great. I tried doing u it but it didn't work I tried copying the code and it didn't work either.

    • @AntonKristensen
      @AntonKristensen 2 ปีที่แล้ว

      Well, i'm having the same issue, but it is obviously clearing the entire array on its way back from the recursion,, everything below after the recursive solve() call gets triggers when the method bubbles back down, and therefore empties the array that it just solved, therefore there should be some kind of a conditional there that should decide if it actually should be emptied or if it should not be emptied, i haven't figured it out myself yet..