I'm doing the pyschools practices and i have a problem at Topic 5 question 12 - Prime Factorization, i have to do this:
Given a positive integer, write a function that computes the prime factors that can be multplied together to get back the same integer.
Examples
>>> primeFactorization(60)
[2, 2, 3, 5]
>>> primeFactorization(1050)
[2, 3, 5, 5, 7]
>>> primeFactorization(1)
[]
This is my code:
import operator
import functools as fun
def primeFactorization(num):
num = num
primes = []
result = []
if num > 1:
[primes.append(x) for x in range(2, num) if all(x % y != 0 for y in range(2, x))]
multy = fun.reduce(operator.mul, result, 1)
for number in primes:
if num % number == 0 and multy != num:
result.append(number)
return result
Which returns me this:
Test Cases Expected Result Returned Result
primeFactorization(33) [3, 11] [3, 11]
primeFactorization(84) [2, 2, 3, 7] [2, 3, 7]
primeFactorization(1) [] []
I've tryed this and i'm getting Private Test Case failed:
import operator
import functools as fun
def primeFactorization(num):
num = num
primes = []
result = []
if num > 1:
[primes.append(x) for x in range(2, num) if all(x % y != 0 for y in range(2, x))]
multy = fun.reduce(operator.mul, result, 1)
for number in primes:
if num % number == 0:
result.append(number)
multy = fun.reduce(operator.mul, result, 1)
y = num/multy
if y != 1 and y in primes:
result.insert(0, int(y))
return result
Test Cases Expected Result Returned Result
primeFactorization(33) [3, 11] [3, 11]
primeFactorization(84) [2, 2, 3, 7] [2, 2, 3, 7]
Private Test Cases Passed Failed
primeFactorization(1) [] []
What can i do to pass?
Why make it so complicated?
The problem of finding all prime factors of a given number X is the same as to find the set of the smallest numbers (that are larger than 1) that we can divide X into.
To solve the problem we can start by finding the smallest number n that divides X.
This is the first prime factor of X. We can then find the rest of the prime factors by finding the prime factors of X/n
def primeFactorization(X):
possible = [2] + range(3,int(ceil(sqrt(X)))+1,2)
for p in possible:
if X % p == 0:
return [p] + primeFactorization(X/p)
return [X]
primeFactorization(3*3*7*5*11*13*31)
> [3,3,5,7,11,13,31]
Related
def encryption(n):
if len(n) == 2:
return n
result = []
for i in range(len(n) - 1):
total = n[i] + n[i + 1]
right_most_digit = total % 10
result.append(right_most_digit)
if len(result) > 2:
result = encryption(result)
return "".join([str(x) for x in result])
if __name__ == '__main__':
numbers = [1, 5, 7, 9]
print(encryption(numbers))
I need help with this code.
The problem is to add the two adjacent numbers and keep the right_most_digit, repeat the process to a point where only two numbers left, and return a string.
For example, 1+5, 5+7, 7+9 will be 6,2,6, then 6+2, 2+6 will be 8,8, then return 88 as a string.
With the least changes,
def encryption(n):
if len(n) == 2:
return n
result = []
for i in range(len(n) - 1):
total = n[i] + n[i + 1]
right_most_digit = total % 10
result.append(right_most_digit)
if len(result) > 2:
result = encryption(result)
return result
if __name__ == '__main__':
numbers = [1, 5, 7, 9]
print("".join([str(x) for x in encryption(numbers)]))
print("".join([str(x) for x in encryption(numbers)]).lstrip("0")) if you also want to strip any leading 0
Since you asked about a different approach, you might consider not doing this recursively. You can simply keep processing the list in a while loop until the list is of length 2 or less. Then convert to a string:
def encryption(n):
while len(n) > 2:
n = [(a + b) % 10 for a, b in zip(n, n[1:])]
return "".join([str(x) for x in n])
numbers = [1, 5, 7, 9]
print(encryption(numbers))
# 88
This is a little easier to reason about and it also makes it easy to debug by sticking a print(n) in the loops to see the progression.
Wrote a simple code for left array rotation, getting the same array without any Rotation done to it as the wrong output.
def leftRotate(arr, d, n):
while (d-1) > 0:
leftRotatebyOne(arr, n)
def leftRotatebyOne(arr, n):
temp = arr[0]
for i in range(n-1):
arr[i] = arr[i + 1]
arr[n - 1] = temp
def PrintArray(arr, size):
for i in range(size):
print("%d" % arr[i], end=" ")
arr = []
l = int(input("Enter the number of elements: "))
for i in range(0, l):
ele = int(input())
arr.append(ele)
d = int(input("Enter the number of rotations: "))
n = len(arr)
leftRotate(arr, d, n)
PrintArray(arr, n)
and here's an example of the output i've got,
Enter the number of elements: 3
1
2
3
Enter the number of rotations: 1
1 2 3
I expected an output of 2 3 1 after one rotation.
I would suggest using array slicing, then adding the slices together, to perform rotation.
def left_rotate(data, num):
return data[num:] + data[:num]
def right_rotate(data, num):
return data[-num:] + data[:-num]
For example
>>> a = [1,2,3,4,5,6,7]
>>> left_rotate(a, 2)
[3, 4, 5, 6, 7, 1, 2]
>>> right_rotate(a, 2)
[6, 7, 1, 2, 3, 4, 5]
Also note that collections.deque has this behavior available already
>>> from collections import deque
>>> d = deque([1,2,3,4,5,6,7])
>>> d.rotate(2)
>>> d
deque([6, 7, 1, 2, 3, 4, 5])
>>> d.rotate(-2)
>>> d
deque([1, 2, 3, 4, 5, 6, 7])
In the function leftRotate,
there is an error in while loop.
Replace
while (d-1) > 0:
leftRotatebyOne(arr, n)
with
while d > 0:
leftRotatebyOne(arr, n)
d -= 1
When d == 1, while (d-1) > 0: will not be executed any time. Also, you never decrement d. The easiest way to solve is by using a for _ in range(d) loop:
def leftRotate(arr, d, n):
for _ in range(d):
leftRotatebyOne(arr, n)
NOTE: Python has way better ways to do rotations than this. This code seems to be C more than Python. Passing the array length makes no sense in Python for example. And the rotation can be done all in one assignation.
def leftRotate(arr, d):
d %= len(arr)
for _ in range(d):
arr[-1], arr[:-1] = arr[0], arr[1:]
Cory Kramer's answer is even more pythonic. But it has a bug and a difference with your question's methods. The bug is that it doesn't work when the number of rotations requested are higher than the length of the list. The difference is that they are returning a new list instead of modifying it. These two issues could be addresed like this:
def left_rotate(data, num):
num %= len(data)
data[:] = data[num:] + data[:num]
def right_rotate(data, num):
num %= len(data)
data[:] = data[-num:] + data[:-num]
Im trying to get prime factors by factorizing a number and adding the factors to list1, and then factorizing every number in list1 using the same method from before and adding to list2, so any prime factor will have a list length of 2 (If the number is a square number it prints out the square root twice, but since it is not a prime, it doesn't matter).
I don't know how to get it to apply my factors() function to every element in the list1 and make a list of all the factorized factors I've made.
import math
list1 = []
list2 = []
def factors(num1):
for x in range(1, int(math.sqrt(num1) + 1)):
if num1 % x == 0:
list2.append(int(x))
list2.append(int(num1/x))
list2.sort()
print("enter a number:")
number = int(input())
for m in range(1, int(math.sqrt(number) + 1)):
if number % m == 0:
list1.append(int(m))
list1.append(int(number/m))
list1.sort()
for y in list1:
factors(y)
print(list2)
desired output
if 20 was the input
((1,1),(1,2),(1,2,2,4)(1,5),(1,2,5,10),(1,2,4,5,10,20))
You can do this using list comprehension like so. I modified the factors function slightly to return the list.
import math
def factors(num):
fact = []
for x in range(1, int(math.sqrt(num)+1)):
if num % x == 0:
fact.append(x)
fact.append(int(num/x))
fact.sort()
return fact
print("enter a number:")
number = int(input())
list1 = factors(number)
list2 = [factors(f) for f in list1]
Result for 20:
[[1, 1], [1, 2], [1, 2, 2, 4], [1, 5], [1, 2, 5, 10], [1, 2, 4, 5, 10, 20]]
In factors function, you are appending the factors themselves to list2 but as you want nested list of factors, you should create another list and append that to list2 instead. Changed code would look something like this.
import math
list1 = []
list2 = []
def factors(num1):
factor_list = []
for x in range(1, int(math.sqrt(num1) + 1)):
if num1 % x == 0:
factor_list.append(int(x))
factor_list.append(int(num1/x))
factor_list.sort()
list2.append(factor_list)
print("enter a number:")
number = int(input())
for m in range(1, int(math.sqrt(number) + 1)):
if number % m == 0:
list1.append(int(m))
list1.append(int(number/m))
list1.sort()
for y in list1:
factors(y)
print(list2)
Also, since you've already wrote the factors function, you can use it for factorizing the input number itself instead of writing the same code again. So a better version of the same code is:
import math
def factors(num1):
factor_list = []
for x in range(1, int(math.sqrt(num1) + 1)):
if num1 % x == 0:
factor_list.append(int(x))
factor_list.append(int(num1/x))
factor_list.sort()
return factor_list
print("enter a number:")
number = int(input())
list1 = factors(number)
list2 = [factors(x) for x in list1]
print(list2)
Following up on the comment, if you want to include only on those elements which have length 2, you can use another list comprehension for that:
list2 = [x for x in list2 if len(x)==2]
The question asks to check if a number is a prime number. If it isn't, then you have to make a separate function that prints the list of factors of the prime numbers. The exact question is:
Write two functions (isPrime and primeFactors). The function
isPrime will return True if its argument is a prime number, False otherwise. The function primeFactors will return a list of prime factors of a number.
So far I have:
def isPrime(x):
if x==1:
return False
elif x==2:
return True
else:
for i in range(2,x):
if (x % i==0):
return False
This first function checks if the number is prime or not. However, I am not sure how to make the primeFactors function then only work when the result is not a prime number.
Since you already have your function for determining if a number is prime, the function of finding the prime factors of a number would be as follows:
def findPrimeFactors(number):
primeFactors = []
for i in range(2, number + 1):
if number % i == 0 and isPrime(i):
primeFactors.append(i)
return primeFactors
If you want to find all the prime factors including duplicates i.e. #Omari Celestine's answer will only return [2] for the findPrimeFactors(8) rather than [2, 2, 2] etc.
You could do something like this, notice how I am only checking up to the square root of n in each function:
def is_prime(n):
if n < 2:
return False
else:
i = 2
while i * i <= n:
if n % i == 0:
return False
i += 1
return True
def prime_factors(n):
primes = []
i = 2
while i * i <= n:
if not is_prime(n):
n = n // i
primes.append(i)
else:
i += 1
if n > 1:
primes.append(n)
return primes
print(is_prime(9)) # False
print(prime_factors(8)) # [2, 2, 2]
print(prime_factors(37)) # [37]
print(prime_factors(56)) # [2, 2, 2, 7]
print(prime_factors(23424)) # [2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 11]
In the following sequence, each number (except the first two) is the sum of the previous two number: 0, 1, 1, 2, 3, 5, 8, 13, .... This sequence is known as the Fibonacci sequence.
Given the positive integers m and n (with m < n) create a list consisting of the portion of the Fibonacci sequence greater than or equal to m and less than or equal to n. For example, if m is 3 and n is 6, then the list would be [3, 5] and if m is 2 and n is 20, then the list would be [2, 3, 5, 8, 13].
Associate the list with the variable fib.
Have done this far, but still getting error.
Where does it need to be fixed?
fib = [0,1,1]
result = 0
while result <=n:
result=fib[-1]+fib[-2]
if result <=n and result>=m:
fib.append(result)
# create a fibonacci series from 0 to n
f = [0,1]
for i in range(1, n+1):
x = f[i]+f[i-1]
if x > n:
break
else:
f.append(x)
# copy only those numbers of series that are in range m to n
fib = []
for i in range(0, len(f)):
if f[i] >= m and f[i] <= n:
fib.append(f[i])
You could use the code below.
fib = [0,1,1]
fibrange = [] # keeps your digits that are in range m < n
result = 0
n = 80
m = 2
while result <=n:
result =fib[-1]+fib[-2]
fib.append(result)
if result <=n and result>=m:
fibrange.append(result)
print fibrange
fib=[0,1]
i=0
while i <=n:
i=fib[-1]+fib[-2]
if i<=n:
fib.append(i)