I have been working on dealing with n! <= 10^6 in python by using sympy.solver. For example, the below is my code:
import sympy as sy
print(sy.solve_univariate_inequality(sy.factorial(n) <= 10**6,n))
I tried solve_univariate_inequality and solve methods but none of them worked. The error was "raise NotImplementedError('solveset is unable to solve this equation.')"
I'm curious if there's any other way to deal with this inequality. Any insight please?
i = 1
factorial = 1
while factorial <= 1_000_000:
factorial *= i
i += 1
print(f"equation valid for n in [1-{i-2}]")
From docs
Currently supported:
polynomial
transcendental
piecewise combinations of the above
systems of linear and polynomial equations
systems containing relational expressions
Looks like factorial is not supported.
If you approach this problem purely mathematically you can just increment n to get the factorial which exceeds the threshold.
results=[]
n=0
n_factorial=1
while n_factorial<=10**6:
results.append(n)
print(n,n_factorial)
n+=1
n_factorial*=n
print(results)
Output:
0 1
1 1
2 2
3 6
4 24
5 120
6 720
7 5040
8 40320
9 362880
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
Related
Given an integer n <= 10^18 which is the product of Fibonacci numbers, I need to factor it into said Fibonacci numbers.
Each factorization has a score, which is one less than the count of factors plus the sum of the indices of the factors in the Fibonacci sequence that begins with f(1) = 1, f(2) = 2.
If multiple such factorizations are possible, I need the factorization that minimizes the score.
Example:
104 = 13 * 8 or 104 = 13 * 2 * 2 * 2
f(6) = 13, f(5) = 8, f(2) = 2
For 104 = 13*8 = f(6)*f(5), we have a count of 2, indices of 6 & 5, giving us 2 + 6 + 5 - 1 = 12.
For 104 = 13 * 2 * 2 * 2 = f(6) * f(2) * f(2) * f(2), we have a count of 4 and indices of 6, 2, 2, 2, giving us 4 + 6 + 2 + 2 + 2 - 1 = 15.
We should pick 13 * 8 since it has the lower score.
The biggest problem I've come across is when we have a number like 1008, which is divisible by 144 and 21, but needs to be divided by 21 because 1008 % 7 == 0. Because my program is first dividing by the biggest numbers, number 144 is 'stealing' 3 from number 21 so my program doesn't find a solution.
Carmichael's theorem proves that each Fibonacci number after 144 has at least one prime divisor that doesn't divide any earlier Fibonacci number.
There aren't many Fibonacci numbers under 10^18; fewer than 90.
Make an array of all the Fibonacci numbers <= 10^18.
Given an input n which is the product of Fibonacci numbers, its factorization into Fibonacci numbers must include every Fibonacci number above 144 that divides it, repeated as many times as it divides it.
Go through your Fibonacci numbers in descending order and keep dividing n by any such number that divides it, until you get to 144.
Now we need to be careful because two Fibonacci numbers don't have any prime factors not seen in previous Fibonacci numbers. These are 8 and 144. Since 8 is 2^3 and 2 is a Fibonacci number, you can't render your number unfactorable into Fibonacci numbers by taking the 8. Under your optimization, you will always choose the 8.
Then 144 is the only factor that you might need to reject for a smaller factor. This can only happen if 34 or 21 are factors, and the 144 eliminates a needed 2 or 3.
34 = 2 * 17, 21 = 3 * 7
That was long-winded, but it gets us to a simple approach.
Go through the Fibonacci numbers <= n in descending order until you get to 144, then skip to 34, then 21, then back to 144 and descending down to 2.
This will give you the optimal factorization under your weird scoring scheme.
----- this order -----
[679891637638612258, 420196140727489673, 259695496911122585, 160500643816367088, 99194853094755497, 61305790721611591, 37889062373143906, 23416728348467685, 14472334024676221, 8944394323791464, 5527939700884757, 3416454622906707, 2111485077978050, 1304969544928657, 806515533049393, 498454011879264, 308061521170129, 190392490709135, 117669030460994, 72723460248141, 44945570212853, 27777890035288, 17167680177565, 10610209857723, 6557470319842, 4052739537881, 2504730781961, 1548008755920, 956722026041, 591286729879, 365435296162, 225851433717, 139583862445, 86267571272, 53316291173, 32951280099, 20365011074, 12586269025, 7778742049, 4807526976, 2971215073, 1836311903, 1134903170, 701408733, 433494437, 267914296, 165580141, 102334155, 63245986, 39088169, 24157817, 14930352, 9227465, 5702887, 3524578, 2178309, 1346269, 832040, 514229, 317811, 196418, 121393, 75025, 46368, 28657, 17711, 10946, 6765, 4181, 2584, 1597, 987, 610, 377, 233, 34, 21, 144, 89, 55, 13, 8, 5, 3, 2]
I couldn't make a better title. Let me explain:
Numpy has the percentile() function, which calculates the Nth percentile of any array:
import numpy as np
arr = np.arange(0, 10)
print(arr)
print(np.percentile(arr, 80))
>>> [0 1 2 3 4 5 6 7 8 9]
>>> 7.2
Which is great - 7.2 marks the 80th percentile on that array.
How can I obtain the same percentile type of calculation, but find out the Nth percentile of both extremities of an array (the positive and negative numbers)?
For example, my array may be:
[-10 -9 -8 -7 -6 -5 -4 -3 -2 -1 0 1 2 3 4 5 6 7 8 9]
So I place them in a number line, it would go from -10 to 10. I like to get the Nth percentile that marks extremities of that number line. For 90th percentile, the output could look like -8.1 and 7.5, for example, since since 90% of the values in the array fall within that range, and the remaining 10% are lower than -8.1 or greater than 7.5.
I made these numbers up of course, just for illustrating what I'm trying to calculate.
Is there any NumPy method for obtaining such boundaries?
Please let me know if I can explain or clarify further, I know this is a complicated question to ask and I'm trying my best to make it clear. Thanks a lot!
Are you looking for something like
import numpy as np
def extremities(array, pct):
# assert 50 <= pct <= 100
return np.percentile(array, [100 - pct, pct])
arr = np.arange(-10, 10)
print(extremities(arr, 90)) # [-8.1, 7.1]
I have a list like this x=[1,2,2,3,1,2,1,1,2,2] where the number is a positive integer that increments by 0 or 1 and sometimes resets to 1, and need to transform it to [1,2,2,3,4,5,6,7,8,8] in an incremental way, where each 1 should be the previous number plus 1 and whatever follows 1 increment accordingly. Is there a simple way to do this via a numpy array etc? I tried using loops but I guess there's a simpler way.
You can use np.add.accumulate():
import numpy as np
x = np.array([1,2,2,3,1,2,1,1,2,2])
x[1:] += np.add.accumulate(x[:-1]*(x[1:]==1))
print(x)
[1 2 2 3 4 5 6 7 8 8]
I want to know if there is a math expression that I can use to find this relation between two numbers.
Some examples of the input and expected output are below:
Input Multiple Result
4 3 3
6 3 6
8 3 6
4 4 4
12 4 12
16 5 15
Also, the expressions below from Wolfram Alpha show me the expected result but since they don't expand on the explanation on how to do it I can't learn from them...
Biggest multiple of 4 from 10
Biggest multiple of 4 from 12
try with // and % operators!
for //, you would do
Result = (Input // Multiple) * Multiple
This way you get how many times Multiple Fits into Input - this number is then multiplied with the Multiple itself and therefore gives you the expected results!
EDIT: how to do it with modulo %?
Result = Input - (Input % Multiple)
taken from MCO's answer!
You can employ modulo for this. For example, to calculate the biggest multiple of 4 that is less or equal than 13:
13 % 4 = 1
13 - 1 = 12
in python, that could look like this:
def biggest_multiple(multiple_of, input_number):
return input_number - input_number % multiple_of
So you use it as:
$ biggest_multiple(4, 9)
8
$ biggest_multiple(4, 12)
12
Here's how I would do it:
return int(input / multiple) * multiple
It truncates the division so that you get an integer, which you can multiply.
This can be trivial but damn easy to understand. To take into account if multiple is negative or zero
Multiple=[3,3,3,4,4,5,0,-5]
Input=[4,6,8,4,12,16,1,8]
Result=[]
for input,multiple in zip(Input,Multiple):
if(multiple):
Result.append((range(multiple,input+1,abs(multiple)))[-1])
else:
Result.append(0)
print(Result)
Output:
[3, 6, 6, 4, 12, 15, 0, 5]
I'm a newbie at python. I started it not long a ago as a hobby after uni lecture hours.
I found this exercise ( forgot where I got it from now) to do which is to print out the factorial numbers.
Which I did. But, problem is that I'm tasked to manipulate line 3 so it only prints out the number 1 once at the start of the sequence and I'm having trouble with that.
Please can any help? :)
In advance sorry if the question wasn't worded as good as it could have been.
a, b = 0, 1
while a < 19:
print b,
a, b = a + 1, b * (a+1)
Result:
1 1 2 6 24 120 720 5040 40320 362880 3628800 39916800 479001600 6227020800 87178291200 1307674368000 20922789888000 355687428096000 6402373705728000
a, b = 0, 1
while a < 19:
if a: print b,
a, b = a + 1, b * (a+1)
Use a in-line if statement to check if a is 1. If it's 1 then you know that you already went through the loop at least once.