Update all new Tasks

This commit is contained in:
Ingy döt Net 2015-02-20 09:02:09 -05:00
parent 00a190b0a6
commit 91df62d461
5697 changed files with 93386 additions and 804 deletions

View file

@ -0,0 +1,35 @@
Starting from the top of a pyramid of numbers like this, you can walk down going one step on the right or on the left, until you reach the bottom row:
<pre>
55
94 48
95 30 96
77 71 26 67</pre>
One of such walks is 55 - 94 - 30 - 26. You can compute the total of the numbers you have seen in such walk, in this case it's 205.
Your problem is to find the maximum total among all possible paths from the top to the bottom row of the triangle. In the little example above it's 321.
'''Task:''' find the maximum total in the triangle below:
<pre>
55
94 48
95 30 96
77 71 26 67
97 13 76 38 45
07 36 79 16 37 68
48 07 09 18 70 26 06
18 72 79 46 59 79 29 90
20 76 87 11 32 07 07 49 18
27 83 58 35 71 11 25 57 29 85
14 64 36 96 27 11 58 56 92 18 55
02 90 03 60 48 49 41 46 33 36 47 23
92 50 48 02 36 59 42 79 72 20 82 77 42
56 78 38 80 39 75 02 71 66 66 01 03 55 72
44 25 67 84 71 67 11 61 40 57 58 89 40 56 36
85 32 25 85 57 48 84 35 47 62 17 01 01 99 89 52
06 71 28 75 94 48 37 10 23 51 06 48 53 18 74 98 15
27 02 92 23 08 71 76 84 15 52 92 63 81 10 44 10 69 93</pre>
Such numbers can be included in the solution code, or read from a "triangle.txt" file.
This task is derived from the [http://projecteuler.net/problem=18 Euler Problem #18].

View file

@ -0,0 +1,46 @@
# create a triangular array of the required values #
[ 1]INT row 1 := ( 55 );
[ 2]INT row 2 := ( 94, 48 );
[ 3]INT row 3 := ( 95, 30, 96 );
[ 4]INT row 4 := ( 77, 71, 26, 67 );
[ 5]INT row 5 := ( 97, 13, 76, 38, 45 );
[ 6]INT row 6 := ( 07, 36, 79, 16, 37, 68 );
[ 7]INT row 7 := ( 48, 07, 09, 18, 70, 26, 06 );
[ 8]INT row 8 := ( 18, 72, 79, 46, 59, 79, 29, 90 );
[ 9]INT row 9 := ( 20, 76, 87, 11, 32, 07, 07, 49, 18 );
[10]INT row 10 := ( 27, 83, 58, 35, 71, 11, 25, 57, 29, 85 );
[11]INT row 11 := ( 14, 64, 36, 96, 27, 11, 58, 56, 92, 18, 55 );
[12]INT row 12 := ( 02, 90, 03, 60, 48, 49, 41, 46, 33, 36, 47, 23 );
[13]INT row 13 := ( 92, 50, 48, 02, 36, 59, 42, 79, 72, 20, 82, 77, 42 );
[14]INT row 14 := ( 56, 78, 38, 80, 39, 75, 02, 71, 66, 66, 01, 03, 55, 72 );
[15]INT row 15 := ( 44, 25, 67, 84, 71, 67, 11, 61, 40, 57, 58, 89, 40, 56, 36 );
[16]INT row 16 := ( 85, 32, 25, 85, 57, 48, 84, 35, 47, 62, 17, 01, 01, 99, 89, 52 );
[17]INT row 17 := ( 06, 71, 28, 75, 94, 48, 37, 10, 23, 51, 06, 48, 53, 18, 74, 98, 15 );
[18]INT row 18 := ( 27, 02, 92, 23, 08, 71, 76, 84, 15, 52, 92, 63, 81, 10, 44, 10, 69, 93 );
[18]REF[]INT triangle := ( row 1, row 2, row 3, row 4, row 5, row 6
, row 7, row 8, row 9, row 10, row 11, row 12
, row 13, row 14, row 15, row 16, row 17, row 18
);
PROC max = ( INT a, INT b )INT: IF a > b THEN a ELSE b FI;
# working backwards, we replace the elements of each row with the sum of that #
# element and the maximum of the two elements below it. #
# That destroys the triangle but leaves element [1][1] equal to the required #
# maximum #
FOR row FROM UPB triangle - 1 BY -1 TO 1
DO
FOR element FROM 1 TO UPB triangle[row]
DO
# the elements "under" triangle[row][element] are #
# triangle[row+1][element] and triangle[row+1][element+1] #
triangle[row][element]
+:= max( triangle[row+1][element], triangle[row+1][element+1] )
OD
OD;
print( ( triangle[1][1], newline ) )

View file

@ -0,0 +1,41 @@
with Ada.Text_Io; use Ada.Text_Io;
procedure Max_Sum is
Triangle : array (Positive range <>) of integer :=
(55,
94, 48,
95, 30, 96,
77, 71, 26, 67,
97, 13, 76, 38, 45,
07, 36, 79, 16, 37, 68,
48, 07, 09, 18, 70, 26, 06,
18, 72, 79, 46, 59, 79, 29, 90,
20, 76, 87, 11, 32, 07, 07, 49, 18,
27, 83, 58, 35, 71, 11, 25, 57, 29, 85,
14, 64, 36, 96, 27, 11, 58, 56, 92, 18, 55,
02, 90, 03, 60, 48, 49, 41, 46, 33, 36, 47, 23,
92, 50, 48, 02, 36, 59, 42, 79, 72, 20, 82, 77, 42,
56, 78, 38, 80, 39, 75, 02, 71, 66, 66, 01, 03, 55, 72,
44, 25, 67, 84, 71, 67, 11, 61, 40, 57, 58, 89, 40, 56, 36,
85, 32, 25, 85, 57, 48, 84, 35, 47, 62, 17, 01, 01, 99, 89, 52,
06, 71, 28, 75, 94, 48, 37, 10, 23, 51, 06, 48, 53, 18, 74, 98, 15,
27, 02, 92, 23, 08, 71, 76, 84, 15, 52, 92, 63, 81, 10, 44, 10, 69, 93);
Last : Integer := Triangle'Length;
Tn : Integer := 1;
begin
while (Tn * (Tn + 1) / 2) < Last loop
Tn := Tn + 1;
end loop;
for N in reverse 2 .. Tn loop
for I in 2 .. N loop
Triangle (Last - N) := Triangle (Last - N) +
Integer'Max(Triangle (Last - 1), Triangle (Last));
Last := Last - 1;
end loop;
Last := Last - 1;
end loop;
Put_Line(Integer'Image(Triangle(1)));
end Max_Sum;

View file

@ -0,0 +1,44 @@
( "
55
94 48
95 30 96
77 71 26 67
97 13 76 38 45
07 36 79 16 37 68
48 07 09 18 70 26 06
18 72 79 46 59 79 29 90
20 76 87 11 32 07 07 49 18
27 83 58 35 71 11 25 57 29 85
14 64 36 96 27 11 58 56 92 18 55
02 90 03 60 48 49 41 46 33 36 47 23
92 50 48 02 36 59 42 79 72 20 82 77 42
56 78 38 80 39 75 02 71 66 66 01 03 55 72
44 25 67 84 71 67 11 61 40 57 58 89 40 56 36
85 32 25 85 57 48 84 35 47 62 17 01 01 99 89 52
06 71 28 75 94 48 37 10 23 51 06 48 53 18 74 98 15
27 02 92 23 08 71 76 84 15 52 92 63 81 10 44 10 69 93
"
: ?triangle
& ( max
= a b
. !arg:(?a.?b)&(!a:>!b|!b)
)
& 0:?accumulator
& whl
' ( @(!triangle:?row (\n|\r) ?triangle)
& :?newaccumulator
& 0:?first
& whl
' ( @(!row:? #%?n (" " ?row|:?row))
& !accumulator:#%?second ?accumulator
& !newaccumulator max$(!first.!second)+!n:?newaccumulator
& !second:?first
)
& !newaccumulator 0:?accumulator
)
& ( -1:?Max
& !accumulator
: ? (%@:>!Max:?Max&~) ?
| out$!Max
)
)

View file

@ -0,0 +1,43 @@
#include <iostream>
int main( int argc, char* argv[] )
{
int triangle[] =
{
55,
94, 48,
95, 30, 96,
77, 71, 26, 67,
97, 13, 76, 38, 45,
7, 36, 79, 16, 37, 68,
48, 7, 9, 18, 70, 26, 6,
18, 72, 79, 46, 59, 79, 29, 90,
20, 76, 87, 11, 32, 7, 7, 49, 18,
27, 83, 58, 35, 71, 11, 25, 57, 29, 85,
14, 64, 36, 96, 27, 11, 58, 56, 92, 18, 55,
2, 90, 3, 60, 48, 49, 41, 46, 33, 36, 47, 23,
92, 50, 48, 2, 36, 59, 42, 79, 72, 20, 82, 77, 42,
56, 78, 38, 80, 39, 75, 2, 71, 66, 66, 1, 3, 55, 72,
44, 25, 67, 84, 71, 67, 11, 61, 40, 57, 58, 89, 40, 56, 36,
85, 32, 25, 85, 57, 48, 84, 35, 47, 62, 17, 1, 1, 99, 89, 52,
6, 71, 28, 75, 94, 48, 37, 10, 23, 51, 6, 48, 53, 18, 74, 98, 15,
27, 2, 92, 23, 8, 71, 76, 84, 15, 52, 92, 63, 81, 10, 44, 10, 69, 93
};
int last = sizeof( triangle ) / sizeof( int ),
tn = 1;
while( ( tn * ( tn + 1 ) / 2 ) < last ) tn += 1;
last--;
for( int n = tn; n >= 2; n-- )
{
for( int i = 2; i <= n; i++ )
{
triangle[last - n] = triangle[last - n] + std::max( triangle[last - 1], triangle[last] );
last--;
}
last--;
}
std::cout << "Maximum total: " << triangle[0] << "\n\n";
return system( "pause" );
}

View file

@ -0,0 +1,45 @@
#include <stdio.h>
#include <math.h>
#define max(x,y) ((x) > (y) ? (x) : (y))
int tri[] = {
55,
94, 48,
95, 30, 96,
77, 71, 26, 67,
97, 13, 76, 38, 45,
7, 36, 79, 16, 37, 68,
48, 7, 9, 18, 70, 26, 6,
18, 72, 79, 46, 59, 79, 29, 90,
20, 76, 87, 11, 32, 7, 7, 49, 18,
27, 83, 58, 35, 71, 11, 25, 57, 29, 85,
14, 64, 36, 96, 27, 11, 58, 56, 92, 18, 55,
2, 90, 3, 60, 48, 49, 41, 46, 33, 36, 47, 23,
92, 50, 48, 2, 36, 59, 42, 79, 72, 20, 82, 77, 42,
56, 78, 38, 80, 39, 75, 2, 71, 66, 66, 1, 3, 55, 72,
44, 25, 67, 84, 71, 67, 11, 61, 40, 57, 58, 89, 40, 56, 36,
85, 32, 25, 85, 57, 48, 84, 35, 47, 62, 17, 1, 1, 99, 89, 52,
6, 71, 28, 75, 94, 48, 37, 10, 23, 51, 6, 48, 53, 18, 74, 98, 15,
27, 2, 92, 23, 8, 71, 76, 84, 15, 52, 92, 63, 81, 10, 44, 10, 69, 93
};
int main(void)
{
const int len = sizeof(tri) / sizeof(tri[0]);
const int base = (sqrt(8*len + 1) - 1) / 2;
int step = base - 1;
int stepc = 0;
int i;
for (i = len - base - 1; i >= 0; --i) {
tri[i] += max(tri[i + step], tri[i + step + 1]);
if (++stepc == step) {
step--;
stepc = 0;
}
}
printf("%d\n", tri[0]);
return 0;
}

View file

@ -0,0 +1,24 @@
(defun find-max-path-sum (s)
(let ((triangle (loop for line = (read-line s NIL NIL)
while line
collect (with-input-from-string (str line)
(loop for n = (read str NIL NIL)
while n
collect n)))))
(flet ((get-max-of-pairs (xs)
(maplist (lambda (ys)
(and (cdr ys) (max (car ys) (cadr ys))))
xs)))
(car (reduce (lambda (xs ys)
(mapcar #'+ (get-max-of-pairs xs) ys))
(reverse triangle))))))
(defparameter *small-triangle*
" 55
94 48
95 30 96
77 71 26 67")
(format T "~a~%" (with-input-from-string (s *small-triangle*)
(find-max-path-sum s)))
(format T "~a~%" (with-open-file (f "triangle.txt")
(find-max-path-sum f)))

View file

@ -0,0 +1,9 @@
void main() {
import std.stdio, std.algorithm, std.range, std.file, std.conv;
"triangle.txt".File.byLine.map!split.map!(to!(int[])).array.retro
.reduce!((x, y) => zip(y, x, x.dropOne)
.map!(t => t[0] + t[1 .. $].max)
.array)[0]
.writeln;
}

View file

@ -0,0 +1,55 @@
package main
import (
"fmt"
"strconv"
"strings"
)
const t = ` 55
94 48
95 30 96
77 71 26 67
97 13 76 38 45
07 36 79 16 37 68
48 07 09 18 70 26 06
18 72 79 46 59 79 29 90
20 76 87 11 32 07 07 49 18
27 83 58 35 71 11 25 57 29 85
14 64 36 96 27 11 58 56 92 18 55
02 90 03 60 48 49 41 46 33 36 47 23
92 50 48 02 36 59 42 79 72 20 82 77 42
56 78 38 80 39 75 02 71 66 66 01 03 55 72
44 25 67 84 71 67 11 61 40 57 58 89 40 56 36
85 32 25 85 57 48 84 35 47 62 17 01 01 99 89 52
06 71 28 75 94 48 37 10 23 51 06 48 53 18 74 98 15
27 02 92 23 08 71 76 84 15 52 92 63 81 10 44 10 69 93`
func main() {
lines := strings.Split(t, "\n")
f := strings.Fields(lines[len(lines)-1])
d := make([]int, len(f))
var err error
for i, s := range f {
if d[i], err = strconv.Atoi(s); err != nil {
panic(err)
}
}
d1 := d[1:]
var l, r, u int
for row := len(lines) - 2; row >= 0; row-- {
l = d[0]
for i, s := range strings.Fields(lines[row]) {
if u, err = strconv.Atoi(s); err != nil {
panic(err)
}
if r = d1[i]; l > r {
d[i] = u + l
} else {
d[i] = u + r
}
l = r
}
}
fmt.Println(d[0])
}

View file

@ -0,0 +1,5 @@
parse = map (map read . words) . lines
f x y z = x + max y z
g xs ys = zipWith3 f xs ys $ tail ys
solve = head . foldr1 g
main = readFile "triangle.txt" >>= print . solve . parse

View file

@ -0,0 +1,2 @@
padTri=: 0 ". [: ];._2 ] NB. parse triangle and pad with zeros
maxSum=: [: {. (+ (0 ,~ 2 >./\ ]))/ NB. find max triangle path sum

View file

@ -0,0 +1,2 @@
maxSum padTri freads 'triangle.txt'
1320

View file

@ -0,0 +1,19 @@
import java.nio.file.*;
import static java.util.Arrays.stream;
public class MaxPathSum {
public static void main(String[] args) throws Exception {
int[][] data = Files.lines(Paths.get("triangle.txt"))
.map(s -> stream(s.trim().split("\\s+"))
.mapToInt(Integer::parseInt)
.toArray())
.toArray(int[][]::new);
for (int r = data.length - 1; r > 0; r--)
for (int c = 0; c < data[r].length - 1; c++)
data[r - 1][c] += Math.max(data[r][c], data[r][c + 1]);
System.out.println(data[0][0]);
}
}

View file

@ -0,0 +1,4 @@
nums={{55},{94,48},{95,30,96},{77,71,26,67},{97,13,76,38,45},{7,36,79,16,37,68},{48,7,9,18,70,26,6},{18,72,79,46,59,79,29,90},{20,76,87,11,32,7,7,49,18},{27,83,58,35,71,11,25,57,29,85},{14,64,36,96,27,11,58,56,92,18,55},{2,90,3,60,48,49,41,46,33,36,47,23},{92,50,48,2,36,59,42,79,72,20,82,77,42},{56,78,38,80,39,75,2,71,66,66,1,3,55,72},{44,25,67,84,71,67,11,61,40,57,58,89,40,56,36},{85,32,25,85,57,48,84,35,47,62,17,1,1,99,89,52},{6,71,28,75,94,48,37,10,23,51,6,48,53,18,74,98,15},{27,2,92,23,8,71,76,84,15,52,92,63,81,10,44,10,69,93}};
ClearAll[DoStep,MaximumTrianglePathSum]
DoStep[lst1_List,lst2_List]:=lst2+Join[{First[lst1]},Max/@Partition[lst1,2,1],{Last[lst1]}]
MaximumTrianglePathSum[triangle_List]:=Max[Fold[DoStep,First[triangle],Rest[triangle]]]

View file

@ -0,0 +1,2 @@
V=[[55],[94,48],[95,30,96],[77,71,26,67],[97,13,76,38,45],[07,36,79,16,37,68],[48,07,09,18,70,26,06],[18,72,79,46,59,79,29,90],[20,76,87,11,32,07,07,49,18],[27,83,58,35,71,11,25,57,29,85],[14,64,36,96,27,11,58,56,92,18,55],[02,90,03,60,48,49,41,46,33,36,47,23],[92,50,48,02,36,59,42,79,72,20,82,77,42],[56,78,38,80,39,75,02,71,66,66,01,03,55,72],[44,25,67,84,71,67,11,61,40,57,58,89,40,56,36],[85,32,25,85,57,48,84,35,47,62,17,01,01,99,89,52],[06,71,28,75,94,48,37,10,23,51,06,48,53,18,74,98,15],[27,02,92,23,08,71,76,84,15,52,92,63,81,10,44,10,69,93]];
forstep(i=#V,2,-1,V[i-1]+=vector(i-1,j,max(V[i][j],V[i][j+1]))); V[1][1]

View file

@ -0,0 +1,106 @@
program TriSum;
{'triangle.txt'
* one element per line
55
94
48
95
30
96
...}
const
cMaxTriHeight = 18;
cMaxTriElemCnt = (cMaxTriHeight+1)*cMaxTriHeight DIV 2 +1;
type
tElem = longint;
tbaseRow = array[0..cMaxTriHeight] of tElem;
tmyTri = array[0..cMaxTriElemCnt] of tElem;
function ReadTri( fname:string;
out t:tmyTri):integer;
{read triangle values into t and returns height}
var
f : text;
s : string;
i : integer;
ValCode : word;
begin
i := 0;
fillchar(t,Sizeof(t),#0);
Assign(f,fname);
{$I-}
reset(f);
IF ioResult <> 0 then
begin
writeln('IO-Error ',ioResult);
close(f);
ReadTri := i;
EXIT;
end;
{$I+}
while NOT(EOF(f)) AND (i<cMaxTriElemCnt) do
begin
readln(f,s);
val(s,t[i],ValCode);
inc(i);
IF ValCode <> 0 then
begin
writeln(ValCode,' conversion error at line ',i);
fillchar(t,Sizeof(t),#0);
i := 0;
BREAK;
end;
end;
close(f);
ReadTri := round(sqrt(2*(i-1)));
end;
function TriMaxSum(var t: tmyTri;hei:integer):integer;
{sums up higher values bottom to top}
var
i,r,h,tmpMax : integer;
idxN : integer;
sumrow : tbaseRow;
begin
h := hei;
idxN := (h*(h+1)) div 2 -1;
{copy base row}
move(t[idxN-h+1],sumrow[0],SizeOf(tElem)*h);
dec(h);
{ for r := 0 to h do write(sumrow[r]:4);writeln;}
idxN := idxN-h;
while idxN >0 do
begin
i := idxN-h;
r := 0;
while r < h do
begin
tmpMax:= sumrow[r];
IF tmpMax<sumrow[r+1] then
tmpMax:=sumrow[r+1];
sumrow[r]:= tmpMax+t[i];
inc(i);
inc(r);
end;
idxN := idxN-h;
dec(h);
{ for r := 0 to h do write(sumrow[r]:4);writeln;}
end;
TriMaxSum := sumrow[0];
end;
var
h : integer;
triangle : tmyTri;
Begin
{ writeln(TriMaxSum(triangle,ReadTri('triangle.txt',triangle))); -> 1320}
h := ReadTri('triangle.txt',triangle);
writeln('height sum');
while h > 0 do
begin
writeln(h:4,TriMaxSum(triangle,h):7);
dec(h);
end;
end.

View file

@ -0,0 +1,8 @@
my @rows = slurp("triangle.txt").lines.map: { [.words] }
while @rows > 1 {
my @last := @rows.pop;
@rows[*-1] = @rows[*-1][] Z+ (@last Zmax @last[1..*]);
}
say @rows;

View file

@ -0,0 +1,3 @@
sub infix:<op>(@a,@b) { (@a Zmax @a[1..*]) Z+ @b }
say [op] slurp("triangle.txt").lines.reverse.map: { [.words] }

View file

@ -0,0 +1,3 @@
sub infix:<op>(@a,@b) is assoc('right') { @a Z+ (@b Zmax @b[1..*]) }
say [op] slurp("triangle.txt").lines.map: { [.words] }

View file

@ -0,0 +1,12 @@
use 5.10.0;
use List::Util 'max';
my @sum;
while (<>) {
my @x = split;
@sum = ($x[0] + $sum[0],
map($x[$_] + max(@sum[$_-1, $_]), 1 .. @x-2),
$x[-1] + $sum[-1]);
}
say max(@sum);

View file

@ -0,0 +1,40 @@
max_path(N, V) :-
data(N, T),
path(0, T, V).
path(_N, [], 0) .
path(N, [H | T], V) :-
nth0(N, H, V0),
N1 is N+1,
path(N, T, V1),
path(N1, T, V2),
V is V0 + max(V1, V2).
data(1, P) :-
P =
[ [55],
[94, 48],
[95, 30, 96],
[77, 71, 26, 67]].
data(2, P) :-
P =
[ [55],
[94, 48],
[95, 30, 96],
[77, 71, 26, 67],
[97, 13, 76, 38, 45],
[7, 36, 79, 16, 37, 68],
[48, 7, 9, 18, 70, 26, 6],
[18, 72, 79, 46, 59, 79, 29, 90],
[20, 76, 87, 11, 32, 7, 7, 49, 18],
[27, 83, 58, 35, 71, 11, 25, 57, 29, 85],
[14, 64, 36, 96, 27, 11, 58, 56, 92, 18, 55],
[2, 90, 3, 60, 48, 49, 41, 46, 33, 36, 47, 23],
[92, 50, 48, 2, 36, 59, 42, 79, 72, 20, 82, 77, 42],
[56, 78, 38, 80, 39, 75, 2, 71, 66, 66, 1, 3, 55, 72],
[44, 25, 67, 84, 71, 67, 11, 61, 40, 57, 58, 89, 40, 56, 36],
[85, 32, 25, 85, 57, 48, 84, 35, 47, 62, 17, 1, 1, 99, 89, 52],
[6, 71, 28, 75, 94, 48, 37, 10, 23, 51, 6, 48, 53, 18, 74, 98, 15],
[27, 2, 92, 23, 8, 71, 76, 84, 15, 52, 92, 63, 81, 10, 44, 10, 69, 93]].

View file

@ -0,0 +1,31 @@
def solve(tri):
while len(tri) > 1:
t0 = tri.pop()
t1 = tri.pop()
tri.append([max(t0[i], t0[i+1]) + t for i,t in enumerate(t1)])
return tri[0][0]
def main():
data = """\
55
94 48
95 30 96
77 71 26 67
97 13 76 38 45
07 36 79 16 37 68
48 07 09 18 70 26 06
18 72 79 46 59 79 29 90
20 76 87 11 32 07 07 49 18
27 83 58 35 71 11 25 57 29 85
14 64 36 96 27 11 58 56 92 18 55
02 90 03 60 48 49 41 46 33 36 47 23
92 50 48 02 36 59 42 79 72 20 82 77 42
56 78 38 80 39 75 02 71 66 66 01 03 55 72
44 25 67 84 71 67 11 61 40 57 58 89 40 56 36
85 32 25 85 57 48 84 35 47 62 17 01 01 99 89 52
06 71 28 75 94 48 37 10 23 51 06 48 53 18 74 98 15
27 02 92 23 08 71 76 84 15 52 92 63 81 10 44 10 69 93"""
print solve([map(int, row.split()) for row in data.splitlines()])
main()

View file

@ -0,0 +1,6 @@
from itertools import imap
f = lambda x, y, z: x + max(y, z)
g = lambda xs, ys: list(imap(f, ys, xs, xs[1:]))
data = [map(int, row.split()) for row in open("triangle.txt")][::-1]
print reduce(g, data)[0]

View file

@ -0,0 +1 @@
Data source: http://rosettacode.org/wiki/Maximum_triangle_path_sum

View file

@ -0,0 +1,34 @@
/*REXX program finds the max sum of a "column" of numbers in a triangle.*/
@. =
@.1 = 55
@.2 = 94 48
@.3 = 95 30 96
@.4 = 77 71 26 67
@.5 = 97 13 76 38 45
@.6 = 07 36 79 16 37 68
@.7 = 48 07 09 18 70 26 06
@.8 = 18 72 79 46 59 79 29 90
@.9 = 20 76 87 11 32 07 07 49 18
@.10 = 27 83 58 35 71 11 25 57 29 85
@.11 = 14 64 36 96 27 11 58 56 92 18 55
@.12 = 02 90 03 60 48 49 41 46 33 36 47 23
@.13 = 92 50 48 02 36 59 42 79 72 20 82 77 42
@.14 = 56 78 38 80 39 75 02 71 66 66 01 03 55 72
@.15 = 44 25 67 84 71 67 11 61 40 57 58 89 40 56 36
@.16 = 85 32 25 85 57 48 84 35 47 62 17 01 01 99 89 52
@.17 = 06 71 28 75 94 48 37 10 23 51 06 48 53 18 74 98 15
@.18 = 27 02 92 23 08 71 76 84 15 52 92 63 81 10 44 10 69 93
do r=1 while @.r\=='' /*build a version of the triangle*/
do k=1 for words(@.r) /*build a row, number by number. */
#.r.k=word(@.r,k) /*assign a number to an array num*/
end /*k*/
end /*r*/
rows=r-1 /*compute the number of rows. */
do r=rows by -1 to 2; p=r-1 /*traipse through triangle rows. */
do k=1 for p; kn=k+1 /*re-calculate the previous row. */
#.p.k=max(#.r.k, #.r.kn) + #.p.k /*replace previous #. */
end /*k*/
end /*r*/
say 'maximum path sum:' #.1.1 /*display the top (row 1) number.*/
/*stick a fork in it, we're done.*/

View file

@ -0,0 +1,59 @@
#lang racket
(require math/number-theory)
(define (trinv n) ; OEIS A002024
(exact-floor (/ (+ 1 (sqrt (* 1 (* 8 n)))) 2)))
(define (triangle-neighbour-bl n)
(define row (trinv n))
(+ n (- (triangle-number row) (triangle-number (- row 1)))))
(define (maximum-triangle-path-sum T)
(define n-rows (trinv (vector-length T)))
(define memo# (make-hash))
(define (inner i)
(hash-ref!
memo# i
(λ ()
(+ (vector-ref T (sub1 i)) ; index is 1-based (so vector-refs need -1'ing)
(cond [(= (trinv i) n-rows) 0]
[else
(define bl (triangle-neighbour-bl i))
(max (inner bl) (inner (add1 bl)))])))))
(inner 1))
(module+ main
(maximum-triangle-path-sum
#(55
94 48
95 30 96
77 71 26 67
97 13 76 38 45
07 36 79 16 37 68
48 07 09 18 70 26 06
18 72 79 46 59 79 29 90
20 76 87 11 32 07 07 49 18
27 83 58 35 71 11 25 57 29 85
14 64 36 96 27 11 58 56 92 18 55
02 90 03 60 48 49 41 46 33 36 47 23
92 50 48 02 36 59 42 79 72 20 82 77 42
56 78 38 80 39 75 02 71 66 66 01 03 55 72
44 25 67 84 71 67 11 61 40 57 58 89 40 56 36
85 32 25 85 57 48 84 35 47 62 17 01 01 99 89 52
06 71 28 75 94 48 37 10 23 51 06 48 53 18 74 98 15
27 02 92 23 08 71 76 84 15 52 92 63 81 10 44 10 69 93)))
(module+ test
(require rackunit)
(check-equal? (for/list ((n (in-range 1 (add1 10)))) (trinv n)) '(1 2 2 3 3 3 4 4 4 4))
; 1
; 2 3
; 4 5 6
; 7 8 9 10
(check-eq? (triangle-neighbour-bl 1) 2)
(check-eq? (triangle-neighbour-bl 3) 5)
(check-eq? (triangle-neighbour-bl 5) 8)
(define test-triangle
#(55 94 48 95 30 96 77 71 26 67))
(check-equal? (maximum-triangle-path-sum test-triangle) 321)
)

View file

@ -0,0 +1,26 @@
triangle =
" 55
94 48
95 30 96
77 71 26 67
97 13 76 38 45
07 36 79 16 37 68
48 07 09 18 70 26 06
18 72 79 46 59 79 29 90
20 76 87 11 32 07 07 49 18
27 83 58 35 71 11 25 57 29 85
14 64 36 96 27 11 58 56 92 18 55
02 90 03 60 48 49 41 46 33 36 47 23
92 50 48 02 36 59 42 79 72 20 82 77 42
56 78 38 80 39 75 02 71 66 66 01 03 55 72
44 25 67 84 71 67 11 61 40 57 58 89 40 56 36
85 32 25 85 57 48 84 35 47 62 17 01 01 99 89 52
06 71 28 75 94 48 37 10 23 51 06 48 53 18 74 98 15
27 02 92 23 08 71 76 84 15 52 92 63 81 10 44 10 69 93"
ar = triangle.each_line.map{|line| line.strip.split.map(&:to_i)}
until ar.size == 1 do
maxes = ar.pop.each_cons(2).map(&:max)
ar[-1]= ar[-1].zip(maxes).map{|r1,r2| r1 + r2}.flatten
end
puts ar # => 1320

View file

@ -0,0 +1,21 @@
object MaximumTrianglePathSum extends App {
// Solution:
def sum(triangle: Array[Array[Int]]) =
triangle.reduceRight((upper, lower) =>
upper zip (lower zip lower.tail)
map {case (above, (left, right)) => above + Math.max(left, right)}
).head
// Tests:
def triangle = """
55
94 48
95 30 96
77 71 26 67
"""
def parse(s: String) = s.trim.split("\\s+").map(_.toInt)
def parseLines(s: String) = s.trim.split("\n").map(parse)
def parseFile(f: String) = scala.io.Source.fromFile(f).getLines.map(parse).toArray
println(sum(parseLines(triangle)))
println(sum(parseFile("triangle.txt")))
}

View file

@ -0,0 +1,45 @@
package require Tcl 8.6
proc maxTrianglePathSum {definition} {
# Parse the definition, stripping whitespace and leading zeroes.
set lines [lmap line [split [string trim $definition] "\n"] {
lmap val $line {scan $val %d}
}]
# Paths are bit strings (0 = go left, 1 = go right).
# Enumerate the possible paths.
set numPaths [expr {2 ** [llength $lines]}]
for {set path 0; set max -inf} {$path < $numPaths} {incr path} {
# Work out how much the current path costs.
set sum [set idx [set row 0]]
for {set bit 1} {$row < [llength $lines]} {incr row} {
incr sum [lindex $lines $row $idx]
if {$path & $bit} {incr idx}
set bit [expr {$bit << 1}]
}
# Remember the max so far.
if {$sum > $max} {set max $sum}
}
return $max
}
puts [maxTrianglePathSum {
55
94 48
95 30 96
77 71 26 67
97 13 76 38 45
07 36 79 16 37 68
48 07 09 18 70 26 06
18 72 79 46 59 79 29 90
20 76 87 11 32 07 07 49 18
27 83 58 35 71 11 25 57 29 85
14 64 36 96 27 11 58 56 92 18 55
02 90 03 60 48 49 41 46 33 36 47 23
92 50 48 02 36 59 42 79 72 20 82 77 42
56 78 38 80 39 75 02 71 66 66 01 03 55 72
44 25 67 84 71 67 11 61 40 57 58 89 40 56 36
85 32 25 85 57 48 84 35 47 62 17 01 01 99 89 52
06 71 28 75 94 48 37 10 23 51 06 48 53 18 74 98 15
27 02 92 23 08 71 76 84 15 52 92 63 81 10 44 10 69 93
}]
# Reading from a file is left as an exercise