Execution timed out (12000ms) kata Generate Numbers from Digits #2 on Code Wars (Python) - python-3.x

Could you give me a hint where the time consuming part of this code is?
It's my temporary solutions for the kata Generate Numbers from Digits #2 from codewars.com.
Thanks!
from collections import Counter
from itertools import permutations
def proc_arrII(arr):
length = Counter(arr).most_common()[-1][1]
b = [''.join(x) for x in list(set(permutations(arr,length)))]
max_count = [max(Counter(x).values()) for x in b]
total = 0
total_rep = 0
maximum_pandigit = 0
for i in range(len(b)):
total+=1
if max_count[i] > 1:
total_rep+=1
elif int(b[i]) > maximum_pandigit:
maximum_pandigit = int(b[i])
if maximum_pandigit == 0:
return([total])
else:
return([total,total_rep,maximum_pandigit])

When posting this,
it would have been helpful to offer example input,
or link to the original question,
or include some python -m cProfile output.
Here is a minor item, it inflates the running time very very slightly.
In the expression [''.join(x) for x in list(set(permutations(arr, length)))]
there's no need to call list( ... ).
The join just needs an iterable, and a set works fine for that.
Here is a bigger item.
permutations already makes the promise that
"if the input elements are unique, there will be no repeat values in each permutation."
Seems like you want to dedup (with set( ... )) on the way in,
rather than on the way out,
for an algorithmic win -- reduced complexity.
The rest looks nice enough.
You might try benching without the elif clause,
using the expression max(map(int, b)) instead.
If there's any gain it would only be minor,
turning O(n) into O(n) with slightly smaller coefficient.
Similarly, you should just assign total = len(b) and be done with it,
no need to increment it that many times.

Related

Finding palindrome of sum

Here's the problem statement:
For a given no. num, perform:
1. Add num and reverse(num)
2. Check whether the sum is palindrome or not. Else repeat.
Here is my solution. The program seems to be working for the 3 test cases given but when I am executing this program, for 1 private test case I am getting server time out error. Is my program not efficient?
flag=0
iteration=0
num = 195 # sample no. output produced is 9339 which is a palindrome.
while(flag!=1):
#print("iteration ",iteration)
num_rev= int(str(num)[::-1]) #finding rev of number
#print(num_rev)
total= num+num_rev #adding no and no_rev
#print(total)
total_rev= int((str(total))[::-1]) # finding total rev
iteration=iteration+1
if total==total_rev: #if equal, printing palindrome
print("palindrome")
flag=1
else:
num=total #else the new no becomes sum of old num and old_rev
Begin by profiling your code for each of your test cases to find out what is taking so long. I suggest using Jupyter Notebook's code profiling magic. Paste your code into a Jupyter Notebook cell and being the cell with %%prun. Along with other information, it will return a list of function calls, the number of times each function is called, and the amount of time each function takes to run. Compare the run time of your test cases to your server's timeout limit.
If the problem is not with your code and its evolving complexity as the number increases in size, it may be a problem with your server.
...
Note that a palindrome must contain at least 2 or 3 elements depending on your accepted definition.
Consider that one of your test cases may be venturing into arbitrarily large integers that take an unpredictable amount of time to compute. Consider that this compute time may exceed your server's timeout limit.
Furthermore, consider this modified version of your code that accepts an arbitrarily-defined max iteration depth per seed number. It also accepts an arbitrary seed number and a max seed number. Then returns an ordered list of all non-duplicate seed numbers, their respective palindrome sums, the number of iterations required to find the palindrome, and the approximate time required to perform the search:
#flag = 0
iteration = 0
maxiter = 1000
num = 0
max_num = 10000
used_seeds = []
palindromes = []
while num < max_num:
seed = num
while(iteration <= maxiter) and len(str(total))>2:
if num in used_seeds:
break
iteration+=1
num_reversed = int(str(num)[::-1])
total = num + num_reversed
total_reversed = int((str(total))[::-1])
if total == total_reversed:
used_seeds.append(num)
palindromes.append( [num, total] )
break
else:
num = total
num = seed+1
iteration = 0
palindromes.sort(key=lambda elem: elem[0])
print(palindromes)
The results are fascinating, by the way. Hopefully this helps.

Non-recursive Most Efficient Big-O Permutation Alghoritm Python3 (non-built-in)

Hi Guys For my Data Structure assignment I have to find the most efficient way (big-o wise) to calculate permutations of a list of objects.
I found recursive examples on the web but this doesn't seem to be the most efficient way; I tried my own code but then I realized that when I count the number of possible permutations I'm actually making my algorithm O(!n). Any suggestions? .-.
from random import sample
import time
start = time.time()
testList = list(x for x in range(7))
print('list lenght: %i objects' % len(testList))
nOfPerms = 1
for i in range(1,len(testList)+1):
nOfPerms *= i
print('number of permutations:', nOfPerms)
listOfPerms = []
n = 1
while n <= nOfPerms:
perm = tuple(sample(testList, len(testList)))
listOfPerms.append(perm)
permutations = set(listOfPerms)
if len(permutations) == len(listOfPerms):
n += 1
else:
del(listOfPerms[-1])
end = time.time() - start
print('time elapsed:', end)
OUTPUT:
list lenght: 7 objects
number of permutations: 5040
time elapsed: 13.142292976379395
If instead of 7 I put 8 or 9, or 10, those are the number of permutations (I won't show the time cause it's taking too long):
list lenght: 8 objects
number of permutations: 40320
list lenght: 9 objects
number of permutations: 362880
list lenght: 10 objects
number of permutations: 3628800
I believe this will be the best you can do. Generating the number of permutations of a list generates n! permutations. As you need to generate them all this is also how much time it will take (O(n!)). What you could try to do is to make it a python generator function so you will always only generate exactly as many as you need instead of precalculating them all and storing them in memory. If you want an example of this i could give you one.
Im sorry this might be a quite negative answer. It's a good question but im pretty sure this is about the best that you can do, asymptotically. You could optimize the code itself a bit to use less instructions but in the end that wont help too much.
Edit:
This is a python implementation of Heap's algorithm which i promised
(https://en.wikipedia.org/wiki/Heap%27s_algorithm) generating N! permutations where the generation of every one permutation takes amortized O(1) time and which uses O(n) space complexity (by alteri
def permute(lst, k=None):
if k == None:
k = len(lst)
if k == 1:
yield lst
else:
yield from permute(lst, k-1)
for i in range(k-1):
if i % 2 == 0:
#even
lst[i], lst[k-1] = lst[k-1], lst[i]
else:
#odd
lst[0], lst[k-1] = lst[k-1], lst[0]
yield from permute(lst, k-1)
for i in permute([1, 2, 3, 4]):
print(i)

Implementation of Depth-First-Search on a permutation tree in Python

I have a quadratic Matrix of size n, say A, with non-negative real entries a_ij.
Furthermore I have a permutation tree. For n = 3 it looks like this: .
Now I would like to do a Depth-search (I don't know really, whether "Depth-search" is the correct description for this, but let's use it for now) along the branches of the tree in the following way:
On the first partial tree on the very left do the following starting with an "empty" Permutation (x,x,x):
If a_12 > a_21 set (1,2,x) and then check whether a_23 > a_32. If this is true as well, save (1,2,3) in a list, say P. Then go back to the first Level and check whether a_13 > a_31 and so on.
If a_21 > a_12 or a_32 > a_23 do not save the Permutation in P and go back to the first Level and check whether a_13 > a_31. If this is true set (1,3,x) and then check whether a_23 > a_32. If this is true save (1,3,2) in P and continue with the next partial tree. If a_31 > a_13 or a_32 > a_23 do not save the Permutation in P and continue with the same procedure for the next partial tree.
This procedure/algorithm I would like to implement for an arbitrary natural n > 0 with Input just the Matrix A and n and as an Output all permutations of size n that fullfill these conditions. By now I am not able to implement this in a general way.
Preferably in Python, but Pseudo Code would be nice as well. I also want to avoid functions like "itertools Permutation", because in the use case I Need to apply this for large n, for example n = 100, and then itertools Permutation is very slow.
If I understand correctly, this should get you what you want:
import numpy as np
from itertools import permutations
def fluboxing_permutations(a, n):
return [p for p in permutations(range(n))
if all(a[i, j] > a[j, i] for i, j in zip(p, p[1:]))]
n = 3
a = np.random.random([n, n])
fluboxing_permutations(a, n)
itertools.permutations will yield permutations in lexicographical order, which corresponds to your tree; then we check that for each consecutive pair of indices in the permutation, the element in the matrix is greater than the element at swapped indices. If so, we retain the permutation.
(No idea how to describe what the function does, so I made a new name. Hope you like it. If anyone knows a better way to describe it, please edit! :P )
EDIT: Here's a recursive function that should do the same, but with pruning:
def fluboxing_permutations_r(a, n):
nset = set(range(n))
def inner(p):
l = len(p)
if l > 1 and a[p[-2]][p[-1]] <= a[p[-1]][p[-2]]:
return []
if l == n:
return [p]
return [r for i in nset - set(p)
for r in inner(p + (i,))]
return inner(())
p starts as empty tuple, but it grows in recursion. Once there's at least two elements in the partial permutation, we can test the last two elements and see if it fails the test, and reject it if it does (pruning its subtree out of the search space). If it is a full permutation that wasn't rejected, we return it. If it's not full yet, we append to it all possible indices that are not already in there, and recurse.
tinyEDIT: BTW, parameter n is kind of redundant, because n = len(a) at the top of the function should take care of it.

Can someone help me with my Goldbach code ? When i call the function and then put 1,000,000 it seems not to spit out any output i dont know why?

I need to reach 1,000,000 and for some reason it doesn't give me the output for 1,000,000, I don't know what i am doing wrong. Every time i put a small number like 500 it would give me the correct output but as soon as i put 999,999 or 1,000,000 it just doesn't give out any output and when i do a keyboard interruption it says it stopped at break but I need that break in order for the values to only repeat once.
bachslst=[]
primeslst=[]
q=[]
newlst=[]
z=[]
def goldbach(limit):
primes = dict()
for i in range(2, limit+1):
primes[i] = True
for i in primes:
factors = range(i, limit+1, i)
for f in factors[1:]:
primes[f] = False
for i in primes:
if primes[i]==True:
z.append(i)
for num in range(4,limit+1,2):
for k in range(len(z)):
for j in z:
if (k + j ) == num :
x=(str(k),str(j))
q.append(x)
newlst.append([x,[num]])
break
bachslst.append(num)
print(bachslst,'\n')
return newlst
The break that is referred to is not the break in the code, it is the break caused by the keyboard interrupt.
If you want to get your result in less than 1.5 hours, try to reduce the amount of computing that you are doing. There are many implementations for testing the Goldbach Conjecture if you do a search. Some are in other languages, but you can still use them to influence your algorithm.
I have not looked at it, but here is another implementation in Python: https://codereview.stackexchange.com/questions/99161/function-to-find-two-prime-numbers-that-sum-up-to-a-given-even-number

make a function that take an integer and reduces it down to an odd number

I'm working on my final for a class I'm taking(Python 3) im stuck at this part.
he gave us a file with numbers inside of it. we opened it and add those numbers to a list.
"Create a function called makeOdd() that returns an integer value. This function should take in any integer and reduce it down to an odd number by dividing it in half until it becomes an odd number.
o For example 10 would be cut in half to 5.
o 9 is already odd, so it would stay 9.
o But 12 would be cut in half to 6, and then cut in half again to 3.
o While 16 would be cut to 8 which gets cut to 4 which gets cut to 2 which gets cut to 1.
 Apply this function to every number in the array. "
I have tried to search the internet but i have not clue where to even begin with this one. any help would be nice.
Here my whole final so far:
#imports needed to run this code.
from Final_Functions import *
#Defines empty list
myList = []
sumthing = 0
sortList = []
oddList = []
count = 0
#Starts the Final Project with my name,class, and quarter
intro()
print("***************************************************************",'\n')
#Opens the data file and reads it then places the intrager into a list we can use later.
with open('FinalData.Data', 'r') as f:
myList = [line.strip() for line in f]
print("File Read Complete",'\n')
#Finds the Sum and Adverage of this list from FinalData.Data
print("*******************sum and avg*********************************")
for oneLine in myList:
tempNum = int(oneLine)
sumthing = sumthing + tempNum
avg = sumthing /1111
print("The Sum of the List is:",sumthing)
print("The Adverage of the List is:",avg,'\n')
print("***************************************************************",'\n')
#finds and prints off the first Ten and the last ten numbers in the list
firstTen(myList)
lastTen(myList)
print("***************************************************************",'\n')
#Lest sort the list then find the first and last ten numbers in this list
sortList = myList
sortList.sort()
firstTen(sortList)
lastTen(sortList)
print("****************************************************************",'\n')
Language:Python 3
I don't want to give you the answer outright, so I'm going to talk you through the process and let you generate your own code.
You can't solve this problem in a single step. You need to divide repeatedly and check the value every time to see if it's odd.
Broadly speaking, when you need to repeat a process there are two ways to proceed; looping and recursion. (Ok, there are lots, but those are the most common)
When looping, you'd check if the current number x is odd. If not, halve it and check again. Once the loop has completed, x will be your result.
If using recursion, have a function that takes x. If it's odd, simply return x, otherwise call the function again, passing in x/2.
Either of those methods will solve your problem and both are fundamental concepts.
adding to what #Basic said, never do import * is a bad practice and is a potential source of problem later on...
looks like you are still confuse in this simple matter, you want to given a number X reduce it to a odd number by dividing it by 2, right? then ask yourself how I do this by hand? the answer is what #Basic said you first ask "X is a even number?" if the answer is No then I and done reducing this number, but if the answer is Yes then the next step dividing it by 2 and save the result in X, then repeat this process until you get to the desire result. Hint: use a while
to answer your question about
for num in myList:
if num != 0:
num = float(num)
num / 2
the problem here is that you don't save the result of the division, to do that is as simple as this
for num in myList:
if num != 0:
num = float(num)
num = num / 2

Resources