I'm trying to do the Collatz conjecture on a list of numbers to check which one is "holding" the most. the problem is the code keeps telling me "TypeError: unsupported operand type(s) for %: 'list' and 'int'"
Collatz = range(1, 1001)
counting = 0
print(Collatz)
while Collatz != 1:
if Collatz % 2 == 0:
Collatz = int(Collatz / 2)
print(Collatz)
counting += 1
else:
Collatz = int(Collatz * 3 + 1)
print(Collatz)
counting += 1
print(counting)
if it's with input it works great...
Would appreciate help :)
try to get a list of all of the ranges, with a number and how long it took to get to "1" or just which one is the longest.
for example:
number 1 took 1 steps to get to "1"
number 2 took 2 steps to get to "1"
number 3 took 8 steps to get to "1" etc
or
number 153 took 736 steps to get to "1" (IDK, just for the example)
This code will work:
def get_collatz(n):
i=1
while True:
if n % 2 == 0:
n /= 2
else:
n = 3 * n + 1
if n == 1:
return(i)
i += 1
for i in range(1, 100000):
print(i, get_collatz(i))
If you want to know the number that took most steps, you can do this:
steps = dict()
for i in range(1, 100000):
steps[i] = get_collatz(i)
n_max = max(steps, key=steps.get)
total_steps = steps[n_max]
print(f'Number {n_max} took {total_steps} steps to reach 1.')
This prints:
Number 77031 took 350 steps to reach 1.
You can also create a sorted dictionary:
sorted_steps = dict(sorted(steps.items(), key=lambda item: item[1]))
When you use range() you get a list of numbers in that range. Did you mean number instead of Collatz because in the for loop you are looping through the Collatz and the value is in number. And while loop isn't doing anything so I recommend removing it.
Use this code:
Collatz = range(1, 1001)
counting = 0
for number in Collatz:
if number % 2 == 0:
number = int(number / 2)
print(number)
counting += 1
else:
number = int(number * 3 + 1)
print(number)
counting += 1
print(counting)
Related
I have a task to make an output program like this
if input : 5
then output : 2,6,10,14,18
Output must as many of total number as the input
My previous code like this
n = 5
num = 2
i = 1
while i <= n:
if num % 2 == 0:
if num % 4 != 0:
print(num)
i = i+1
num = num+1
But my output was just 2 numbers, i should get 5 numbers.
2,6
Can anyone help me?
Put the i+1 under the second if condition
if num % 4 != 0:
print(num)
i = i + 1
As you can see your output is following the Arithmetic progression
#### first number
a = 2
#### diffrence between the seq numbers
d = 4
#### number of terms in sequence
n = 5
### running loop n times
### a + (n-1) * d ( geeting the nth didgit in AP `enter code here`)
for i in range(1, n+1):
print(2 + (i-1)*d , end=',')
I am trying to make code that takes a list of numbers starting from a billion to 2 billion with an increment of 100 million and outputs a list of the number of steps it takes to reach one using the Collatz conjecture for each number.
My code:
from math import pow
# Defining the function
def collatz(the_input):
step = 1
while the_input > 1:
if (the_input % 2) == 0:
the_input = the_input / 2
else:
the_input = ((the_input * 3) + 1) / 2
step += 1
return step
the_inputs = []
the_number = pow(10, 9)
increment = pow(10, 8)
while the_number <= 2 * pow(10, 9):
the_inputs.append(the_number)
the_number += increment
print(the_inputs)
Loop through the list:
for num in the_inputs:
steps = collatz(num)
print(f"it takes {steps} steps for {num}")
This code uses f-strings.
Or, use a list comprehension for a list:
step_list = [collatz(num) for num in the_inputs)]
A version of your collatz function for lists:
def collatz_list(numbers):
result = []
for number in numbers:
step = 1
while number > 1:
if (number % 2) == 0:
number = number / 2
else:
number = ((number * 3) + 1) / 2
step += 1
result.append(step)
return result
Or you could just reuse your function like this:
result = [collatz(number) for number in the_inputs]
You can Create a list of all your input like :
inputs = [k for k in range(pow(10,9),2*pow(10,9),pow(10,8))]
And iterate for each element of your list:
outputs = []
for input in inputs :
outputs.append(collatz(input))
print(outputs)
I have some code where I must find the multiples of number 3 and then summarize them
I have done the first job, I mean I found all the multiples of number 3 with for loop but I can't summarize all the numbers which I found.
I have tried so many times and tried to find the solution on google, but could not find
x = 3
for number in range(1000):
if number%x == 0:
print(number)
I need now the sum of all the numbers which indicates on this code, when you run this code you can see that there is publishing only the numbers that can divide by 3 now I need the sum of them
It's easier than you think:
sum(range(0, 1000, 3))
Explanation:
range is defined as such: range([start], end[, step]) so range(0, 1000, 3) means go from 0 to 1000 in steps of 3
The sum function will sum over any iterable (which includes range)
You need a variable to hold the sum (If you are in learning stage):
x = 3
total = 0
for number in range(1000):
if number % x == 0:
print(number)
total += number # equivalent to: total = total + number
print(total)
Edit:
To answer your comment use condition or condition:
x = 3
y = 5
total = 0
for number in range(10):
if number % x == 0 or number % y == 0:
print(number)
total += number # equivalent to: total = total + number
print(total)
You could create a result variable to which you can keep adding:
result = 0
x = 3
for number in range(1000):
if number%x == 0:
result += number
print(result)
The best way is using filter and sum:
# any iterable variable
iterable_var = range(100)
res = sum(filter(lambda x: x % 3 == 0, iterable_var), 0)
I have the following problem to solve:
The numbers 545, 5995 and 15151 are the three smallest palindromes divisible by 109. There are nine palindromes less than 100000 which are divisible by 109.
How many palindromes less than 10**32 are divisible by 10000019 ?
So my code is shown below.
In theory my code will work, but to count all the way from 0 to 10**32 would take my computer literally YEARS.
Is there anyway to improve this code?
Python code:
listPalindroms=[]
for i in range (0,10**32):
strI = str(i)
printTrue = 1
if len(strI) == 1:
listPalindroms.append(i)
else:
if len(strI)%2 ==0:
FinalVal = int(len(strI)/2)
for count in range (0,FinalVal):
if strI[count]!=strI[-count-1]:
printTrue = 0
if printTrue==1: listPalindroms.append(i)
else:
FinalVal = int(round(len(strI)/2))-1
for count in range (0,FinalVal):
if strI[count]!=strI[-count-1]:
printTrue = 0
if printTrue ==1: listPalindroms.append(i)
i=0
for item in listPalindroms:
if item%10000019 ==0:
i = i + 1
print (i)
The problem is presented as Project Euler 655
You are getting all palindromes between 0 and 10**32 then filtering using divisibility. But you can do it the other way around also. Just find the multiples of 10000019 that are less than 10**32 then check if each multiple is a palindrome.
This way you can avoid checking palindromes for numbers that are not required.
i = 1
number = 10000019
list_palindromes = []
element = number * i
while element < (10**32):
e = str(element)
for j in range(len(e)):
if e[j] != e[len(e)-j-1]:
break
if len(e)-1 == j:
list_palindromes.append(e)
print(e)
i += 1
element = number * i
Given that MathJax doesn't work here it's gonna be tough to present my solution.
When you look at a number, eg. 1991, you can write this as 1000*1+100*9+10*9+1*1.
If you look at the remainder when dividing by 19 we have that:
(1000*1+100*9+10*9+1*1)%19 = ((1000%19)*1+(100%19)*9+(10%19)*9+(1%19)*1)%19 = (12*1+5*9+10*9+1*1)%19 = 10.
Therefore 19 doesn't divide 1991
For a palindrome, abcba, we can use this property of modular arithmetic to see that 19 divides abcba if and only if:
(7*a + 3*b + 5*c)%19 = 0
Because
(10000*a+1000*b+100*c+10*b+a)%19 = (10001*a+1010*b+100*c)%19 = (10001*a%19+1010*b%19+100*c%19)%19 = (7*a + 3*b + 5*c)%19
By using this method we can cut the number of iterations down to the square root of the max value. A routine for calculating the sum of ever palindrome less than 10**10 that is divisible by 109 will look some thing like this.
maxValue = 10**5
divisor = 109
moduli = []
for i in range(0,33):
moduli.append((10**i)%divisor)
def test(n,div):
n = str(n)
sum_odd = 0
sum_even = 0
for i in range(len(n)):
sum_even = sum_even + int(n[i])*(moduli[i]+moduli[2*len(n)-i-1])
if i != len(n)-1:
sum_odd = sum_odd + int(n[i])*(moduli[i]+moduli[2*len(n)-i-2])
else:
sum_odd = sum_odd + int(n[i])*(moduli[i])
if sum_odd%div==0 and sum_even%div==0:
return 2
if sum_odd%div==0 or sum_even%div==0:
return 1
else:
return 0
# The sum starts at -1 because 0 is counted twice
sum = -1
for a in range(maxValue):
sum = sum + test(a,divisor)
print(sum)
Running the calculation for every palindrome less than 10**32, still requires 10**16 iterations, so it's not efficient enough for your problem, it's however better than previous answers (requiring about 10**24 iterations).
Well, you just need to check for numbers divisible by your divisor, so why check numbers before that, and while incrementing, why not just increment the divisor amount?
def is_palin(num):
num_str = str(num)
for index in range(len(num_str)/2):
if num_str[index]==num_str[len(num_str)-1-index]:
continue
return False
return True
def multiple(divisor, end):
count=0
index = divisor*2
while index<end:
if is_palin(index):
count+=1
index+=divisor
return count
if __name__=="__main__":
print(multiple(109, 100000))
# print(multiple(10000019, 10**32))
This approach still takes a lot of time, and I'd recommend finding a better method.
I am working on project Euler problem #111. I have created this program which works fantastic for the given example but apparently is not producing the desired answer to the problem. Here's my source code in python:-
#This function generates all the primes of 4 digits with the highest repeated digits 1 to 9 and returns their sum for eg. 3313, 4441, 4111 etc.
Note that any digit from 1 to 9 can come at most of 3 times in a 4 digit prime number. I have highlighted the same in the code.`
from more_itertools import distinct_permutations
from sympy.ntheory.primetest import isprime
def fn1to9():
s = 0
for digit in range(1, 10):
for j in range(0, 10):
permutations = list(distinct_permutations(str(digit) * 3 + str(j)))
for perm in permutations:
num = int("".join(perm))
if (num > 1000000000):
if (isprime(num)):
print(num)
s = s + num
return s
This function is for the special case of 0. Note that 0 can come atmost 2 times in a 4 digit prime no. I have bolded the number 2 in the code.
def fnFor0():
s = 0
for firstDigit in range(1, 10):
permutations = list(distinct_permutations(str(0) *2+ str(firstDigit)))
for perm in permutations:
for msd in range(1, 10):
temp = list(perm)
temp.insert(0, str(msd))
num = int("".join(temp))
if (num > 1000000000):
if (isprime(num)):
print(num)
s = s + num
return s
Now, this program works well and produces the desired sum of 273700 as has been stated in the question. So, I made the required changes and ran it for 10 digits. The required changes were changing the str(digit)*3 to str(digit)*9 in fn1to9 and str(digit)*2 to str(digit)*8 in fnFor0 in the distinct_permutations() function (Hoping that 9 digits will be repeated for every digit from 1 to 9 in the prime number and 8 0s for the prime number containing 0s). But it did not give the desired answer. Then I inspected and found out that for repeated digits of 2 and 8, the maximum repetition can be of 8 digits, so I wrote another function specifically for these 2 digits which is as follows:
def fnFor2and8():
s = 0
for digit in [2,8]:
for firstDigit in range(0, 10):
for secondDigit in range(0, 10):
permutations = list(distinct_permutations(str(digit) * 8 + str(firstDigit) + str(secondDigit)))
for perm in permutations:
num = int("".join(perm))
if (num > 1000000000):
if (isprime(num)):
print(num)
s = s + num
return s
This function as expected produces the desired 10 digits numbers with 2 and 8 repeated exactly 8 times. I had hoped it summing up the results from all of these 3 functions will give me the answer but seems like I am missing some numbers. Can someone please help me point out the flaw in my reasoning or in my program. Thanks a lot in advance.
Here was the solution I came by wehn I was working on this problem:
import eulerlib
def compute():
DIGITS = 10
primes = eulerlib.list_primes(eulerlib.sqrt(10**DIGITS))
# Only valid if 1 < n <= 10^DIGITS.
def is_prime(n):
end = eulerlib.sqrt(n)
for p in primes:
if p > end:
break
if n % p == 0:
return False
return True
ans = 0
# For each repeating digit
for digit in range(10):
# Search by the number of repetitions in decreasing order
for rep in range(DIGITS, -1, -1):
sum = 0
digits = [0] * DIGITS
# Try all possibilities for filling the non-repeating digits
for i in range(9**(DIGITS - rep)):
# Build initial array. For example, if DIGITS=7, digit=5, rep=4, i=123, then the array will be filled with 5,5,5,5,1,4,7.
for j in range(rep):
digits[j] = digit
temp = i
for j in range(DIGITS - rep):
d = temp % 9
if d >= digit: # Skip the repeating digit
d += 1
if j > 0 and d > digits[DIGITS - j]: # If this is true, then after sorting, the array will be in an already-tried configuration
break
digits[-1 - j] = d
temp //= 9
else:
digits.sort() # Start at lowest permutation
while True: # Go through all permutations
if digits[0] > 0: # Skip if the number has a leading zero, which means it has less than DIGIT digits
num = int("".join(map(str, digits)))
if is_prime(num):
sum += num
if not eulerlib.next_permutation(digits):
break
if sum > 0: # Primes found; skip all lesser repetitions
ans += sum
break
return str(ans)
if __name__ == "__main__":
print(compute())