Pascal's triangle/Puzzle: Difference between revisions

Added zkl
(Added zkl)
Line 1,950:
16.0 24.0 17.0 12.0
5.0 11.0 13.0 4.0 8.0</pre>
 
=={{header|zkl}}==
{{trans|Python}}
<lang zkl># Pyramid solver
# [151]
# [ ] [ ]
# [ 40] [ ] [ ]
# [ ] [ ] [ ] [ ]
#[ X ] [ 11] [ Y ] [ 4 ] [ Z ]
# X - Y + Z + k = 0
p:=T( L(151), L(Void,Void), L(40,Void,Void), L(Void,Void,Void,Void),
L("X", 11, "Y", 4, "Z") );
addlConstraint := D( "X",1, "Y",-1, "Z",1, "1",0 );
solvePyramid(p, addlConstraint);</lang>
<lang zkl>fcn solvePyramid([List]vl,[D]cnstr){ //ListOfLists,Hash-->zip
vl=vl.reverse();
constraints:=L(cnstr);
lvls:=vl.len();
foreach lvln in ([1..lvls-1]){
lvd:=vl[lvln];
foreach k in (lvls-lvln){
sn:=lvd[k];
ll:=vl[lvln-1];
vn:=combine(ll[k], ll[k+1]);
if(Void==sn) lvd[k]=vn;
else constraints.append(constrainK(sn,vn));
}
}
println("Constraint Equations:");
constraints.pump(Console.println,fcn(hash){
hash.pump(List,fcn([(k,v)]){"%d*%s".fmt(v,k)}).concat(" + ") + " = 0"
});
mtx,vmap := makeMatrix(constraints);
mtxSolve(mtx);
d:=vmap.len();
foreach j in (d){ println(vmap[j]," = ", mtx[j][d]); }
}
 
fcn [mixin=D] constrainK([Int]nsum,[D]vn){ //-->new hash of old hash, sum K
nn:=vn.copy(); nn["1"]=nn.find("1",0) - nsum;
return(nn.makeReadOnly());
}
 
fcn combine(snl,snr){ //Int|String|Hash *2 --> new Hash
cl:=D();
if(snl.isInstanceOf(Int)) cl["1"] = snl;
else if(snl.isInstanceOf(String)) cl[snl] = 1;
else cl = snl.copy();
if(snr.isInstanceOf(Int)) cl["1"] = cl.find("1",0) + snr;
else if(snr.isInstanceOf(String)) cl[snr] = cl.find(snr,0) + 1;
else{ foreach k,v in (snr){ cl[k] = cl.find(k,0)+v; } }
return(cl.makeReadOnly())
}
//-->(listMatrix(row(X,Y,Z,c),row...),List("X","Y","Z"))
fcn makeMatrix([D]constraints){
vmap:=D(); // create a sorted list of the variable names in constraints
foreach c in (constraints){ vmap.extend(c) } // no duplicate names
vmap.del("1"); vmap=vmap.keys.sort(); # sort here so output is in sorted order
 
mtx:=constraints.pump(List,'wrap(c){ // create list of [writeable] rows
vmap.pump(List, c.find.fp1(0),"toFloat").copy()
.append(-c.find("1",0).toFloat())
}).copy();
 
nvars:=vmap.len();
if(constraints.len() == nvars) println("System appears solvable");
else if(constraints.len() < nvars)
println("System is not solvable - needs more constraints.");
return(mtx,vmap);
}
fcn mtxSolve([List]mtx){ //munge mtx # Simple Matrix solver...
mDim:=mtx.len(); # num rows
foreach j in (mDim){
rw0:=mtx[j];
f:=1.0/rw0[j];
foreach k in ([j..mDim]){ rw0[k]=rw0[k]*f }
foreach l in ([j+1..mDim-1]){
rwl:=mtx[l]; f:=-rwl[j];
foreach k in ([j..mDim]){ rwl[k]=rwl[k] + f * rw0[k] }
}
}
# backsolve part ---
foreach j1 in ([1..mDim-1]){
j:=mDim - j1; rw0:=mtx[j];
foreach l in (j){
rwl:=mtx[l]; f:=-rwl[j];
rwl[j]=rwl[j] + f * rw0[j];
rwl[mDim]=rwl[mDim] + f * rw0[mDim];
}
}
return(mtx);
}</lang>
{{out}}
<pre>
Constraint Equations:
0*1 + 1*X + -1*Y + 1*Z = 0
-18*1 + 1*X + 1*Y = 0
-73*1 + 5*Y + 1*Z = 0
System appears solvable
X = 5
Y = 13
Z = 8
</pre>
 
[[Category:Puzzles]]
Anonymous user