Pascal's triangle/Puzzle: Difference between revisions

Content added Content deleted
(Go solution)
Line 575: Line 575:
(doseq [row rows]
(doseq [row rows]
(println (map #(dot [1 x z] %) row)))</lang>
(println (map #(dot [1 x z] %) row)))</lang>
=={{header|Go}}==
'''Preferred solution'''

The following solution is based on several observations on the task:

* The task does not ask for solutions to any generalization of the problem, only this one problem.
* The (twice) linked reference in the task description similarly does not describe any generalizations, but only this one problem.
* The talk page notes that intermediate work need not be coded, and indeed, a number of existing solutions do intermediate work.
* The entire problem is solvable with elementary algebra, thus a decision to actually code any part of the problem is arbitrary.
* Any part coded is not only done frivolously, but represents unnecessary chances for errors.
* Skills needed to develop this solution are prerequisite to any other solution. No other solution is easier.
* The task does not specify program output. This program provides the solution to the problem in a form that is clear to anyone wishing to further adapt the program to their needs.
<lang go>package main

func main() {
// bottom row given: [X] [11] [Y] [4] [Z]

// given sum relation of bricks,
// next row up: [x+11] [y+11] [y+4] [z+4]
// middle row: [x+y+22] [2y+15] [y+z+8]

// given brick=40 and relation y=x+z,
// middle row: [40] [2y+15] [3y-10]

// continuing sum relation of bricks,
// next row up: [2y+55] [5y+5]
// top brick: [7y+60]

// given top brick = 151,
// 7y = 91: y = 13
// x + y = 18: x = 5
// z = y - x: z = 8
}</lang>
'''Alternative solution'''

Showing a possible data representation of the problem, using the computer to do some arithmetic, and displaying intermediate and final results.
<lang go>package main

import "fmt"

// representation of an expression in x, y, and z
type expr struct {
x, y, z float64 // coefficients
c float64 // constant term
}

// add two expressions
func addExpr(a, b expr) expr {
return expr{a.x + b.x, a.y + b.y, a.z + b.z, a.c + b.c}
}
// subtract two expressions
func subExpr(a, b expr) expr {
return expr{a.x - b.x, a.y - b.y, a.z - b.z, a.c - b.c}
}

// multiply expression by a constant
func mulExpr(a expr, c float64) expr {
return expr{a.x * c, a.y * c, a.z * c, a.c * c}
}

// given a row of expressions, produce the next row up, by the given
// sum relation between blocks
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
}

// given expression b in a variable, and expression a,
// take b == 0 and substitute to remove that variable from a.
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))
}

// given an expression in a single variable, return value of that variable
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() {
// representation of given information for bottom row
r5 := []expr{{x: 1}, {c: 11}, {y: 1}, {c: 4}, {z: 1}}
fmt.Println("bottom row:", r5)

// given definition of brick sum relation
r4 := addRow(r5)
fmt.Println("next row up:", r4)
r3 := addRow(r4)
fmt.Println("middle row:", r3)

// given relation y = x + z
xyz := subExpr(expr{y: 1}, expr{x: 1, z: 1})
fmt.Println("xyz relation:", xyz)
// remove z from third cell using xyz relation
r3[2] = substZ(r3[2], xyz)
fmt.Println("middle row after substituting for z:", r3)

// given cell = 40,
b := expr{c: 40}
// this gives an xy relation
xy := subExpr(r3[0], b)
fmt.Println("xy relation:", xy)
// substitute 40 for cell
r3[0] = b

// remove x from third cell using xy relation
r3[2] = substX(r3[2], xy)
fmt.Println("middle row after substituting for x:", r3)
// continue applying brick sum relation to get top cell
r2 := addRow(r3)
fmt.Println("next row up:", r2)
r1 := addRow(r2)
fmt.Println("top row:", r1)

// given top cell = 151, we have an equation in y
y := subExpr(r1[0], expr{c: 151})
fmt.Println("y relation:", y)
// using xy relation, we get an equation in x
x := substY(xy, y)
fmt.Println("x relation:", x)
// using xyz relation, we get an equation in z
z := substX(substY(xyz, y), x)
fmt.Println("z relation:", z)

// show final answers
fmt.Println("x =", solveX(x))
fmt.Println("y =", solveY(y))
fmt.Println("z =", solveZ(z))
}</lang>
Output:
<pre>
bottom row: [{1 0 0 0} {0 0 0 11} {0 1 0 0} {0 0 0 4} {0 0 1 0}]
next row up: [{1 0 0 11} {0 1 0 11} {0 1 0 4} {0 0 1 4}]
middle row: [{1 1 0 22} {0 2 0 15} {0 1 1 8}]
xyz relation: {-1 1 -1 0}
middle row after substituting for z: [{1 1 0 22} {0 2 0 15} {-1 2 0 8}]
xy relation: {1 1 0 -18}
middle row after substituting for x: [{0 0 0 40} {0 2 0 15} {0 3 0 -10}]
next row up: [{0 2 0 55} {0 5 0 5}]
top row: [{0 7 0 60}]
y relation: {0 7 0 -91}
x relation: {1 0 0 -5}
z relation: {0 0 -1 8}
x = 5
y = 13
z = 8
</pre>


=={{header|Haskell}}==
=={{header|Haskell}}==