Substitution trace python code - python

I'm trying to do a substitution trace for this code:
def hanoi(n):
if n == 1:
return 1
else:
return 2 * hanoi(n - 1) + 1
print hanoi(4)
Output:
15
This is what I did:
2 * (4 - 1) + 1
2 * (3) + 1
6 + 1
7
I'm not sure what I'm doing wrong.

You have a recursion function and after each step it converted to sub functions with n-1 :
Actually you have this :
2 * hanoi(4 - 1) + 1
2 * hanoi(3) + 1
2 * (2 * hanoi(2) + 1) + 1
2 * (2 * (2 * hanoi(1) + 1) + 1) + 1
2 * (2 * (2 * 1 + 1) + 1) + 1 = 15

2 * hanoi(4-1) + 1 is not the same as 2 * (4-1) + 1

Related

I am .5 off when trying to figure this out

x = 1 / 2 + 3 // 3 + 4 ** 2 # Why is this equivalent to 17?
y = 1 / 2 + 3 # This is equivalent to 3.5
z = 1 / 2 + 3 // 3 # This should be equivalent to 3.5 // 3
t = 3.5 // 3 + 4 ** 2 # Why is this 17 but the original statement is 17.5?
Why are the expressions for t and x providing different results? Are they not equivalent?
(Original image)
It's 17.5 because your statement is as follows:
1/2 - this is evaluated to 0.5
3 // 3 - this is evaluated to 1
4 ** 2 - this is evaluated to 16
16 + 1 + 0.5 = 17.5
You need to understand the order of operations in your initial statement:
1 / 2 + 3 // 3 + 4 ** 2
This can be bracketed according to standard order of operations (BODMAS or some variant):
(1 / 2) + (3 // 3) + (4 ** 2)
Which then evaluates as above. Your confusion stems from the fact that 1 / 2 + 3 // 3 is not equivalent to (1/2 + 3) // 3, but instead equivalent to (1/2) + (3 // 3) - they're both division, so they'll both take precedence over the addition operator.

Solve equations with combinations and for loops

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)).

Get zeros with car plates

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

Finding the number of k-primes within a range

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

How to make triangle x in python from source code below

Hello I want to ask everybody...
Like this...
I want to make a triangle X or *, like below:
*
***
*****
*******
*********
My Algorithm is like this:
for y:=1 to i do
for x:=1 to j do
for j-x to 1 do write(' ');
for i to 2*(x-1)+1 do write('*');
Can anybody tell me how is the source code for python like pascal in above?
Thanks for your answer
You can simply do this like that:
def triangle(lines):
for i in range(lines):
print(' '*(lines-i) + '*'*(i*2+1))
triangle(5)
Output as expected
*
***
*****
*******
*********
I have some code to do that lying around here, maybe this can help you :)
def pascals_triangle(order):
"""
:brief: Compute the line of pascal's triangle with order 'order'
| line | order |
|---------------------|-------|
| 1 | 0 |
| 1 1 | 1 |
| 1 2 1 | 2 |
| 1 3 3 1 | 3 |
| 1 4 6 4 1 | 4 |
:param order: order of the line in pascal's triangle
(starting with 0, which returns just [1])
:return: a list of the pascal's triangle line of order 'order'
"""
line = [1]
for k in xrange(order):
line.append(line[k] * (order - k) / (k + 1))
return line
Here's a possible solution:
def print_pascals_triangle(levels, debug_char=None):
triangle = []
for order in range(levels):
line = [debug_char] if debug_char is not None else [1]
for k in range(order):
if debug_char is None:
value = line[k] * (order - k) / (k + 1)
line.append(value)
else:
line.append(debug_char)
triangle.append(line)
def format_row(row):
return ' '.join(map(str, row))
triangle_width = len(format_row(triangle[-1]))
for row in triangle:
print(format_row(row).center(triangle_width))
If you want the real pascal triangle you can use it like this:
for level in range(1, 8):
print_pascals_triangle(level)
print('-' * 80)
And you'll get:
1
--------------------------------------------------------------------------------
1
1 1
--------------------------------------------------------------------------------
1
1 1
1 2 1
--------------------------------------------------------------------------------
1
1 1
1 2 1
1 3 3 1
--------------------------------------------------------------------------------
1
1 1
1 2 1
1 3 3 1
1 4 6 4 1
--------------------------------------------------------------------------------
1
1 1
1 2 1
1 3 3 1
1 4 6 4 1
1 5 10 10 5 1
--------------------------------------------------------------------------------
1
1 1
1 2 1
1 3 3 1
1 4 6 4 1
1 5 10 10 5 1
1 6 15 20 15 6 1
--------------------------------------------------------------------------------
Otherwise, you can fake the numbers with another character, like this:
for level in range(1, 8):
print_pascals_triangle(level, debug_char='*')
print('-' * 80)
And you'll get this:
*
--------------------------------------------------------------------------------
*
* *
--------------------------------------------------------------------------------
*
* *
* * *
--------------------------------------------------------------------------------
*
* *
* * *
* * * *
--------------------------------------------------------------------------------
*
* *
* * *
* * * *
* * * * *
--------------------------------------------------------------------------------
*
* *
* * *
* * * *
* * * * *
* * * * * *
--------------------------------------------------------------------------------
*
* *
* * *
* * * *
* * * * *
* * * * * *
* * * * * * *
--------------------------------------------------------------------------------

Categories

Resources