Greatest subsequential sum: Difference between revisions

Content added Content deleted
(Rename Perl 6 -> Raku, alphabetize, minor clean-up)
Line 506: Line 506:
</pre>
</pre>


=={{header|Component Pascal}}==
Works with BlackBox Component Builder
<lang oberon2>
MODULE OvctGreatestSubsequentialSum;
IMPORT StdLog, Strings, Args;

PROCEDURE Gss(iseq: ARRAY OF INTEGER;OUT start, end, maxsum: INTEGER);
VAR
i,j,sum: INTEGER;
BEGIN
i := 0; maxsum := 0; start := 0; end := -1;
WHILE i < LEN(iseq) - 1 DO
sum := 0; j := i;
WHILE j < LEN(iseq) -1 DO
INC(sum ,iseq[j]);
IF sum > maxsum THEN
maxsum := sum;
start := i;
end := j
END;
INC(j);
END;
INC(i)
END
END Gss;

PROCEDURE Do*;
VAR
p: Args.Params;
iseq: POINTER TO ARRAY OF INTEGER;
i, res, start, end, sum: INTEGER;
BEGIN
Args.Get(p); (* Get Params *)
NEW(iseq,p.argc);
(* Transform params to INTEGERs *)
FOR i := 0 TO p.argc - 1 DO
Strings.StringToInt(p.args[i],iseq[i],res)
END;
Gss(iseq,start,end,sum);
StdLog.String("[");
FOR i := start TO end DO
StdLog.Int(iseq[i]);
IF i < end THEN StdLog.String(",") END
END;
StdLog.String("]=");StdLog.Int(sum);StdLog.Ln;
END Do;

END OvctGreatestSubsequentialSum.
</lang>
Execute: <br/>
<pre>
[Ctrl-Q]OvctGreatestSubsequentialSum.Do -1 -2 3 5 6 -2 -1 4 -4 2 -2 ~
[Ctrl-Q]OvctGreatestSubsequentialSum.Do -1 -5 -3 ~
</pre>
{{out}}
<pre>
[ 3, 5, 6, -2, -1, 4]= 15
[]= 0
</pre>
=={{header|Bracmat}}==
=={{header|Bracmat}}==


Line 648: Line 589:
<pre>Max sum = 15
<pre>Max sum = 15
3 5 6 -2 -1 4 </pre>
3 5 6 -2 -1 4 </pre>

=={{header|C sharp|C#}}==
'''The challange'''
<lang csharp>using System;

namespace Tests_With_Framework_4
{
class Program
{
static void Main(string[] args)
{
int[] integers = { -1, -2, 3, 5, 6, -2, -1, 4, -4, 2, -1 }; int length = integers.Length;
int maxsum, beginmax, endmax, sum; maxsum = beginmax = sum = 0; endmax = -1;

for (int i = 0; i < length; i++)
{
sum = 0;
for (int k = i; k < length; k++)
{
sum += integers[k];
if (sum > maxsum)
{
maxsum = sum;
beginmax = i;
endmax = k;
}
}
}

for (int i = beginmax; i <= endmax; i++)
Console.WriteLine(integers[i]);

Console.ReadKey();
}
}
}</lang>


=={{header|C++}}==
=={{header|C++}}==
Line 738: Line 715:


return 0;
return 0;
}</lang>

=={{header|C sharp|C#}}==
'''The challange'''
<lang csharp>using System;

namespace Tests_With_Framework_4
{
class Program
{
static void Main(string[] args)
{
int[] integers = { -1, -2, 3, 5, 6, -2, -1, 4, -4, 2, -1 }; int length = integers.Length;
int maxsum, beginmax, endmax, sum; maxsum = beginmax = sum = 0; endmax = -1;

for (int i = 0; i < length; i++)
{
sum = 0;
for (int k = i; k < length; k++)
{
sum += integers[k];
if (sum > maxsum)
{
maxsum = sum;
beginmax = i;
endmax = k;
}
}
}

for (int i = beginmax; i <= endmax; i++)
Console.WriteLine(integers[i]);

Console.ReadKey();
}
}
}</lang>
}</lang>


Line 861: Line 802:
if (= sum max) do (setf max-subsequence subsequence)
if (= sum max) do (setf max-subsequence subsequence)
finally (return max-subsequence))))</lang>
finally (return max-subsequence))))</lang>

=={{header|Component Pascal}}==
Works with BlackBox Component Builder
<lang oberon2>
MODULE OvctGreatestSubsequentialSum;
IMPORT StdLog, Strings, Args;

PROCEDURE Gss(iseq: ARRAY OF INTEGER;OUT start, end, maxsum: INTEGER);
VAR
i,j,sum: INTEGER;
BEGIN
i := 0; maxsum := 0; start := 0; end := -1;
WHILE i < LEN(iseq) - 1 DO
sum := 0; j := i;
WHILE j < LEN(iseq) -1 DO
INC(sum ,iseq[j]);
IF sum > maxsum THEN
maxsum := sum;
start := i;
end := j
END;
INC(j);
END;
INC(i)
END
END Gss;

PROCEDURE Do*;
VAR
p: Args.Params;
iseq: POINTER TO ARRAY OF INTEGER;
i, res, start, end, sum: INTEGER;
BEGIN
Args.Get(p); (* Get Params *)
NEW(iseq,p.argc);
(* Transform params to INTEGERs *)
FOR i := 0 TO p.argc - 1 DO
Strings.StringToInt(p.args[i],iseq[i],res)
END;
Gss(iseq,start,end,sum);
StdLog.String("[");
FOR i := start TO end DO
StdLog.Int(iseq[i]);
IF i < end THEN StdLog.String(",") END
END;
StdLog.String("]=");StdLog.Int(sum);StdLog.Ln;
END Do;

END OvctGreatestSubsequentialSum.
</lang>
Execute: <br/>
<pre>
[Ctrl-Q]OvctGreatestSubsequentialSum.Do -1 -2 3 5 6 -2 -1 4 -4 2 -2 ~
[Ctrl-Q]OvctGreatestSubsequentialSum.Do -1 -5 -3 ~
</pre>
{{out}}
<pre>
[ 3, 5, 6, -2, -1, 4]= 15
[]= 0
</pre>


=={{header|D}}==
=={{header|D}}==
Line 938: Line 939:
[-1, -2, -3, -5, -6, -2, -1, -4, -4, -2, -1].maxSubseq.writeln;
[-1, -2, -3, -5, -6, -2, -1, -4, -4, -2, -1].maxSubseq.writeln;
}</lang>
}</lang>

=={{header|E}}==
This implementation tests every combination, but it first examines the sequence to reduce the number of combinations tried: We need not consider beginning the subsequence at any point which is not the beginning, or a change from negative to positive. We need not consider ending the subsequence at any point which is not the end, or a change from positive to negative. (Zero is moot and treated as negative.)

This algorithm is therefore <math>O(nm^2)</math> where <math>n</math> is the size of the sequence and <math>m</math> is the number of sign changes in the sequence. [[User:Kevin Reid|I]] think it could be improved to <math>O(n + m^2)</math> by recording the positive and negative intervals' sums during the initial pass and accumulating the sum of those sums in the inner for loop.

<code>maxSubseq</code> returns both the maximum sum found, and the interval of indexes which produces it.

<lang e>pragma.enable("accumulator")

def maxSubseq(seq) {
def size := seq.size()

# Collect all intervals of indexes whose values are positive
def intervals := {
var intervals := []
var first := 0
while (first < size) {
var next := first
def seeing := seq[first] > 0
while (next < size && (seq[next] > 0) == seeing) {
next += 1
}
if (seeing) { # record every positive interval
intervals with= first..!next
}
first := next
}
intervals
}
# For recording the best result found
var maxValue := 0
var maxInterval := 0..!0
# Try all subsequences beginning and ending with such intervals.
for firstIntervalIx => firstInterval in intervals {
for lastInterval in intervals(firstIntervalIx) {
def interval :=
(firstInterval.getOptStart())..!(lastInterval.getOptBound())
def value :=
accum 0 for i in interval { _ + seq[i] }
if (value > maxValue) {
maxValue := value
maxInterval := interval
}
}
}
return ["value" => maxValue,
"indexes" => maxInterval]
}</lang>

<lang e>def seq := [-1, -2, 3, 5, 6, -2, -1, 4, -4, 2, -1]
def [=> value, => indexes] := maxSubseq(seq)
println(`$\
Sequence: $seq
Maximum subsequence sum: $value
Indexes: ${indexes.getOptStart()}..${indexes.getOptBound().previous()}
Subsequence: ${seq(indexes.getOptStart(), indexes.getOptBound())}
`)</lang>


=={{header|EchoLisp}}==
=={{header|EchoLisp}}==
Line 1,180: Line 1,242:
>test
>test
</lang>
</lang>

=={{header|E}}==
This implementation tests every combination, but it first examines the sequence to reduce the number of combinations tried: We need not consider beginning the subsequence at any point which is not the beginning, or a change from negative to positive. We need not consider ending the subsequence at any point which is not the end, or a change from positive to negative. (Zero is moot and treated as negative.)

This algorithm is therefore <math>O(nm^2)</math> where <math>n</math> is the size of the sequence and <math>m</math> is the number of sign changes in the sequence. [[User:Kevin Reid|I]] think it could be improved to <math>O(n + m^2)</math> by recording the positive and negative intervals' sums during the initial pass and accumulating the sum of those sums in the inner for loop.

<code>maxSubseq</code> returns both the maximum sum found, and the interval of indexes which produces it.

<lang e>pragma.enable("accumulator")

def maxSubseq(seq) {
def size := seq.size()

# Collect all intervals of indexes whose values are positive
def intervals := {
var intervals := []
var first := 0
while (first < size) {
var next := first
def seeing := seq[first] > 0
while (next < size && (seq[next] > 0) == seeing) {
next += 1
}
if (seeing) { # record every positive interval
intervals with= first..!next
}
first := next
}
intervals
}
# For recording the best result found
var maxValue := 0
var maxInterval := 0..!0
# Try all subsequences beginning and ending with such intervals.
for firstIntervalIx => firstInterval in intervals {
for lastInterval in intervals(firstIntervalIx) {
def interval :=
(firstInterval.getOptStart())..!(lastInterval.getOptBound())
def value :=
accum 0 for i in interval { _ + seq[i] }
if (value > maxValue) {
maxValue := value
maxInterval := interval
}
}
}
return ["value" => maxValue,
"indexes" => maxInterval]
}</lang>

<lang e>def seq := [-1, -2, 3, 5, 6, -2, -1, 4, -4, 2, -1]
def [=> value, => indexes] := maxSubseq(seq)
println(`$\
Sequence: $seq
Maximum subsequence sum: $value
Indexes: ${indexes.getOptStart()}..${indexes.getOptBound().previous()}
Subsequence: ${seq(indexes.getOptStart(), indexes.getOptBound())}
`)</lang>


=={{header|Euphoria}}==
=={{header|Euphoria}}==
Line 1,270: Line 1,271:
{}
{}
{}</pre>
{}</pre>



=={{header|F_Sharp|F#}}==
=={{header|F_Sharp|F#}}==
Line 1,922: Line 1,922:
end sub
end sub
</lang>
</lang>

=={{header|Lua}}==
=={{header|Lua}}==
<lang lua>function sumt(t, start, last) return start <= last and t[start] + sumt(t, start+1, last) or 0 end
<lang lua>function sumt(t, start, last) return start <= last and t[start] + sumt(t, start+1, last) or 0 end
Line 2,402: Line 2,403:


print "@maxsubarray\n";</lang>
print "@maxsubarray\n";</lang>

=={{header|Perl 6}}==
{{trans|Python}}

{{works with|Rakudo|2016.12}}

<lang perl6>sub max-subseq (*@a) {
my ($start, $end, $sum, $maxsum) = -1, -1, 0, 0;
for @a.kv -> $i, $x {
$sum += $x;
if $maxsum < $sum {
($maxsum, $end) = $sum, $i;
}
elsif $sum < 0 {
($sum, $start) = 0, $i;
}
}
return @a[$start ^.. $end];
}</lang>

Another solution, not translated from any other language:

For each starting position, we calculate all the subsets starting at that position.
They are combined with the best subset ($max-subset) from previous loops, to form (@subsets).
The best of those @subsets is saved at the new $max-subset.

Consuming the array (.shift) allows us to skip tracking the starting point; it is always 0.

The empty sequence is used to initialize $max-subset, which fulfils the "all negative" requirement of the problem.

<lang perl6>sub max-subseq ( *@a ) {

my $max-subset = ();
while @a {
my @subsets = [\,] @a;
@subsets.push: $max-subset;
$max-subset = @subsets.max: { [+] .list };
@a.shift;
}

return $max-subset;
}

max-subseq( -1, -2, 3, 5, 6, -2, -1, 4, -4, 2, -1 ).say;
max-subseq( -2, -2, -1, 3, 5, 6, -1, 4, -4, 2, -1 ).say;
max-subseq( -2, -2, -1, -3, -5, -6, -1, -4, -4, -2, -1 ).say;</lang>

{{out}}
<pre>
(3 5 6 -2 -1 4)
(3 5 6 -1 4)
()</pre>


=={{header|Phix}}==
=={{header|Phix}}==
Line 2,875: Line 2,824:
15
15
</lang>
</lang>

=={{header|Raku}}==
(formerly Perl 6)
{{trans|Python}}

{{works with|Rakudo|2016.12}}

<lang perl6>sub max-subseq (*@a) {
my ($start, $end, $sum, $maxsum) = -1, -1, 0, 0;
for @a.kv -> $i, $x {
$sum += $x;
if $maxsum < $sum {
($maxsum, $end) = $sum, $i;
}
elsif $sum < 0 {
($sum, $start) = 0, $i;
}
}
return @a[$start ^.. $end];
}</lang>

Another solution, not translated from any other language:

For each starting position, we calculate all the subsets starting at that position.
They are combined with the best subset ($max-subset) from previous loops, to form (@subsets).
The best of those @subsets is saved at the new $max-subset.

Consuming the array (.shift) allows us to skip tracking the starting point; it is always 0.

The empty sequence is used to initialize $max-subset, which fulfils the "all negative" requirement of the problem.

<lang perl6>sub max-subseq ( *@a ) {

my $max-subset = ();
while @a {
my @subsets = [\,] @a;
@subsets.push: $max-subset;
$max-subset = @subsets.max: { [+] .list };
@a.shift;
}

return $max-subset;
}

max-subseq( -1, -2, 3, 5, 6, -2, -1, 4, -4, 2, -1 ).say;
max-subseq( -2, -2, -1, 3, 5, 6, -1, 4, -4, 2, -1 ).say;
max-subseq( -2, -2, -1, -3, -5, -6, -1, -4, -4, -2, -1 ).say;</lang>

{{out}}
<pre>
(3 5 6 -2 -1 4)
(3 5 6 -1 4)
()</pre>


=={{header|Raven}}==
=={{header|Raven}}==
Line 3,140: Line 3,142:
{{out}}
{{out}}
<pre>Sum: 3, 5, 6, -2, -1, 4, = 15</pre>
<pre>Sum: 3, 5, 6, -2, -1, 4, = 15</pre>



=={{header|Rust}}==
=={{header|Rust}}==