This puzzle involves a Pascals Triangle, also known as a Pyramid of Numbers.

           [ 151]
          [  ][  ]
        [40][  ][  ]
      [  ][  ][  ][  ]
    [ X][11][ Y][ 4][ Z]

Each brick of the pyramid is the sum of the two bricks situated below it.

Of the three missing numbers at the base of the pyramid,
the middle one is the sum of the other two (that is, Y = X + Z).



Task

Write a program to find a solution to this puzzle.




--
-- demo\rosetta\Pascal_triangle_Puzzle.exw
-- =======================================
--
-- I approached this with a view to solving general pyramid puzzles, not just the one given.
--
-- This little ditty converts the pyramid to rules quite nicely, then uses a modified copy
--  of solveN() from Solving_coin_problems#Phix to solve those simultaneous equations.
--
with javascript_semantics
 
sequence pyramid = {{151},
                   {"",""},
                  {40,"",""},
                 {"","","",""},
               {"x",11,"y",4,"z"}}
 
sequence rules = {}
 
-- each cell in the pyramid is either an integer final value or an equation.
-- initially the equations are strings, we substitute all with triplets of
-- the form {k,x,z} ie k+l*x+m*z, and known values < last row become rules.
 
for r=5 to 1 by -1 do
    for c=1 to length(pyramid[r]) do
        object prc = pyramid[r][c], equ
        if    prc="x" then  prc = {0,1,0}     -- ie 0 + one x
        elsif prc="y" then  prc = {0,1,1}     -- ie 0 + one x plus one z
        elsif prc="z" then  prc = {0,0,1}     -- ie 0 +            one z
        else
            if prc="" or r<=4 then
                -- examples: x+11 is {0,1,0}+{11,0,0} -> {11,1,0},
                --           11+y is {11,0,0}+{0,1,1} -> {11,1,1},
                --       40=""+"" is {40,0,0}={22,2,1} ==> {18,2,1}
                equ = sq_add(pyramid[r+1][c],pyramid[r+1][c+1])
            end if
            if prc="" then  prc = equ
            else            prc = {prc,0,0}
                            if r<=4 then
                                equ[1] = prc[1]-equ[1]
                                rules = append(rules,equ)
                            end if
            end if
        end if
        pyramid[r][c] = prc             
    end for
end for
 
ppOpt({pp_Nest,1,pp_StrFmt,2,pp_IntCh,false})
?"equations"
pp(pyramid)
?"rules"
pp(rules)   -- {18,2,1} === 18=2x+z
            -- {73,5,6} === 73=5x+6z
puts(1,"=====\n")
 
assert(length(rules)==2)    -- more work needed!?
 
-- modified copy of solveN() from Solving_coin_problems.exw as promised, a
-- bit of a sledgehammer to crack a peanut is the phrase you are looking for:
function solveN(sequence rules)
--
-- Based on https://mathcs.clarku.edu/~djoyce/ma105/simultaneous.html
--  aka the ancient Chinese Jiuzhang suanshu ~100 B.C. (!!)
--
-- Example (not related to the task problem):
--  rules = {{18,1,1},{38,1,5}}, ie 18==x+y, 38==x+5y
--  ==> {13,5}, ie x=13, y=5
--
--  In the elimination phase, both x have multipliers of 1, ie both rii and rij are 1,
--  so we can ignore the two sq_mul and just do [sq_sub] (38=x+5y)-(18=x+y)==>(20=4y).
--  Obviously therefore y is 5 and substituting backwards x is 13.
--
-- Example2 (taken from the task problem):
--  rules = {{18,2,1},{73,5,6}}, ie 18==2x+z, 73==5x+6z
--      ==> {{18,2,1},{56,0,7}}, ie rules[2]:=rules[2]*2-rules[1]*5     (eliminate)
--      ==> {{18,2,1},8},        ie rules[2]:=56/7, aka z:=8            (substitute)
--      ==> {{10,2,0},8},        ie rules[1]-=1z                        (substitute)
--      ==> {5,8},               ie rules[1]:=10/2, aka x:=5            (substitute)
--  ==> {5,8}, ie x=5, z=8
-- 
    sequence ri, rj
    integer l = length(rules), rii, rji
    rules = deep_copy(rules)
    for i=1 to l do
        -- successively eliminate (grow lower left triangle of 0s)
        ri = rules[i]
        assert(length(ri)=l+1)
        rii = ri[i+1]
        assert(rii!=0)  -- (see note below)
        for j=i+1 to l do
            rj = rules[j]
            rji = rj[i+1]
            if rji!=0 then
                rj = sq_sub(sq_mul(rj,rii),sq_mul(ri,rji))
                assert(rj[i+1]==0) -- (job done)
                rules[j] = rj
            end if
        end for 
    end for 
    for i=l to 1 by -1 do
        -- then substitute each backwards
        ri = rules[i]
        rii = ri[1]/ri[i+1] -- (all else should be 0)
        rules[i] = rii
        for j=i-1 to 1 by -1 do
            rj = rules[j]
            rji = rj[i+1]
            if rji!=0 then
                rules[j] = 0
                rj[1] -= rji*rii
                rj[i+1] = 0
                rules[j] = rj
            end if
        end for
    end for 
    return rules
end function

-- Obviously these next two lines directly embody knowledge from the task, and
--  would need changing for an even slightly different version of the problem:
integer {x,z} = solveN(rules),
        y = x+z -- (as per task desc)
 
printf(1,"x=%d, y=%d, z=%d\n",{x,y,z})
 
-- finally evaluate all the equations and print it.
for r=1 to length(pyramid) do
    for c=1 to length(pyramid[r]) do
        integer {k, l, m} = pyramid[r][c]
        pyramid[r][c] = k+l*x+m*z
    end for
end for
 
pp(pyramid)
