Task: Pascal's triangle_Puzzle







Python: 







def combine( snl, snr ):

	cl = {}
	if isinstance(snl, int):
		cl['1'] = snl
	elif isinstance(snl, string):
		cl[snl] = 1
	else:
		cl.update( snl)

	if isinstance(snr, int):
		n = cl.get('1', 0)
		cl['1'] = n + snr
	elif isinstance(snr, string):
		n = cl.get(snr, 0)
		cl[snr] = n + 1
	else:
		for k,v in snr.items():
			n = cl.get(k, 0)
			cl[k] = n+v
	return cl


def constrain(nsum, vn ):
	nn = {}
	nn.update(vn)
	n = nn.get('1', 0)
	nn['1'] = n - nsum
	return nn

def makeMatrix( constraints ):
	vmap = set()
	for c in constraints:
		vmap.update( c.keys())
	vmap.remove('1')
	nvars = len(vmap)
	vmap = sorted(vmap)		
	mtx = []
	for c in constraints:
		row = []
		for vv in vmap:
			row.append(float(c.get(vv, 0)))
		row.append(-float(c.get('1',0)))
		mtx.append(row)
	
	if len(constraints) == nvars:
		print 'System appears solvable'
	elif len(constraints) < nvars:
		print 'System is not solvable - needs more constraints.'
	return mtx, vmap


def SolvePyramid( vl, cnstr ):

	vl.reverse()
	constraints = [cnstr]
	lvls = len(vl)
	for lvln in range(1,lvls):
		lvd = vl[lvln]
		for k in range(lvls - lvln):
			sn = lvd[k]
			ll = vl[lvln-1]
			vn = combine(ll[k], ll[k+1])
			if sn is None:
				lvd[k] = vn
			else:
				constraints.append(constrain( sn, vn ))

	print 'Constraint Equations:'
	for cstr in constraints:
		fset = ('%d*%s'%(v,k) for k,v in cstr.items() )
		print ' + '.join(fset), ' = 0'

	mtx,vmap = makeMatrix(constraints)

	MtxSolve(mtx)

	d = len(vmap)
	for j in range(d):
		print vmap[j],'=', mtx[j][d]


def MtxSolve(mtx):
	

	mDim = len(mtx)			
	for j in range(mDim):
		rw0= mtx[j]
		f = 1.0/rw0[j]
		for k in range(j, mDim+1):
			rw0[k] *= f
		
		for l in range(1+j,mDim):
			rwl = mtx[l]
			f = -rwl[j]
			for k in range(j, mDim+1):
				rwl[k] += f * rw0[k]

	
	for j1 in range(1,mDim):
		j = mDim - j1
		rw0= mtx[j]
		for l in range(0, j):
			rwl = mtx[l]
			f = -rwl[j]
			rwl[j]    += f * rw0[j]
			rwl[mDim] += f * rw0[mDim]

	return mtx


p = [ [151], [None,None], [40,None,None], [None,None,None,None], ['X', 11, 'Y', 4, 'Z'] ]
addlConstraint = { 'X':1, 'Y':-1, 'Z':1, '1':0 }
SolvePyramid( p, addlConstraint)





Ada: with Ada.Text_IO; use Ada.Text_IO;
 
procedure Pyramid_of_Numbers is

   B_X, B_Y, B_Z : Integer := 0; 

   type Block_Value is record
      Known   : Integer := 0;
      X, Y, Z : Integer := 0;
   end record;
   X : constant Block_Value := (0, 1, 0, 0);
   Y : constant Block_Value := (0, 0, 1, 0);
   Z : constant Block_Value := (0, 0, 0, 1);
   procedure Add (L : in out Block_Value; R : Block_Value) is
   begin 
      L.Known := L.Known + R.Known;
      L.X := L.X + R.X - R.Z; 
      L.Y := L.Y + R.Y + R.Z;
   end Add;
   procedure Add (L : in out Block_Value; R : Integer) is
   begin 
      L.Known := L.Known + R;
   end Add;
   
   function Image (N : Block_Value) return String is
   begin 
      return Integer'Image (N.Known + N.X * B_X + N.Y * B_Y + N.Z * B_Z);
   end Image;

   procedure Solve_2x2 (A11, A12, B1, A21, A22, B2 : Integer) is
   begin 
      if A22 = 0 then
         B_X := B2 / A21;
         B_Y := (B1 - A11*B_X) / A12;
      else
         B_X := (B1*A22 - B2*A12) / (A11*A22 - A21*A12);
         B_Y := (B1 - A11*B_X) / A12;
      end if;
      B_Z := B_Y - B_X;
   end Solve_2x2;
   
   B : array (1..5, 1..5) of Block_Value; 

begin
   
   Add (B(5,1),X); Add (B(5,2),11); Add (B(5,3),Y); Add (B(5,4),4); Add (B(5,5),Z);

   
   for Row in reverse 1..4 loop
      for Column in 1..Row loop
         Add (B (Row, Column), B (Row + 1, Column));
         Add (B (Row, Column), B (Row + 1, Column + 1));
      end loop;
   end loop;
   
   
   Solve_2x2
   (  B(1,1).X, B(1,1).Y, 151 - B(1,1).Known,
      B(3,1).X, B(3,1).Y,  40 - B(3,1).Known
   );

   
   for Row in 1..5 loop
      New_Line;
      for Column in 1..Row loop
         Put (Image (B(Row,Column)));
      end loop;
   end loop;
end Pyramid_of_Numbers;