Task: Pascal's triangle_Puzzle




Go: package main

import "fmt"


type expr struct {
    x, y, z float64 
    c       float64 
}


func addExpr(a, b expr) expr {
    return expr{a.x + b.x, a.y + b.y, a.z + b.z, a.c + b.c}
}   
    

func subExpr(a, b expr) expr {
    return expr{a.x - b.x, a.y - b.y, a.z - b.z, a.c - b.c}
}   


func mulExpr(a expr, c float64) expr {
    return expr{a.x * c, a.y * c, a.z * c, a.c * c}
}



func addRow(l []expr) []expr {
    if len(l) == 0 {
        panic("wrong")
    }
    r := make([]expr, len(l)-1)
    for i := range r {
        r[i] = addExpr(l[i], l[i+1])
    }
    return r
}   



func substX(a, b expr) expr {
    if b.x == 0 {
        panic("wrong")
    }
    return subExpr(a, mulExpr(b, a.x/b.x))
}

func substY(a, b expr) expr {
    if b.y == 0 {
        panic("wrong")
    }
    return subExpr(a, mulExpr(b, a.y/b.y))
}

func substZ(a, b expr) expr {
    if b.z == 0 {
        panic("wrong")
    }
    return subExpr(a, mulExpr(b, a.z/b.z))
}


func solveX(a expr) float64 {
    if a.x == 0 || a.y != 0 || a.z != 0 {
        panic("wrong")
    }
    return -a.c / a.x
}

func solveY(a expr) float64 {
    if a.x != 0 || a.y == 0 || a.z != 0 {
        panic("wrong")
    }
    return -a.c / a.y
}

func solveZ(a expr) float64 {
    if a.x != 0 || a.y != 0 || a.z == 0 {
        panic("wrong")
    }
    return -a.c / a.z
}

func main() {
    
    r5 := []expr{{x: 1}, {c: 11}, {y: 1}, {c: 4}, {z: 1}}
    fmt.Println("bottom row:", r5)

    
    r4 := addRow(r5)
    fmt.Println("next row up:", r4)
    r3 := addRow(r4)
    fmt.Println("middle row:", r3)

    
    xyz := subExpr(expr{y: 1}, expr{x: 1, z: 1})
    fmt.Println("xyz relation:", xyz)
    
    r3[2] = substZ(r3[2], xyz)
    fmt.Println("middle row after substituting for z:", r3)

    
    b := expr{c: 40}
    
    xy := subExpr(r3[0], b)
    fmt.Println("xy relation:", xy)
    
    r3[0] = b

    
    r3[2] = substX(r3[2], xy)
    fmt.Println("middle row after substituting for x:", r3)
    
    
    r2 := addRow(r3)
    fmt.Println("next row up:", r2)
    r1 := addRow(r2)
    fmt.Println("top row:", r1)

    
    y := subExpr(r1[0], expr{c: 151})
    fmt.Println("y relation:", y)
    
    x := substY(xy, y)
    fmt.Println("x relation:", x)
    
    z := substX(substY(xyz, y), x)
    fmt.Println("z relation:", z)

    
    fmt.Println("x =", solveX(x))
    fmt.Println("y =", solveY(y))
    fmt.Println("z =", solveZ(z)) 
}




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)