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,178 @@
-- equilibriumIndices :: [Int] -> [Int]
on equilibriumIndices(xs)
script balancedPair
on |λ|(a, pair, i)
set {x, y} to pair
if x = y then
{i - 1} & a
else
a
end if
end |λ|
end script
script plus
on |λ|(a, b)
a + b
end |λ|
end script
-- Fold over zipped pairs of sums from left
-- and sums from right
foldr(balancedPair, {}, ¬
zip(scanl1(plus, xs), scanr1(plus, xs)))
end equilibriumIndices
-- TEST -----------------------------------------------------------------------
on run
map(equilibriumIndices, {¬
{-7, 1, 5, 2, -4, 3, 0}, ¬
{2, 4, 6}, ¬
{2, 9, 2}, ¬
{1, -1, 1, -1, 1, -1, 1}, ¬
{1}, ¬
{}})
--> {{3, 6}, {}, {1}, {0, 1, 2, 3, 4, 5, 6}, {0}, {}}
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
-- foldr :: (a -> b -> a) -> a -> [b] -> a
on foldr(f, startValue, xs)
tell mReturn(f)
set v to startValue
set lng to length of xs
repeat with i from lng to 1 by -1
set v to |λ|(v, item i of xs, i, xs)
end repeat
return v
end tell
end foldr
-- init :: [a] -> [a]
on init(xs)
set lng to length of xs
if lng > 1 then
items 1 thru -2 of xs
else if lng > 0 then
{}
else
missing value
end if
end init
-- map :: (a -> b) -> [a] -> [b]
on map(f, xs)
tell mReturn(f)
set lng to length of xs
set lst to {}
repeat with i from 1 to lng
set end of lst to |λ|(item i of xs, i, xs)
end repeat
return lst
end tell
end map
-- min :: Ord a => a -> a -> a
on min(x, y)
if y < x then
y
else
x
end if
end min
-- 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
-- scanl :: (b -> a -> b) -> b -> [a] -> [b]
on scanl(f, startValue, xs)
tell mReturn(f)
set v to startValue
set lng to length of xs
set lst to {startValue}
repeat with i from 1 to lng
set v to |λ|(v, item i of xs, i, xs)
set end of lst to v
end repeat
return lst
end tell
end scanl
-- scanl1 :: (a -> a -> a) -> [a] -> [a]
on scanl1(f, xs)
if length of xs > 0 then
scanl(f, item 1 of xs, tail(xs))
else
{}
end if
end scanl1
-- scanr :: (b -> a -> b) -> b -> [a] -> [b]
on scanr(f, startValue, xs)
tell mReturn(f)
set v to startValue
set lng to length of xs
set lst to {startValue}
repeat with i from lng to 1 by -1
set v to |λ|(v, item i of xs, i, xs)
set end of lst to v
end repeat
return reverse of lst
end tell
end scanr
-- scanr1 :: (a -> a -> a) -> [a] -> [a]
on scanr1(f, xs)
if length of xs > 0 then
scanr(f, item -1 of xs, init(xs))
else
{}
end if
end scanr1
-- tail :: [a] -> [a]
on tail(xs)
if length of xs > 1 then
items 2 thru -1 of xs
else
{}
end if
end tail
-- zip :: [a] -> [b] -> [(a, b)]
on zip(xs, ys)
set lng to min(length of xs, length of ys)
set lst to {}
repeat with i from 1 to lng
set end of lst to {item i of xs, item i of ys}
end repeat
return lst
end zip

View file

@ -0,0 +1,27 @@
equilibriumIndices :: [Int] -> [Int]
equilibriumIndices xs =
foldr
(\(x, y, i) a ->
(if x == y
then i : a
else a))
[]
(zip3
(scanl1 (+) xs) -- Sums from the left
(scanr1 (+) xs) -- Sums from the right
[0 ..] -- Indices
)
-- TEST -----------------------------------------------------------------------
main :: IO ()
main =
mapM_
print
(equilibriumIndices <$>
[ [-7, 1, 5, 2, -4, 3, 0]
, [2, 4, 6]
, [2, 9, 2]
, [1, -1, 1, -1, 1, -1, 1]
, [1]
, []
])

View file

@ -0,0 +1,93 @@
(() => {
// EQUILIBRIUM INDICES ----------------------------------------------------
// equilibriumIndices :: [Int] -> [Int]
const equilibriumIndices = xs =>
foldr((a, [x, y], i) =>
x === y ? cons(i, a) : a,
[],
zip(
scanl1(plus, xs), // Sums from the left
scanr1(plus, xs) // Sums from the right
)
);
// GENERIC FUNCTIONS ------------------------------------------------------
// cons :: a -> [a] -> [a]
const cons = (x, xs) => [x].concat(xs);
// foldr (a -> b -> a) -> a -> [b] -> a
const foldr = (f, a, xs) => xs.reduceRight(f, a);
// map :: (a -> b) -> [a] -> [b]
const map = (f, xs) => xs.map(f);
// plus :: Num a => a -> a -> a
const plus = (a, b) => a + b;
// scanl :: (b -> a -> b) -> b -> [a] -> [b]
const scanl = (f, startValue, xs) =>
xs.reduce((a, x) => {
const v = f(a.acc, x);
return {
acc: v,
scan: a.scan.concat(v)
};
}, {
acc: startValue,
scan: [startValue]
})
.scan;
// scanl1 :: (a -> a -> a) -> [a] -> [a]
const scanl1 = (f, xs) =>
xs.length > 0 ? scanl(f, xs[0], xs.slice(1)) : [];
// scanr :: (b -> a -> b) -> b -> [a] -> [b]
const scanr = (f, startValue, xs) =>
xs.reduceRight((a, x) => {
const v = f(a.acc, x);
return {
acc: v,
scan: [v].concat(a.scan)
};
}, {
acc: startValue,
scan: [startValue]
})
.scan;
// scanr1 :: (a -> a -> a) -> [a] -> [a]
const scanr1 = (f, xs) =>
xs.length > 0 ? scanr(f, xs.slice(-1)[0], xs.slice(0, -1)) : [];
// Any value -> optional number of indents -> String
// show :: a -> String
// show :: a -> Int -> String
const show = (...x) =>
JSON.stringify.apply(
null, x.length > 1 ? [x[0], null, x[1]] : x
);
// tail :: [a] -> [a]
const tail = xs => xs.length ? xs.slice(1) : undefined;
// zip :: [a] -> [b] -> [(a,b)]
const zip = (xs, ys) =>
xs.slice(0, Math.min(xs.length, ys.length))
.map((x, i) => [x, ys[i]]);
// TEST -------------------------------------------------------------------
return show(
map(equilibriumIndices, [
[-7, 1, 5, 2, -4, 3, 0],
[2, 4, 6],
[2, 9, 2],
[1, -1, 1, -1, 1, -1, 1],
[1],
[]
])
);
// -> [[3, 6], [], [1], [0, 1, 2, 3, 4, 5, 6], [0], []]
})();

View file

@ -0,0 +1 @@
[[3,6],[],[1],[0,1,2,3,4,5,6],[0],[]]

View file

@ -0,0 +1,19 @@
# v0.6.0
function equindex2pass(data::Array)
rst = Array{Int}([])
suml, sumr, ddelayed = 0, sum(data), 0
for (i, d) in enumerate(data)
suml += ddelayed
sumr -= d
ddelayed = d
if suml == sumr
push!(rst, i)
end
end
return length(rst) > 0 ? rst : nothing
end
@show equindex2pass([1, -1, 1, -1, 1, -1, 1])
@show equindex2pass([1, 2, 2, 1])
@show equindex2pass([-7, 1, 5, 2, -4, 3, 0])

View file

@ -0,0 +1,25 @@
// version 1.1
fun equilibriumIndices(a: IntArray): MutableList<Int> {
val ei = mutableListOf<Int>()
if (a.isEmpty()) return ei // empty list
val sumAll = a.sumBy { it }
var sumLeft = 0
var sumRight: Int
for (i in 0 until a.size) {
sumRight = sumAll - sumLeft - a[i]
if (sumLeft == sumRight) ei.add(i)
sumLeft += a[i]
}
return ei
}
fun main(args: Array<String>) {
val a = intArrayOf(-7, 1, 5, 2, -4, 3, 0)
val ei = equilibriumIndices(a)
when (ei.size) {
0 -> println("There are no equilibrium indices")
1 -> println("The only equilibrium index is : ${ei[0]}")
else -> println("The equilibrium indices are : ${ei.joinToString(", ")}")
}
}

View file

@ -1,5 +1,5 @@
sub equilibrium_index(@list) {
my @a = [\+] @list;
my @b := reverse [\+] reverse @list;
my @b = reverse [\+] reverse @list;
^@list Zxx (@a »==« @b);
}

View file

@ -1,21 +1,17 @@
/*REXX program calculates and displays the equilibrium index for a numeric array (list).*/
parse arg x /*obtain the optional arguments from CL*/
if x='' then x=copies(" 7 -7", 50) 7 /*Not specified? Then use the default.*/
say ' array list: ' space(x) /*echo the array list to the terminal. */
n=words(x) /*the number of numbers in the X list.*/
do j=0 for n /*zero─start is for zero─based array. */
A.j=word(x, j+1) /*define the array element ───► A.j */
end /*j*/ /* [↑] assign A.0 A.1 A.3 ··· */
say ' array list: ' space(x) /*echo the array list to the terminal. */
#=words(x) /*the number of elements in the X list.*/
do j=0 for #; @.j=word(x, j+1) /*zero─start is for zero─based array. */
end /*j*/ /* [↑] assign @.0 @.1 @.3 ··· */
say /* ··· and also display a blank line. */
ans=equilibriumIDX(n) /*calculate the equilibrium index. */
say 'equilibrium' word("indices index", 1 + (words(ans==1)))': ' ans
answer=equilibriumIDX(); w=words(answer) /*calculate the equilibrium index. */
say 'equilibrium' word("(none) index: indices:", 1 + (w>0) + (w>1)) answer
exit /*stick a fork in it, we're all done. */
/*──────────────────────────────────────────────────────────────────────────────────────*/
equilibriumIDX: procedure expose A.; parse arg # /*expose the array A. (make global).*/
$= /*equilibrium indices (so far). */
do i=0 for #; sum=0
do k=0 for #; sum=sum + A.k*sign(k-i); end /*k*/
if sum=0 then $=$ i
end /*i*/
if $=='' then $="(none)" /*adjust if no indices were found. */
return strip($) /*return the equilibrium list. */
equilibriumIDX: $=; do i=0 for #; sum=0
do k=0 for #; sum=sum + @.k*sign(k-i); end /*k*/
if sum==0 then $=$ i
end /*i*/ /* [↑] Zero? Found an equilibrium index*/
return $ /*return equilibrium list (may be null)*/

View file

@ -0,0 +1,9 @@
fcn equilibrium(lst){ // two pass
reg acc=List(), left=0,right=lst.sum(0),i=0;
foreach x in (lst){
right-=x;
if(left==right) acc.write(i);
i+=1; left+=x;
}
acc
}

View file

@ -0,0 +1,3 @@
fcn equilibrium(lst){ // lst should immutable, n^2
(0).filter(lst.len(),'wrap(n){ lst[0,n].sum(0) == lst[n+1,*].sum(0) })
}

View file

@ -0,0 +1 @@
equilibrium(T(-7, 1, 5, 2, -4, 3, 0)).println();