September 2017 Update

This commit is contained in:
Ingy döt Net 2017-09-23 10:01:46 +02:00
parent bba7bfd280
commit ba8067c3b7
14570 changed files with 153136 additions and 63871 deletions

View file

@ -0,0 +1,170 @@
-- MAX PATH SUM ---------------------------------------------------------------
-- Working from the bottom of the triangle upwards,
-- summing each number with the larger of the two below
-- until the maximum emerges at the top.
-- maxPathSum :: [[Int]] -> Int
on maxPathSum(xss)
-- With the last row as the initial accumulator,
-- folding from the penultimate line,
-- towards the top of the triangle:
-- sumWithRowBelow :: [Int] -> [Int] -> [Int]
script sumWithRowBelow
on |λ|(row, accum)
-- plusGreaterOfTwoBelow :: Int -> Int -> Int -> Int
script plusGreaterOfTwoBelow
on |λ|(x, intLeft, intRight)
x + max(intLeft, intRight)
end |λ|
end script
-- The accumulator, zipped with the tail of the
-- accumulator, yields pairs of adjacent sums so far.
zipWith3(plusGreaterOfTwoBelow, row, accum, tail(accum))
end |λ|
end script
-- A list of lists folded down to a list of just one remaining integer.
-- Head returns that integer from the list.
head(foldr1(sumWithRowBelow, xss))
end maxPathSum
-- TEST -----------------------------------------------------------------------
on run
maxPathSum({¬
{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} ¬
})
--> 1320
end run
-- GENERIC FUNCTIONS ----------------------------------------------------------
-- foldl :: (a -> b -> a) -> a -> [b] -> a
on foldl(f, startValue, xs)
tell mReturn(f)
set v to startValue
set lng to length of xs
repeat with i from 1 to lng
set v to |λ|(v, item i of xs, i, xs)
end repeat
return v
end tell
end foldl
-- foldr1 :: (a -> a -> a) -> [a] -> a
on foldr1(f, xs)
if length of xs > 1 then
tell mReturn(f)
set v to item -1 of xs
set lng to length of xs
repeat with i from lng - 1 to 1 by -1
set v to |λ|(item i of xs, v, i, xs)
end repeat
return v
end tell
else
xs
end if
end foldr1
-- head :: [a] -> a
on head(xs)
if length of xs > 0 then
item 1 of xs
else
missing value
end if
end head
-- max :: Ord a => a -> a -> a
on max(x, y)
if x > y then
x
else
y
end if
end max
-- min :: Ord a => a -> a -> a
on min(x, y)
if y < x then
y
else
x
end if
end min
-- minimum :: [a] -> a
on minimum(xs)
script min
on |λ|(a, x)
if x < a or a is missing value then
x
else
a
end if
end |λ|
end script
foldl(min, missing value, xs)
end minimum
-- Lift 2nd class handler function into 1st class script wrapper
-- mReturn :: Handler -> Script
on mReturn(f)
if class of f is script then
f
else
script
property |λ| : f
end script
end if
end mReturn
-- tail :: [a] -> [a]
on tail(xs)
if length of xs > 1 then
items 2 thru -1 of xs
else
{}
end if
end tail
-- zipWith3 :: (a -> b -> c -> d) -> [a] -> [b] -> [c] -> [d]
on zipWith3(f, xs, ys, zs)
set lng to minimum({length of xs, length of ys, length of zs})
set lst to {}
tell mReturn(f)
repeat with i from 1 to lng
set end of lst to |λ|(item i of xs, item i of ys, item i of zs)
end repeat
return lst
end tell
end zipWith3

View file

@ -0,0 +1,28 @@
fun solve(!tri):
while tri.size > 1:
let t0 = tri.pop()
for (i, t) in enumerate(tri[!0]):
tri[!0, i] = max(t0[i], t0[i+1]) + t
tri[0, 0]
let 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 data.lines.map |x| -> x.trim().split().map(int)

View file

@ -0,0 +1,26 @@
maxPathSum :: [[Int]] -> Int
maxPathSum = head . foldr1 ((<*> tail) . zipWith3 (\x y z -> x + max y z))
main :: IO ()
main =
print $
maxPathSum
[ [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]
]

View file

@ -0,0 +1,39 @@
var arr = [
[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]
];
while (arr.length !== 1) {
var len = arr.length;
var row = [];
var current = arr[len-2];
var currentLen = current.length - 1;
var end = arr[len-1];
for ( var i = 0; i <= currentLen; i++ ) {
row.push(Math.max(current[i] + end[i] || 0, current[i] + end[i+1] || 0) )
}
arr.pop();
arr.pop();
arr.push(row);
}
console.log(arr);

View file

@ -0,0 +1 @@
[ [ 1320 ] ]

View file

@ -0,0 +1,50 @@
(function () {
// Right fold using final element as initial accumulator
// (a -> a -> a) -> t a -> a
function foldr1(f, lst) {
return lst.length > 1 ? (
f(lst[0], foldr1(f, lst.slice(1)))
) : lst[0];
}
// function of arity 3 mapped over nth items of each of 3 lists
// (a -> b -> c -> d) -> [a] -> [b] -> [c] -> [d]
function zipWith3(f, xs, ys, zs) {
return zs.length ? [f(xs[0], ys[0], zs[0])].concat(
zipWith3(f, xs.slice(1), ys.slice(1), zs.slice(1))) : [];
}
// Evaluating from bottom up (right fold)
// and with recursion left to right (head and first item of tail at each stage)
return foldr1(
function (xs, ys) {
return zipWith3(
function (x, y, z) {
return x + (y < z ? z : y);
},
xs, ys, ys.slice(1) // item above, and larger of two below
);
}, [
[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]
]
)[0];
})();

View file

@ -0,0 +1,42 @@
function maximumTrianglePathSum(triangle) {
function distilLastLine() {
let lastLine = triangle.pop(),
aboveLine = triangle.pop();
for (let i = 0; i < aboveLine.length; i++)
aboveLine[i] = Math.max(
aboveLine[i] + lastLine[i],
aboveLine[i] + lastLine[i + 1]
);
triangle.push(aboveLine);
}
do {
distilLastLine();
} while (triangle.length > 1);
return triangle[0][0];
}
// testing
let theTriangle = [
[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]
];
console.log(maximumTrianglePathSum(theTriangle));

View file

@ -0,0 +1,88 @@
(() => {
'use strict';
// MAX PATH SUM -----------------------------------------------------------
// Working from the bottom of the triangle upwards,
// summing each number with the larger of the two below
// until the maximum emerges at the top.
// maxPathSum ::[[Int]] -> Int
const maxPathSum = xss =>
// A list of lists folded down to a list of just one remaining integer.
// The head function returns that integer from the list.
head(
foldr1(
// The accumulator, zipped with the tail of the
// accumulator, yields pairs of adjacent sums so far.
(ys, xs) => zipWith3(
// Plus greater of two below
(a, b, c) => a + max(b, c),
xs, ys, tail(ys)
),
xss
)
);
// GENERIC FUNCTIONS ------------------------------------------------------
// Right fold using final element as initial accumulator
// foldr1 :: (a -> a -> a) -> [a] -> a
const foldr1 = (f, xs) =>
xs.length > 0 ? init(xs)
.reduceRight(f, last(xs)) : [];
// head :: [a] -> a
const head = xs => xs.length ? xs[0] : undefined;
// init :: [a] -> [a]
const init = xs => xs.length ? xs.slice(0, -1) : undefined;
// last :: [a] -> a
const last = xs => xs.length ? xs.slice(-1)[0] : undefined;
// max :: Ord a => a -> a -> a
const max = (a, b) => b > a ? b : a;
// minimum :: [a] -> a
const minimum = xs =>
xs.reduce((a, x) => (x < a || a === undefined ? x : a), undefined);
// tail :: [a] -> [a]
const tail = xs => xs.length ? xs.slice(1) : undefined;
// Function of arity 3 mapped over nth items of each of 3 lists
// zipWith3 :: (a -> b -> c -> d) -> [a] -> [b] -> [c] -> [d]
const zipWith3 = (f, xs, ys, zs) =>
Array.from({
length: minimum([xs.length, ys.length, zs.length])
}, (_, i) => f(xs[i], ys[i], zs[i]));
// TEST -------------------------------------------------------------------
return maxPathSum([
[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,40 @@
// version 1.1.2
val tri = intArrayOf(
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
)
fun main(args: Array<String>) {
val triangles = arrayOf(tri.sliceArray(0..9), tri)
for (triangle in triangles) {
val size = triangle.size
val base = ((Math.sqrt(8.0 * size + 1.0) - 1.0)/ 2.0).toInt()
var step = base - 1
var stepc = 0
for (i in (size - base - 1) downTo 0) {
triangle[i] += maxOf(triangle[i + step], triangle[i + step + 1])
if (++stepc == step) {
step--
stepc = 0
}
}
println("Maximum total = ${triangle[0]}")
}
}

View file

@ -0,0 +1,27 @@
sequence 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}}
-- update each row from last but one upwards, with the larger
-- child, so the first step is to replace 6 with 6+27 or 6+2.
for r=length(tri)-1 to 1 by -1 do
for c=1 to length(tri[r]) do
tri[r][c] += max(tri[r+1][c..c+1])
end for
end for
?tri[1][1]

View file

@ -0,0 +1,8 @@
tri:=File("triangle.txt").pump(List,fcn(s){ s.strip().split(" ").apply("toInt") }).copy();
while(tri.len()>1){
t0:=tri.pop();
t1:=tri.pop();
tri.append( [[(it); t1.enumerate();
'wrap([(i,t)]){ t + t0[i].max(t0[i+1]) }]])
}
tri[0][0].println();

View file

@ -0,0 +1,4 @@
data:=File("triangle.txt").pump(List,fcn(s){ s.strip().split(" ").apply("toInt") });
fcn f(x,y,z){ x + y.max(z) }
fcn g(xs,ys){ Utils.zipWith(f,ys,xs,xs[1,*]); }
data.reverse().reduce(g)[0].println();

View file

@ -0,0 +1,11 @@
lines:=File("triangle.txt").pump(List,fcn(s){ s.strip().split(" ").apply("toInt") });
d:=lines[-1].copy();
foreach row in ([lines.len()-2..0,-1]){
d1:=d[1,*];
l :=d[0];
foreach i,u in (lines[row].enumerate()){
d[i] = u + l.max(r:=d1[i]);
l = r;
}
}
println(d[0]);