New to learning python and am having some trouble understanding a solution provided?
It has to do with Pascal Triangle and printing the rows when asking a user to "enter a row number"
There were bits of the solution provided and the rest I fit in (first for loop)..
n=int(input("Enter a row number: "))
a=[]
for i in range(n):
a.append([])
a[i].append(1)
for j in range(1,i):
a[i].append(a[i-1][j-1]+a[i-1][j])
if(n!=0):
a[i].append(1)
for i in range(n):
print(" "*(n-i),end=" ",sep=" ")
for j in range(0,i+1):
print('{:4}'.format(a[i][j]),end=" ")
print()
My question is which part of the code is printing the triangle structure? I assume the last for loop?
Also if I wanted to just print 1 row, what would I be changing?
EX: Input: 5 and output would be [1 4 6 4 1 ]
Thank you and any help/advice would be appreciated
You are right, the last loop is printing every row of the triangle. To print any specific row, jut run the second loop with specific value of i.
Before that, there is an easier way to more forward. Let's consider the output of below code:
n = 7
a = []
for i in range(n):
a.append([])
a[i].append(1)
for j in range(1, i):
a[i].append(a[i - 1][j - 1] + a[i - 1][j])
if (n != 0):
a[i].append(1)
print(a)
The output is:
[[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]]
From this 2d array, you can decide which single element you want to print. For example at index 4 you have [1, 4, 6, 4, 1]. From these values in the array a you can figure out which row to print.
Now for 5 if you want [1, 4, 6, 4, 1], you can simply do the following:
n = 7
a = []
for i in range(n):
a.append([])
a[i].append(1)
for j in range(1, i):
a[i].append(a[i - 1][j - 1] + a[i - 1][j])
if (n != 0):
a[i].append(1)
to_print = 5
for i in range(0, len(a[to_print-1])):
print(a[to_print-1][i], end=" ")
The output will be:
1 4 6 4 1
#riam_98, would you like to try this version: It's simplified the logic/flow to take advantage of Pascal key characteristics.
More reading can be found here - https://en.wikipedia.org/wiki/Pascal's_triangle
from typing import List
def getRow(index: int) -> List[int]:
row = [1] # firsts row
if index == 1: return row
for i in range(index-1):
for j in range(i, 0, -1):
row[j] = row[j] + row[j-1]
row.append(1)
return row
print(getRow(2))
print(getRow(3))
print(getRow(4))
print(getRow(5))
Outputs:
[1, 1]
[1, 2, 1]
[1, 3, 3, 1]
[1, 4, 6, 4, 1] # 5th
if I wanted to just print 1 row, what would I be changing?
I believe the answers given (and accepted) so far do too much work to obtain the values for an individual row. If we look at Calculating a row or diagonal by itself in the Wikipedia page that #DanielHao recommends, we can generate a simpler solution:
n = int(input("Enter a row number: "))
numbers = [1]
for k in range(1, n):
numbers.append(numbers[-1] * (n - k) // k)
print(numbers)
We don't need to generate the entire triangle up to the row we desire nor use nested loops to calculate it.
OUTPUT
> python3 test.py
Enter a row number: 5
[1, 4, 6, 4, 1]
> python3 test.py
Enter a row number: 10
[1, 9, 36, 84, 126, 126, 84, 36, 9, 1]
>
which part of the code is printing the triangle structure? I assume
the last for loop?
Yes, but note that it is a fragile, limited solution due to the hardcoding of the number width:
print('{:4}'.format(a[i][j]),end=" ")
For smaller values, the triangle is lopsided, and for values larger than 16, it loses all its symmetry. Here's an example of a Pascal's triangle output that self adjusts Compare it's output to the solution you're asking about.
Related
I have a matrix, G (size PxN), and I would like to make the first N/2 columns of G form the N/2×N/2 identity matrix by row operations. Any idea how I could write code for this? (not using sympy.rref).
Note P is a prime number slightly larger than N.
The matrix itself is a vandermonde matrix over the field of P i.e. all values are modulo P.
def ReedSolomon(k,p):
rr = np.arange(k).reshape((-1, 1))
cc = np.arange(p)
return cc**rr % p
An example would be:
ReedSolomon(4,5)
= [[1, 1, 1, 1, 1],
[0, 1, 2, 3, 4],
[0, 1, 4, 4, 1],
[0, 1, 3, 2, 4]]
And i would like to produce the following:
= [[1, 0, -1, -2, -3],
[0, 1, 2, 3, 4],
[0, 1, 4, 4, 1],
[0, 1, 3, 2, 4]]
In this case the N/2 x N/2 submatrix is the identity.
Using sympy.rref would lead to some rows being swapped around and for more rows to be reduced. I would like to stop once the N/2 columns have been turned into the identity. Hence writing custom code is preferred.
Thanks!
The following code works (adapted from: python built-in function to do matrix reduction)
def rref(V, tol = 1.0e-12):
m, n = V.shape
i, j = 0, 0
jb = []
while i < (n//2) and j < (n//2):
# Find value and index of largest element in the remainder of column j
k = np.argmax(np.abs(V[i:n, j])) + i
p = np.abs(V[k, j])
if p <= tol:
# The column is negligible, zero it out
V[i:n//2, j] = 0.0
j += 1
else:
# Remember the column index
jb.append(j)
if i != k:
# Do not swap the i-th and k-th rows
pass
# Divide the pivot row i by the pivot element A[i, j]
V[i, j:n] = V[i, j:n] / V[i, j]
# Subtract multiples of the pivot row from all the other rows
for k in range(n//2):
if k != i:
V[k, j:n] -= V[k, j] * V[i, j:n]
i += 1
j += 1
return V
The adaptations include removing any row switching capability and limiting to the first n//2 columns and rows.
If anybody knows a more efficient way please let me know. Thanks
I have written a program where I need to input a length and it returns the digits in the Fibonacci number sequence.
Write a program that given an input n, outputs the first n Fibonacci numbers. The format of the output is that at most 4 numbers can be displayed in a row.
My problem is, when i run the program the output shows [0, 1, 1, 2, 3, 5, 8, 13, 21, 34].
I need the solution to show 4 numbers per row ie
0 1 1 2
3 5 8 13
21 34
Please find attached my code.
def number(n):
if n ==1:
print(0)
else:
li = [0, 1]
for i in range(2, n): # start the loop from second index as 'li' is assigned for 0th and 1st index
li.append(li[-1] + li[-2])
i += 1
print(li)
n = int(input('Enter a positive number:'))
number(n)
Can you please explain how I can achieve the desired result?
The trouble is this line of code:
print(li)
which only prints out a big list.
Instead, split the list into groups of 4:
li = [li[i:i+4] for i in range(0, len(li), 4)]
Now you can print each element in this list, with a newline so that they are on different lines:
print(*li, sep="\n")
This "unpacks" the list into its elements (which are themselves lists of at most length 4), then prints them out, separating each element with a newline.
Putting it all together:
def number(n):
if n ==1:
print(0)
else:
li = [0, 1]
for i in range(2, n): # start the loop from second index as 'li' is assigned for 0th and 1st index
li.append(li[-1] + li[-2])
i += 1
li = [li[i:i+4] for i in range(0, len(li), 4)]
print(*li, sep="\n")
>>> number(10)
[0, 1, 1, 2]
[3, 5, 8, 13]
[21, 34]
I have written the following code and it runs but I am using 4 for loops and I would like to know if there is more effective way to write this code.
n = int(input('Please Enter the highest number \n'))
col = 2*n-1
for i in range(1, n+1):
for j in range(1, col+1):
if j >= i and j <= col-i+1:
print(n-i+1, end=' ')
elif j < i:
print(n+1-j, end=' ')
else:
print(j+1-n, end=' ')
print()
for i in range(n-1, 0, -1):
for j in range(1, col+1):
if j >= i and j <= col - i + 1:
print(n-i+1, end=' ')
elif j < i:
print(n + 1 - j, end=' ')
else:
print(j + 1 - n, end=' ')
print()
You could find the position relative to the center (di, dj), and then use its largest component as the label for that cell:
n = int(input('Please Enter the highest number \n'))
col = 2 * n
for i in range(1, col):
row = []
for j in range(1, col):
di, dj = abs(n-i), abs(n-j)
row.append(max(di,dj) + 1)
print(' '.join(str(x) for x in row))
Problem Definition
Breaking this down into a few logical obsevations.
We have a grid of numbers that appears symmetrical.
However, the middle row / middle column are only repeated once, this is
important.
Therefore it is more similar to looking down on a pyramid
from above, where 1 represents the highest point, and 4 / n the
lowest.
So we know that to follow DRY principle, we only need to generate one corner of the pyramid, and then we simply copy it to the other 3 corners.
Solution
(assuming use of pure python 3.x only, without libraries such as numpy)
def print_pyramid(n=4):
"""Print a symmetrical pyramid of numbers descending from n"""
# Calculate bottom half of grid
bottom = []
for j in range(n):
row = [max(i, j + 1) for i in range(1, n + 1)]
row = row[::-1][:-1] + row
bottom.append(row)
# Invert bottom to get top
rows = bottom[::-1][:-1] + bottom
# Print formatted
for row in rows:
row_str = [str(i) for i in row]
print(f"{' '.join(row_str)}")
print_pyramid(4)
This is definitely not the most efficient method (see recursive functions), but it is fairly quick and pythonic.
Explanation
Bottom Right corner
First we generate an array of numbers, 1 => n:
[i for i in range(1, n + 1)]
[1, 2, 3, 4]
Then we loop n times to generate this for each row (j), but replace any values lower than j using max:
for j in range(n):
row = [max(i, j+1) for i in range(1,n+1)]
[1, 2, 3, 4]
[2, 2, 3, 4]
[3, 3, 3, 4]
[4, 4, 4, 4]
Bottom Left Corner (~mirror image)
First we select the row elements in reverse with slice notation [::-1]
Then we remove the last element [:-1]
row = [max(i, j+1) for i in range(1,n+1)]
row[::-1][:-1]
[4, 3, 2]
[4, 3, 2]
[4, 3, 3]
[4, 4, 4]
Top Half
Now we create the top half using the same slicing technique to reverse and select from our existing nested array.
bottom[::-1][:-1]
[4, 4, 4, 4, 4, 4, 4]
[4, 3, 3, 3, 3, 3, 4]
[4, 3, 2, 2, 2, 3, 4]
Finally, we print our full array with string formatting
for row in rows:
row_str = [str(i) for i in row]
print(f"{' '.join(row_str)}")
4 4 4 4 4 4 4
4 3 3 3 3 3 4
4 3 2 2 2 3 4
4 3 2 1 2 3 4
4 3 2 2 2 3 4
4 3 3 3 3 3 4
4 4 4 4 4 4 4
P.S. Please don't cheat on your homework assignments ;)
Since the inner loops are identical, you could join the two outer loops into one, e.g. by chaining the two ranges:
from itertools import chain
...
for i in chain(range(1, n + 1), range(n - 1, 0, -1)):
...
The condition can be simplified like this:
i <= j <= col - i + 1
I am trying to find an algorithm to solve the following problem with python.
Given a list of integers, check if after dropping two elements of the list, is it possible to divide the list in 3 where the sum of the consecutive numbers are equals.
For example:
A = [1, 3, 4, 2, 2, 2, 1, 1, 2] should return TRUE because we would drop the elements in bold the list can be slit in [1, 3], [2, 2], [2, 1, 1] where all sum 4
B = [1, 1, 1, 1, 1, 1] should return FALSE
C = [1, 1, 3, 1, 1, 1034, 5, 9900, 1, 2] should also return FALSE because eventhough after droping the numbers in bold you can sum have the numbers to sum 5 (1,1,3), (5), (1, 1, 1, 2) the list should be sorted first and that's not allowed.
I have come with a solution that seems to work but it is very, very bad and not sure if always work, and the complexity is too high when should be O(n)
I don't know how to iterate removing 2 numbers from a list without having a complexity of O(n^2)
Thanks
It is indeed possible to solve this problem in O(n) (given that the integers are positive) where n is the size of your array A.
It can be surprising since the problem reminds of the bin packing, or subset sum problems, but the fact that we look for consecutive sum in the array makes the task much easier.
Here is a python code doing it:
def find_couple_list_sum(int_list):
n = len(int_list)
left_sum = [0 for _ in range(n)]
for i in range(1, n):
left_sum[i] = left_sum[i-1] + int_list[i-1]
right_sum = [0 for _ in range(n)]
for j in range(n-2, -1, -1):
right_sum[j] = right_sum[j+1] + int_list[j+1]
total_sum = sum(int_list)
print(left_sum)
print(right_sum)
print(total_sum)
i, j = 0, n-1
while True:
print(i, j)
mid_sum = total_sum - left_sum[i] - right_sum[j] - int_list[i] - int_list[j]
if left_sum[i] == right_sum[j] and left_sum[i] == mid_sum:
return i, j
elif i == j:
return None, None
elif left_sum[i] < right_sum[j]:
i += 1
else:
j -= 1
int_list = [1, 3, 4, 2, 2, 2, 1, 1, 2]
print(find_couple_list_sum(int_list))
The whole thing runs indeed in O(n).
Here two cells are considered adjacent if they share a boundary.
For example :
A = 5 6 4
2 1 3
7 9 8
Here adjacent elements to index 0,0 is at index [0,1] and [1,0] and for index 1,1 the adjacent elements are at index [0,1],[1,0],[2,1] and [1,2].
Supposed you have mxn matrix, and you want to find the adjacent indices of the cell (i, j):
def get_adjacent_indices(i, j, m, n):
adjacent_indices = []
if i > 0:
adjacent_indices.append((i-1,j))
if i+1 < m:
adjacent_indices.append((i+1,j))
if j > 0:
adjacent_indices.append((i,j-1))
if j+1 < n:
adjacent_indices.append((i,j+1))
return adjacent_indices
To also check for diagonals, regarding what Casper Dijkstrao asked, I usually write some code like this:
def adj_finder(matrix, position):
adj = []
for dx in range(-1, 2):
for dy in range(-1, 2):
rangeX = range(0, matrix.shape[0]) # X bounds
rangeY = range(0, matrix.shape[1]) # Y bounds
(newX, newY) = (position[0]+dx, position[1]+dy) # adjacent cell
if (newX in rangeX) and (newY in rangeY) and (dx, dy) != (0, 0):
adj.append((newX, newY))
return adj
The function gets the matrix argument to extract the size of its row and column (I use numpy, so matrix.shape returns (row_size, column_size) tuple).
It also gets the current cell as pointer argument (it's like (X,Y)).
Then It generate adjacent cells, and if they were legit (1. they were not out of the bound, and 2. not identical to reference position), it adds them to adjacent list, adj.
I'd like to emphasize that using the above algorithm, you can easily obtain neighbors in farther distances as well. Just modify the range in the for loops, like this:
for v in range(0-distance, 1+distance):
for h in range(0-distance, 1+distance):
...
Where distance is the maximum distance of adjacent you want to let in.
This will be another way - prob. involve some math tricks or regarded more concise (if you're more math-inclined) :
def neighbours(grid, r, c):
vals = sum((row[c -(c>0): c+2]
for row in grid[r -(r>0):r+2]), [])
vals.remove(grid[r][c]) # rm itself.
return vals
grid = [[1, 5, 4, 9],
[2, 8, 3, 8],
[6, 3, 6, 3],
[7, 4, 7, 1]]
Outputs: (all items are in order)
print(f' {neighbours(grid, 2, 2)} ') # [8, 3, 8, 3, 3, 4, 7, 1]
print(f' {neighbours(grid, 0, 0)} ') # [5, 2, 8]
print(f' {neighbours(grid, 1, 1)} ') # [[1, 5, 4, 2, 3, 6, 3, 6]