n = 0
for a in xrange(999, 100, -1):
for b in xrange(a, 100, -1):
x = a * b
if x > n:
s = str(a * b)
if s == s[::-1]:
n = a * b
print n
I have a question about this solution to the problem.
I know it is right but I am wondering why in the xrange(999,100,-1) the -1 is there
For the a and b for loops. Please explain. I am new to this :)
The third parameter to xrange() is the increment value. The default is 1, which means the counter will count in an increasing direction. To count in a decreasing direction, use -1. Your a counter will go from 999 to 101 (the xrange() iterator stops just before it reaches the second parameter value).
For future reference, see the xrange() documentation.
The -1 specifies a negative step. Thus moving from 999 descending to 100 (exclusive).
xrange function takes three arguments: start, stop and step.
It returns a range of numbers starting from start continuing to stop, but not including it. If 'start' is bigger than stop, negative step must be provided.
So basically xrange(999, 100, -1) will give you [999, 998, ..., 101]
It means that you are decreasing (hence the negative sign) in increments of 1, from 999 to 100
This is what I got for the project Euler #4 question:
def Palindrome(s):
if s == s[::-1]:
return True
else:
return False
i = 100
j = 100
greatest = 0
while (i <= 999):
while (j <= 999):
product = i * j
if (product > greatest and Palindrome(str(product))):
greatest = product
j += 1
j = 100
i += 1
print "Answer: " + str(greatest)
-M1K3
My Python solution:
container = []
for i in range(100, 999):
for j in range(100, 999):
num = i * j
if str(num) == str(num)[::-1]:
container.append(num)
print(max(container))
__author__ = 'shreysatapara'
f=0
for a in range(100,1000):
for b in range(100,1000):
c=a*b
d=c
s=0
x=0
for i in range(0,len(str(c))):
s=c%10
x=x*10+s
c=c//10
if(x==d):
if(x>f):
f=x
print(f)
bingo answer is your last number in compiler....
import time
start_time = time.time()
largest_number = 0
for i in range(999,100,-1):
for j in range(i,100,-1):
string_number = str(i * j)
if string_number == string_number[::-1]:
if i*j > largest_number:
largest_number = i * j
print(largest_number)
print(time.time() - start_time," seconds")
The negative one is the modifier. Basically the loops start at 999, end at 100, and get there by modifying each number by negative one.
for x in range(100, 1000):
for y in range(100, 1000):
product = x*y
if product > x*y:
break
if str(product) == str(product)[::-1] and product > 900000:
print (x, y, product)
def reverse(s):
str = ""
for i in s:
str = i + str
return str
MAXN = 0
for i in range(100, 1000):
for j in range(100, 1000):
a = i * j
b = str(a)
if b == reverse(b) and a > MAXN:
MAXN = a
print(MAXN)
Related
l=0
temp=[]
for i in range(10000,100000):
for j in range(11000,12000):
n1=str(i)
n2=str(j)
for k in range(0,5):
a=int(n1[k])
b=int(n2[k])
if a+b<=9:
s=(a,b)
temp.append(s)
if len(temp)==5:
l+=1
temp.clear()
print(l)
this code is not giving any output, it is meant to count the number of 5digit number such that their sum does not involve any carrying
Your code does print stuff out, but the execution time is very high. Your aim should be on reducing the runtime of your code.
One way of doing this is by realizing that for a five-digit number a_1 a_2 a_3 a_4 a_5, there are (9 - a_1) ways to pick the first digit of the other summand, (10 - a_2) ways to pick the second digit of the other summand, (10 - a_2) ways to pick the third digit of the other summand, etc. (In this calculation, we use 9 rather than 10 for the first digit. This is because we can't use 0 for the first digit, but we can for the others.)
By using this observation, we can use a single for loop, greatly enhancing the runtime. This should run nearly instantaneously.
total = 0
for i in range(10000, 100000):
summand_count = 1
while i != 0:
if i < 10:
summand_count *= (9 - (i % 10))
else:
summand_count *= (10 - (i % 10))
i //= 10
total += summand_count
print(total)
Actually, you can solve this problem without any loops at all: 36*55^4 == 329422500
Test:
s = 0
for i in range(10, 100):
I = str(i)
for j in range(10, 100):
J = str(j)
for k in range(2):
if int(I[k]) + int(J[k]) >= 10:
break
else:
s += 1
print(s)
1980
If you want to count distinct pairs in the sense that (10000, 10001) and (10001, 10000) is the same pair, the result will be (36*55^4-4*5^4)/2+4*5^4 == 164712500
Test:
s = 0
for i in range(10, 100):
I = str(i)
for j in range(i, 100):
J = str(j)
for k in range(2):
if int(I[k]) + int(J[k]) >= 10:
break
else:
s += 1
print(s)
1000
How many pairs (i, j) exist such that 1 <= i <= j <= n, j - i <= a?
'n' and 'a' input numbers.
The problem is my algorithm is too slow when increasing 'n' or 'a'.
I cannot think of a correct algorithm.
Execution time must be less than 10 seconds.
Tests:
n = 3
a = 1
Number of pairs = 5
n = 5
a = 4
Number of pairs = 15
n = 10
a = 5
Number of pairs = 45
n = 100
a = 0
Number of pairs = 100
n = 1000000
a = 333333
Number of pairs = 277778388889
n = 100000
a = 555555
Number of pairs = 5000050000
n = 1000000
a = 1000000
Number of pairs = 500000500000
n = 998999
a = 400000
Number of pairs = 319600398999
n = 898982
a = 40000
Number of pairs = 35160158982
n, a = input().split()
i = 1
j = 1
answer = 0
while True:
if n >= j:
if a >= (j-i):
answer += 1
j += 1
else:
i += 1
j = i
if j > n:
break
else:
i += 1
j = i
if j > n:
break
print(answer)
One can derive a direct formula to solve this problem.
ans = ((a+1)*a)/2 + (a+1) + (a+1)*(n-a-1)
Thus the time complexity is O(1). This is the fastest way to solve this problem.
Derivation:
The first a number can have pairs of (a+1)C2 + (a+1).
Every additional number has 'a+1' options to pair with. So, therefore, there are n-a-1 number remaining and have (a+1) options, (a+1)*(n-a-1)
Therefore the final answer is (a+1)C2 + (a+1) + (a+1)*(n-a-1) implies ((a+1)*a)/2 + (a+1) + (a+1)*(n-a-1).
You are using a quadratic algorithm but you should be able to get it to linear (or perhaps even better).
The main problem is to determine how many pairs, given i and j. It is natural to split that off into a function.
A key point is that, for i fixed, the j which go with that i are in the range i to min(n,i+a). This is since j-i <= a is equivalent to j <= i+a.
There are min(n,i+a) - i + 1 valid j for a given i. This leads to:
def count_pairs(n,a):
return sum(min(n,i+a) - i + 1 for i in range(1,n+1))
count_pairs(898982,40000) evaluates to 35160158982 in about a second. If that is still to slow, do some more mathematical analysis.
Here is an improvement:
n, a = map(int, input().split())
i = 1
j = 1
answer = 0
while True:
if n >= j <= a + i:
answer += 1
j += 1
continue
i = j = i + 1
if j > n:
break
print(answer)
I'm a new at programming, I like solving this euler questions and I know there are solutions for this problem but it's not about the problem at all actually.
So, i managed to create a working function for finding example: 33. triangular number. It works but i couldn't manage to properly desing my while loop. I wanted to make it like, it starts from first triangular checks it's divisors make list of it's divisors, checks the length of the divisors, because problem wants "What is the value of the first triangle number to have over five hundred divisors?" . But i never managed to work the while loop. Thank you for reading.
nums = [1]
triangles = [1]
divisors = []
def triangularcreator(x):
if x == 1:
return 1
n = 1
sum = 0
while n!=0:
n += 1
nums.append(n)
for i in range(len(nums)):
sum += nums[i]
triangles.append(sum)
sum = 0
if x == len(triangles):
n = 0
return triangles[-1]
counter = 1
while True:
for i in range(1, triangularcreator(counter) + 1):
if triangularcreator(counter) % i == 0:
divisors.append(i)
if len(divisors) == 500:
print(triangularcreator(counter))
break
counter +=1
divisors.clear()
You should try to change a few things, starting with calculating just once the value of triangularcreator(counter) and assigning this value to a variable that you can use in different points of your code.
Second, you create a loop which will be calculate always triangularcreator(1). At the end of each iteration you increase the value of counter+=1, but then at the beginign of the new iteration you assignt it again value 1, so it will not progress as you expect. Try this few things:
counter = 1
while True:
triangle = triangularcreator(counter)
for i in range(1, triangle + 1):
if triangle % i == 0:
divisors.append(i)
if len(divisors) == 500:
print(triangle )
break
counter +=1
Also these two arrays nums = [1], triangles = [1] should be declared and initialized inside the def triangularcreator. Otherwise you would be appending elements in each iteration
Edit: I believe it is better to give you my own answer to the problem, since you are doing some expensive operations which will make code to run for a long time. Try this solution:
import numpy as np
factor_num = 0
n = 0
def factors(n):
cnt = 0
# You dont need to iterate through all the numbers from 1 to n
# Just to the sqrt, and multiply by two.
for i in range(1,int(np.sqrt(n)+1)):
if n % i == 0:
cnt += 1
# If n is perfect square, it will exist a middle number
if (np.sqrt(n)).is_integer():
return (cnt*2)-1
else:
return (cnt*2)-1
while factor_num < 500:
# Here you generate the triangle, by summing all elements from 1 to n
triangle = sum(list(range(n)))
# Here you calculate the number of factors of the triangle
factor_num = factors(triangle)
n += 1
print(triangle)
Turns out that both of your while loop are infinite either in triangularcreatorin the other while loop:
nums = [1]
triangles = [1]
divisors = []
def triangularcreator(x):
if x == 1:
return 1
n = 1
sum = 0
while n:
n += 1
nums.append(n)
for i in range(len(nums)):
sum += nums[i]
triangles.append(sum)
sum = 0
if len(triangles) >= x:
return triangles[-1]
return triangles[-1]
counter = 1
while True:
check = triangularcreator(counter)
for i in range(1, check + 1):
if check % i == 0:
divisors.append(i)
if len(divisors) >= 500:
tr = triangularcreator(counter)
print(tr)
break
counter +=1
Solution
Disclaimer: This is not my solution but is #TamoghnaChowdhury, as it seems the most clean one in the web. I wanted to solve it my self but really run out of time today!
import math
def count_factors(num):
# One and itself are included now
count = 2
for i in range(2, int(math.sqrt(num)) + 1):
if num % i == 0:
count += 2
return count
def triangle_number(num):
return (num * (num + 1) // 2)
def divisors_of_triangle_number(num):
if num % 2 == 0:
return count_factors(num // 2) * count_factors(num + 1)
else:
return count_factors((num + 1) // 2) * count_factors(num)
def factors_greater_than_triangular_number(n):
x = n
while divisors_of_triangle_number(x) <= n:
x += 1
return triangle_number(x)
print('The answer is', factors_greater_than_triangular_number(500))
For example:
input: A = [ 6 4 3 -5 0 2 -7 1 ]
output: 5
Since 5 is the smallest positive integer that does not occur in the array.
I have written two solutions to that problem. The first one is good but I don't want to use any external libraries + its O(n)*log(n) complexity. The second solution "In which I need your help to optimize it" gives an error when the input is chaotic sequences length=10005 (with minus).
Solution 1:
from itertools import count, filterfalse
def minpositive(a):
return(next(filterfalse(set(a).__contains__, count(1))))
Solution 2:
def minpositive(a):
count = 0
b = list(set([i for i in a if i>0]))
if min(b, default = 0) > 1 or min(b, default = 0) == 0 :
min_val = 1
else:
min_val = min([b[i-1]+1 for i, x in enumerate(b) if x - b[i - 1] >1], default=b[-1]+1)
return min_val
Note: This was a demo test in codility, solution 1 got 100% and
solution 2 got 77 %.
Error in "solution2" was due to:
Performance tests ->
medium chaotic sequences length=10005 (with minus) got 3 expected
10000
Performance tests -> large chaotic + many -1, 1, 2, 3 (with
minus) got 5 expected 10000
Testing for the presence of a number in a set is fast in Python so you could try something like this:
def minpositive(a):
A = set(a)
ans = 1
while ans in A:
ans += 1
return ans
Fast for large arrays.
def minpositive(arr):
if 1 not in arr: # protection from error if ( max(arr) < 0 )
return 1
else:
maxArr = max(arr) # find max element in 'arr'
c1 = set(range(2, maxArr+2)) # create array from 2 to max
c2 = c1 - set(arr) # find all positive elements outside the array
return min(c2)
I have an easy solution. No need to sort.
def solution(A):
s = set(A)
m = max(A) + 2
for N in range(1, m):
if N not in s:
return N
return 1
Note: It is 100% total score (Correctness & Performance)
def minpositive(A):
"""Given an list A of N integers,
returns the smallest positive integer (greater than 0)
that does not occur in A in O(n) time complexity
Args:
A: list of integers
Returns:
integer: smallest positive integer
e.g:
A = [1,2,3]
smallest_positive_int = 4
"""
len_nrs_list = len(A)
N = set(range(1, len_nrs_list+2))
return min(N-set(A)) #gets the min value using the N integers
This solution passes the performance test with a score of 100%
def solution(A):
n = sorted(i for i in set(A) if i > 0) # Remove duplicates and negative numbers
if not n:
return 1
ln = len(n)
for i in range(1, ln + 1):
if i != n[i - 1]:
return i
return ln + 1
def solution(A):
B = set(sorted(A))
m = 1
for x in B:
if x == m:
m+=1
return m
Continuing on from Niroj Shrestha and najeeb-jebreel, added an initial portion to avoid iteration in case of a complete set. Especially important if the array is very large.
def smallest_positive_int(A):
sorted_A = sorted(A)
last_in_sorted_A = sorted_A[-1]
#check if straight continuous list
if len(sorted_A) == last_in_sorted_A:
return last_in_sorted_A + 1
else:
#incomplete list, iterate to find the smallest missing number
sol=1
for x in sorted_A:
if x == sol:
sol += 1
else:
break
return sol
A = [1,2,7,4,5,6]
print(smallest_positive_int(A))
This question doesn't really need another answer, but there is a solution that has not been proposed yet, that I believe to be faster than what's been presented so far.
As others have pointed out, we know the answer lies in the range [1, len(A)+1], inclusively. We can turn that into a set and take the minimum element in the set difference with A. That's a good O(N) solution since set operations are O(1).
However, we don't need to use a Python set to store [1, len(A)+1], because we're starting with a dense set. We can use an array instead, which will replace set hashing by list indexing and give us another O(N) solution with a lower constant.
def minpositive(a):
# the "set" of possible answer - values_found[i-1] will tell us whether i is in a
values_found = [False] * (len(a)+1)
# note any values in a in the range [1, len(a)+1] as found
for i in a:
if i > 0 and i <= len(a)+1:
values_found[i-1] = True
# extract the smallest value not found
for i, found in enumerate(values_found):
if not found:
return i+1
We know the final for loop always finds a value that was not marked, because it has one more element than a, so at least one of its cells was not set to True.
def check_min(a):
x= max(a)
if x-1 in a:
return x+1
elif x <= 0:
return 1
else:
return x-1
Correct me if i'm wrong but this works for me.
def solution(A):
clone = 1
A.sort()
for itr in range(max(A) + 2):
if itr not in A and itr >= 1:
clone = itr
break
return clone
print(solution([2,1,4,7]))
#returns 3
def solution(A):
n = 1
for i in A:
if n in A:
n = n+1
else:
return n
return n
def not_in_A(a):
a=sorted(a)
if max(a)<1:
return(1)
for i in range(0,len(a)-1):
if a[i+1]-a[i]>1:
out=a[i]+1
if out==0 or out<1:
continue
return(out)
return(max(a)+1)
mark and then find the first one that didn't find
nums = [ 6, 4, 3, -5, 0, 2, -7, 1 ]
def check_min(nums):
marks = [-1] * len(nums)
for idx, num in enumerate(nums):
if num >= 0:
marks[num] = idx
for idx, mark in enumerate(marks):
if mark == -1:
return idx
return idx + 1
I just modified the answer by #najeeb-jebreel and now the function gives an optimal solution.
def solution(A):
sorted_set = set(sorted(A))
sol = 1
for x in sorted_set:
if x == sol:
sol += 1
else:
break
return sol
I reduced the length of set before comparing
a=[1,222,3,4,24,5,6,7,8,9,10,15,2,3,3,11,-1]
#a=[1,2,3,6,3]
def sol(a_array):
a_set=set()
b_set=set()
cnt=1
for i in a_array:
#In order to get the greater performance
#Checking if element is greater than length+1
#then it can't be output( our result in solution)
if i<=len(a) and i >=1:
a_set.add(i) # Adding array element in set
b_set.add(cnt) # Adding iterator in set
cnt=cnt+1
b_set=b_set.difference(a_set)
if((len(b_set)) > 1):
return(min(b_set))
else:
return max(a_set)+1
sol(a)
def solution(A):
nw_A = sorted(set(A))
if all(i < 0 for i in nw_A):
return 1
else:
ans = 1
while ans in nw_A:
ans += 1
if ans not in nw_A:
return ans
For better performance if there is a possibility to import numpy package.
def solution(A):
import numpy as np
nw_A = np.unique(np.array(A))
if np.all((nw_A < 0)):
return 1
else:
ans = 1
while ans in nw_A:
ans += 1
if ans not in nw_A:
return ans
def solution(A):
# write your code in Python 3.6
min_num = float("inf")
set_A = set(A)
# finding the smallest number
for num in set_A:
if num < min_num:
min_num = num
# print(min_num)
#if negative make positive
if min_num < 0 or min_num == 0:
min_num = 1
# print(min_num)
# if in set add 1 until not
while min_num in set_A:
min_num += 1
return min_num
Not sure why this is not 100% in correctness. It is 100% performance
def solution(A):
arr = set(A)
N = set(range(1, 100001))
while N in arr:
N += 1
return min(N - arr)
solution([1, 2, 6, 4])
#returns 3
In problem 4 from http://projecteuler.net/ it says:
A palindromic number reads the same both ways. The largest palindrome made from the product of two 2-digit numbers is 9009 = 91 * 99.
Find the largest palindrome made from the product of two 3-digit numbers.
I have this code here
def isPalindrome(num):
return str(num) == str(num)[::-1]
def largest(bot, top):
for x in range(top, bot, -1):
for y in range(top,bot, -1):
if isPalindrome(x*y):
return x*y
print largest(100,999)
It should find the largest palindrome, it spits out 580085 which I believe to be correct, but project euler doesn't think so, do I have something wrong here?
When I revered the for loop I didn't think it through, I removed the thing that checks for the biggest, silly me. Heres the working code
def isPalindrome(num):
return str(num) == str(num)[::-1]
def largest(bot, top):
z = 0
for x in range(top, bot, -1):
for y in range(top,bot, -1):
if isPalindrome(x*y):
if x*y > z:
z = x*y
return z
print largest(100,999)
it spits out 906609
Iterating in reverse doesn't find the largest x*y, it finds the palindrome with the largest x. There's a larger answer than 580085; it has a smaller x but a larger y.
This would more efficiently be written as:
from itertools import product
def is_palindrome(num):
return str(num) == str(num)[::-1]
multiples = ( (a, b) for a, b in product(xrange(100,999), repeat=2) if is_palindrome(a*b) )
print max(multiples, key=lambda (a,b): a*b)
# (913, 993)
You'll find itertools and generators very useful if you're doing Euler in Python.
Not the most efficient answer but I do like that it's compact enough to fit on one line.
print max(i*j for i in xrange(1,1000) for j in xrange(1,1000) if str(i*j) == str(i*j)[::-1])
Tried making it more efficient, while keeping it legible:
def is_palindrome(num):
return str(num) == str(num)[::-1]
def fn(n):
max_palindrome = 1
for x in range(n,1,-1):
for y in range(n,x-1,-1):
if is_palindrome(x*y) and x*y > max_palindrome:
max_palindrome = x*y
elif x * y < max_palindrome:
break
return max_palindrome
print fn(999)
Here I added two 'break' to improve the speed of this program.
def is_palindrome(num):
return str(num) == str(num)[::-1]
def max_palindrome(n):
max_palindrome = 1
for i in range(10**n-1,10**(n-1)-1,-1):
for j in range(10**n-1,i-1,-1):
if is_palindrome(i*j) and i*j > max_palindrome:
max_palindrome = i * j
break
elif i*j < max_palindrome:
break
return max_palindrome
n=int(raw_input())
print max_palindrome(n)
Simple:
def is_pallindrome(n):
s = str(n)
for n in xrange(1, len(s)/2 + 1):
if s[n-1] != s[-n]:
return False
return True
largest = 0
for j in xrange(100, 1000):
for k in xrange(j, 1000):
if is_pallindrome(j*k):
if (j*k) > largest: largest = j*k
print largest
Each time it doesnot have to start from 999 as it is already found earlier.Below is a simple method using string function to find largest palindrome using three digit number
def palindrome(y):
z=str(y)
w=z[::-1]
if (w==z):
return 0
elif (w!=z):
return 1
h=[]
a=999
for i in range (999,0,-1):
for j in range (a,0,-1):
l=palindrome(i*j)
if (l==0):
h=h+[i*j]
a-=1
print h
max=h[0]
for i in range(0,len(h)):
if (h[i] > max):
max= h[i]
print "largest palindrome using multiple of three digit number=%d"%max
Here is my code to solve this problem.
lst = []
for i in range(100,1000):
for n in range(2,i) :
lst.append (i* n)
lst.append(i*i)
lst2=[]
for i in lst:
if str(i) == str(i)[::-1]:
lst2.append(i)
print max(lst2)
Here is my Python code:
max_pal = 0
for i in range(100,999):
for j in range(100,999):
mult = i * j
if str(mult) == str(mult)[::-1]: #Check if the number is palindrome
if mult > max_pal:
max_pal = mult
print (max_pal)
def div(n):
for i in range(999,99,-1):
if n%i == 0:
x = n/i
if x % 1 == 0:
x = n//i
if len(str(x)) == 3:
print(i)
return True
return False
def palindrome():
ans = []
for x in range(100*100,999*999+1):
s = str(x)
s = int (s[::-1])
if x - s == 0:
ans.append(x)
for x in range(len(ans)):
y = ans.pop()
if div(y):
return y
print(palindrome())
580085 = 995 X 583, where 906609 = 993 X 913.
Found it only by applying brute-forcing from top to bottom!
Here is the function I made in python to check if the product of 3 digit number is a palindrome
Function:
def is_palindrome(x):
i = 0
result = True
while i < int(len(str(x))/2):
j = i+1
if str(x)[i] == str(x)[-(j)]:
result = True
else:
result = False
break
i = i + 1
return result
Main:
max_pal = 0
for i in range (100,999):
for j in range (100,999):
x = i * j
if (is_palindrome(x)):
if x > max_pal:
max_pal = x
print(max_pal)
Here is my solution for that:
lst1 = [x for x in range(1000)]
palindrome = []
def reverse(x):
a = str(x)[::-1]
return int(a)
x = 0
while x < len(lst1):
for y in range(1000):
z = lst1[x] * y
if z == reverse(z):
palindrome.append(z)
x += 1
duppal = set(palindrome)
sortpal = sorted(duppal)
total = sortpal[-1]
print(sortpal)
print('Largest palindrome: ' + str(total))
ReThink: efficiency and performance
def palindrome(n):
maxNumberWithNDigits = int('9' * n) #find the max number with n digits
product = maxNumberWithNDigits * maxNumberWithNDigits
#Since we are looking the max, stop on the first match
while True:
if str(product) == str(product)[::-1]: break;
product-=1
return product
start=time.time()
palindrome(3)
end=time.time()-start
palindrome...: 997799, 0.000138998031616 secs