Another update from ingydotnet^djgoku

This commit is contained in:
Ingy döt Net 2015-11-18 06:14:39 +00:00
parent 91df62d461
commit 948b86eafa
7604 changed files with 108452 additions and 22726 deletions

View file

@ -5,7 +5,9 @@ Starting from the top of a pyramid of numbers like this, you can walk down going
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.
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.

View file

@ -0,0 +1,39 @@
data :=[
(join ltrim
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
)]
i := data.MaxIndex()
row := Ceil((Sqrt(8*i+1) - 1) / 2)
path:=[]
loop % row {
path[i] := data[i]
i--
}
while i {
row := Ceil((Sqrt(8*i+1) - 1) / 2)
path[i] := data[i] "+" (data[i+row] > data[i+row+1] ? path[i+row] : path[i+row+1])
data[i] += data[i+row] > data[i+row+1] ? data[i+row] : data[i+row+1]
i --
}
MsgBox % data[1] "`n" path[1]

View file

@ -24,20 +24,14 @@ int main( int argc, char* argv[] )
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;
const int size = sizeof( triangle ) / sizeof( int );
const int tn = static_cast<int>(sqrt(2.0 * size));
assert(tn * (tn + 1) == 2 * size); // size should be a triangular number
// walk backward by rows, replacing each element with max attainable therefrom
for (int n = tn - 1; n > 0; --n) // n is size of row, note we do not process last row
for (int k = (n * (n-1)) / 2; k < (n * (n+2)) / 2; ++k)
triangle[k] += std::max(triangle[k + n], triangle[k + n + 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,36 @@
defmodule Maximum do
def triangle_path(text) do
String.split(text, "\n", trim: true)
|> Enum.map(fn line -> String.split(line) |> Enum.map(&String.to_integer(&1)) end)
|> Enum.reduce([], fn x,total ->
Enum.chunk([0]++total++[0], 2, 1)
|> Enum.map(&Enum.max(&1))
|> Enum.zip(x)
|> Enum.map(fn{a,b} -> a+b end)
end)
|> Enum.max
end
end
text = """
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
"""
IO.puts Maximum.triangle_path(text)

View file

@ -0,0 +1,110 @@
MODULE PYRAMIDS !Produces a pyramid of numbers in 1-D array.
INTEGER MANY !The usual storage issues.
PARAMETER (MANY = 666) !This should suffice.
INTEGER BRICK(MANY),IN,LAYERS !Defines a pyramid.
CONTAINS
SUBROUTINE IMHOTEP(PLAN)!The architect.
Counting is from the apex down, the Erich von Daniken construction.
CHARACTER*(*) PLAN !The instruction file.
INTEGER I,IT !Steppers.
CHARACTER*666 ALINE !A scratchpad for input.
IN = 0 !No bricks.
LAYERS = 0 !In no courses.
WRITE (6,*) "Reading from ",PLAN !Here we go.
OPEN(10,FILE=PLAN,FORM="FORMATTED",ACTION="READ",ERR=6) !I hope.
GO TO 10 !Why can't OPEN be a function?@*&%#^%!
6 STOP "Can't grab the file!"
Chew into the plan.
10 READ (10,11,END = 20) ALINE !Get the whole line in one piece.
11 FORMAT (A) !As plain text.
IF (ALINE .EQ. "") GO TO 10 !Ignoring any blank lines.
IF (ALINE(1:1).EQ."%") GO TO 10 !A comment opportunity.
LAYERS = LAYERS + 1 !Righto, this should be the next layer.
IF (IN + LAYERS.GT.MANY) STOP "Too many bricks!" !Perhaps not.
READ (ALINE,*,END = 15,ERR = 15) BRICK(IN + 1:IN + LAYERS) !Free format.
IN = IN + LAYERS !Insufficient numbers will provoke trouble.
GO TO 10 !Extra numbers/stuff will be ignored.
Caught a crab? A bad number, or too few numbers on a line? No read-next-record antics, thanks.
15 WRITE (6,16) LAYERS,ALINE !Just complain.
16 FORMAT ("Bad layer ",I0,": ",A)
Completed the plan.
20 WRITE (6,21) IN,LAYERS !Announce some details.
21 FORMAT (I0," bricks in ",I0," layers.")
CLOSE(10) !Finished with input.
Cast forth the numbers in a nice pyramid.
30 IT = 0 !For traversing the pyramid.
DO I = 1,LAYERS !Each course has one more number than the one before.
WRITE (6,31) BRICK(IT + 1:IT + I) !Sweep along the layer.
31 FORMAT (<LAYERS*2 - 2*I>X,666I4) !Leading spaces may be zero in number.
IT = IT + I !Thus finger the last of a layer.
END DO !On to the start of the next layer.
END SUBROUTINE IMHOTEP !The pyramid's plan is ready.
SUBROUTINE TRAVERSE !Clamber around the pyramid. Thoroughly.
C The idea is that a pyramid of numbers is provided, and then, starting at the peak,
c work down to the base summing the numbers at each step to find the maximum value path.
c The constraint is that from a particular brick, only the two numbers below left and below right
c may be reached in stepping to that lower layer.
c Since that is a 0/1 choice, recorded in MOVE, a base-two scan searches the possibilities.
INTEGER MOVE(LAYERS) !Choices are made at the various positions.
INTEGER STEP(LAYERS),WALK(LAYERS) !Thus determining the path.
INTEGER I,L,IT !Steppers.
INTEGER PS,WS !Scores.
WRITE (6,1) LAYERS !Announce the intention.
1 FORMAT (//,"Find the highest score path across a pyramid of ",
1 I0," layers."/) !I'm not worrying over singular/plural.
MOVE = 0 !All 0/1 values to zero.
MOVE(1) = 1 !Except the first.
STEP(1) = 1 !Every path starts here, without option.
WS = -666 !The best score so far.
Commence a multi-level loop, using the values of MOVE as the digits, one digit per level.
10 IT = 1 !All paths start with the first step.
PS = BRICK(1) !The starting score,.
c write (6,8) "Move",MOVE,WS
DO L = 2,LAYERS !Deal with the subsequent layers.
IT = IT + L - 1 + MOVE(L) !Choose a brick.
STEP(L) = IT !Remember this step.
PS = PS + BRICK(IT) !Count its score.
c WRITE (6,6) L,IT,BRICK(IT),PS
6 FORMAT ("Layer ",I0,",Brick(",I0,")=",I0,",Sum=",I0)
END DO !Thus is the path determined.
IF (PS .GT. WS) THEN !An improvement?
IF (WS.GT.0) WRITE (6,7) WS,PS !Yes! Announce.
7 FORMAT ("Improved path score: ",I0," to ",I0)
WRITE (6,8) "Moves",MOVE !Show the choices at each layer..
WRITE (6,8) "Steps",STEP !That resulted in this path.
WRITE (6,8) "Score",BRICK(STEP) !Whose steps were scored thus.
8 FORMAT (A8,666I4) !This should suffice.
WS = PS !Record the new best value.
WALK = STEP !And the path thereby.
END IF !So much for an improvement.
DO L = LAYERS,1,-1 !Now add one to the number in MOVE.
IF (MOVE(L).EQ.0) THEN !By finding the lowest order zero.
MOVE(L) = 1 !Making it one,
MOVE(L + 1:LAYERS) = 0 !And setting still lower orders back to zero.
GO TO 10 !And if we did, there's more to do!
END IF !But if that bit wasn't zero,
END DO !Perhaps the next one up will be.
WRITE (6,*) WS," is the highest score." !So much for that.
END SUBROUTINE TRAVERSE !All paths considered...
SUBROUTINE REFINE !Ascertain the highest score without searching.
INTEGER BEST(LAYERS) !A scratchpad.
INTEGER I,L !Steppers.
L = LAYERS*(LAYERS - 1)/2 + 1 !Finger the first brick of the lowest layer.
BEST = BRICK(L:L + LAYERS - 1)!Syncopation. Copy the lowest layer.
DO L = LAYERS - 1,1,-1 !Work towards the peak.
FORALL (I = 1:L) BEST(I) = BRICK(L*(L - 1)/2 + I) !Add to each brick's value
1 + MAXVAL(BEST(I:I + 1)) !The better of its two possibles.
END DO !On to the next layer.
WRITE (6,*) BEST(1)," is the highest score. By some path."
END SUBROUTINE REFINE !Who knows how we get there.
END MODULE PYRAMIDS
PROGRAM TRICKLE
USE PYRAMIDS
c CALL IMHOTEP("Sakkara.txt")
CALL IMHOTEP("Cheops.txt")
CALL TRAVERSE !Do this the definite way.
CALL REFINE !Only the result by more cunning.
END

View file

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

View file

@ -0,0 +1 @@
maxsum=: ((] + #@] {. [)2 >./\ ])/

View file

@ -0,0 +1,52 @@
local triangleSmall = {
{ 55 },
{ 94, 48 },
{ 95, 30, 96 },
{ 77, 71, 26, 67 },
}
local triangleLarge = {
{ 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 },
};
function solve(triangle)
-- Get total number of rows in triangle.
local nRows = table.getn(triangle)
-- Start at 2nd-to-last row and work up to the top.
for row = nRows-1, 1, -1 do
-- For each value in row, add the max of the 2 children beneath it.
for i = 1, row do
local child1 = triangle[row+1][i]
local child2 = triangle[row+1][i+1]
triangle[row][i] = triangle[row][i] + math.max(child1, child2)
end
end
-- The top of the triangle now holds the answer.
return triangle[1][1];
end
print(solve(triangleSmall))
print(solve(triangleLarge))

View file

@ -0,0 +1,42 @@
*process source xref attributes or(!);
triang: Proc Options(Main);
Dcl nn(18,18) Bin Fixed(31);
Dcl (rows,i,j) Bin Fixed(31);
Dcl (p,k,kn) Bin Fixed(31);
Call f_r(1 ,' 55 ');
Call f_r(2 ,' 94 48 ');
Call f_r(3 ,' 95 30 96 ');
Call f_r(4 ,' 77 71 26 67 ');
Call f_r(5 ,' 97 13 76 38 45 ');
Call f_r(6 ,' 07 36 79 16 37 68 ');
Call f_r(7 ,' 48 07 09 18 70 26 06 ');
Call f_r(8 ,' 18 72 79 46 59 79 29 90 ');
Call f_r(9 ,' 20 76 87 11 32 07 07 49 18 ');
Call f_r(10,' 27 83 58 35 71 11 25 57 29 85 ');
Call f_r(11,' 14 64 36 96 27 11 58 56 92 18 55 ');
Call f_r(12,' 02 90 03 60 48 49 41 46 33 36 47 23 ');
Call f_r(13,' 92 50 48 02 36 59 42 79 72 20 82 77 42 ');
Call f_r(14,' 56 78 38 80 39 75 02 71 66 66 01 03 55 72 ');
Call f_r(15,' 44 25 67 84 71 67 11 61 40 57 58 89 40 56 36 ');
Call f_r(16,' 85 32 25 85 57 48 84 35 47 62 17 01 01 99 89 52 ');
Call f_r(17,' 06 71 28 75 94 48 37 10 23 51 06 48 53 18 74 98 15 ');
Call f_r(18,' 27 02 92 23 08 71 76 84 15 52 92 63 81 10 44 10 69 93');
rows=hbound(nn,1);
do r=rows by -1 to 2;
p=r-1; /*traipse through triangle rows. */
do k=1 to p;
kn=k+1; /*re-calculate the previous row. */
nn(p,k)=max(nn(r,k),nn(r,kn))+nn(p,k); /*replace previous nn */
end;
end;
Put Edit('maximum path sum:',nn(1,1))(Skip,a,f(5)); /*display result*/
f_r: Proc(r,vl);
/* fill row r with r values */
Dcl r Bin Fixed(31);
Dcl vl Char(*);
Dcl vla Char(100) Var;
vla=' '!!trim(vl);
get string(vla) Edit((nn(r,j) Do j=1 To r))(f(3));
End;
End;

View file

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

View file

@ -0,0 +1,12 @@
(de maxpath (Lst)
(let (Lst (reverse Lst) R (car Lst))
(for I (cdr Lst)
(setq R
(mapcar
+
(maplist
'((L)
(and (cdr L) (max (car L) (cadr L))) )
R )
I ) ) )
(car R) ) )

View file

@ -5,9 +5,8 @@ def solve(tri):
tri.append([max(t0[i], t0[i+1]) + t for i,t in enumerate(t1)])
return tri[0][0]
def main():
data = """\
55
data = """ 55
94 48
95 30 96
77 71 26 67
@ -26,6 +25,4 @@ def main():
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()
print solve([map(int, row.split()) for row in data.splitlines()])

View file

@ -18,9 +18,9 @@ triangle =
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
ar = triangle.each_line.map{|line| line.split.map(&:to_i)}
puts ar.inject([]){|res,x|
maxes = [0, *res, 0].each_cons(2).map(&:max)
x.zip(maxes).map{|a,b| a+b}
}.max
# => 1320

View file

@ -0,0 +1,49 @@
use std::cmp::max;
fn max_path(vector: &mut Vec<Vec<u32>>) -> u32 {
while vector.len() > 1 {
let last = vector.pop().unwrap();
let ante = vector.pop().unwrap();
let mut new: Vec<u32> = Vec::new();
for (i, value) in ante.iter().enumerate() {
new.push(max(last[i], last[i+1]) + value);
};
vector.push(new);
};
vector[0][0]
}
fn main() {
let mut 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";
let mut vector = data.split("\n").map(|x| x.split(" ").map(|s: &str| s.parse::<u32>().unwrap())
.collect::<Vec<u32>>()).collect::<Vec<Vec<u32>>>();
let max_value = max_path(&mut vector);
println!("{}", max_value);
//=> 7273
}

View file

@ -0,0 +1,25 @@
'Solution derived from http://stackoverflow.com/questions/8002252/euler-project-18-approach.
Set objfso = CreateObject("Scripting.FileSystemObject")
Set objinfile = objfso.OpenTextFile(objfso.GetParentFolderName(WScript.ScriptFullName) &_
"\triangle.txt",1,False)
row = Split(objinfile.ReadAll,vbCrLf)
For i = UBound(row) To 0 Step -1
row(i) = Split(row(i)," ")
If i < UBound(row) Then
For j = 0 To UBound(row(i))
If (row(i)(j) + row(i+1)(j)) > (row(i)(j) + row(i+1)(j+1)) Then
row(i)(j) = CInt(row(i)(j)) + CInt(row(i+1)(j))
Else
row(i)(j) = CInt(row(i)(j)) + CInt(row(i+1)(j+1))
End If
Next
End If
Next
WScript.Echo row(0)(0)
objinfile.Close
Set objfso = Nothing