0

there is a pyramid, each brick weighs 1, the function takes the position of the brick, gives out how much pressure is on it from above

it's something like Pascal's triangle but I couldn't solve it

i tried to print the pyramid at least but failed

n_blocks = 0

for i in range (1, 11):
  print(n_blocks, f" _{n_blocks/i}_ "*i)
  
  n_blocks +=i

enter image description here

reny_smith
  • 83
  • 5
  • 1
    what do you mean you failed? what happened? – Anentropic Mar 09 '23 at 17:12
  • 3
    Before you try coding your loop, try to come up with the formula that you will use in the loop. Since you know the values for (3, 2) and (3, 3), how would you deduce the value for (4, 3)? Solve this problem by hand first, and once you have the formula, including the formula in code will be easy. – Stef Mar 09 '23 at 17:15

1 Answers1

1

This is similar to Pascal's triangle, but not quite. The weight on a brick is equal to half of (the weight on the two bricks above it plus the weight of those bricks themselves).

In other words, W(n, k) = (W(n-1, k-1) + W(n-1, k) + 2) / 2,

except for k == 0, we have W(n, 0) = (W(n-1, 0) + 1) / 2
and for k == n, we have W(n, n) = (W(n-1, n-1) + 1) / 2

So let's implement this:

def brick_triangle(n_layers):
    layers = [[0]]
    if n_layers == 1: return layers

    for n in range(1, n_layers):
        # Initialize this_layer with weight on first brick
        this_layer = [(layers[-1][0] + 1) / 2]
        # Append weight on other bricks in layer except the last one
        for k in range(1, n):
            w = (layers[-1][k-1] + layers[-1][k] + 2) / 2
            this_layer.append(w)

        # Append the weight on the last brick
        this_layer.append((layers[-1][-1] + 1) / 2)
        
        # Add this layer to all layers
        layers.append(this_layer)

    return layers

Printing this gives:

for layer in brick_triangle(5):
    print(*layer, sep="\t")
0
0.5     0.5
0.75    1.5     0.75
0.875   2.125   2.125   0.875
0.9375  2.5     3.125   2.5     0.9375

Note: I'm leaving the previous incorrect version of my answer here so you can compare the differences in the output.

You've correctly recognized that this is related to Pascal's triangle. The numbers in each layer of Pascal's triangle give you the proportion of weight that is carried by the bricks in that layer. The total weight carried by a layer is equal to the number of bricks above it, which for the nth layer is simply sum(range(1, n)) (where n is one-based)

Given this, and understanding that the element in the nth row and kth column of Pascal's triangle is easily calculated as nCk = n!/(k! * (n - k)!), we have:

import math

def brick_triangle(n_layers):
    layers = []
    for n in range(n_layers):
        weight_above = n * (n + 1) / 2 # sum(range(1, n))
        brick_proportions = [math.comb(n, k) for k in range(n+1)]
        s = sum(brick_proportions)
        brick_weights = [weight_above * b / s for b in brick_proportions]
        layers.append(brick_weights)

    return layers

Note: I used math.comb to calculate nCk, but that's only available in Python 3.8+. If you have Python <3.8, see counting combinations and permutations efficiently

Now, we can call this function for n layers and print the results:

for layer in brick_triangle(5):
    print(*layer, sep="\t")

which gives the result:

0.0
0.5     0.5
0.75    1.5     0.75
0.75    2.25    2.25    0.75
0.625   2.5     3.75    2.5     0.625
Pranav Hosangadi
  • 23,755
  • 7
  • 44
  • 70