Tim explains the backtrack algo really well, and I give him credit for writing the code on the fly instead of having it pre-canned. He is a real programmer's programmer. I am going to follow alone but I want to tweak it a bit and use a RANDOM function to pick the an empty square. And then do a monte carlo simulaton with time lapse to compare. I am going to make my CPU work! Good job.
@@lolololololololol-sc1rp The short answer is the RANDOM method did NOT improve the performance. 1) Created a sudoku generator. 2) Created a 2nd version of the solver using the RANDOM function, instead of sequential method, 4) ran them side by side over 100,000 simulations. The avg time of both were within msecs of each other. I have the code in my google colab. I will share with you in my github,
Thank you so much for this series, I will definitely finish it. I have always been intimidated by algorithms and AI-related topics, but this video helped me become more comfortable with that.
You could avoid having things like 'range(len(bo[0]))' and 'bo[i][j]' by using the enumerate() function, which takes an iterable (in this case bo) and returns an enumerate object which can be iterated over for index- value pairs. In code you'd write: for i, row in enumerate(bo): for j, val in enumerate(row): if val == 0: return (i, j) It's a very useful function if you need to iterate over both the index and the value at that index.
Mannnnn, You are killing it. Really you are inspiring me to learn programming. Maybe this isn't the vauu thing to learn but I fell that I am learning something. ( Not wasting time ) Thanks a lot
Great video! 9^81 assumes every square has 9 options but every correctly placed number significantly decreases the number of possible numbers. The actual number is surprisingly not as big as you would expect. Nevertheless it is much better to use the backtracking approach.
Hi Tim! I'm very exited for this series, i just started out with python and i'm learning a great deal of your videos! i wanted to ask why this dosn't work? i = 100 while True: if len(str(i)) == 1: print(i) break else: i = (i / 2) print(i) i have also tried to set the condition for the while loop to while len(str(i)) > 1:
Wow, me and my classmates were bored at school today, we tried making a sudoku solver, and woah, I didn’t think we would make efficient logic, we actually managed to make logic similar to the backtracking method, only we didn’t have enough skill to be able to code it
thks man, i needed this for a homework and i didnt understand how to do it, you saved me man. Keep going with this kind of examples i enjoyed how you teach us. More baktracking examples please, like the 4 queen s chess table .
@@leventegyorgydeak1300 you're stupid, only our own sun is 10^57 already smh, and all of the atoms in body masses in space are a small fraction of all the space dust atoms
@@rafvissersraf do you realise that 10^77 is 10^20 times more than 10^57? that is an insanely huge number, and you have to multiply by that. Maybe 10^77 is not more than the atoms in the universe, but it is 10^80-something
The magnitude of 9^81 is mind-bogglingly vast, making a trillion seem like a mere drop in the ocean. To put it into perspective, a trillion, which is 10^12, is dwarfed by 9^81, which is an incomprehensible 2*10^77. Just think about that for a moment: 2 followed by 77 zeros. That's an astronomical number that's hard to fathom. To drive the point home, consider this: a trillion times a trillion is "just" 10^24, which is barely a blip on the radar compared to 9^81. As the exponent increases by just 1, the number multiplies by a factor of 10. So, even a million of these trillion-to-the-trillionth-power calculations is a paltry 10^27. Now, imagine multiplying trillions together six times and then multiplying that by a million. That's what it would take to reach 9^81. This number is so unimaginably large that it's comparable to the estimated number of atoms in the universe. Yes, you read that right: the number of atoms in the universe. It's difficult to wrap one's head around just how staggeringly large 9^81 is. Suffice it to say, it's a number that's beyond our comprehension, a true testament to the incomprehensible vastness of mathematics.
12:46 you explain how you are creating the verticle lines but you say horizontal instead. im not that great at python yet so i was trying to understand how the code would create horizontal lines until i finally realized you meant vertical. this was a headache lol
@@TechWithTim Yes, it uses the backtracking algorithm although I modified it slightly. Before running the backtracking algorithm, the program runs a method on the 'Sudoku board' which checks which numbers already appear within each row. The function then returns a 2D array, where each child array corresponds to a row on the Sudoku board and contains the numbers which do not appear within the given row. The program then runs the backtracking algorithm as standard, but rather than potentially checking each number 1-9 for each empty square, it iterates through the numbers which are not already found in the row. This method ensures that time is not wasted checking trivial cases. I wrote it in JS hoping to implement it within a profile/portfolio website for colleges to view.
9^81 power is 3^162. We know, that 2^20 is a bit bigger than a million, hence 2^40 is a bit bigger than a trillion. Imagine what's left for 3^162. Another way to visualize it is, that 3^2 ~=10. 3^42 is a bit (in percent) bigger than 10^20. 3^162 is a bit (in percent) bigger than the forth power of 3^42. In fact, it's 3^168/729. So we know, that 3^162 ~~ 10^77, so we can safely assume 3^162 has around 78 digits. (Just checked the calculator - it's around 1.966×10^77. Can't believe how close I was). Edit: 9^81 is only if you literally have no digits on the board or rules about how to position them on it.
Hey Tim, love your videos! Thanks for making them. What would be the best way to randomly generate a partially solved Sudoku puzzle as an array of lists like you have in this video?
hey man, what keyboard do you use, i cant stand mine. I use wireless Logitech K270 its decent but i am tempted to get a better keyboard with buttons that feel good and a proper space bar , all these space bars on most keyboards are so bloody rattly , i mean u get used to it, but im sure i can find a good keyboard
why are you writing len(bo) and len(bo)[0] in the for loops when you could just write range(9), sudoku grids are always 9x9 so you shouldn't complicate the code accounting for an impossibility. You're sacrificing readability for no reason.
hey Tim, Thanks for the great tutorial. Im totally new to programming so I guess this is still a little too advanced for me because I'm already having trouble understanding what is you do exactly when defining the print_board function (the range and Len stuff) :(
For i in range(len(bo)) just creates a list which is as long as the amount of rows on the board and the loops over all the items in that list. for example For i in range(2): print(i) would print out 0 and 1.
@@confidential303 Let me take a crack at explaining if u still need it. Parentheses like these work like the ones from math. So it looks at the inner most then works out. So it start at (bo), then it looks at (len(bo)) which gives an answer, 9 in this case. So range(9) then happens. I hope this helped
How might you analyze the runtime/spacetime of this? I see n^2 work done and then there's a recursive call, but I'm not sure how the recurrence relation would look.
Would it be fair to say the print(board[ i ][ j ]) prints the last number in the row, but unlike the previously printed numbers, the last number printed is not a string?
Formal definition from Wikipedia: Backtracking is a general algorithm for finding all (or some) solutions to some computational problems, notably constraint satisfaction problems, that incrementally builds candidates to the solutions, and abandons a Candidate (backtracks) as soon as it determines that the candidate can not possibly be completed to be a valid solution.
Hey, I am trying this myself but I am getting nameerror: global name end is not defined or syntax errors with print(" | ", end=""). Any suggestions why that is happening?
Hey Tim! I am really in need of your help with the natural solver. Is it possible to make a video about the natural solver as soon as possible? greetings from Zurich
Wouldn't saving all possible options for the empty positions and then eliminating them one by one be faster? Once there is a single option then we fill in the position. The way I'd do it would involve different steps at first the most efficient option, looking for places a number can already be placed with 100% certainty, if no success then the next step. Like a human (who knows how to play) would play it.
Isn't it the possibility like for each row and column multiplication of factorials but subtracting given number of numbers for each row column like 1row and 1column let's say4 numbers given for first row so (9-4)! And for first column 2 given number so (9-2)! And for first cubic let's say 3 numbers given we can consider that tooo like (9-3)! But not all individually a correlation of these 3.. row, column and 3x3 matrix.. maybe that algorithm could be faster??
3:31 I'm sorry but I laughed with loud when you said at 9^81 is in the trillions. I'm super rusty at math but I'm sure it's way beyond trillion trillions.
Dude I have been struggling to understand backtracking for a long time now. You just made it so simple to understand. Thanks for the video
Tim explains the backtrack algo really well, and I give him credit for writing the code on the fly instead of having it pre-canned. He is a real programmer's programmer. I am going to follow alone but I want to tweak it a bit and use a RANDOM function to pick the an empty square. And then do a monte carlo simulaton with time lapse to compare. I am going to make my CPU work! Good job.
How did it go? I'm curious.
@@lolololololololol-sc1rp The short answer is the RANDOM method did NOT improve the performance. 1) Created a sudoku generator. 2) Created a 2nd version of the solver using the RANDOM function, instead of sequential method, 4) ran them side by side over 100,000 simulations. The avg time of both were within msecs of each other. I have the code in my google colab. I will share with you in my github,
Thank you so much for this series, I will definitely finish it. I have always been intimidated by algorithms and AI-related topics, but this video helped me become more comfortable with that.
By the way, 9^81 is very much above trillions (10^12). In fact, it is nine hundred quinvigintillion
😮
'quinvingintillion' hahahahahhahaha
it is 196627050475552913618075908526912116283103450944214766927315415537966391196809
196627050475552913618075908526912116283103450944214766927315415537966391196809
Pro tip : you can watch series on KaldroStream. I've been using them for watching a lot of movies lately.
You could avoid having things like 'range(len(bo[0]))' and 'bo[i][j]' by using the enumerate() function, which takes an iterable (in this case bo) and returns an enumerate object which can be iterated over for index- value pairs. In code you'd write:
for i, row in enumerate(bo):
for j, val in enumerate(row):
if val == 0:
return (i, j)
It's a very useful function if you need to iterate over both the index and the value at that index.
Hey Tim! I'm Brasilian but i love ur videos. I'm starting now at python.
Hey! Glad you like them
@@sasmitvaidya no, the way I said this is because the videos are not in portuguese.
@@sasmitvaidya ow, it was good, I evolved a lot. I`ve been learning Pyside, Pygame, and other tools . Was very cool.
Mannnnn, You are killing it. Really you are inspiring me to learn programming. Maybe this isn't the vauu thing to learn but I fell that I am learning something. ( Not wasting time ) Thanks a lot
I survived my BSc thanks to this chanell, now it's saving my life in masters, Thank you!
Thank you for putting the mistakes in, it helps a new learner like me!
Great video! 9^81 assumes every square has 9 options but every correctly placed number significantly decreases the number of possible numbers. The actual number is surprisingly not as big as you would expect. Nevertheless it is much better to use the backtracking approach.
2:28 two 8s in one row... seems legit
i was just about to say that lol
MuabYT that’s a column not row
Thing S
Google “column row”. When I was young, I also got that wrong a lot. But if you practice your english will get better.
@@things990 What do you smoke and where can I get some?
@@muabyt7333 I like calling it x y, x for horizontal, y for the vertical
thanks Tim it's the best one I saw
very interesting. Will be a good series. Thanks Tim.
Just the series I've been looking for man!
Thanku
I found your explanation on backtracking really useful!
9^81 is way, way more than a value in the trillions. It's 2 x 10^77.
Wtf
Lol
Omg lincoln Im ur big fan
That's like the total number of atom in the universe
Thanks Tim you are the best
Great video! keep upload more code using different algorithms :)
For sure !
Looking forward for the next video
That was fun. On to the next one. Cool vid. Thx
Tim is my hero!
You make really awesome and interesting and useful videos sir
Thankss for this amazing tutorial Tim
finally i understand it!! ur the best
You are a genius 👍🏻
Thank you Tim! I finally understood it! :D
Hi Tim! I'm very exited for this series, i just started out with python and i'm learning a great deal of your videos!
i wanted to ask why this dosn't work?
i = 100
while True:
if len(str(i)) == 1:
print(i)
break
else:
i = (i / 2)
print(i)
i have also tried to set the condition for the while loop to
while len(str(i)) > 1:
Aha because when you divide you get a float which has a length of 3 because it counts the “.0” . Try checking if i//10 < 1
13:17 the "up thing" is called a pipe...
Vertical Bar
Great content! Keep up the work!!
Lovely bro !
Thanks a lot for your donations for others.
Wow, me and my classmates were bored at school today, we tried making a sudoku solver, and woah, I didn’t think we would make efficient logic, we actually managed to make logic similar to the backtracking method, only we didn’t have enough skill to be able to code it
Nice explanation. One of the clearest videos on the network.
Thanks, I feel like I understand recursion a little bit better now.
Awesome! Try watching the next video where I implement it
thks man, i needed this for a homework and i didnt understand how to do it, you saved me man. Keep going with this kind of examples i enjoyed how you teach us.
More baktracking examples please, like the 4 queen s chess table .
why in the second for loop is there an [0], wouldn't you want to use [i] ? To refer to the current array?
very good now i go to next one
”9^81 is probably like in the trillions or something”... not even close lmao
9.something * 10^77 LMAO
it is more than the number of atoms in the observable universe
@@leventegyorgydeak1300 it isnt
@@leventegyorgydeak1300 you're stupid, only our own sun is 10^57 already smh, and all of the atoms in body masses in space are a small fraction of all the space dust atoms
@@rafvissersraf do you realise that 10^77 is 10^20 times more than 10^57? that is an insanely huge number, and you have to multiply by that. Maybe 10^77 is not more than the atoms in the universe, but it is 10^80-something
The magnitude of 9^81 is mind-bogglingly vast, making a trillion seem like a mere drop in the ocean. To put it into perspective, a trillion, which is 10^12, is dwarfed by 9^81, which is an incomprehensible 2*10^77. Just think about that for a moment: 2 followed by 77 zeros. That's an astronomical number that's hard to fathom.
To drive the point home, consider this: a trillion times a trillion is "just" 10^24, which is barely a blip on the radar compared to 9^81. As the exponent increases by just 1, the number multiplies by a factor of 10. So, even a million of these trillion-to-the-trillionth-power calculations is a paltry 10^27.
Now, imagine multiplying trillions together six times and then multiplying that by a million. That's what it would take to reach 9^81. This number is so unimaginably large that it's comparable to the estimated number of atoms in the universe. Yes, you read that right: the number of atoms in the universe.
It's difficult to wrap one's head around just how staggeringly large 9^81 is. Suffice it to say, it's a number that's beyond our comprehension, a true testament to the incomprehensible vastness of mathematics.
in the source code provided by, the GUI isn't working in website
Absolutely amazing of u
Coding starts at 11:27
12:46 you explain how you are creating the verticle lines but you say horizontal instead. im not that great at python yet so i was trying to understand how the code would create horizontal lines until i finally realized you meant vertical. this was a headache lol
thank you so much Tim for this code and for making us understand so clearly . just coding isn't effective explaining the concept is so great .
Thanks nicely presented.
The biggest puzzle was foguring out what the top right corner was :D
3:25 "9^81 is probably in the trillions" I facepalmed to hard at that. Come on Tim.
This is very strange. Yesterday I finished a sudoku solver- what a wonderful coincidence.
Is it similar to mine?
@@TechWithTim Yes, it uses the backtracking algorithm although I modified it slightly.
Before running the backtracking algorithm, the program runs a method on the 'Sudoku board' which checks which numbers already appear within each row. The function then returns a 2D array, where each child array corresponds to a row on the Sudoku board and contains the numbers which do not appear within the given row.
The program then runs the backtracking algorithm as standard, but rather than potentially checking each number 1-9 for each empty square, it iterates through the numbers which are not already found in the row. This method ensures that time is not wasted checking trivial cases.
I wrote it in JS hoping to implement it within a profile/portfolio website for colleges to view.
9^81 power is 3^162. We know, that 2^20 is a bit bigger than a million, hence 2^40 is a bit bigger than a trillion. Imagine what's left for 3^162. Another way to visualize it is, that 3^2 ~=10. 3^42 is a bit (in percent) bigger than 10^20. 3^162 is a bit (in percent) bigger than the forth power of 3^42. In fact, it's 3^168/729. So we know, that 3^162 ~~ 10^77, so we can safely assume 3^162 has around 78 digits. (Just checked the calculator - it's around 1.966×10^77. Can't believe how close I was).
Edit: 9^81 is only if you literally have no digits on the board or rules about how to position them on it.
Good one !
Hey Tim, love your videos! Thanks for making them. What would be the best way to randomly generate a partially solved Sudoku puzzle as an array of lists like you have in this video?
Make a video on algorithms and data types
Nice, I did something similar in PHP.
hey man, what keyboard do you use, i cant stand mine. I use wireless Logitech K270 its decent but i am tempted to get a better keyboard with buttons that feel good and a proper space bar , all these space bars on most keyboards are so bloody rattly , i mean u get used to it, but im sure i can find a good keyboard
Amazing video
9**81 is actually so high, that I believe that no computer would be ever able to solve it.
tim is the best
Why the extra step in 14:00? It works with just print(bo[i][j], end="")
for making spaces in the other position
and if j==8:==> we don't need spaces in the last position and we don't need to stay in the same line
Hey man Tim how can we type a modulus please answer
Thanks Tim.
why are you writing len(bo) and len(bo)[0] in the for loops when you could just write range(9), sudoku grids are always 9x9 so you shouldn't complicate the code accounting for an impossibility. You're sacrificing readability for no reason.
yeah
it makes it easier to work with non-traditional sudokus.
was great. thanks
What if the puzzle given by user is not solvable?
Dude, why couldnt you have made this video when I was in uni and smashed my face into my keyboard when my teacher assigned this as hw lol.
9^81 is roughly equivalent to the amount of atoms in the universe to put that into perspective
hey Tim,
Thanks for the great tutorial. Im totally new to programming so I guess this is still a little too advanced for me because I'm already having trouble understanding what is you do exactly when defining the print_board function (the range and Len stuff) :(
For i in range(len(bo)) just creates a list which is as long as the amount of rows on the board and the loops over all the items in that list. for example For i in range(2): print(i) would print out 0 and 1.
@@Alan-pi1vn you making it more confusing
@@confidential303 Let me take a crack at explaining if u still need it. Parentheses like these work like the ones from math. So it looks at the inner most then works out. So it start at (bo), then it looks at (len(bo)) which gives an answer, 9 in this case. So range(9) then happens. I hope this helped
How might you analyze the runtime/spacetime of this? I see n^2 work done and then there's a recursive call, but I'm not sure how the recurrence relation would look.
which is the best database to work with python?
Hey can u clear doubt which is isn't there 11 rows( a single line takes one row right?)so how u set logic for printing horizontal lines after 3 row
Amazing... can you give me a solution to the Ubongo puzzle?
How does this work
if j == 8:
print(bo[i][j])
else:
print(str(bo[i][j]) + " ", end="")
What application do you use to record your screen and edit it?
I am confused about the printBoard() function.. %? Modulous?? what is that?
can you tell me whether you are coding in pycharm?
What would the 6x6 box loop look like? Having troubles with it
What software did you use to type in the codes?
Thanks so much dude, this code Will be use from Argentina ♥
I dont understand how for loops work or anything.. also what is print([i][j])
@@Pranav-x8q Why should we do that?
where did you find sudoku boards ? I'm looking for CSV exportable boards
Would it be fair to say the print(board[ i ][ j ]) prints the last number in the row, but unlike the previously printed numbers, the last number printed is not a string?
Pleaseeeee any response would help my understanding. I’m new to coding
hi just wanted to understand how will it be 9 raise to the power 81 possibilities , i think there will be only 729 possibilities right ?
if j == 8:
print(boardfunc[i][j])
what does this line do?
Please explain why we use( if i ==08)
Can you do a video on killer sudokus?
how does one return the grid when its solved instead of returning True/False values ?
hey tim, i really want to do this project,but if i build this being guided by you,is it leggit to link this code on my resume?
Ofc it is
isnt backtracking like a definitive property that declarative approaches have where you use rules and pattern matching and trial and error
Formal definition from Wikipedia: Backtracking is a general algorithm for finding all (or some) solutions to some computational problems, notably constraint satisfaction problems, that incrementally builds candidates to the solutions, and abandons a Candidate (backtracks) as soon as it determines that the candidate can not possibly be completed to be a valid solution.
@@TechWithTim ah yes, constraint satisfaction with a lot of trials
Hey, I am trying this myself but I am getting nameerror: global name end is not defined or syntax errors with print(" | ", end="").
Any suggestions why that is happening?
Which python version are you using?
Bronko Python 3
@@jalenthomas2337 msg me on discord if you still need help vecom#6091
What did you do to fix it? I'm having the same issue
Hey Tim! I am really in need of your help with the natural solver. Is it possible to make a video about the natural solver as soon as possible? greetings from Zurich
What is a natural solver?
Gee i feel silly here , how do u generate the board, i mean the numbers... is this part of the print bo function
Is this the best way to make a sudoku board?
Wouldn't saving all possible options for the empty positions and then eliminating them one by one be faster? Once there is a single option then we fill in the position.
The way I'd do it would involve different steps at first the most efficient option, looking for places a number can already be placed with 100% certainty, if no success then the next step. Like a human (who knows how to play) would play it.
Isn't it the possibility like for each row and column multiplication of factorials but subtracting given number of numbers for each row column like
1row and 1column let's say4 numbers given for first row so (9-4)! And for first column 2 given number so (9-2)! And for first cubic let's say 3 numbers given we can consider that tooo like (9-3)! But not all individually a correlation of these 3.. row, column and 3x3 matrix.. maybe that algorithm could be faster??
3:31 I'm sorry but I laughed with loud when you said at 9^81 is in the trillions. I'm super rusty at math but I'm sure it's way beyond trillion trillions.
Love it.
Are there any additional packages I need to run this? every time i try run your code it says there's an error in the syntax 'end='
same, unfortunately I am on a chromebook and have to use Repl.it and sublime.
At the end, in the last loop it should be `len(bo[i])`, as currently you are looping only over the first row :)
I see what you mean but it’s actually fine. Since we known the length of each row is the same we can do that.
@@TechWithTim true
When is the next tutorial on PyOpenGl coming ??
And what will it be about ??
Just watch sendex videos on it if u cant wait
I’m trying to create an FPS camera but it’s pretty difficult so no estimate atm
How can i print out just the first collum, i want to know so i can understand the code better
im a massive newbie to this so take this with a grain of salt but maybe change the range in J to 1
Hey, Can we use A* Search to solve Sudoku?
I love it