Just another update

This commit is contained in:
Ingy döt Net 2015-02-20 00:35:01 -05:00
parent a25938f123
commit 00a190b0a6
6591 changed files with 94363 additions and 23227 deletions

View file

@ -7,6 +7,7 @@ This puzzle involves a [http://xunor.free.fr/en/riddles/auto/pyramidnb.php Pasca
[ X][11][ Y][ 4][ Z]
</pre>
Each brick of the pyramid is the sum of the two bricks situated below it.<br>
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).
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).
Write a program to find a solution to this puzzle.

View file

@ -0,0 +1,25 @@
import CLPFD
import Constraint (allC, andC)
import Findall (findall)
import List (init, last)
solve :: [[Int]] -> Success
solve body@([n]:rest) =
domain (concat body) 1 n
& andC (zipWith atop body rest)
& labeling [] (concat body)
where
xs `atop` ys = andC $ zipWith3 tri xs (init ys) (tail ys)
tri :: Int -> Int -> Int -> Success
tri x y z = x =# y +# z
test (x,y,z) | tri y x z =
[ [151]
, [ _, _]
, [40, _, _]
, [ _, _, _, _]
, [ x, 11, y, 4, z]
]
main = findall $ solve . test

View file

@ -1,45 +1,38 @@
import std.stdio, std.algorithm;
void iterate(bool doPrint=true)(double[] v, double[] diff)
/*pure nothrow*/ {
void iterate(bool doPrint=true)(double[] v, double[] diff) @safe {
static ref T E(T)(T[] x, in size_t row, in size_t col)
pure nothrow {
pure nothrow @safe @nogc {
return x[row * (row + 1) / 2 + col];
}
double tot = 0.0;
do {
// enforce boundary conditions
// Enforce boundary conditions.
E(v, 0, 0) = 151;
E(v, 2, 0) = 40;
E(v, 4, 1) = 11;
E(v, 4, 3) = 4;
// calculate difference from equilibrium
// Calculate difference from equilibrium.
foreach (immutable i; 1 .. 5) {
foreach (immutable j; 0 .. i + 1) {
E(diff, i, j) = 0;
if (j < i)
E(diff, i, j) += E(v, i - 1, j) -
E(v, i, j + 1) -
E(v, i, j);
E(diff, i, j) += E(v, i - 1, j) - E(v, i, j + 1) - E(v, i, j);
if (j)
E(diff, i, j) += E(v, i - 1, j - 1) -
E(v, i, j - 1) -
E(v, i, j);
E(diff, i, j) += E(v, i - 1, j - 1) - E(v, i, j - 1) - E(v, i, j);
}
}
foreach (immutable i; 1 .. 4)
foreach (immutable j; 0 .. i)
E(diff, i, j) += E(v, i + 1, j) +
E(v, i + 1, j + 1) -
E(v, i, j);
E(diff, i, j) += E(v, i + 1, j) + E(v, i + 1, j + 1) - E(v, i, j);
E(diff, 4, 2) += E(v, 4, 0) + E(v, 4, 4) - E(v, 4, 2);
// do feedback, check if we are close enough
// 4: scale down the feedback to avoid oscillations
// Do feedback, check if we are close enough.
// 4: scale down the feedback to avoid oscillations.
v[] += diff[] / 4;
tot = diff.map!q{ a ^^ 2 }.sum;
@ -53,18 +46,16 @@ void iterate(bool doPrint=true)(double[] v, double[] diff)
}
void main() {
static void show(in double[] x) nothrow {
static void show(in double[] x) nothrow @nogc {
int idx;
foreach (immutable i; 0 .. 5)
foreach (immutable j; 0 .. i+1) {
printf("%4d%c", cast(int)(0.5 + x[idx]),
j < i ? ' ' : '\n');
printf("%4d%c", cast(int)(0.5 + x[idx]), j < i ? ' ' : '\n');
idx++;
}
}
double[15] v = 0.0;
double[15] diff = 0.0;
double[15] v = 0.0, diff = 0.0;
iterate(v, diff);
show(v);
}

View file

@ -7,7 +7,8 @@ pyramid = [
[nil,nil,nil,nil],
["x", 11,"y", 4,"z"]
]
p pyramid
pyramid.each{|row| p row}
equations = [[1,-1,1,0]] # y = x + z
def parse_equation(str)
@ -16,10 +17,10 @@ def parse_equation(str)
eqn[3] = rhs.to_i
for term in lhs.split("+")
case term
when "x": eqn[0] += 1
when "y": eqn[1] += 1
when "z": eqn[2] += 1
else eqn[3] -= term.to_i
when "x" then eqn[0] += 1
when "y" then eqn[1] += 1
when "z" then eqn[2] += 1
else eqn[3] -= term.to_i
end
end
eqn
@ -28,7 +29,7 @@ end
-2.downto(-5) do |row|
pyramid[row].each_index do |col|
val = pyramid[row][col]
sum = "%s+%s" % [pyramid[row+1][col].to_s, pyramid[row+1][col+1].to_s]
sum = "%s+%s" % [pyramid[row+1][col], pyramid[row+1][col+1]]
if val.nil?
pyramid[row][col] = sum
else
@ -42,12 +43,13 @@ reduced = convert_to(reduced_row_echelon_form(equations), :to_i)
for eqn in reduced
if eqn[0] + eqn[1] + eqn[2] != 1
fail "no unique solution! #{equations.inspect} ==> #{reduced.inspect}"
elsif eqn[0] == 1: x = eqn[3]
elsif eqn[1] == 1: y = eqn[3]
elsif eqn[2] == 1: z = eqn[3]
elsif eqn[0] == 1 then x = eqn[3]
elsif eqn[1] == 1 then y = eqn[3]
elsif eqn[2] == 1 then z = eqn[3]
end
end
puts
puts "x == #{x}"
puts "y == #{y}"
puts "z == #{z}"
@ -56,4 +58,5 @@ answer = []
for row in pyramid
answer << row.collect {|cell| eval cell.to_s}
end
p answer
puts
answer.each{|row| p row}