Permuting Magic Squares - python

I'm having a little bit of trouble writing a recursive permutation function for solving Magic Squares. For this function, I'm not allowed to use two-dimensional arrays, only lists. Below is what I have currently:
def permute(size):
magicSquare = []
for value in permute(size**2):
for pos in range(size**2 + 1):
magicSquare.append(value)
return magicSquare
size is defined by the user through command-line argument.
I'm slightly confused if the function written above accomplishes the task of permuting the values.

It wouldn't appear to and in fact should basically never terminate the way it is currently written.
An easy way to start thinking about this problem is that a magic square can be represented by a list of size n**2, so a 3x3 magic square can be represented by a 9-length list. Since it is a magic square, you then need to permute over the values range(1,n+1), e.g., for a 3x3:
1 2 3
4 5 6
7 8 9
Check to see if this is a magic square (it isn't since the rows don't sum to the same value) and if it is, add it to your magic squares list. Either way, try the next permutation:
1 2 3
4 5 6
7 9 8
…until you are out of permutations. This is, of course, a non-optimal route because the trouble row (1, 2, 3) still won't sum to 15, so there is clear room for optimization and easily discarding possibilities that won't work.
An easy tool to either check your work or do the permutation piece for you is itertools.permutations. Which will create a generator that will yield each additional permutation until there aren't any more.
Note that for anything beyond a trivial square size you are going to exceed the maximum recursion limit if you try to make another recursive call each time using this method. You'll need to find a way to manage that situation once size=3. There are a couple of ways to handle that of varying degrees of complexity, depending on what exactly you are trying to do.

Here is a simple method for checking magic square or not.
Note: please try by using 3*3 grid.
def magic():
print "maximam 9 values"
a=[]
for i in range(3):
a.append([])
for j in range(3):
a[i].append(input('Enter the values'))
print a
l1= a[0][0]+a[1][0]+a[2][0]
l2=a[0][1]+a[1][1]+a[2][1]
l3=a[0][2]+a[1][2]+a[2][2]
r1=sum(a[0])
r2=sum(a[1])
r3=sum(a[2])
if l1 == l2 == l3 == r1 == r2 == r3:
print a,"Its magic square"
else:
print a,"not magic square"
magic()

Related

How to find the nth value in a Fibonacci series? [duplicate]

This question already has answers here:
How does the fibonacci recursive function "work"?
(12 answers)
Closed 2 years ago.
# Function for nth Fibonacci number
def Fibonacci(n):
if n<0:
print("Incorrect input")
# First Fibonacci number is 0
elif n==1:
return 0
# Second Fibonacci number is 1
elif n==2:
return 1
else:
return Fibonacci(n-1)+Fibonacci(n-2)
# Driver Program
print(Fibonacci(9))
I am new to programming.
I cant get how this codes finds out the Fibonacci number....
How does the program calculates the value of (n-1) and (n-2)
Your program uses recursion.
Here you can find visualization, which could help you with understanding:
https://observablehq.com/#victormutai/visualizing-recursive-fibonacci-algorithm
Alternative implementation is iterative algorithm. I could be easier to understand
def f(n):
a, b = 0, 1
for i in range(0, n):
a, b = b, a + b
return a
Here is an illustratory diagram from the SICP book.
When Fibonacci(5) is invoked, Fibonacci(5-1) (fib 4) and Fibonacci(5-2) (fib 3) are invoked in return. When Fibonacci(4) is invoked, Fibonacci(4-1) and Fibonacci(4-2) are invoked in return, so on and so forth. This is called a recursion.
Finally, when either Fibonacci(2) or Fibonacci(1) is invoked, its result 1 and 0 is returned directly without further invocation. It is the termination conditions of such recursion.
By the way, as is depicted in the diagram, the multiple times' invocations of fib 3, which is seen as repeated calculation, result in inefficiency. So it is only for demonstrating how recursion works while usually not used to calculate fibs in practice.
return Fibonacci(n-1)+Fibonacci(n-2)
This is a recursion. You should cache values to reduce recalculation.
moreover, there is Binet's formula to calculate it at O(1) time.
https://en.wikipedia.org/wiki/Fibonacci_number
The idea behind that piece of code is recursion. Have a look at this to find out more about it.
To explain how your code works to identify the nth number in the Fibonacci series, first you need to understand how a Fibonacci series is generated.
0, 1, 1, 2, 3, 5, 8, 13, and so on.
Here if you look at the first two numbers it is 0 and 1, these are the base numbers, from there on the next number is found out by the addition of the previous two numbers. Hence the formula.
F(1) = 0
F(2) = 1
F(n) = F(n-1) + F(n-2)
Now if you look at your code the above is exactly depicted here. Any value of n less that 1 will be considered as invalid. A value of 1 returns a 0 and a value of 2 returns a 1. this is exactly the same as we have mentioned above.
Fibonacci(n-1)+Fibonacci(n-2)
Finally for all other cases we find the previous two numbers in the series by using the same rule(function) and sum them to get the desired number.

Python Coin Change Dynamic Programming

I am currently trying to implement dynamic programming in Python, but I don't know how to setup the backtracking portion so that it does not repeat permutations.
For example, an input would be (6, [1,5]) and the expected output should be 2 because there are 2 possible ways to arrange 1 and 5 so that their sum is equivalent to 6. Those combinations are {1,1,1,1,1,1} and {1,5} but the way my program currently works, it accounts for the combinations displayed above and the combination {5,1}. This causes the output to be 3 which is not what I wanted. So my question is "How do I prevent from repeating permutations?". My current code is shown below.
import collections as c
class DynamicProgram(object):
def __init__(self):
self.fib_memo = {}
# nested dictionary, collections.defaultdict works better than a regular nested dictionary
self.coin_change_memo = c.defaultdict(dict)
self.__dict__.update({x:k for x, k in locals().items() if x != 'self'})
def coin_change(self, n, coin_array):
# check cache
if n in self.coin_change_memo:
if len(coin_array) in self.coin_change_memo[n]:
return [n][len(coin_array)]
# base cases
if n < 0: return 0
elif n == 1 or n == 0: return 1
result = 0
i = 0
# backtracking (the backbone of how this function works)
while i <= n and i < len(coin_array):
result += self.coin_change(n-coin_array[i], coin_array)
i += 1
# append to cache
self.coin_change_memo[n][len(coin_array)] = result
# return result
return result
One of the way of avoiding permutation is to use the numbers in "non-decreasing" order. By doing so you will never add answer for [5 1] because it is not in "non-decreasing" order.And [1 5] will be added as it is in "non-decreasing" order.
So the change in your code will be if you fix to use the ith number in sorted order than you will never ever use the number which is strictly lower than this.
The code change will be as described in Suparshva's answer with initial list of numbers sorted.
Quick fix would be:
result += self.coin_change(n-coin_array[i], coin_array[i:]) # notice coin_array[i:] instead of coin_array
But you want to avoid this as each time you will be creating a new list.
Better fix would be:
Simply add a parameter lastUsedCoinIndex in the function. Then always use coins with index >= lastUsedCoinIndex from coin array. This will ensure that the solutions are distinct.
Also you will have to make changes in your memo state. You are presently storing sum n and size of array(size of array is not changing in your provided implementation unlike the quick fix I provided, so its of no use there!!) together as a state for memo. Now you will have n and lastUsedCoinIndex, together determining a memo state.
EDIT:
Your function would look like:
def coin_change(self,coin_array,n,lastUsedCoinIndex):
Here, the only variables changing will be n and lastUsedCoinIndex. So you can also modify your constructor such that it takes coin_array as input and then you will access the coin_array initialized by constructor through self.coin_array. Then the function would become simply:
def coin_change(self,n,lastUsedCoinIndex):

Python Non-recursive Permutation

Does anyone understand the following iterative algorithm for producing all permutations of a list of numbers?
I do not understand the logic within the while len(stack) loop. Can someone please explain how it works?
# Non-Recursion
#param nums: A list of Integers.
#return: A list of permutations.
def permute(self, nums):
if nums is None:
return []
nums = sorted(nums)
permutation = []
stack = [-1]
permutations = []
while len(stack):
index = stack.pop()
index += 1
while index < len(nums):
if nums[index] not in permutation:
break
index += 1
else:
if len(permutation):
permutation.pop()
continue
stack.append(index)
stack.append(-1)
permutation.append(nums[index])
if len(permutation) == len(nums):
permutations.append(list(permutation))
return permutations
I'm just trying to understand the code above.
As mentioned in the comments section to your question, debugging may provide a helpful way to understand what the code does. However, let me provide a high-level perspective of what your code does.
First of all, although there are no recursive calls to the function permute, the code your provided is effectively recursive, as all it does is keeping its own stack, instead of using the one provided by the memory manager of your OS. Specifically, the variable stack is keeping the recursive state, so to speak, that is passed from one recursive call to another. You could, and perhaps should, consider each iteration of the outer while loop in the permute function as a recursive call. If you do so, you will see that the outer while loop helps 'recursively' traverse each permutation of nums in a depth-first manner.
Noticing this, it's fairly easy to figure out what each 'recursive call' does. Basically, the variable permutation keeps the current permutation of nums which is being formed as while loop progresses. Variable permutations store all the permutations of nums that are found. As you may observe, permutations are updated only when len(permutation) is equal to len(nums) which can be considered as the base case of the recurrence relation that is being implemented using a custom stack. Finally, the inner while loop picks which element of nums to add to the current permutation(i.e. stored in variable permutation) being formed.
So that is about it, really. You can figure out what is exactly being done on the lines relevant to the maintenance of stack using a debugger, as suggested. As a final note, let me repeat that I, personally, would not consider this implementation to be non-recursive. It just so happens that, instead of using the abstraction provided by the OS, this recursive solution keeps its own stack. To provide a better understanding of how a proper non-recursive solution would be, you may observe the difference in recursive and iterative solutions to the problem of finding nth Fibonacci number provided below. As you can see, the non-recursive solution keeps no stack, and instead of dividing the problem into smaller instances of it(recursion) it builds up the solution from smaller solutions. (dynamic programming)
def recursive_fib(n):
if n == 0:
return 0
elif n == 1:
return 1
return recursive_fib(n-1) + recursive_fib(n-2)
def iterative_fib(n):
f_0 = 0
f_1 = 1
for i in range(3, n):
f_2 = f_1 + f_0
f_0 = f_1
f_1 = f_2
return f_1
The answer from #ilim is correct and should be the accepted answer but I just wanted to add another point that wouldn't fit as a comment. Whilst I imagine you are studying this algorithm as an exercise it should be pointed out that a better way to proceed, depending on the size of the list, may be to user itertools's permutations() function:
print [x for x in itertools.permutations([1, 2, 3])]
Testing on my machine with a list of 11 items (39m permutations) took 1.7secs with itertools.permutations(x) but took 76secs using the custom solution above. Note however that with 12 items (479m permutations) the itertools solution blows up with a memory error. If you need to generate permutations of such size efficiently you may be better dropping to native code.

Summation Combination code

Hi I am new to Python and am trying to solve a coding challenge where the objective is to create a function which takes an array of integers (both negative and positive) and a target value (also an integer) and then outputs true if any combinations of the numbers sum up to the target value, which will always be larger than any other single element in the input array. I tried to do this but horribly failed. I found someone else's code who did it in 2 lines, but I have no idea how it works and was hoping someone here could point me in the right direction. Here is the code
def subsetsum(target, arr):
if len(arr) == 0:
return target == 0
return subsetsum(target, arr[1:]) or subsetsum(target - arr[0], arr[1:])
I mean I don't even see where they sum up the numbers and compare to the target, any help will be greatly appreciated. Thanks in advance.
Their solution uses recursion to express all possible combinations of the numbers in a pretty clever way. But clever does not always mean readable or easy to understand (which all code should be) so don't feel bad for not getting it right away. Personally, I would not consider this good code.
The simplest way to think of it is to work backwards.
What happens if arr has 0 elements? Well, it's explicitly checked at the beginning of the function: it can only be a solution to the problem if target is already 0. Let's refer to this special case of subsetsum (where arr is []) as is_zero, because that's all it does.
What happens if arr has 1 element [x]? For a solution to exist, you have to get target by either including or not including x in the sum. This is done by converting the problem in to the 0-element version, as arr[1:] will be the empty list ([]). The first part of the or expression, subsetsum(target, arr[1:]), ignores x and basically asks if is_zero(target). The second part of the expression includes x in the sum by asking if is_zero(target - x). Try it with arr = [9]. You get True if is_zero(target) OR if is_zero(target - 9). Which makes sense, right? If the target is 0 or 9, then [0] or [9] are solutions to the problem, respectively.
What happens if arr has 2 elements [x, y]? Again, the problem is reduced into the 1-element-smaller version, as arr[1:] is just [y]. So, is there a solution in subsetsum(target, [y]) OR is there a solution in subsetsum(target - x, [y]). Try it with [3, 9]. The first part of the expression ignores 3 and evaluates True if target is 9 or 0. The second part includes 3 and evaluates True if target - 3 is 9 or 0 (i.e. if target is 12 or 3). Thus, it "tries" all possible combinations: [], [9], [3], and [9, 3].
subsetsum(target, [x, y, z]) is reduced to subsetsum(target, [y, z]) OR subsetsum(target - x, [y, z]), and so on...
Looking from the top down now, what happens is that for every element in arr, the question is split into two subquestions of "is there a solution if we do not include this element?" and "is there a solution if we do include this element?" That way, you end up trying all 2**len(arr) combinations.
A much cleaner (and more efficient) solution to this problem is definitely possible using Python's really sweet module itertools, but I don't have time to write it at the moment. I may try it tomorrow just for fun, though.
Edit: Here's my more readable (and probably faster) version.
import itertools
def subsetsum(target, arr):
for subset_len in range(len(arr) + 1):
if any(sum(subset) == target for subset in itertools.combinations(arr, subset_len)):
return True
return False
It simply finds all subsets, starting with length 0 (so []) and working up to length len(arr), and checks if any of them sum to target. Python is a beautiful language!
edit There's a bug in that code (depending on whether you think there is a combination of the numbers in [1] that sum up to 0). Try
subsetsum(0,[1])
> True
I explain a bit more below.
end edit
So I think the challenge in understanding the code isn't so much about Python as about understanding a recursive function.
Let's assume that the function subsetsum works for lists of length less than N. Now let's take some list of length N. If there is a subset that sums to the target it either involves the first element (arr[0]) or it doesn't. So we'll break this into two problems - checking if there is a subset that has the first element, and checking if there is a subset that doesn't.
Note that arr[1:] is an array of length N-1 starting with the second element of arr.
So if there is a subset that does not involve arr[0], then subsetsum(target,arr[1:]) will give True. If there is a subset that involves arr[0] then subsetsum(target-arr[0],arr[1:]) will return True. If neither holds then it's going to return False.
So basically whether this works for N depends on whether it works for N-1, which depends on whether it works for N-2 etc. Finally we get down to length 0. If the target is 0, at this point, it should return True. If not, the False, or at least, that's what the person writing this code thought. I disagree. Explanation of the bug below.
Personally, I would argue that there is a bug in this code. If I give it any list and a target of 0, it'll return True. The test should be that when it gets down to a length 1 list, is the target equal to that one value. The test should be if the first element is the target, and if it gets down to a length 0 list, it's failed.
def subsetsum(target, arr):
if len(arr)==0:
return False
elif arr[0]==target:
return True
else:
return subsetsum(target, arr[1:]) or subsetsum(target - arr[0], arr[1:])

Python: determining if a number is prime [duplicate]

This question already has answers here:
How to create the most compact mapping n → isprime(n) up to a limit N?
(29 answers)
Closed 7 years ago.
I am new to Python and I'm attempting to write a code that checks to see whether or not a number is prime. So far, I've written this:
def main():
n = input("Enter number:")
isprime(n)
def isprime():
x = Prime
for m in range (1,n+1,1)
result = n % m
print result
main()
I'm not sure how to proceed after this. I know I have to define isprime. Any help would be greatly appreciated. Thank you!
Your first and biggest problem is that you need to list n as a parameter to isprime before you can use it within isprime, and before you can pass an argument in main. See the tutorial on Defining Functions for more details. But basically, it's like this:
def isprime(n):
Also, that x = Prime is going to raise a NameError, because there's nothing named Prime. Given that it doesn't actually do anything at all, you should just delete it.
Of course that won't make this a complete working prime testing function, but it is how to proceed from where you are.
The next step is to consider what to return from the function. If you find a value that divides n, then obviously n isn't prime, and therefore isprime is false. If you go through all possibilities and don't find anything that divides n, then isprime is true. So, with two return statements in the right places, you can finish the function.
Once it's at least always returning True or False, you have bugs to fix.*
Look at what numbers you get from range(1, n+1, 1). Two of those numbers are guaranteed to divide any n. How do you avoid that problem?
After you've got it working, then you can work on optimizing it. If you look up primality test on Wikipedia, you can see a really simple way to improve the naive trial division test. A bit of research will show the pros and cons of different algorithms. But if what you've got is fast enough for your purposes, it's usually not worth putting more effort into optimizing.
* You might want to consider writing a test program that calls isprime on a bunch of numbers and compares the results with the right answers (for answers you already know off the top of your head—1 is not prime, 2 is prime, 17 is prime, etc.). This is called Test Driven Development, and it's a great way to make sure you've covered all the possible cases—including outliers like 0, 1, 2, -3, etc.
Your isprime is quite close. The first line x = Prime is unnecessary, so let's get rid of that.
Now, let's take a look at what you're doing next:
You seem to want to check if there are any numbers that divide n perfectly. While this is the correct approach, you are including n and 1 in the numbers that you are testing. This is wrong for obvious reasons.
There is another error: you use n without ever defining it (I think you want it to be a parameter to your function). So let's put all this together:
def isprime(n):
for m in range(2, n):
if not n%m: # m divides n perfectly
return False
return True # if n were not prime, the function would have already returned
But going a step further, you don't really have to check every number between 2 and n-1. You just need to check the numbers between 2 and the square-root of n:
def isprime(n):
for m in range(2, int(n**0.5)+1):
if not n%m:
return False
return True

Categories

Resources