Pascal's triangle/Puzzle: Difference between revisions

Updated to work with Nim 1.4. Many changes to make code more idiomatic, especially regarding identifier case and indentation. Avoided float division. Some simplifications.t
(Added XPL0 example.)
(Updated to work with Nim 1.4. Many changes to make code more idiomatic, especially regarding identifier case and indentation. Avoided float division. Some simplifications.t)
Line 1,717:
 
=={{header|Nim}}==
{{trans|Ada}}
Translation of Ada solution:
<lang nim>import math, strutils
var B_X, B_Y, B_Z : int = 0
type
Block_Value = object
Known : int
X, Y, Z : int
 
type
let
X: Block_Value = Block_Value(Known:0, X:1, Y:0, Z:0)
Y: Block_Value = Block_Value(Known:0, X:0, Y:1, Z:0)
Z: Block_Value = Block_Value(Known:0, X:0, Y:0, Z:1)
proc Add (L : var Block_Value, R : Block_Value) =
# Symbolically adds one block to another
L.Known = L.Known + R.Known
L.X = L.X + R.X - R.Z # Z is excluded as n(Y - X - Z) = 0
L.Y = L.Y + R.Y + R.Z
 
BlockValue = object
proc Add (L: var Block_Value, R: int) =
known: int
# Symbolically adds a value to the block
L.Known =x, L.Knowny, +z: Rint
proc Image (N : Block_Value): string =
# The block value, when X,Y,Z are known
result = $(N.Known + N.X * B_X + N.Y * B_Y + N.Z * B_Z)
proc Solve_2x2 (A11: int, A12:int, B1:int, A21:int, A22:int, B2: int) =
# Don't care about things, supposing an integer solution exists
if A22 == 0:
B_X = toInt(B2 / A21)
B_Y = toInt((B1 - (A11*B_X)) / A12)
else:
B_X = toInt((B1*A22 - B2*A12) / (A11*A22 - A21*A12))
B_Y = toInt((B1 - A11*B_X) / A12)
B_Z = B_Y - B_X
var B : array [1..5, array[1..5, Block_Value]] # The lower triangle contains blocks
 
Variables = tuple[x, y, z: int]
# The bottom blocks
 
Add(B[5][1],X)
func `+=`(left: var BlockValue; right: BlockValue) =
Add(B[5][2],11)
## Symbolically add one block to another.
Add(B[5][3],Y)
left.known += right.known
Add(B[5][4],4)
left.x += right.x - right.z # Z is excluded as n(Y - X - Z) = 0.
Add(B[5][5],Z)
left.y += right.y + right.z
 
# Upward run
proc toString(n: BlockValue; vars: Variables): string =
for Row in countdown(4,1):
## Return the representation of the block value, when X, Y, Z are known.
for Column in 1 .. Row:
result = $(n.known + n.x * vars.x + n.y * vars.y + n.z * vars.z)
Add (B[Row][Column], B[Row + 1][Column])
 
Add (B[Row][Column], B[Row + 1][Column + 1])
proc Solve2x2(a11, a12, b1, a21, a22, b2: int): Variables =
## Solve a puzzle, supposing an integer solution exists.
# Now have known blocks 40=[3][1], 151=[1][1] and Y=X+Z to determine X,Y,Z
if a22 == 0:
Solve_2x2( B[1][1].X,
result.x = b2 div B[1][1].Y, a21
result.y = (b1 - a11 * result.x) div a12
151 - B[1][1].Known,
else:
B[3][1].X,
result.x = (b1 * a22 - b2 B[3][1].Y,* a12) div (a11 * a22 - a21 * a12)
result.y = (b1 - a11 * 40 - B[3][1]result.Knownx) div a12
result.z = result.y - result.x
 
#Print the results
var blocks : array[1..5, array[1..5, BlockValue]] # The lower triangle contains blocks.
for Row in 1..5:
 
writeln(stdout,"")
# The bottom blocks.
for Column in 1..Row:
blocks[5][1] = BlockValue(x: 1)
write(stdout, Image(B[Row][Column]), " ")</lang>
blocks[5][2] = BlockValue(known: 11)
blocks[5][3] = BlockValue(y: 1)
blocks[5][4] = BlockValue(known: 4)
blocks[5][5] = BlockValue(z: 1)
 
# Upward run.
for row in countdown(4, 1):
for column in 1..row:
blocks[row][column] += blocks[row + 1][column]
blocks[row][column] += blocks[row + 1][column + 1]
 
# Now have known blocks 40=[3][1], 151=[1][1] and Y=X+Z to determine X,Y,Z.
let vars = Solve2x2(blocks[1][1].x,
blocks[1][1].y,
151 - blocks[1][1].known,
blocks[3][1].x,
blocks[3][1].y,
40 - blocks[3][1].known)
 
# Print the results.
for row in 1..5:
var line = ""
for column in 1..row:
line.addSep(" ")
line.add toString(blocks[row][column], vars)
echo line</lang>
{{out}}
<pre>151
81 70
40 41 29
16 24 17 12
5 11 13 4 8</pre>
 
Anonymous user