I came across this solution for this problem and don't understand a couple of lines in it. What does the n<=1 and 1 part mean in the definition of fib(n) and, the bigger one, why is it not in the if not fib(i)%2? How does that not mean "if the given Fibonacci number is not even, then we add it to our total"?
cache = {}
def fib(n):
cache[n] = cache.get(n, 0) or (n<=1 and 1
or fib(n-1)+fib(n-2))
return cache[n]
i = 0
n = 0
# we have to pretend the series doesn't go beyond 4 mil
while fib(i) <= (4000000):
if not fib(i) % 2:
n = n + fib(i)
i = i + 1
print n
Let's break this down a bit:
(n <= 1) and 1 or (fib(n - 1) + fib(n - 2))
This is a way that python programmers used to emulate the conditional ternary operator that is typically available in C but not in Python. So basically the condition shows that if n is less than equal to 1, return 1, or do fib(n - 1) + fib(n - 2).
Second question:
This has to do with how python (and other some languages) convert numbers into a boolean condition. For integers, 0 evaluates to False and every other integers evaluate to True. In this case, taking the modulo 2 of an even number results in 0, and odd number results in 1, meaning it really checks for whether a number is odd, and there it wants a not odd number, i.e. even number.
Fibonacci series start with 1. At that part code checks whether the given value is smaller than or equals to 1 or not.
1 1 2 3 5 8 13 ...
As you can see the Fibonacci function is a partial function:
Related
This question already has answers here:
Is there a ceiling equivalent of // operator in Python?
(9 answers)
Closed 10 days ago.
I'm trying to divide number into groups in plain python without importing or the use of if-statements, and get the division into groups + remainder forming one extra group so that 200 / 99 would be 3, And 7 / 3 would be 3, but that 8 / 4 would still be just 2, and 4 / 2 would be 2 etc.. I cannot import anything so it needs to be in plain python.
I tried storing the numbers from inputs from user into variables and dividing them, and then adding one. I also tried // and adding 1 but I cannot get it to work.
How about this:
a, b = 200, 99
result, remainder = a // b + int(bool(a % b)), a % b
This computes the result by performing an integer divide a // b and computing the remainder a % b. Converting an integer value to a boolean is False for 0 and True for any other value, and converting that back to an integer gives you the value you want to add to the result. The remainder is computed again to assign it, if you need it.
As user #markransom commented, the conversion to int() isn't even necessary, as bool already 'is' an integer type:
>>> isinstance(True, int)
True
So, this works (although it may be considered a bit less readable):
a, b = 200, 99
result, remainder = a // b + bool(a % b), a % b
If you're using a modern version of Python and really want it to be short, this also works:
result = a // b + bool(remainder := a % b)
This uses the walrus operator to assign the remainder when it is first computed, avoiding having to compute it twice as well.
Python boolean operations short-circuit and return the last value evaluated and you can use that to convert a non-zero remainder to 1 for addition to a quotient
def group_me(dividend, divisor):
quotient, remainder = divmod(dividend, divisor)
return quotient + (remainder and 1 or 0)
print(group_me(200, 99))
print(group_me(7, 3))
print(group_me(8, 4))
Output
3
3
2
If remainder is non-zero, remainder and 1 short-circuits and returns 1. Otherwise, the or now becomes 0 or 0, which retains its last value 0.
You could do an if statement mathematically without using if itself:
n, d = 200, 99
x, y = n/d, n//d + 1
result = int((x%1 == 0) * x + (x%1 != 0) * y)
Essentially it is condition * answer 1 + (1 - condition) * answer 2. Then it switch to whichever answer depending on condition being 1 or 0.
I've been trying to implement the algorithm which does raising to a power every previous digit to current digit, which is also raised to. Then I find the last digit of this number. Here is the formula of this algorithm:
(x0 ** (x1 ** (x2 ** (x3 ** (...) **(Xn))))))
Then I find the last digit like that:
return find_last_digit % 10
If the list is empty, programm must return 1.
I have the Solution of this problem:
def last_digit(lst):
if len(lst) > 0:
temp = lst[-1]
for i in range(len(lst) - 2, -1, -1):
temp = lst[i] ** temp
return temp % 10
else:
return 1
But as you can see, this code takes a lot of time to be implemented if any value of the input list is large. Could you answer me, how can I make this code more effecient? Thx a lot
Here are some observations that can make the calculations more efficient:
As we need the last digit, and we are essentially doing multiplications, we can use the rules of modular arithmetic. If 𝑎⋅𝑏 = 𝑐, then 𝑎(mod 𝑚)⋅𝑏(mod 𝑚) = 𝑐(mod 𝑚). So a first idea could be to take 𝑚 as 10, and perform the multiplications. But we don't want to split up exponentiation in individual mutliplications, so then see the next point:
For all unsigned integers 𝑏 it holds that 𝑏2 = 𝑏6 modulo 20. You can verify this by doing this for all values of 𝑏 in the range {0,...,19}. By consequence, 𝑏𝑛 = 𝑏𝑛+4 for 𝑛 > 1. We choose 20 as modulus as that is both a multiple of 10 and 4. A multiple of 10, because we need to maintain the last digit in the process, and 4 as we will reduce the exponent by a multiple of 4. Both are necessary conditions at the same time, so not to lose out on the final digit. In the end we have that 𝑎(mod 20)(mod 10) = 𝑎(mod 10)
With these simplification rules, you can keep the involved exponents limited to at most 5, the base to at most 21, and the resulting power to at most 215 = 4084101.
The code could become:
def last_digit(lst):
power = 1
for base in reversed(lst):
power = (base if base < 2 else (base - 2) % 20 + 2) ** (
power if power < 2 else (power - 2) % 4 + 2)
return power % 10
In practice you can skip the reduction of base to (base - 2) % 20 + 2 if these input numbers are not very large.
Stumbled across this coding challenge today and, the goal is to check if n is a power of two. Not all too happy with my solution although it does seem pass all tests.
For one, it doesn't really seem to match the Pseudo code written before it and when trying to compare n to a number greater than those used in the tests ie: while n < 10: I am hit with an infinite loop.
Having trouble wrapping my head around this one!
I've heard of purposefully inducing an indefinite loop; is this some sort of abstract rendition of that concept?
def is_power_of_two(n):
# Check if the number can be divided by two without a remainder
while n % 2 != n:
n = n / 2
# If after dividing by two the number is 1, it's a power of two
if n == 1:
return True
return False
print(is_power_of_two(0)) # Should be False
print(is_power_of_two(1)) # Should be True
print(is_power_of_two(8)) # Should be True
print(is_power_of_two(9)) # Should be False
The code seems to work well for many inputs, but it relies on floating point numbers, by applying a (non-integer) division by 2. If in the end this nicely ends up with n being 1, then indeed the original number was a power of 2.
However, because of floating point limitations, this will break far large enough inputs. You'll get false positives.
For instance:
is_power_of_two((1<<80) + 1)
This should return False, as there are clearly two 1-bits in this number. But your function will return True, as if the input had been 1<<80.
To get a correct implementation, you should use integer division (//) and keep looping as long as the remainder is 0.
And to the topic of infinite loops: it could not loop infinitely for because n becomes smaller by the division, and eventually, it will get below the value of 2, when n % 2 == n.
Even when n is negative... in that case it will remain negative by the division, but again because of floating point limitations, the division will eventually give 0, and at that moment the loop condition is fulfilled.
The integer-based version, could loop forever if the input is 0, and would need protection for that case. We can use the opportunity to also capture negative inputs:
if n <= 0:
return False
while n % 2 == 0:
n = n // 2
Now the above test case will return the correct result.
Note that you can do this without explicit loop, using some bit wise operators:
return n > 0 and (n & -n == n)
Or possibly more readable:
return n > 0 and (1 << (n.bit_length() - 1) == n)
This algorithm can actually be solved without a loop at all.
If you choose to use bit shifting, the algorithm can look like:
def is_power_two(n):
if n < 1:
return False
return n == (1 << n.bit_length() - 1)
Give a number n, you can use a bit shift of 1 << number of bits - 1 along with a equality check to n. If the number is a power of two, zero (True) is returned, otherwise a non-zero value (False) is returned.
Example:
The number 8 occupies four bits: 0b1000. A bit left shifted three (1 << 3) with an equality check to 8 (0b1000 == 8) returns True. However, the number 10 also occupies four bits: 0b1010. Yet, a bit left shifted three (0b1000), an equality check with 8 (0b1010 == 8) returns False.
Testing:
for i in range(65):
print(i, is_power_two(i))
0 False
1 True # 2**0
2 True
3 False
4 True
5 False
6 False
7 False
8 True
9 False
...
62 False
63 False
64 True
This works for smaller numbers:
def is_power_of_two(n):
while n > 1:
n /= 2
return n == 1
print(is_power_of_two(0)) # False
print(is_power_of_two(1)) # True
print(is_power_of_two(8)) # True
print(is_power_of_two(9)) # False
But for bigger numbers, its accuracy is compromised by Python's floating point accuracy. So, you can use this:
def is_power_of_two(n):
return bin(n).count('1') == 1
print(is_power_of_two(0)) # False
print(is_power_of_two(1)) # True
print(is_power_of_two(8)) # True
print(is_power_of_two(9)) # False
print(is_power_of_two(2**54)) # True
print(is_power_of_two(2**54 - 1)) # False
print(is_power_of_two(2**54 + 1)) # False
This works by using the fact that a number is a power of two if in binary it has no other 1s after the leading digit (e.g. 2 = 10, 4
= 100, 8 = 1000, etc.)
I came across this problem Unlucky number 13! recently but could not think of efficient solution this.
Problem statement :
N is taken as input.
N can be very large 0<= N <= 1000000009
Find total number of such strings that are made of exactly N characters which don't include "13". The strings may contain any integer from 0-9, repeated any number of times.
# Example:
# N = 2 :
# output : 99 (0-99 without 13 number)
# N =1 :
# output : 10 (0-9 without 13 number)
My solution:
N = int(raw_input())
if N < 2:
print 10
else:
without_13 = 10
for i in range(10, int('9' * N)+1):
string = str(i)
if string.count("13") >= 1:
continue
without_13 += 1
print without_13
Output
The output file should contain answer to each query in a new line modulo 1000000009.
Any other efficient way to solve this ? My solution gives time limit exceeded on coding site.
I think this can be solved via recursion:
ans(n) = { ans([n/2])^2 - ans([n/2]-1)^2 }, if n is even
ans(n) = { ans([n/2]+1)*ans([n/2]) - ans([n/2])*ans([n/2]-1) }, if n is odd
Base Cases:
ans(0) = 1
ans(1) = 10
It's implementation is running quite fast even for larger inputs like 10^9 ( which is expected as its complexity is O(log[n]) instead of O(n) like the other answers ):
cache = {}
mod = 1000000009
def ans(n):
if cache.has_key(n):
return cache[n]
if n == 0:
cache[n] = 1
return cache[n]
if n == 1:
cache[n] = 10
return cache[n]
temp1 = ans(n/2)
temp2 = ans(n/2-1)
if (n & 1) == 0:
cache[n] = (temp1*temp1 - temp2*temp2) % mod
else:
temp3 = ans(n/2 + 1)
cache[n] = (temp1 * (temp3 - temp2)) % mod
return cache[n]
print ans(1000000000)
Online Demo
Explanation:
Let a string s have even number of digits 'n'.
Let ans(n) be the answer for the input n, i.e. the number of strings without the substring 13 in them.
Therefore, the answer for string s having length n can be written as the multiplication of the answer for the first half of the string (ans([n/2])) and the answer for the second half of the string (ans([n/2])), minus the number of cases where the string 13 appears in the middle of the number n, i.e. when the last digit of the first half is 1 and the first digit of the second half is 3.
This can expressed mathematically as:
ans(n) = ans([n/2])^2 - ans([n/2]-1)*2
Similarly for the cases where the input number n is odd, we can derive the following equation:
ans(n) = ans([n/2]+1)*ans([n/2]) - ans([n/2])*ans([n/2]-1)
I get the feeling that this question is designed with the expectation that you would initially instinctively do it the way you have. However, I believe there's a slightly different approach that would be faster.
You can produce all the numbers that contain the number 13 yourself, without having to loop through all the numbers in between. For example:
2 digits:
13
3 digits position 1:
113
213
313 etc.
3 digits position 2: 131
132
133 etc.
Therefore, you don't have to check all the number from 0 to n*9. You simply count all the numbers with 13 in them until the length is larger than N.
This may not be the fastest solution (in fact I'd be surprised if this couldn't be solved efficiently by using some mathematics trickery) but I believe it will be more efficient than the approach you have currently taken.
This a P&C problem. I'm going to assume 0 is valid string and so is 00, 000 and so on, each being treated distinct from the other.
The total number of strings not containing 13, of length N, is unsurprisingly given by:
(Total Number of strings of length N) - (Total number of strings of length N that have 13 in them)
Now, the Total number of strings of length N is easy, you have 10 digits and N slots to put them in: 10^N.
The number of strings of length N with 13 in them is a little trickier.
You'd think you can do something like this:
=> (N-1)C1 * 10^(N-2)
=> (N-1) * 10^(N-2)
But you'd be wrong, or more accurately, you'd be over counting certain strings. For example, you'd be over counting the set of string that have two or more 13s in them.
What you really need to do is apply the inclusion-exclusion principle to count the number of strings with 13 in them, so that they're all included once.
If you look at this problem as a set counting problem, you have quite a few sets:
S(0,N): Set of all strings of Length N.
S(1,N): Set of all strings of Length N, with at least one '13' in it.
S(2,N): Set of all strings of Length N, with at least two '13's in it.
...
S(N/2,N): Set of all strings of Length N, with at least floor(N/2) '13's in it.
You want the set of all strings with 13 in them, but counted at most once. You can use the inclusion-exclusion principle for computing that set.
Let f(n) be the number of sequences of length n that have no "13" in them, and g(n) be the number of sequences of length n that have "13" in them.
Then f(n) = 10^n - g(n) (in mathematical notation), because it's the number of possible sequences (10^n) minus the ones that contain "13".
Base cases:
f(0) = 1
g(0) = 0
f(1) = 10
g(1) = 0
When looking for the sequences with "13", a sequence can have a "13" at the beginning. That will account for 10^(n-2) possible sequences with "13" in them. It could also have a "13" in the second position, again accounting for 10^(n-2) possible sequences. But if it has a "13" in the third position, and we'd assume there would also be 10^(n-2) possible sequences, we could those twice that already had a "13" in the first position. So we have to substract them. Instead, we count 10^(n-4) times f(2) (because those are exactly the combinations in the first two positions that don't have "13" in them).
E.g. for g(5):
g(5) = 10^(n-2) + 10^(n-2) + f(2)*10^(n-4) + f(3)*10^(n-5)
We can rewrite that to look the same everywhere:
g(5) = f(0)*10^(n-2) + f(1)*10^(n-3) + f(2)*10^(n-4) + f(3)*10^(n-5)
Or simply the sum of f(i)*10^(n-(i+2)) with i ranging from 0 to n-2.
In Python:
from functools import lru_cache
#lru_cache(maxsize=1024)
def f(n):
return 10**n - g(n)
#lru_cache(maxsize=1024)
def g(n):
return sum(f(i)*10**(n-(i+2)) for i in range(n-1)) # range is exclusive
The lru_cache is optional, but often a good idea when working with recursion.
>>> [f(n) for n in range(10)]
[1, 10, 99, 980, 9701, 96030, 950599, 9409960, 93149001, 922080050]
The results are instant and it works for very large numbers.
In fact this question is more about math than about python.
For N figures there is 10^N possible unique strings. To get the answer to the problem we need to subtract the number of string containing "13".
If string starts from "13" we have 10^(N-2) possible unique strings. If we have 13 at the second possition (e.i. a string like x13...), we again have 10^(N-2) possibilities. But we can't continue this logic further as this will lead us to double calculation of string which have 13 at different possitions. For example for N=4 there will be a string "1313" which we will calculate twice. To avoid this we should calculate only those strings which we haven't calculated before. So for "13" on possition p (counting from 0) we should find the number of unique string which don't have "13" on the left side from p, that is for each p
number_of_strings_for_13_at_p = total_number_of_strings_without_13(N=p-1) * 10^(N-p-2)
So we recursevily define the total_number_of_strings_without_13 function.
Here is the idea in the code:
def number_of_strings_without_13(N):
sum_numbers_with_13 = 0
for p in range(N-1):
if p < 2:
sum_numbers_with_13 += 10**(N-2)
else:
sum_numbers_with_13 += number_of_strings_without_13(p) * 10**(N-p-2)
return 10**N - sum_numbers_with_13
I should say that 10**N means 10 in the power of N. All the other is described above. The functions also has a surprisingly pleasent ability to give correct answers for N=1 and N=2.
To test this works correct I've rewritten your code into function and refactored a little bit:
def number_of_strings_without_13_bruteforce(N):
without_13 = 0
for i in range(10**N):
if str(i).count("13"):
continue
without_13 += 1
return without_13
for N in range(1, 7):
print(number_of_strings_without_13(N),
number_of_strings_without_13_bruteforce(N))
They gave the same answers. With bigger N bruteforce is very slow. But for very large N recursive function also gets mush slower. There is a well known solution for that: as we use the value of number_of_strings_without_13 with parameters smaller than N multiple times, we should remember the answers and not recalculate them each time. It's quite simple to do like this:
def number_of_strings_without_13(N, answers=dict()):
if N in answers:
return answers[N]
sum_numbers_with_13 = 0
for p in range(N-1):
if p < 2:
sum_numbers_with_13 += 10**(N-2)
else:
sum_numbers_with_13 += number_of_strings_without_13(p) * 10**(N-p-2)
result = 10**N - sum_numbers_with_13
answers[N] = result
return result
Thanks to L3viathan's comment now it is clear. The logic is beautiful.
Let's assume a(n) is a number of strings of n digits without "13" in it. If we know all the good strings for n-1, we can add one more digit to the left of each string and calculate a(n). As we can combine previous digits with any of 10 new, we will get 10*a(n-1) different strings. But we must subtract the number of strings, which now starts with "13" which we wrongly summed like OK at the previous step. There is a(n-2) of such wrongly added strings. So a(n) = 10*a(n-1) - a(n-2). That is it. Such simple.
What is even more interesting is that this sequence can be calculated without iterations with a formula https://oeis.org/A004189 But practically that doesn't helps much, as the formula requires floating point calculations which will lead to rounding and would not work for big n (will give answer with some mistake).
Nevertheless the original sequence is quite easy to calculate and it doesn't need to store all the previous values, just the last two. So here is the code
def number_of_strings(n):
result = 0
result1 = 99
result2 = 10
if n == 1:
return result2
if n == 2:
return result1
for i in range(3, n+1):
result = 10*result1 - result2
result2 = result1
result1 = result
return result
This one is several orders faster than my previous suggestion. And memory consumption is now just O(n)
P.S. If you run this with Python2, you'd better change range to xrange
This python3 solution meets time and memory requirement of HackerEarth
from functools import lru_cache
mod = 1000000009
#lru_cache(1024)
def ans(n):
if n == 0:
return 1
if n == 1:
return 10
temp1 = ans(n//2)
temp2 = ans(n//2-1)
if (n & 1) == 0:
return (temp1*temp1 - temp2*temp2) % mod
else:
temp3 = ans(n//2 + 1)
return (temp1 * (temp3 - temp2)) % mod
for t in range(int(input())):
n = int(input())
print(ans(n))
I came across this problem on
https://www.hackerearth.com/problem/algorithm/the-unlucky-13-d7aea1ff/
I haven't been able to get the judge to accept my solution(s) in Python but (2) in ANSI C worked just fine.
Straightforward recursive counting of a(n) = 10*a(n-1) - a(n-2) is pretty slow when getting to large numbers but there are several options (one which is not mentioned here yet):
1.) using generating functions:
https://www.wolframalpha.com/input/?i=g%28n%2B1%29%3D10g%28n%29+-g%28n-1%29%2C+g%280%29%3D1%2C+g%281%29%3D10
the powers should be counted using squaring and modulo needs to be inserted cleverly into that and the numbers must be rounded but Python solution was slow for the judge anyway (it took 7s on my laptop and judge needs this to be counted under 1.5s)
2.) using matrices:
the idea is that we can get vector [a(n), a(n-1)] by multiplying vector [a(n-1), a(n-2)] by specific matrix constructed from equation a(n) = 10*a(n-1) - a(n-2)
| a(n) | = | 10 -1 | * | a(n-1) |
| a(n-1) | | 1 0 | | a(n-2) |
and by induction:
| a(n) | = | 10 -1 |^(n-1) * | a(1) |
| a(n-1) | | 1 0 | | a(0) |
the matrix multiplication in 2D should be done via squaring using modulo. It should be hardcoded rather counted via for cycles as it is much faster.
Again this was slow for Python (8s on my laptop) but fast for ANSI C (0.3s)
3.) the solution proposed by Anmol Singh Jaggi above which is the fastest in Python (3s) but the memory consumption for cache is big enough to break memory limits of the judge. Removing cache or limiting it makes the computation very slow.
You are given a string S of length N. The string S consists of digits from 1-9, Consider the string indexing to be 1-based.
You need to divide the string into blocks such that the i block contains the elements from the index((i 1) • X +1) to min(N, (i + X)) (both inclusive). A number is valid if it is formed by choosing exactly one digit from each block and placing the digits in the order of their block
number
I need help with an assigment I'm working on. the task is to write a program to find all Wieferich prime numbers between two given values. The equation to determine if it is a Wieferich prime is this:
a Wieferich prime number p is such that p2 divides 2(p − 1) − 1
This is what I have so far:
start=int(input("enter start value"))
end=int(input("enter end value"))
for c in range(start,end):
if c%2!=0:
primedet=(c**2)/((2**(c-1))-1)
if primedet%1==0:
print(c," is a Wiefrich Prime")
Every time I run it, it just prints all the odd numbers between the given values. I know that there are only two Wieferich prime numbers: 1093 and 3011. I really just not sure how to make this work. Any guidance would be appreciated.
The use of modular arithmetic make this a more easy task, because you want that 2p-1 -1 be divisible by p2, that is 2p-1 -1 = 0 (mod p2) rearrange this you get 2p-1 = 1 (mod p2) in python this is
(2**(p-1)) % (p**2) == 1
but that is inefficient because first calculate 2p-1 to then take the modulo, but don't worry, python have a efficient way of doing modular exponentiation with the 3 argument call of pow
pow(2,p-1,p**2) == 1
finally you also need that p be a prime, then with implementing a primality test you are ready to go
def isPrime(n:int) -> bool:
return True #put here the code for primality check
def find_Wieferich_prime_in(star,end) -> [int]:
resul = list()
for p in range(star,end):
if isPrime(p) and pow(2,p-1,p**2)==1:
resul.append(p)
return resul
print(find_Wieferich_prime_in(0,4000))
and that is everything that you need to find the Wieferich prime
Your other mistake is in here
primedet=(c**2)/((2**(c-1))-1)
2c-1-1 is always bigger that c2 (to a sufficient large c ) so the division c2/(2c-1-1) < 1
furthermore
primedet%1
because primedet is a float, when you do float%1 it give you the decimal part of that number, mix round issues and you will get too many zeros,
but more than that, what you are testing there is something that is not the definition of a Wieferich prime.
This is very simple. Based on your statement, the numbers have the property of being prime prime and Wieferich just by the means of the equation you gave, so (2(p - 1) - 1) % p2 == 0 returns True means you found a number. As explained by #Copperfield, this can be written as (2(p-1)) % p2 == 1. Then you can do (with the help of pow which is faster):
# I assume we have `start` and `end` given by user. Now we can safely
# start from the first odd number greater or equal to start so we can
# stride by 2 in the `range` call which will half our iteration
start = start + 1 if start % 2 == 0 else start
# next I'm using filter because it's faster then the normal `for` loop
# and gives us exactly what we need, that is the list of numbers
# that pass the equation test. Note I've also included the `end`
# number. If I were to write `range(start, end, 2)` we wouldn't
# test for `end`
restult = list(filter(lambda n: pow(2, n - 1, n*n) == 1, range(start, end + 2, 2)))