The question is:
A triangular number is a number that is the sum of the integers from 1 to some integer n. Thus 1 is a triangular number because it's the sum of the integers from 1 to 1; 6 is a triangular number because it's 1+2+3=6.
Given the non-negative integers m and n (with m < n), create a list of the triangular numbers between (and including) m and n. Thus if m is 3 and n is 20, the list would be: [3, 6, 10, 15]. Associate the list with the variable triangulars.
The code I've tried:
Sum = 0
triangulars = []
for i in range(m,m+n):
if (n >= m) and (m >= 0):
Sum += 1
triangulars.append(Sum)
The error I have is the programming lab recommends I use the sum function, and the results I am getting are no triangular numbers (I should get 6, 10 , 15 when m = 5 and n = 17, instead I get 5, 11, 18 and so on)
I changed it around a bit, put it in a function, renamed some variables, and threw in the test cases of m=3,n=20. I also tested several other combos including m=5,n=17. I also employed the sum() function you mentioned that you were asked to use. Here's the working code:
def triangulars(m,n):
if (n >= m) and (m >= 0):
sum_list = []
triangular_list = []
for i in range(1,n+1):
sum_list.append(i)
a_triangular = sum(sum_list)
if m <= a_triangular <= n:
print(m,n,a_triangular)
triangular_list.append(a_triangular)
print(m,n,triangular_list)
else:
print('Invalid m,n values')
m = 3
n = 20
triangulars(m,n)
Related
"""5. 2520 is the smallest number that can be divided by each of the numbers from 1 to 10 without any remainder.
What is the smallest positive number that is evenly divisible by all of the numbers from 1 to 20?"""
list=[]
possibility_list=[]
base=1
numberlist=[1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20]
for number in numberlist:
for iteration in range(1000):
list.append(iteration*number)
for possibility in list:
if list.count(possibility)==20:
print("Found LCM of [1:21] -->", str(possibility))
possibility_list.append(possibility)
else: continue
print(min(possibility_list))
I am currently trying to solve Euler Problem #5, which wants to find the LCM of numbers 1-20. The code above is brute force, but for some reason it doesn't work. Can someone point me in the right direction?
As of python 3.9 you can compute the least common multiple directly:
from math import lcm
print(lcm(*range(1, 11)))
If that's "cheating", start with a loop like this:
from math import lcm
result = 1
for i in range (1, 11):
result = lcm(result, i)
Then replace lcm with gcd. The two-arg version of gcd (greatest common divisor) has been around since python 3.5:
from math import gcd
result = 1
for i in range (1, 11):
result *= i // gcd(result, i)
Now gcd is something that's relatively easy to implement using Euclid's algorithm. The idea is that if the GCD of two numbers x and y is g, then x = a * g and y = b * g, with a, b relatively prime. If a and b weren't relatively prime, you could divide them by their common multiple and multiply g by that amount. Let's say a >= b. If x is a multiple of y, b must be 1 (again, a and b are relatively prime) and therefore y = g. Otherwise, c = a - b must be relatively prime to both a and b (else they all have a common factor). We can therefore repeat the same reasoning for y and z = x - y until the two numbers become multiples of each other. The sequence must converge because the numbers decrease with every subtraction:
def gcd(x, y):
if x < y:
x, y = y, x
if x % y == 0:
return y
return gcd(x - y, y)
result = 1
for i in range (1, 11):
result *= i // gcd(result, i)
You can probably make this more efficient, but this should be sufficient to form an understanding of how to solve the problem.
A non-recursive GCD might be advisable in the general case, since python supports arbitrary sized integers. You could implemented it as
def gcd(x, y):
while True:
if x < y:
x, y = y, x
if x % y == 0:
return y
x -= y
Even if you're going to use brute force, I suggest that you do it with a little more intelligence. For example, you know that 10 < lcm <= 1 * 2 * ... * 9 * 10 you can therefore write your check like this:
numbers = range(1, 11)
product = 1
for i in numbers:
product *= i
for n in range(max(numbers) + 1, product + 1):
for i in numbers:
if n % i != 0:
break
else:
break
print(n)
The inner loop checks the current possibility against all the numbers. If the loop terminates without breaking, n is a multiple of all the numbers. This triggers the else clause, which breaks out of the outer loop. The result is guaranteed to be correct because if nothing breaks the loop, n will be the multiple of all the numbers.
In all the above cases, it's trivial to include the range [1, 20] in place of [1, 10].
numberlist = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20]
def is_prime(num: int) -> bool:
for factor in range(2, num):
if num % factor == 0:
return False
return True
prime_list = list(filter(is_prime, numberlist))
additional_factor_prime = []
for number in numberlist:
temp_factor_list = [*prime_list] + additional_factor_prime
temp_number = number
for index in range(len(temp_factor_list) - 1, -1, -1):
if temp_number in prime_list:
break
cur_factor = temp_factor_list[index]
if temp_number % cur_factor == 0:
temp_factor_list.pop(index)
temp_number //= cur_factor
if temp_number not in temp_factor_list and temp_number != 0 and temp_number != 1:
additional_factor_prime.append(temp_number)
factor_list = [*prime_list] + additional_factor_prime
LCM = 1
for number in factor_list:
LCM *= number
print(LCM)
So here is the challenge: I am given four numbers: a,b,c,d. Then the number n is given which describes how many numbers to check will be. Then these numbers are inputted and the goal is to find which probability that number will be gotten if multiply two random numbers one from the range a to b and one from c to d range. Finally, I need to output that probability in 'p/q' format. I figured out the solution and it works but the problem is when working with bigger numbers it uses too much time. I also have another solution where I first create a list with all possible combinations but in that case it uses too much memory.
from math import gcd
a,b,c,d = (map(int,input().split(" ")))
combs_quantity = (b-a+1)*(d-c+1)
def findProb(z):
repeats = 0
nec_mulps = [z//x for x in range(a,b+1) if z%x == 0]
for n in nec_mulps:
if n in range(c,d+1):
repeats+=1
probGCD = gcd(repeats,combs_quantity)
return str(repeats//probGCD) + "/" + str(combs_quantity//probGCD)
probability = []
n = int(input())
for i in range(n):
probability.append(findProb(int(input())))
for p in probability:
print(p)
Get all divisors of n
For every divisor Z that belongs to range a..b check whether complementary divisor n//Z lies in range c..d
#MBo said above that complexity is sqrt(z). You can to calculcate repeats as:
divisors = []
i = 1
while i * i <= z:
if z % i == 0:
divisors.append(i)
if i * i < z:
divisors.append(z // i)
i += 1
repeats = 0
for divisor in divisors:
if a <= divisor <= b and c <= z // divisor <= d:
repeats += 1
I Was trying a problem but my time complexity is very high. Is there any way to reduce my time complexity. The Question Below with my code.
A number is said to be a complete ‘n’ digit factor, if it is a factor
of all ‘n’ digit numbers when concatenated (joined to right) to
itself.
For example, 7 is a complete 3-digit factor as it divides all three
digit numbers from 100 to 999 when concatenated to itself (i.e.
100100, 101101,102102, ... ..., 998998, 999999).
Given the value of n and m(Max Value to be checked), write a code to
generate all numbers from 2 to m (both inclusive) that are complete
n-digit factor and print ‘No complete factors’ otherwise. For example,
if n is 3 and m is 15 then print 7, 11, 13
N = int(input()) #No Of Digits
M = int(input()) #Max Value to be Checked
#Im Assuming Max Value will be less than or equal to 9
Nu = '100000000'
NuN = '9'*N
NuM_1 = int(Nu[:N])
NuM_2 = int(NuN)
Lis = [int(str(i)*2) for i in range(NuM_1,NuM_2+1)]
Count = 0
Res = []
for i in range(2,M+1):
Count = 0
for j in Lis:
if(j%i==0):
Count += 1
if(Count==len(Lis)):
Res.append(i)
if(len(Res)!=0):
for i in Res:
print(i)
You're attacking the problem from the functional definition, rather than analyzing the numerical properties of that definition.
Concatenating an n-digit number to itself is the same as multiplying by 10^n + 1. For instance, doing this with 3-digit numbers is equivalent to multiplying each by 10^3 + 1, or 1001.
A number divides all such integers iff that number divides the multiplier. Therefore, you can drop this massive iteration and check; simply factor 10^n + 1.
For instance, 1001 factors into 7 * 11 * 13; from there, you can generate the seven needed integers in the answer: 7, 11, 13, 77, 91, 143, 1001.
There are many available factoring programs; a simple search will find you that code.
Try this variation, using a break, and a faster creation of Lis :
N = int(input("Enter N: ")) #No Of Digits
M = int(input("Enter M: ")) #Max Value to be Checked
#Im Assuming Max Value will be less than or equal to 9
Nu = '100000000'
NuN = '9'*N
NuM_1 = int(Nu[:N])
NuM_2 = int(NuN)
Lis = [i + (i * (10**N)) for i in range(NuM_1, NuM_2+1)]
Res = []
for i in range(2,M+1):
for j in Lis:
if j%i:
break
else:
Res.append(i)
print(Res)
I have been writing in python for only few months now, so please don't be too harsh on me. But I've wrote this code and I don't know how I can make it faster.
n = 2
ListOfTriangles = []
ListOfDivisors = []
term = 0
for x in range(1,100001):
x = (n*(n-1))/2
ListOfTriangles.append(int(x))
n += 1
for y in range(1,100001):
Tri = ListOfTriangles[term]
for i in range(1,Tri+1):
if(Tri%i==0):
ListOfDivisors.append(i)
if len(ListOfDivisors) >= 500:
print("---------------------------------------------------")
print(len(ListOfDivisors))
print(ListOfDivisors)
print(ListOfTriangles[term])
print("---------------------------------------------------")
break
print(ListOfTriangles[term]," - ",len(ListOfDivisors)," - ",(term/100000)*(10**2),"%")
ListOfDivisors = []
term += 1
Basically what I have done if you can't tell by this mess, is that i created a list with Triangular Numbers and then put this list through loop that list all factors for each number found in the list and then stop when it finds number that meats the requirement of number having over 500 factors.
One idea applicable to this problem is as follows:
The n'th triangular number t[n] is given by n * (n + 1) / 2. Note that the only common divisor of n and n + 1 is 1. Let divs[n] denote the number of divisors of n. Then,
for even n, we have divs[t[n]] = divs[n//2] * divs[n+1] - 1
for odd n, we have divs[t[n]] = divs[n] * divs[(n+1)/2] - 1
We can precompute the number of divisors for each number from 1 to n in O(n^2) time (this can be improved asymptotically), and use the formula above to compute the number of divisors for the corresponding triangular number. With numpy, we have:
import numpy as np
# pick a number of elements for divisor computation
n = 20_000
# store number of divisors of n; O(n^2), can be optimized asymptotically
divs = np.zeros(n+1, dtype=int)
for i in range(1,n+2):
# i divides every number in the sequence i, 2i, 3i... (up to n)
divs[i:n+2:i] += 1
# store number of divisors of n'th triangular number
divs_tri = np.zeros(n, dtype=int)
# treat evens and odds separately
evens = np.arange(0, n, 2) # e.g. [0, 2, 4...]
odds = np.arange(1, n, 2) # e.g. [1, 3, 5...]
# with even k, k/2 and k+1 are coprime; -1 accounts for 1 being a factor of both
divs_tri[evens] = divs[evens//2] * divs[evens+1] - 1
# with odd k, k and (k+1)/2 are coprime; -1 accounts for 1 being a factor of both
divs_tri[odds] = divs[odds] * divs[(odds+1)//2] - 1
# index of first triangular number with at least 500 divisors
k = (divs_tri >= 500).argmax()
# compute the value of k'th triangular number
ans = k * (k + 1) // 2
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)