Related
def sum(a):
if a==1:
s=1
else:
s=1+2*sum(a-1)
return s
function:calculate the sum of the sequence of number. Its common ratio is 2, last term is 2^( a-1) and first term is 1.
Why does it use s=1+2*sum(a-1) to implement the function?
def sum1(a):
if a==1:
s=1
else:
s=1+2*sum1(a-1)
return s
What this function does, let's take a=4.
(1) s = 1 + 2*sum1(4-1) = 1 + 2*sum1(3) = 1 + 2*s2
(2) s2 = 1 + 2*sum1(3-1) = 1 + 2*sum1(2) = 1 + 2*s3
(3) s3 = 1 + 2*sum(2-1) = 1 + 2*sum(1) = 1 + 2*s4 = 1+2 = 3
Going BackWard : (3 * 2 + 1 ) * 2 + 1 = (7) * 2 + 1 = 15
Do it for bigger numbers, you will notice that this is the formula of 2^a - 1.
Print 2^a and 2^a - 1
Difference: (4, 3)
Difference: (8, 7)
Difference: (16, 15)
Difference: (32, 31)
Difference: (64, 63)
Difference: (128, 127)
Difference: (256, 255)
#Zhongyi I'm understanding this question as asking "how does recursion work."
Recursion exists in Python, but I find it a little difficult to explain how it works in Python. Instead I'll show how this works in Racket (a Lisp dialect).
First, I'lll rewrite yoursum provided above into mysum:
def yoursum(a):
if a==1:
s=1
else:
s=1+2*yoursum(a-1)
return s
def mysum(a):
if a == 1:
return 1
return 1 + (2 * mysum(a - 1))
for i in range(1, 11):
print(mysum(i), yoursum(i))
They are functionally the same:
# Output
1 1
3 3
7 7
15 15
31 31
63 63
127 127
255 255
511 511
1023 1023
In Racket, mysum looks like this:
#lang racket
(define (mysum a)
(cond
((eqv? a 1) 1)
(else (+ 1 (* 2 (mysum (sub1 a)))))))
But we can use language features called quasiquoting and unquoting to show what the recursion is doing:
#lang racket
(define (mysum a)
(cond
((eqv? a 1) 1)
(else `(+ 1 (* 2 ,(mysum (sub1 a))))))) ; Notice the ` and ,
Here is what this does for several outputs:
> (mysum 1)
1
> (mysum 2)
'(+ 1 (* 2 1))
> (mysum 3)
'(+ 1 (* 2 (+ 1 (* 2 1))))
> (mysum 4)
'(+ 1 (* 2 (+ 1 (* 2 (+ 1 (* 2 1))))))
> (mysum 5)
'(+ 1 (* 2 (+ 1 (* 2 (+ 1 (* 2 (+ 1 (* 2 1))))))))
You can view the recursive step as substituting the expression (1 + 2 * rest-of-the-computation)
Please comment or ask for clarification if there are parts that still do not make sense.
Formula Explanation
1+2*(sumOf(n-1))
This is not a generic formula for Geometric Progression.
this formula is only valid for the case when ratio is 2 and first term is 1
So how it is working.
The Geometric Progression with first term = 1 and r = 2 will be
1,2,4,6,8,16,32,64
FACT 1
Here you can clearly see nth term is always equals to sumOf(n-1) terms + 1
Let declare an equation from fact 1
n = sumOf(n-1) + 1 =======> Eq1.
Let put our equation to test
put n = 2 in Eq1
2 = sumOf(2-1) + 1
we know that sumOf(1) is 1 then
2 = 2 ==> proved
so if n = sumOf(n-1)+1 then
FACT 2
Sum of n term is n term + sum(n-1) terms
Lets declare an Equation from FACT 2
sumOf(n) = sumOf(n-1) + n ==> eq2
let us put eq1 in eq2 i.e. n = sumOf(n-1) + 1
sumOf(n) = sumOf(n-1) + sumOf(n-1) + 1 ==> eq3
Simplifying
sumOf(n) = 2 * sumOf(n-1) + 1
Rearranging
sumOf(n) = 1 + 2 * sumOf(n-1) ==> final Equation
Now Code this equation
we know sumOf 1st term is alway 1 so, this is our base case.
def sumOf(a):
if a==1:
return 1
so now sum of first n terms will be 1 + 2 * sumOf(n-1) ==> From final Equation
put this equation in else part
def sumOf(a):
if a==1:
return 1
else:
return 1 + 2 * sumOf(a-1)
I have equations with multiple unknowns, and a number range:
eq1 = (x + 5 + y) #
ans = 15
no_range = [1..5]
I know that I can solve the equation by checking all possible combinations:
solved = False
for i in range(1, 5+1) # for x
for j in range(1, 5+1) # for y
if i + 5 + j == ans:
solved = True
So, the problem is that I want a function to deal with unknown_count amount of unknowns. So that both the following equations, or any, can be solved in the same manner above:
eq1 = (x + 5 + y)
ans = 15
eq2 = (x + 5 + y + z * a + 5 * b / c)
ans = 20
I just cannot think of a way, since for each unknown you need a for loop.
You could use itertools.product to generate the Cartesian product for an
arbitrary number of variables:
In [4]: import itertools
In [5]: list(itertools.product(range(1, 5+1), repeat=2))
Out[5]:
[(1, 1),
(1, 2),
(1, 3),
...
(5, 3),
(5, 4),
(5, 5)]
So you could modify your code like this:
import itertools as IT
unknown_count = 6
ans = 20
solved = False
def func(*args):
x, y, z, a, b, c = args
return x + 5 + y + z * a + 5 * b / c
for args in IT.product(range(1, 5+1), repeat=unknown_count):
if func(*args) == ans:
solved = True
print('{} + 5 + {} + {} * {} + 5 * {} / {} = {}'.format(*(args+(ans,))))
which yields a lot of solutions, such as
1 + 5 + 1 + 1 * 3 + 5 * 2 / 1 = 20
1 + 5 + 1 + 1 * 3 + 5 * 4 / 2 = 20
1 + 5 + 1 + 2 * 4 + 5 * 1 / 1 = 20
...
5 + 5 + 5 + 2 * 2 + 5 * 1 / 5 = 20
5 + 5 + 5 + 3 * 1 + 5 * 2 / 5 = 20
5 + 5 + 5 + 4 * 1 + 5 * 1 / 5 = 20
The * unpacking operator was used
to create a function, func, which accepts an arbitrary number of arguments (i.e. def func(*args)), and also to
pass an arbitrary number of arguments to func (i.e. func(*args)).
When I was little, I played the next game with my cousins:
"Zero in the car's license plates": by using the numbers in the car's license plate numbers and using the elementary operations (sum, subtraction, product and division) once each, you had to find an order that equaled 0.
For example, if we have the following license plate:
2591 --> (2*5)-(9+1) = 0
2491 --> (2*4)+1 -9 = 0
I would like to make a program in Haskell or Python that it is able to play this game, and print the steps that gives a result of 0.
getZero 2491 = 2*4+1-9
getZero 2591 = 2*5-9+1
Maybe its impossible to make this; I hope that you can help me.
This is probably off topic but a fun toy puzzle.
An easy way to think of the issue is in perhaps four separate parts:
Boring plumbing for the arguments and printing the results
Construct all possible expressions of binary operations of the given numbers.
Interpret these expressions to obtain a numeric literal and drop any result that is not zero.
Pretty print the expression.
We could perform extra steps, such as filtering out duplicates based on algebraic rules (a + b and b + a are morally the same), but I skipped that.
The boring plumbing is just getting our plate numbers (one for each argument), breaking those down into digits, running our computation, and printing the solution.
import Data.Foldable
import Data.List
import System.Environment
main :: IO ()
main =
do ns <- getArgs
for_ ns $ \n -> do
let digitList = map (read . (:[])) (n :: String) :: [Int]
putStrLn $ "---------- " ++ show n ++ " ----------"
putStrLn $ unlines (map render (solutions digitList))
Construction The real fun is in this construction of a binary tree of operations and leafs with the literals. First we define our expression language:
data Expr = Add Expr Expr
| Sub Expr Expr
| Mul Expr Expr
| Div Expr Expr
| Lit Int
deriving (Eq, Ord, Show)
And we can use these expressions along with a Haskell list monad to build all possible expressions (assuming a non-empty list as input):
operations :: [Expr -> Expr -> Expr]
operations = [Add, Sub, Mul, Div]
exprsOf :: [Expr] -> [Expr]
exprsOf [term] = [term]
exprsOf xs =
do x <- xs
y <- (delete x xs)
o <- operations
exprsOf (o x y : delete y (delete x xs))
That is, x is one of the elements in the original set of expressions. y is another element (but not x). o is one of our legal operations (addition, subtraction, etc). And we recursively reduce this list size till we are left with the top level expression (variable name term). If you don't understand the operation that's OK - specific parts that confuse you would make a fine (on topic) question.
Interpretation With the expressions built we can now interpret them and filter out any that don't result in zero.
The interpreter is just using addition (+) when we see our Add constructor and same for the other operations. I lifted everything into the Maybe Applicative because I didn't want division by zero or with a remainder to show up in our results.
interp :: Expr -> Maybe Int
interp (Lit n) = Just n
interp (Add a b) = (+) <$> interp a <*> interp b
interp (Sub a b) = (-) <$> interp a <*> interp b
interp (Mul a b) = (*) <$> interp a <*> interp b
interp (Div a b) | interp b == Just 0 = Nothing
| interp b == Nothing = Nothing
| otherwise =
case divMod <$> interp a <*> interp b of
Nothing -> Nothing
Just (x,0) -> Just x
_ -> Nothing -- Ignore uneven division
Applying this interpretation is just a matter of filtering for Just 0:
solutions :: [Int] -> [Expr]
solutions xs = filter ((== Just 0) . interp) $ exprsOf (map Lit xs)
Rendering Finally, there's a pretty ugly render function just to emit the proper parenthesis so we see the right order of operations:
render :: Expr -> String
render (Lit n) = show n
render (Add a b) = "(" ++ render a ++ " + " ++ render b ++ ")"
render (Sub a b) = "(" ++ render a ++ " - " ++ render b ++ ")"
render (Mul a b) = "(" ++ render a ++ " * " ++ render b ++ ")"
render (Div a b) = "(" ++ render a ++ " / " ++ render b ++ ")"
Example Run
*Main> :main 2591
---------- "2591" ----------
(((2 * 5) - 9) - 1)
(1 - ((2 * 5) - 9))
(((2 * 5) - 1) - 9)
(9 - ((2 * 5) - 1))
((9 - (2 * 5)) + 1)
(1 + (9 - (2 * 5)))
((9 + 1) - (2 * 5))
((2 * 5) - (9 + 1))
((1 - (2 * 5)) + 9)
(9 + (1 - (2 * 5)))
((1 + 9) - (2 * 5))
((2 * 5) - (1 + 9))
(((5 * 2) - 9) - 1)
(1 - ((5 * 2) - 9))
(((5 * 2) - 1) - 9)
(9 - ((5 * 2) - 1))
((9 - (5 * 2)) + 1)
(1 + (9 - (5 * 2)))
((9 + 1) - (5 * 2))
((5 * 2) - (9 + 1))
((1 - (5 * 2)) + 9)
(9 + (1 - (5 * 2)))
((1 + 9) - (5 * 2))
((5 * 2) - (1 + 9))
(((9 + 1) / 2) - 5)
(5 - ((9 + 1) / 2))
(((9 + 1) / 5) - 2)
(2 - ((9 + 1) / 5))
((2 * 5) - (9 + 1))
((9 + 1) - (2 * 5))
((5 * 2) - (9 + 1))
((9 + 1) - (5 * 2))
(((1 + 9) / 2) - 5)
(5 - ((1 + 9) / 2))
(((1 + 9) / 5) - 2)
(2 - ((1 + 9) / 5))
((2 * 5) - (1 + 9))
((1 + 9) - (2 * 5))
((5 * 2) - (1 + 9))
((1 + 9) - (5 * 2))
This isn't the best implementation, because there are quite a lot of repeats, but does get a result.
Using itertools, I generated every different state (permutation) that the numbers and operations could be in, e.g.:
[('1', '2', '3', '4'), ('1', '2', '4', '3'), ('1', '3', '2', '4'), ('1', '3', '4', '2'), ('1', '4', '2', '3'), ....... ('4', '1', '3', '2'), ('4', '2', '1', '3'), ('4', '2', '3', '1'), ('4', '3', '1', '2'), ('4', '3', '2', '1')]
[('+', '-', '*'), ('+', '*', '-') ...... ('/', '-', '*'), ('/', '*', '-')]
...then, I made a function that adds brackets to every possible state of the calculation:
[1,'+',2,'-',3,'*',4] becomes:
1 + 2 - 3 * 4
( 1 + 2 ) - ( 3 * 4 )
( 1 + 2 - 3 ) * 4
1 + ( 2 - 3 * 4 )
( 1 + 2 ) - 3 * 4
1 + 2 - ( 3 * 4 )
1 + ( 2 - 3 ) * 4
... and then, evaluated each different possibility, and if it was zero I printed it out.
Heres all the code:
from itertools import permutations, combinations, chain
import sys
operations = ['+', '-', '*', '/'] # basic operations
# add every combination of brackets to the calculation
def addBrackets(calc):
possibilities = []
possibilities.append(" ".join(calc))
possibilities.append(" ".join(str(s) for s in list(chain(["("], calc[:3], [")"], [calc[3]], ["("], calc[4:], [")"]))))
possibilities.append(" ".join(str(s) for s in list(chain(["("], calc[:-2], [")"], calc[-2:]))))
possibilities.append(" ".join(str(s) for s in list(chain(calc[:2], ["("], calc[2:], [")"]))))
possibilities.append(" ".join(str(s) for s in list(chain(["("], calc[:3], [")"], calc[3:]))))
possibilities.append(" ".join(str(s) for s in list(chain(calc[:4], ["("], calc[4:], [")"]))))
return possibilities
def getZero(n): # 2491
nums = [x for x in str(n)] # [2, 4, 9, 1]
while len(nums) < 4:
nums = ['0'] + nums # add zeroes if the input was less than 1000 e.g. [5, 3, 1] -> [0, 5, 3, 1]
possible_number_order = list(permutations(nums)) # get every number order
possible_op_order = list(combinations(operations, 3)) # get combinations of 3 of the operations
possible_op_permutations = list(chain(list(permutations(p)) for p in possible_op_order)) # chain together all the permutations of each combination
possible_op_order = []
for perms in possible_op_permutations:
possible_op_order.extend(perms) # add all the lists into one
for n in possible_number_order: # for each number order
for op in possible_op_order: # for each operation order
calculation = [n[0],op[0],n[1],op[1],n[2],op[2],n[3]] # create a list with the order of the operation
for calc in addBrackets(calculation): # for each bracket position
try:
result = eval(calc) # evaluate
if abs(result) <= 0.001: # to check for float comparison
print("{} = {}".format(calc, 0))
except: # ZeroDivisionError
continue
if __name__ == "__main__":
for user_input in [int(n) for n in sys.argv[1:]]:
print("-------{0:04}-------".format(user_input)) # print 0 padded output
getZero(user_input)
Enter the input as command line arguments:
$ python3.6 zerogame.py 2491 2591
-------2491-------
( 2 * 4 - 9 ) + 1 = 0
( 2 * 4 ) - 9 + 1 = 0
( 2 * 4 ) + ( 1 - 9 ) = 0
( 2 * 4 + 1 ) - 9 = 0
( 2 * 4 ) + 1 - 9 = 0
2 * 4 + ( 1 - 9 ) = 0
2 + ( 1 - 9 ) / 4 = 0
( 4 * 2 - 9 ) + 1 = 0
( 4 * 2 ) - 9 + 1 = 0
( 4 * 2 ) + ( 1 - 9 ) = 0
( 4 * 2 + 1 ) - 9 = 0
( 4 * 2 ) + 1 - 9 = 0
4 * 2 + ( 1 - 9 ) = 0
4 + ( 1 - 9 ) / 2 = 0
9 - ( 2 * 4 + 1 ) = 0
9 - ( 4 * 2 + 1 ) = 0
9 - ( 1 + 2 * 4 ) = 0
9 - ( 1 + 4 * 2 ) = 0
( 1 + 2 * 4 ) - 9 = 0
1 + ( 2 * 4 - 9 ) = 0
1 + ( 2 * 4 ) - 9 = 0
( 1 + 4 * 2 ) - 9 = 0
1 + ( 4 * 2 - 9 ) = 0
1 + ( 4 * 2 ) - 9 = 0
( 1 - 9 ) + ( 2 * 4 ) = 0
( 1 - 9 ) + 2 * 4 = 0
1 - 9 + ( 2 * 4 ) = 0
( 1 - 9 ) / 2 + 4 = 0
( 1 - 9 ) + ( 4 * 2 ) = 0
( 1 - 9 ) + 4 * 2 = 0
1 - 9 + ( 4 * 2 ) = 0
( 1 - 9 ) / 4 + 2 = 0
-------2591-------
( 2 * 5 ) - ( 9 + 1 ) = 0
2 * 5 - ( 9 + 1 ) = 0
( 2 * 5 ) - ( 1 + 9 ) = 0
2 * 5 - ( 1 + 9 ) = 0
2 - ( 9 + 1 ) / 5 = 0
2 - ( 1 + 9 ) / 5 = 0
( 5 * 2 ) - ( 9 + 1 ) = 0
5 * 2 - ( 9 + 1 ) = 0
( 5 * 2 ) - ( 1 + 9 ) = 0
5 * 2 - ( 1 + 9 ) = 0
5 - ( 9 + 1 ) / 2 = 0
5 - ( 1 + 9 ) / 2 = 0
( 9 - 2 * 5 ) + 1 = 0
9 - ( 2 * 5 ) + 1 = 0
( 9 - 5 * 2 ) + 1 = 0
9 - ( 5 * 2 ) + 1 = 0
( 9 + 1 ) - ( 2 * 5 ) = 0
9 + ( 1 - 2 * 5 ) = 0
( 9 + 1 ) - 2 * 5 = 0
9 + 1 - ( 2 * 5 ) = 0
( 9 + 1 ) / 2 - 5 = 0
( 9 + 1 ) - ( 5 * 2 ) = 0
9 + ( 1 - 5 * 2 ) = 0
( 9 + 1 ) - 5 * 2 = 0
9 + 1 - ( 5 * 2 ) = 0
( 9 + 1 ) / 5 - 2 = 0
( 1 - 2 * 5 ) + 9 = 0
1 - ( 2 * 5 ) + 9 = 0
( 1 - 5 * 2 ) + 9 = 0
1 - ( 5 * 2 ) + 9 = 0
( 1 + 9 ) - ( 2 * 5 ) = 0
1 + ( 9 - 2 * 5 ) = 0
( 1 + 9 ) - 2 * 5 = 0
1 + 9 - ( 2 * 5 ) = 0
( 1 + 9 ) / 2 - 5 = 0
( 1 + 9 ) - ( 5 * 2 ) = 0
1 + ( 9 - 5 * 2 ) = 0
( 1 + 9 ) - 5 * 2 = 0
1 + 9 - ( 5 * 2 ) = 0
( 1 + 9 ) / 5 - 2 = 0
Write function count_Kprimes with given parameters k, start, nd, that returns a list of the k-primes between start (inclusive) and end (inclusive).
Here is my attempt:
def count_Kprimes(k, start, nd):
ls = []
for x in range(start, nd + 1):
y = x
l = []
for i in range(2, x + 1):
while y % i == 0:
l.append(i)
y /= i
if len(l) == k:
ls.append(x)
return ls
However, my code takes too much time to process and I want to simply my code. How can it be done? Thank you so much!
This task is taken from Codewar
Well, I had fun solving this anyway. Here is a solution based on array-logic
def count_Kprimes(k, start, nd):
x = np.arange(start, nd + 1, dtype=np.float)
# divs will contain all divisors (plus one extra column)
divs = np.ones((x.size, k + 1))
# we have to loop only nd / 2^(k-1) to get all divisors
for i in range(2, int(nd / 2 ** (k - 1)) + 1):
# but each possible divisor "i" may occur up to k times
# we loop until k+1 to catch also number that exceed our target,
# so we can discard them later
for j in range(1, k + 2):
# check for each row (dimension 0) if i is a divisor
# then set the first zero-value in dimension 1 to be this divisor
d = np.prod(divs, axis=1)
divs[[[np.rint(x/d/i)==x/d/i][0],np.argmin(divs[np.rint(x/d/i)==x/d/i], axis=1)]] = i
# The correct result we're looking for is each row that has exactly
# k values != 1 (which equals to exactly one "1" per row)
indices = np.apply_along_axis(lambda x: x[x==1].size == 1, 1, divs)
for val, d in zip(x[indices], divs[indices]):
print "{} = {}".format(int(val), " * ".join([str(int(_)) for _ in d[:-1]]))
count_Kprimes(3, 1, 100)
returns
8 = 2 * 2 * 2
12 = 2 * 2 * 3
18 = 2 * 3 * 3
20 = 2 * 2 * 5
27 = 3 * 3 * 3
28 = 2 * 2 * 7
30 = 2 * 3 * 5
42 = 2 * 3 * 7
44 = 2 * 2 * 11
45 = 3 * 3 * 5
50 = 2 * 5 * 5
52 = 2 * 2 * 13
63 = 3 * 3 * 7
66 = 2 * 3 * 11
68 = 2 * 2 * 17
70 = 2 * 5 * 7
75 = 3 * 5 * 5
76 = 2 * 2 * 19
78 = 2 * 3 * 13
92 = 2 * 2 * 23
98 = 2 * 7 * 7
99 = 3 * 3 * 11
Using the while loop, I wrote a procedure that takes as input a positive whole number, and prints out a multiplication table showing all the whole number multiplications up to and including the input number. The order in which the equations are printed matters.
for example, print_multiplication_table(2) gives:
1 * 1
1 * 2
2 * 1
2 * 2
This is my code:
def print_multiplication_table(n):
a = 1
b = 1
while a <= n:
while b <= n:
print str(a) + " * " + str(b)
b = b + 1
a = a + 1
However, this doesn't seem to work as it only print out
1 * 1
1 * 2
Does anyone know why? thanks!
You need to initialize counter for inner loop before its execution
def print_multiplication_table(n):
a = 1
b = 1 # won't do harm, but doesn't really need now
while a <= n:
b = 1 # <-- note
while b <= n:
print str(a) + " * " + str(b)
b = b + 1
a = a + 1
Consider using for in place of while:
def print_multiplication_table(n):
for a in range(1, n+1):
for b in range(1, n+1):
print str(a) + " * " + str(b)
which gives:
1 * 1
1 * 2
2 * 1
2 * 2
Using for will automatically keep track of your counter variables and avoid the type of error you encountered (this of course doesn't mean you can't make errors with for-loops, but it's easier to avoid the type of error you had)
Easier still with a Python comprehension:
>>> print '\n'.join('{} * {}'.format(a,b) for a in range(1,6) for b in range(1,6))
1 * 1
1 * 2
1 * 3
1 * 4
1 * 5
2 * 1
# etc...
Or, if you want the terminal new line:
>>> gen=('{} * {}'.format(a,b) for a in range(1,6) for b in range(1,6))
>>> print '\n'.join(gen),'\n'
I used a separate gen expression just to more clear about the print with the comma. This also works:
>>> print '\n'.join('{} * {}'.format(a,b) for a in range(1,6) for b in range(1,6)),'\n'
There is no reason to do an explicit call to str in your code. If you don't, you can still use a and b as integers:
>>> gen=('{} * {} = {:2}'.format(a,b,a*b) for a in range(1,3) for b in range(1,4))
>>> print '\n'.join(gen),'\n'
1 * 1 = 1
1 * 2 = 2
1 * 3 = 3
2 * 1 = 2
2 * 2 = 4
2 * 3 = 6