Decreasing contiguous subsequences
Given a List (abstract data type) of integer values, find all its maximal-length non-increasing subsequences. Categorize each of these subsequences by its percentage change using the following groups:
- Greater than 0% and less than 4%
- Greater than or equal to 4% and less than 8%
- Greater than or equal to 8% and less than 12%
- Greater than or equal to 12% and less than 16%
- Greater than or equal to 16% and less than 25%
- Greater than or equal to 25%
If we were to plot these values, we'd be looking for peaks and troughs, categorized by the difference between the local maximum and the local minimum, as a percentage of the local maximum.
Using the following example sequence, display the count of subsequences per group.
90, 90, 90, 91, 91, 92, 92, 92, 91, 91, 91, 90, 90, 90, 89, 89, 88, 87, 87, 87, 86, 86, 86, 85, 85, 86, 86, 87, 87, 88, 89, 89, 89, 90, 90, 91, 91, 91, 92, 92, 92, 92, 92, 92, 92, 92, 92, 91, 91, 90, 90, 90, 90, 90, 89, 89, 89, 89, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 89, 89, 89, 89, 89, 89, 90, 90, 90, 89, 89, 89, 89, 89, 89, 88, 88, 88, 88, 88, 88, 87, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 89, 89, 89, 89, 89, 88, 88, 88, 88, 88, 88, 89, 89, 89, 89, 89, 89, 89, 89, 88, 88, 88, 88, 88, 88, 88, 88, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 88, 88, 88, 88, 88, 88, 88, 88, 88, 89, 89, 89, 89, 89, 89, 89, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 88, 88, 88, 87, 87, 87, 87, 86, 86, 86, 86, 86, 86, 87, 87, 87, 87, 87, 87, 87, 88, 88, 88, 88, 88, 88, 88, 88, 88, 89, 89, 89, 89, 89, 89, 89, 88, 88, 88, 88, 88, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 89, 89, 91, 94, 94, 95, 96, 96, 96, 97, 97, 96, 96, 96, 96, 95, 95, 94, 93, 93, 92, 92, 91, 91, 90, 89, 89, 88, 86, 86, 85, 83, 83, 81, 80, 80, 80, 79, 79, 79, 78, 78, 79, 81, 82, 82, 85, 89, 89, 91, 93, 93, 94, 95, 95, 95, 95, 95, 95, 95, 95, 95, 94, 94, 94, 94, 93, 93, 93, 92, 92, 91, 91, 91, 90, 90, 90, 88, 87, 87, 86, 85, 85, 84, 84, 84, 83, 84, 84, 84, 85, 86, 86, 87, 87, 87, 88, 88, 88, 89, 90, 90, 90, 91, 91, 92, 92, 92, 93, 94, 94, 94, 95, 95, 95, 95, 94, 94, 94, 93, 93, 93, 92, 92, 92, 91, 91, 90, 89, 89, 87, 86, 85, 85, 84, 83, 83, 82, 82, 82, 81, 81, 81, 81, 81, 81, 82, 85, 85, 86, 89, 89, 91, 92, 93, 93, 93, 94, 94, 94, 94, 94, 94, 94, 94, 94, 93, 93, 93, 92, 92, 92, 91, 91, 91, 90, 89, 89, 88, 88, 88, 87, 87, 87, 86, 86, 86, 85, 85, 85, 85, 85, 85, 86, 87, 87, 87, 88, 88, 88, 88, 88, 88, 89, 89, 89, 89, 89, 89, 90, 90, 90, 90, 91, 91, 92, 93, 93, 94, 94, 95, 95, 95, 96, 96, 96, 95, 95, 95, 94, 94, 93, 93, 93, 92, 90, 90, 89, 87, 87, 87, 85, 83, 83, 82, 81, 81, 81, 80, 80, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 81, 83, 86, 88, 88, 90, 91, 91, 91, 92, 92, 93, 93, 93, 94, 95, 95, 95, 96, 96, 96, 96, 96, 96, 96, 95, 95, 95, 95, 95, 94, 93, 93, 92, 92, 92, 91, 90, 90, 90, 90, 90, 91, 93, 93, 94, 94, 94, 94, 95, 94, 94, 94, 94, 94, 94, 93, 93, 93, 93, 93, 93, 92, 92, 92, 92, 92, 91, 91, 91, 91, 91, 91, 91, 91, 90, 90, 90, 90, 90, 90, 90, 90, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 90, 90, 90, 90, 91, 91, 92, 93, 93, 93, 94, 94, 94, 94, 94, 94, 94, 94, 94, 95, 95, 95, 95, 95, 95, 95, 95, 95, 94, 93, 93, 93, 93, 93, 92, 92, 92, 91, 91, 91, 91, 90, 90, 90, 89, 89, 89, 88, 88, 88, 88, 88, 88, 88, 88, 88, 89, 89, 89, 89, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 91, 92, 92, 93, 93, 93, 93, 94, 94, 94, 93, 93, 93, 93, 93, 93, 92, 92, 92, 91, 91, 91, 90, 90, 90, 89, 88, 88, 87, 87, 87, 86, 86, 85, 85, 85, 86, 86, 86, 87, 87, 88, 88, 88, 89, 90, 90, 90, 91, 91, 91, 91, 91, 91, 91, 91, 91, 92, 92, 92, 93, 93, 93, 93, 93, 93, 93, 92, 92, 92, 91, 91, 90, 90, 90, 89, 88, 87, 87, 87, 86, 86, 86, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 86, 86, 86, 86, 87, 88, 88, 88, 89, 89, 90, 91, 91, 92, 93, 93, 93, 94, 94, 94, 94, 94, 94, 94, 94, 94, 93, 93, 93, 92, 92, 92, 91, 90, 90, 90, 89, 89, 88, 88, 88, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 88, 88, 88, 90, 90, 91, 93, 93, 93, 93, 93, 94, 93, 93, 93, 93, 93, 93, 92, 92, 92, 91, 91, 91, 90, 90, 90, 89, 89, 89, 88, 87, 87, 87, 87, 87, 86, 87, 87, 87, 87, 87, 87, 87, 87, 87, 88, 88, 88, 88, 88, 88, 88, 89
It's OK to hard code the example sequence or read it from a file. Plotting decreasing subsequences is optional.
ALGOL 68
BEGIN # find non-ascending subsequences in a list of integer values and #
# count those with the percentage change in various ranges #
# mode to hold the details of a non-ascending sequence #
MODE SEQUENCE = STRUCT( INT start index, end index );
# returns the next non-ascending SEQUENCE from data starting at prev, #
# or a SEQUENCE with start index > end index if there isn't one #
PRIO NEXTSEQUENCE = 1;
OP NEXTSEQUENCE = ( []INT data, SEQUENCE prev )SEQUENCE:
IF INT s pos = end index OF prev + 1;
s pos > UPB data
THEN SEQUENCE( s pos, UPB data ) # reached the end of the data #
ELSE INT value := data[ s pos ]; # still some data left #
INT e pos := s pos + 1;
WHILE IF e pos > UPB data THEN FALSE ELSE data[ e pos ] <= value FI
DO
value := data[ e pos ];
e pos +:= 1
OD;
SEQUENCE( s pos, e pos - 1 )
FI # NEXTSEQUENCE # ;
# returns the first non-ascending SEQUENCE from data #
# or a SEQUENCE with start index > end index if there isn't one #
OP FIRSTSEQUENCE = ( []INT data )SEQUENCE:
IF LWB data > UPB data
THEN SEQUENCE( LWB data, UPB data ) # data has no elements #
ELSE # data is not empty #
data NEXTSEQUENCE SEQUENCE( -1, LWB data - 1 )
FI # FIRSTSEQUENCE # ;
# count the non-ascending SEQUENCEs in data, grouping by the percentage #
# changes in the specified ranges #
# ranges must be the upper bound of the required range and must be #
# specified in order, the first range will start at 0, there will be a #
# final element for percentages >= the final range #
# SEQUENCEs with a single element or 0 percentage change are ignored #
# returns the counts #
PRIO COUNTCHANGESBYPERCENTAGE = 1;
OP COUNTCHANGESBYPERCENTAGE = ( []INT data, ranges )[]INT:
BEGIN
[ LWB ranges : UPB ranges + 1 ]INT counts;
FOR i FROM LWB counts TO UPB counts DO counts[ i ] := 0 OD;
SEQUENCE prev := FIRSTSEQUENCE data;
WHILE INT start pos = start index OF prev;
INT end pos = end index OF prev;
end pos >= start pos
DO
IF end pos > start pos THEN # more than one element #
INT s value = data[ start pos ], e value = data[ end pos ];
REAL change = ( ( s value - e value ) / s value ) * 100;
IF change > 0 THEN # there was a decrease #
BOOL found := FALSE;
FOR i FROM LWB counts TO UPB counts - 1 WHILE NOT found DO
IF found := ranges[ i ] > change THEN counts[ i ] +:= 1 FI
OD;
IF NOT found THEN counts[ UPB counts ] +:= 1 FI
FI
FI;
prev := data NEXTSEQUENCE prev
OD;
counts
END # COUNTCHANGESBYPERCEBTAGE # ;
BEGIN # task test case #
[]INT ranges = ( 4, 8, 12, 16, 25 );
[]INT data = (
90, 90, 90, 91, 91, 92, 92, 92, 91, 91, 91, 90, 90, 90, 89, 89, 88, 87, 87, 87, 86, 86, 86, 85, 85,
86, 86, 87, 87, 88, 89, 89, 89, 90, 90, 91, 91, 91, 92, 92, 92, 92, 92, 92, 92, 92, 92, 91, 91, 90,
90, 90, 90, 90, 89, 89, 89, 89, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 89, 89, 89, 89, 89,
89, 90, 90, 90, 89, 89, 89, 89, 89, 89, 88, 88, 88, 88, 88, 88, 87, 88, 88, 88, 88, 88, 88, 88, 88,
88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 89, 89, 89, 89, 89, 88, 88, 88, 88, 88, 88, 89,
89, 89, 89, 89, 89, 89, 89, 88, 88, 88, 88, 88, 88, 88, 88, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87,
87, 87, 88, 88, 88, 88, 88, 88, 88, 88, 88, 89, 89, 89, 89, 89, 89, 89, 88, 88, 88, 88, 88, 88, 88,
88, 88, 88, 88, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 88, 88, 88, 87, 87, 87, 87, 86, 86, 86, 86,
86, 86, 87, 87, 87, 87, 87, 87, 87, 88, 88, 88, 88, 88, 88, 88, 88, 88, 89, 89, 89, 89, 89, 89, 89,
88, 88, 88, 88, 88, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 89, 89, 91,
94, 94, 95, 96, 96, 96, 97, 97, 96, 96, 96, 96, 95, 95, 94, 93, 93, 92, 92, 91, 91, 90, 89, 89, 88,
86, 86, 85, 83, 83, 81, 80, 80, 80, 79, 79, 79, 78, 78, 79, 81, 82, 82, 85, 89, 89, 91, 93, 93, 94,
95, 95, 95, 95, 95, 95, 95, 95, 95, 94, 94, 94, 94, 93, 93, 93, 92, 92, 91, 91, 91, 90, 90, 90, 88,
87, 87, 86, 85, 85, 84, 84, 84, 83, 84, 84, 84, 85, 86, 86, 87, 87, 87, 88, 88, 88, 89, 90, 90, 90,
91, 91, 92, 92, 92, 93, 94, 94, 94, 95, 95, 95, 95, 94, 94, 94, 93, 93, 93, 92, 92, 92, 91, 91, 90,
89, 89, 87, 86, 85, 85, 84, 83, 83, 82, 82, 82, 81, 81, 81, 81, 81, 81, 82, 85, 85, 86, 89, 89, 91,
92, 93, 93, 93, 94, 94, 94, 94, 94, 94, 94, 94, 94, 93, 93, 93, 92, 92, 92, 91, 91, 91, 90, 89, 89,
88, 88, 88, 87, 87, 87, 86, 86, 86, 85, 85, 85, 85, 85, 85, 86, 87, 87, 87, 88, 88, 88, 88, 88, 88,
89, 89, 89, 89, 89, 89, 90, 90, 90, 90, 91, 91, 92, 93, 93, 94, 94, 95, 95, 95, 96, 96, 96, 95, 95,
95, 94, 94, 93, 93, 93, 92, 90, 90, 89, 87, 87, 87, 85, 83, 83, 82, 81, 81, 81, 80, 80, 81, 81, 81,
81, 81, 81, 81, 81, 81, 81, 81, 81, 83, 86, 88, 88, 90, 91, 91, 91, 92, 92, 93, 93, 93, 94, 95, 95,
95, 96, 96, 96, 96, 96, 96, 96, 95, 95, 95, 95, 95, 94, 93, 93, 92, 92, 92, 91, 90, 90, 90, 90, 90,
91, 93, 93, 94, 94, 94, 94, 95, 94, 94, 94, 94, 94, 94, 93, 93, 93, 93, 93, 93, 92, 92, 92, 92, 92,
91, 91, 91, 91, 91, 91, 91, 91, 90, 90, 90, 90, 90, 90, 90, 90, 89, 89, 89, 89, 89, 89, 89, 89, 89,
89, 90, 90, 90, 90, 91, 91, 92, 93, 93, 93, 94, 94, 94, 94, 94, 94, 94, 94, 94, 95, 95, 95, 95, 95,
95, 95, 95, 95, 94, 93, 93, 93, 93, 93, 92, 92, 92, 91, 91, 91, 91, 90, 90, 90, 89, 89, 89, 88, 88,
88, 88, 88, 88, 88, 88, 88, 89, 89, 89, 89, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 91, 91, 91, 91,
91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 91, 92,
92, 93, 93, 93, 93, 94, 94, 94, 93, 93, 93, 93, 93, 93, 92, 92, 92, 91, 91, 91, 90, 90, 90, 89, 88,
88, 87, 87, 87, 86, 86, 85, 85, 85, 86, 86, 86, 87, 87, 88, 88, 88, 89, 90, 90, 90, 91, 91, 91, 91,
91, 91, 91, 91, 91, 92, 92, 92, 93, 93, 93, 93, 93, 93, 93, 92, 92, 92, 91, 91, 90, 90, 90, 89, 88,
87, 87, 87, 86, 86, 86, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 86, 86, 86, 86, 87, 88, 88, 88,
89, 89, 90, 91, 91, 92, 93, 93, 93, 94, 94, 94, 94, 94, 94, 94, 94, 94, 93, 93, 93, 92, 92, 92, 91,
90, 90, 90, 89, 89, 88, 88, 88, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 88, 88, 88,
90, 90, 91, 93, 93, 93, 93, 93, 94, 93, 93, 93, 93, 93, 93, 92, 92, 92, 91, 91, 91, 90, 90, 90, 89,
89, 89, 88, 87, 87, 87, 87, 87, 86, 87, 87, 87, 87, 87, 87, 87, 87, 87, 88, 88, 88, 88, 88, 88, 88,
89 );
# shows start percentage, end percentage and count #
PROC show range count = ( INT p start, p end, count )VOID:
print( ( IF p start = 0 THEN "(" ELSE "[" FI
, whole( p start, -3 ), "% .. ", whole( p end, -3 ), "% "
, IF p end = 100 THEN "]" ELSE ")" FI, ": ", whole( count, 0 )
, newline ) );
[]INT counts = data COUNTCHANGESBYPERCENTAGE ranges;
INT r start := 0;
FOR i FROM LWB counts TO UPB counts - 1 DO
show range count( r start, ranges[ i ], counts[ i ] );
r start := ranges[ i ]
OD;
IF r start < 100 THEN show range count( r start, 100, counts[ UPB counts ] ) FI
END
END
- Output:
( 0% .. 4% ): 7 [ 4% .. 8% ): 6 [ 8% .. 12% ): 4 [ 12% .. 16% ): 2 [ 16% .. 25% ): 2 [ 25% .. 100% ]: 0
DuckDB
Some possible points of interest:
- the use of regexp_extract_all() for parsing and of unnest() for creating a column vector
- the use of lag() and sum() for identifying the subsequences
Note also that intermediate tables are retained to facilitate understanding and reuse but are inessential.
The input as shown in the problem description is assumed to be in a text file named `input.txt`. The program will actually parse the input for all non-negative integers quite flexibly.
# The data
create or replace table sequence as (
select row_number() over () as id, c::INTEGER as c
from (select unnest(regexp_extract_all(content, '[0-9]+') ) as c
from read_text('input.txt') )
);
# The buckets
create or replace function bucketize(value) as (
case
when value <= 0 then NULL
when value <= 4 then 4
when value < 8 then 8
when value < 12 then 12
when value < 16 then 16
when value < 25 then 25
else 100
end
);
# Add a flag to signal the start of a new subsequence, and then form partitions
create or replace table partitions as (
select *, sum(flag) over (order by id) as partition_number
from (select *, if(id=1 or (c > (lag(c) over ())), 1, 0) as flag
from sequence)
);
# The classification
select histogram(decline) as buckets
from (select partition_number,
bucketize( 100 * (max(c) - min(c)) / max(c)) as decline
from partitions
group by partition_number);
- Output:
┌──────────────────────────────┐ │ buckets │ │ map(integer, ubigint) │ ├──────────────────────────────┤ │ {4=7, 8=6, 12=4, 16=2, 25=2} │ └──────────────────────────────┘
EasyLang
global seq[] .
proc read . .
repeat
s$ = input
until s$ = ""
for e in number strsplit s$ ","
seq[] &= e
.
.
.
read
func[] percdesc a[] .
init = a[1]
prev = init
for i = 2 to len a[]
if a[i] > prev
if prev <> init
percents[] &= 100 * (init - prev) / init
.
prev = a[i]
init = a[i]
else
prev = a[i - 1]
.
.
return percents[]
.
bin[] = [ 4 8 12 16 25 101 ]
func[] countbins percents[] .
len cnts[] len bin[]
for p in percents[]
i = 1
while p >= bin[i]
i += 1
.
cnts[i] += 1
.
return cnts[]
.
print countbins percdesc seq[]
#
input_data
90, 90, 90, 91, 91, 92, 92, 92, 91, 91, 91, 90, 90, 90, 89, 89, 88, 87, 87, 87, 86, 86, 86, 85, 85,
86, 86, 87, 87, 88, 89, 89, 89, 90, 90, 91, 91, 91, 92, 92, 92, 92, 92, 92, 92, 92, 92, 91, 91, 90,
90, 90, 90, 90, 89, 89, 89, 89, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 89, 89, 89, 89, 89,
89, 90, 90, 90, 89, 89, 89, 89, 89, 89, 88, 88, 88, 88, 88, 88, 87, 88, 88, 88, 88, 88, 88, 88, 88,
88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 89, 89, 89, 89, 89, 88, 88, 88, 88, 88, 88, 89,
89, 89, 89, 89, 89, 89, 89, 88, 88, 88, 88, 88, 88, 88, 88, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87,
87, 87, 88, 88, 88, 88, 88, 88, 88, 88, 88, 89, 89, 89, 89, 89, 89, 89, 88, 88, 88, 88, 88, 88, 88,
88, 88, 88, 88, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 88, 88, 88, 87, 87, 87, 87, 86, 86, 86, 86,
86, 86, 87, 87, 87, 87, 87, 87, 87, 88, 88, 88, 88, 88, 88, 88, 88, 88, 89, 89, 89, 89, 89, 89, 89,
88, 88, 88, 88, 88, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 89, 89, 91,
94, 94, 95, 96, 96, 96, 97, 97, 96, 96, 96, 96, 95, 95, 94, 93, 93, 92, 92, 91, 91, 90, 89, 89, 88,
86, 86, 85, 83, 83, 81, 80, 80, 80, 79, 79, 79, 78, 78, 79, 81, 82, 82, 85, 89, 89, 91, 93, 93, 94,
95, 95, 95, 95, 95, 95, 95, 95, 95, 94, 94, 94, 94, 93, 93, 93, 92, 92, 91, 91, 91, 90, 90, 90, 88,
87, 87, 86, 85, 85, 84, 84, 84, 83, 84, 84, 84, 85, 86, 86, 87, 87, 87, 88, 88, 88, 89, 90, 90, 90,
91, 91, 92, 92, 92, 93, 94, 94, 94, 95, 95, 95, 95, 94, 94, 94, 93, 93, 93, 92, 92, 92, 91, 91, 90,
89, 89, 87, 86, 85, 85, 84, 83, 83, 82, 82, 82, 81, 81, 81, 81, 81, 81, 82, 85, 85, 86, 89, 89, 91,
92, 93, 93, 93, 94, 94, 94, 94, 94, 94, 94, 94, 94, 93, 93, 93, 92, 92, 92, 91, 91, 91, 90, 89, 89,
88, 88, 88, 87, 87, 87, 86, 86, 86, 85, 85, 85, 85, 85, 85, 86, 87, 87, 87, 88, 88, 88, 88, 88, 88,
89, 89, 89, 89, 89, 89, 90, 90, 90, 90, 91, 91, 92, 93, 93, 94, 94, 95, 95, 95, 96, 96, 96, 95, 95,
95, 94, 94, 93, 93, 93, 92, 90, 90, 89, 87, 87, 87, 85, 83, 83, 82, 81, 81, 81, 80, 80, 81, 81, 81,
81, 81, 81, 81, 81, 81, 81, 81, 81, 83, 86, 88, 88, 90, 91, 91, 91, 92, 92, 93, 93, 93, 94, 95, 95,
95, 96, 96, 96, 96, 96, 96, 96, 95, 95, 95, 95, 95, 94, 93, 93, 92, 92, 92, 91, 90, 90, 90, 90, 90,
91, 93, 93, 94, 94, 94, 94, 95, 94, 94, 94, 94, 94, 94, 93, 93, 93, 93, 93, 93, 92, 92, 92, 92, 92,
91, 91, 91, 91, 91, 91, 91, 91, 90, 90, 90, 90, 90, 90, 90, 90, 89, 89, 89, 89, 89, 89, 89, 89, 89,
89, 90, 90, 90, 90, 91, 91, 92, 93, 93, 93, 94, 94, 94, 94, 94, 94, 94, 94, 94, 95, 95, 95, 95, 95,
95, 95, 95, 95, 94, 93, 93, 93, 93, 93, 92, 92, 92, 91, 91, 91, 91, 90, 90, 90, 89, 89, 89, 88, 88,
88, 88, 88, 88, 88, 88, 88, 89, 89, 89, 89, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 91, 91, 91, 91,
91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 91, 92,
92, 93, 93, 93, 93, 94, 94, 94, 93, 93, 93, 93, 93, 93, 92, 92, 92, 91, 91, 91, 90, 90, 90, 89, 88,
88, 87, 87, 87, 86, 86, 85, 85, 85, 86, 86, 86, 87, 87, 88, 88, 88, 89, 90, 90, 90, 91, 91, 91, 91,
91, 91, 91, 91, 91, 92, 92, 92, 93, 93, 93, 93, 93, 93, 93, 92, 92, 92, 91, 91, 90, 90, 90, 89, 88,
87, 87, 87, 86, 86, 86, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 86, 86, 86, 86, 87, 88, 88, 88,
89, 89, 90, 91, 91, 92, 93, 93, 93, 94, 94, 94, 94, 94, 94, 94, 94, 94, 93, 93, 93, 92, 92, 92, 91,
90, 90, 90, 89, 89, 88, 88, 88, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 88, 88, 88,
90, 90, 91, 93, 93, 93, 93, 93, 94, 93, 93, 93, 93, 93, 93, 92, 92, 92, 91, 91, 91, 90, 90, 90, 89,
89, 89, 88, 87, 87, 87, 87, 87, 86, 87, 87, 87, 87, 87, 87, 87, 87, 87, 88, 88, 88, 88, 88, 88, 88,
89
- Output:
[ 7 6 4 2 2 0 ]
F#
// Decreasing contiguous subsequences. Nigel Galloway: September 6th., 2024
let data=[90; 90; 90; 91; 91; 92; 92; 92; 91; 91; 91; 90; 90; 90; 89; 89; 88; 87; 87; 87; 86; 86; 86; 85; 85;86; 86; 87; 87; 88; 89; 89; 89; 90; 90; 91; 91; 91; 92; 92; 92; 92; 92; 92; 92; 92; 92; 91; 91; 90;90; 90; 90; 90; 89; 89; 89; 89; 88; 88; 88; 88; 88; 88; 88; 88; 88; 88; 88; 88; 89; 89; 89; 89; 89;89; 90; 90; 90; 89; 89; 89; 89; 89; 89; 88; 88; 88; 88; 88; 88; 87; 88; 88; 88; 88; 88; 88; 88; 88;88; 88; 88; 88; 88; 88; 88; 88; 88; 88; 88; 88; 88; 89; 89; 89; 89; 89; 88; 88; 88; 88; 88; 88; 89;89; 89; 89; 89; 89; 89; 89; 88; 88; 88; 88; 88; 88; 88; 88; 87; 87; 87; 87; 87; 87; 87; 87; 87; 87;87; 87; 88; 88; 88; 88; 88; 88; 88; 88; 88; 89; 89; 89; 89; 89; 89; 89; 88; 88; 88; 88; 88; 88; 88;88; 88; 88; 88; 89; 89; 89; 89; 89; 89; 89; 89; 89; 89; 88; 88; 88; 87; 87; 87; 87; 86; 86; 86; 86;86; 86; 87; 87; 87; 87; 87; 87; 87; 88; 88; 88; 88; 88; 88; 88; 88; 88; 89; 89; 89; 89; 89; 89; 89;88; 88; 88; 88; 88; 87; 87; 87; 87; 87; 87; 87; 87; 87; 87; 87; 87; 87; 87; 87; 87; 87; 89; 89; 91;94; 94; 95; 96; 96; 96; 97; 97; 96; 96; 96; 96; 95; 95; 94; 93; 93; 92; 92; 91; 91; 90; 89; 89; 88;86; 86; 85; 83; 83; 81; 80; 80; 80; 79; 79; 79; 78; 78; 79; 81; 82; 82; 85; 89; 89; 91; 93; 93; 94;95; 95; 95; 95; 95; 95; 95; 95; 95; 94; 94; 94; 94; 93; 93; 93; 92; 92; 91; 91; 91; 90; 90; 90; 88;87; 87; 86; 85; 85; 84; 84; 84; 83; 84; 84; 84; 85; 86; 86; 87; 87; 87; 88; 88; 88; 89; 90; 90; 90;91; 91; 92; 92; 92; 93; 94; 94; 94; 95; 95; 95; 95; 94; 94; 94; 93; 93; 93; 92; 92; 92; 91; 91; 90;89; 89; 87; 86; 85; 85; 84; 83; 83; 82; 82; 82; 81; 81; 81; 81; 81; 81; 82; 85; 85; 86; 89; 89; 91;92; 93; 93; 93; 94; 94; 94; 94; 94; 94; 94; 94; 94; 93; 93; 93; 92; 92; 92; 91; 91; 91; 90; 89; 89;88; 88; 88; 87; 87; 87; 86; 86; 86; 85; 85; 85; 85; 85; 85; 86; 87; 87; 87; 88; 88; 88; 88; 88; 88;89; 89; 89; 89; 89; 89; 90; 90; 90; 90; 91; 91; 92; 93; 93; 94; 94; 95; 95; 95; 96; 96; 96; 95; 95;95; 94; 94; 93; 93; 93; 92; 90; 90; 89; 87; 87; 87; 85; 83; 83; 82; 81; 81; 81; 80; 80; 81; 81; 81;81; 81; 81; 81; 81; 81; 81; 81; 81; 83; 86; 88; 88; 90; 91; 91; 91; 92; 92; 93; 93; 93; 94; 95; 95;95; 96; 96; 96; 96; 96; 96; 96; 95; 95; 95; 95; 95; 94; 93; 93; 92; 92; 92; 91; 90; 90; 90; 90; 90;91; 93; 93; 94; 94; 94; 94; 95; 94; 94; 94; 94; 94; 94; 93; 93; 93; 93; 93; 93; 92; 92; 92; 92; 92;91; 91; 91; 91; 91; 91; 91; 91; 90; 90; 90; 90; 90; 90; 90; 90; 89; 89; 89; 89; 89; 89; 89; 89; 89;89; 90; 90; 90; 90; 91; 91; 92; 93; 93; 93; 94; 94; 94; 94; 94; 94; 94; 94; 94; 95; 95; 95; 95; 95;95; 95; 95; 95; 94; 93; 93; 93; 93; 93; 92; 92; 92; 91; 91; 91; 91; 90; 90; 90; 89; 89; 89; 88; 88;88; 88; 88; 88; 88; 88; 88; 89; 89; 89; 89; 90; 90; 90; 90; 90; 90; 90; 90; 90; 90; 91; 91; 91; 91;91; 91; 91; 91; 91; 91; 91; 91; 91; 91; 90; 90; 90; 90; 90; 90; 90; 90; 90; 90; 90; 90; 90; 91; 92;92; 93; 93; 93; 93; 94; 94; 94; 93; 93; 93; 93; 93; 93; 92; 92; 92; 91; 91; 91; 90; 90; 90; 89; 88;88; 87; 87; 87; 86; 86; 85; 85; 85; 86; 86; 86; 87; 87; 88; 88; 88; 89; 90; 90; 90; 91; 91; 91; 91;91; 91; 91; 91; 91; 92; 92; 92; 93; 93; 93; 93; 93; 93; 93; 92; 92; 92; 91; 91; 90; 90; 90; 89; 88;87; 87; 87; 86; 86; 86; 85; 85; 85; 85; 85; 85; 85; 85; 85; 85; 85; 86; 86; 86; 86; 87; 88; 88; 88;89; 89; 90; 91; 91; 92; 93; 93; 93; 94; 94; 94; 94; 94; 94; 94; 94; 94; 93; 93; 93; 92; 92; 92; 91;90; 90; 90; 89; 89; 88; 88; 88; 87; 87; 87; 87; 87; 87; 87; 87; 87; 87; 87; 87; 87; 87; 88; 88; 88;90; 90; 91; 93; 93; 93; 93; 93; 94; 93; 93; 93; 93; 93; 93; 92; 92; 92; 91; 91; 91; 90; 90; 90; 89;89; 89; 88; 87; 87; 87; 87; 87; 86; 87; 87; 87; 87; 87; 87; 87; 87; 87; 88; 88; 88; 88; 88; 88; 88;89]
type cat=LT4 |LT8 |LT12 |LT16 |LT25 |GT25
let cat=function n when n<4.0->LT4 |n when n<8.0->LT8 |n when n<12.0->LT12 |n when n<16.0->LT16 |n when n<25.0->LT25 |_->GT25
let t1=data|>List.pairwise|>List.filter(fun(n,g)->g<>n)|>List.filter(fun(n,g)->(n>g))
let n,g=t1|>List.pairwise |>List.filter(fun((_,n),(g,_))->n<g)|>List.unzip
let res=List.map2(fun(n,_)(_,g)->100.0-(((float g)/(float n))*100.0)) (t1.Head::g) (n@[t1|>List.last])|>List.countBy cat|>List.sortBy fst
printfn "%A" res
- Output:
[(LT4, 7); (LT8, 6); (LT12, 4); (LT16, 2); (LT25, 2)]
FreeBASIC
' Define the Sequence structure
Type Sequence
startIndex As Integer
endIndex As Integer
End Type
Dim As Integer datos(900) = { _
90, 90, 90, 91, 91, 92, 92, 92, 91, 91, 91, 90, 90, 90, 89, 89, 88, 87, 87, 87, _
86, 86, 86, 85, 85, 86, 86, 87, 87, 88, 89, 89, 89, 90, 90, 91, 91, 91, 92, 92, _
92, 92, 92, 92, 92, 92, 92, 91, 91, 90, 90, 90, 90, 90, 89, 89, 89, 89, 88, 88, _
88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 89, 89, 89, 89, 89, 89, 90, 90, 90, 89, _
89, 89, 89, 89, 89, 88, 88, 88, 88, 88, 88, 87, 88, 88, 88, 88, 88, 88, 88, 88, _
88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 89, 89, 89, 89, 89, 88, 88, _
88, 88, 88, 88, 89, 89, 89, 89, 89, 89, 89, 89, 88, 88, 88, 88, 88, 88, 88, 88, _
87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 88, 88, 88, 88, 88, 88, 88, 88, _
88, 89, 89, 89, 89, 89, 89, 89, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 89, _
89, 89, 89, 89, 89, 89, 89, 89, 89, 88, 88, 88, 87, 87, 87, 87, 86, 86, 86, 86, _
86, 86, 87, 87, 87, 87, 87, 87, 87, 88, 88, 88, 88, 88, 88, 88, 88, 88, 89, 89, _
89, 89, 89, 89, 89, 88, 88, 88, 88, 88, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, _
87, 87, 87, 87, 87, 87, 87, 89, 89, 91, 94, 94, 95, 96, 96, 96, 97, 97, 96, 96, _
96, 96, 95, 95, 94, 93, 93, 92, 92, 91, 91, 90, 89, 89, 88, 86, 86, 85, 83, 83, _
81, 80, 80, 80, 79, 79, 79, 78, 78, 79, 81, 82, 82, 85, 89, 89, 91, 93, 93, 94, _
95, 95, 95, 95, 95, 95, 95, 95, 95, 94, 94, 94, 94, 93, 93, 93, 92, 92, 91, 91, _
91, 90, 90, 90, 88, 87, 87, 86, 85, 85, 84, 84, 84, 83, 84, 84, 84, 85, 86, 86, _
87, 87, 87, 88, 88, 88, 89, 90, 90, 90, 91, 91, 92, 92, 92, 93, 94, 94, 94, 95, _
95, 95, 95, 94, 94, 94, 93, 93, 93, 92, 92, 92, 91, 91, 90, 89, 89, 87, 86, 85, _
85, 84, 83, 83, 82, 82, 82, 81, 81, 81, 81, 81, 81, 82, 85, 85, 86, 89, 89, 91, _
92, 93, 93, 93, 94, 94, 94, 94, 94, 94, 94, 94, 94, 93, 93, 93, 92, 92, 92, 91, _
91, 91, 90, 89, 89, 88, 88, 88, 87, 87, 87, 86, 86, 86, 85, 85, 85, 85, 85, 85, _
86, 87, 87, 87, 88, 88, 88, 88, 88, 88, 89, 89, 89, 89, 89, 89, 90, 90, 90, 90, _
91, 91, 92, 93, 93, 94, 94, 95, 95, 95, 96, 96, 96, 95, 95, 95, 94, 94, 93, 93, _
93, 92, 90, 90, 89, 87, 87, 87, 85, 83, 83, 82, 81, 81, 81, 80, 80, 81, 81, 81, _
81, 81, 81, 81, 81, 81, 81, 81, 81, 83, 86, 88, 88, 90, 91, 91, 91, 92, 92, 93, _
93, 93, 94, 95, 95, 95, 96, 96, 96, 96, 96, 96, 96, 95, 95, 95, 95, 95, 94, 93, _
93, 92, 92, 92, 91, 90, 90, 90, 90, 90, 91, 93, 93, 94, 94, 94, 94, 95, 94, 94, _
94, 94, 94, 94, 93, 93, 93, 93, 93, 93, 92, 92, 92, 92, 92, 91, 91, 91, 91, 91, _
91, 91, 91, 90, 90, 90, 90, 90, 90, 90, 90, 89, 89, 89, 89, 89, 89, 89, 89, 89, _
89, 90, 90, 90, 90, 91, 91, 92, 93, 93, 93, 94, 94, 94, 94, 94, 94, 94, 94, 94, _
95, 95, 95, 95, 95, 95, 95, 95, 95, 94, 93, 93, 93, 93, 93, 92, 92, 92, 91, 91, _
91, 91, 90, 90, 90, 89, 89, 89, 88, 88, 88, 88, 88, 88, 88, 88, 88, 89, 89, 89, _
89, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 91, 91, 91, 91, 91, 91, 91, 91, 91, _
91, 91, 91, 91, 91, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 91, 92, _
92, 93, 93, 93, 93, 94, 94, 94, 93, 93, 93, 93, 93, 93, 92, 92, 92, 91, 91, 91, _
90, 90, 90, 89, 88, 88, 87, 87, 87, 86, 86, 85, 85, 85, 86, 86, 86, 87, 87, 88, _
88, 88, 89, 90, 90, 90, 91, 91, 91, 91, 91, 91, 91, 91, 91, 92, 92, 92, 93, 93, _
93, 93, 93, 93, 93, 92, 92, 92, 91, 91, 90, 90, 90, 89, 88, 87, 87, 87, 86, 86, _
86, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 86, 86, 86, 86, 87, 88, 88, 88, _
89, 89, 90, 91, 91, 92, 93, 93, 93, 94, 94, 94, 94, 94, 94, 94, 94, 94, 93, 93, _
93, 92, 92, 92, 91, 90, 90, 90, 89, 89, 88, 88, 88, 87, 87, 87, 87, 87, 87, 87, _
87, 87, 87, 87, 87, 87, 87, 88, 88, 88, 90, 90, 91, 93, 93, 93, 93, 93, 94, 93, _
93, 93, 93, 93, 93, 92, 92, 92, 91, 91, 91, 90, 90, 90, 89, 89, 89, 88, 87, 87, _
87, 87, 87, 86, 87, 87, 87, 87, 87, 87, 87, 87, 87, 88, 88, 88, 88, 88, 88, 88, _
89 }
Dim ranges(4) As Integer = {4, 8, 12, 16, 25}
Dim counts(Lbound(ranges) To Ubound(ranges) + 1) As Integer
' Function to get the next non-ascending Sequence
Function nextSequence(datos() As Integer, prev As Sequence) As Sequence
Dim As Integer sPos, ePos, value
sPos = prev.endIndex + 1
If sPos > Ubound(datos) Then
Return Type<Sequence>(sPos, Ubound(datos))
Else
value = datos(sPos)
ePos = sPos + 1
While ePos <= Ubound(datos) Andalso datos(ePos) <= value
value = datos(ePos)
ePos += 1
Wend
Return Type<Sequence>(sPos, ePos - 1)
End If
End Function
' Function to get the first non-ascending Sequence
Function firstSequence(datos() As Integer) As Sequence
If Lbound(datos) > Ubound(datos) Then
Return Type<Sequence>(Lbound(datos), Ubound(datos))
Else
Return nextSequence(datos(), Type<Sequence>(-1, Lbound(datos) - 1))
End If
End Function
' Subroutine to count the non-ascending Sequence by percentage change
Sub countChangesByPercentage(datos() As Integer, ranges() As Integer, counts() As Integer)
Dim prev As Sequence = firstSequence(datos())
While prev.endIndex >= prev.startIndex
If prev.endIndex > prev.startIndex Then
Dim As Double change = ((datos(prev.startIndex) - datos(prev.endIndex)) / datos(prev.startIndex)) * 100
If change > 0 Then
For i As Integer = Lbound(counts) To Ubound(counts)
If ranges(i) > change Then
counts(i) += 1
Exit For
End If
Next
If change > ranges(Ubound(ranges)) Then counts(Ubound(counts)) += 1
End If
End If
prev = nextSequence(datos(), prev)
Wend
End Sub
' Procedure to show the range count
Sub showRangeCount(pStart As Integer, pEnd As Integer, cnt As Integer)
Print Using "! ##_% .. ###_% ! : &"; (Iif(pStart = 0, "(", "[")); pStart; pEnd; Iif(pEnd = 100, "]", ")"); cnt
End Sub
' Main program
countChangesByPercentage(datos(), ranges(), counts())
Dim As Integer i, start
start = 0
For i = Lbound(counts) To Ubound(counts) - 1
showRangeCount(start, ranges(i), counts(i))
start = ranges(i)
Next
If start < 100 Then showRangeCount(start, 100, counts(Ubound(counts)))
Sleep
- Output:
Same as ALGOL 68 entry.
jq
Works with jq, the C implementation of jq
Works with jaq, the Rust implementation of jq
Works with gojq, the Go implementation of jq
To save space, this entry supposes that the list of values is provided as input to the program as a JSON array -- see the Wren entry, for example, for its presentation as such.
Also to save space, the output is shown as a JSON object corresponding in the obvious way to the categorization specified in the task description.
### Generic functions
# bag of words
def bow(stream):
reduce stream as $word ({}; .[($word|tostring)] += 1);
# Input: a nonempty array of non-increasing non-negative integers
# Output: the overall percentage decrease
def percentageDecrease:
if .[0] == 0
then 0
else 100 - ((.[-1] / .[0]) * 100)
end;
# Input: an array
# Emit a stream of maximal non-increasing subsequences, include singletons
def maximal_nonincreasing_subsequences:
foreach (.[], null) as $x ({subsequence: []};
.emit = null
| if $x == null
then if (.subsequence|length) > 0 then .emit = .subsequence
else empty
end
elif (.subsequence | length) == 0 or $x <= .subsequence[-1]
then .subsequence += [$x]
else if (.subsequence | length) > 0
then .emit = .subsequence
end
| .subsequence = [$x]
end )
| select(.emit).emit;
# Classify the input numbers as per the implementation
def bucketize:
if . <= 0 then empty
elif . < 4 then " 4"
elif . < 8 then " 8"
elif . < 12 then " 12"
elif . < 16 then " 16"
elif . < 25 then " 25"
else "100"
end;
# Input: an array of non-negative numbers.
# Output: a JSON object that gives the classification of the maximal
# non-decreasing subsequences as per the task description
def classify:
def zero: {" 4":0, " 8":0, " 12":0, " 16":0, " 25":0, "100": 0};
bow(maximal_nonincreasing_subsequences
| percentageDecrease
| bucketize)
| to_entries
| zero + from_entries;
# The example:
classify
Invocation: jq -cf classify-decreasing-contiguous-subsequences.jq < input.json
- Output:
{" 4":7," 8":6," 12":4," 16":2," 25":2,"100":0}
Julia
const seq = [90, 90, 90, 91, 91, 92, 92, 92, 91, 91, 91, 90, 90, 90, 89, 89, 88, 87, 87, 87, 86, 86, 86, 85, 85,
86, 86, 87, 87, 88, 89, 89, 89, 90, 90, 91, 91, 91, 92, 92, 92, 92, 92, 92, 92, 92, 92, 91, 91, 90,
90, 90, 90, 90, 89, 89, 89, 89, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 89, 89, 89, 89, 89,
89, 90, 90, 90, 89, 89, 89, 89, 89, 89, 88, 88, 88, 88, 88, 88, 87, 88, 88, 88, 88, 88, 88, 88, 88,
88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 89, 89, 89, 89, 89, 88, 88, 88, 88, 88, 88, 89,
89, 89, 89, 89, 89, 89, 89, 88, 88, 88, 88, 88, 88, 88, 88, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87,
87, 87, 88, 88, 88, 88, 88, 88, 88, 88, 88, 89, 89, 89, 89, 89, 89, 89, 88, 88, 88, 88, 88, 88, 88,
88, 88, 88, 88, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 88, 88, 88, 87, 87, 87, 87, 86, 86, 86, 86,
86, 86, 87, 87, 87, 87, 87, 87, 87, 88, 88, 88, 88, 88, 88, 88, 88, 88, 89, 89, 89, 89, 89, 89, 89,
88, 88, 88, 88, 88, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 89, 89, 91,
94, 94, 95, 96, 96, 96, 97, 97, 96, 96, 96, 96, 95, 95, 94, 93, 93, 92, 92, 91, 91, 90, 89, 89, 88,
86, 86, 85, 83, 83, 81, 80, 80, 80, 79, 79, 79, 78, 78, 79, 81, 82, 82, 85, 89, 89, 91, 93, 93, 94,
95, 95, 95, 95, 95, 95, 95, 95, 95, 94, 94, 94, 94, 93, 93, 93, 92, 92, 91, 91, 91, 90, 90, 90, 88,
87, 87, 86, 85, 85, 84, 84, 84, 83, 84, 84, 84, 85, 86, 86, 87, 87, 87, 88, 88, 88, 89, 90, 90, 90,
91, 91, 92, 92, 92, 93, 94, 94, 94, 95, 95, 95, 95, 94, 94, 94, 93, 93, 93, 92, 92, 92, 91, 91, 90,
89, 89, 87, 86, 85, 85, 84, 83, 83, 82, 82, 82, 81, 81, 81, 81, 81, 81, 82, 85, 85, 86, 89, 89, 91,
92, 93, 93, 93, 94, 94, 94, 94, 94, 94, 94, 94, 94, 93, 93, 93, 92, 92, 92, 91, 91, 91, 90, 89, 89,
88, 88, 88, 87, 87, 87, 86, 86, 86, 85, 85, 85, 85, 85, 85, 86, 87, 87, 87, 88, 88, 88, 88, 88, 88,
89, 89, 89, 89, 89, 89, 90, 90, 90, 90, 91, 91, 92, 93, 93, 94, 94, 95, 95, 95, 96, 96, 96, 95, 95,
95, 94, 94, 93, 93, 93, 92, 90, 90, 89, 87, 87, 87, 85, 83, 83, 82, 81, 81, 81, 80, 80, 81, 81, 81,
81, 81, 81, 81, 81, 81, 81, 81, 81, 83, 86, 88, 88, 90, 91, 91, 91, 92, 92, 93, 93, 93, 94, 95, 95,
95, 96, 96, 96, 96, 96, 96, 96, 95, 95, 95, 95, 95, 94, 93, 93, 92, 92, 92, 91, 90, 90, 90, 90, 90,
91, 93, 93, 94, 94, 94, 94, 95, 94, 94, 94, 94, 94, 94, 93, 93, 93, 93, 93, 93, 92, 92, 92, 92, 92,
91, 91, 91, 91, 91, 91, 91, 91, 90, 90, 90, 90, 90, 90, 90, 90, 89, 89, 89, 89, 89, 89, 89, 89, 89,
89, 90, 90, 90, 90, 91, 91, 92, 93, 93, 93, 94, 94, 94, 94, 94, 94, 94, 94, 94, 95, 95, 95, 95, 95,
95, 95, 95, 95, 94, 93, 93, 93, 93, 93, 92, 92, 92, 91, 91, 91, 91, 90, 90, 90, 89, 89, 89, 88, 88,
88, 88, 88, 88, 88, 88, 88, 89, 89, 89, 89, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 91, 91, 91, 91,
91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 91, 92,
92, 93, 93, 93, 93, 94, 94, 94, 93, 93, 93, 93, 93, 93, 92, 92, 92, 91, 91, 91, 90, 90, 90, 89, 88,
88, 87, 87, 87, 86, 86, 85, 85, 85, 86, 86, 86, 87, 87, 88, 88, 88, 89, 90, 90, 90, 91, 91, 91, 91,
91, 91, 91, 91, 91, 92, 92, 92, 93, 93, 93, 93, 93, 93, 93, 92, 92, 92, 91, 91, 90, 90, 90, 89, 88,
87, 87, 87, 86, 86, 86, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 86, 86, 86, 86, 87, 88, 88, 88,
89, 89, 90, 91, 91, 92, 93, 93, 93, 94, 94, 94, 94, 94, 94, 94, 94, 94, 93, 93, 93, 92, 92, 92, 91,
90, 90, 90, 89, 89, 88, 88, 88, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 88, 88, 88,
90, 90, 91, 93, 93, 93, 93, 93, 94, 93, 93, 93, 93, 93, 93, 92, 92, 92, 91, 91, 91, 90, 90, 90, 89,
89, 89, 88, 87, 87, 87, 87, 87, 86, 87, 87, 87, 87, 87, 87, 87, 87, 87, 88, 88, 88, 88, 88, 88, 88,
89]
function percentdescent(arr)
percents = Float64[]
initial = arr[begin]
previous = initial
for i in firstindex(arr)+1:lastindex(arr)
if arr[i] > previous
previous != initial && push!(percents, 100 * (initial - previous) / initial)
previous = arr[i]
initial = arr[i]
else
previous = arr[i-1]
end
end
return percents
end
function countbins(percents, bins)
counts = zeros(Int, length(bins)-1)
for p in percents
bin = findfirst(x -> p < x, bins)
counts[bin-1] += 1
end
return counts
end
function test_decreasing(arr = seq, bins = [0, 4, 8, 12, 16, 25, 100])
counts = countbins(percentdescent(arr), bins)
println(" Bin Count\n===================")
for i in eachindex(counts)
println("($(lpad(bins[i], 2))% - $(rpad(bins[i+1], 3))%] ", counts[i])
end
end
test_decreasing()
- Output:
Bin Count =================== ( 0% - 4 %] 7 ( 4% - 8 %] 6 ( 8% - 12 %] 4 (12% - 16 %] 2 (16% - 25 %] 2 (25% - 100%] 0
PascalABC.NET
// Decreasing contiguous subsequences. Nigel Galloway: September 11th., 2024
var f: file of integer;
type Tcat=(LT4,LT8,LT12,LT25,GT25);
function cat(n:integer;g:integer):Tcat;
begin
var t:=100-(g/n)*100;
Result:=if t<4.0 then LT4 else if t<8.0 then LT8 else if t<12.0 then LT12 else if t<25.0 then LT25 else GT25;
end;
function fN(f:file of integer;n:integer;g:integer):sequence of Tcat;
begin
if not eof(f) then begin
var t:= f.read;
if t<=g then begin yield sequence fN(f,n,t); exit; end;
if n>g then yield cat(n,g);
yield sequence fN(f,t,t);
exit;
end;
if n>g then yield cat(n,g);
end;
begin
assign(f,'test.dat');
reset(f);
var t:=f.read;
print(fN(f,t,t).eachCount);
close(f);
end.
- Output:
{(LT8,6),(LT4,7),(LT25,4),(LT12,4)}
Phix
with javascript_semantics
function percentdescent(sequence data)
sequence percents = {}
integer initial = data[1],
previous = initial
for d in data from 2 do
if d > previous then
if previous != initial then
percents &= 100 * (initial - previous) / initial
end if
initial = d
end if
previous = d
end for
return percents
end function
function countbins(sequence percents, bins)
sequence counts = repeat(0,length(bins)-1)
for p in percents do
integer bin = 1
while p>=bins[bin+1] do bin += 1 end while
counts[bin] += 1
end for
return counts
end function
procedure test_decreasing(sequence data, bins)
sequence counts = countbins(percentdescent(data), bins)
printf(1," Bin Count\n===================\n")
for i,c in counts do
printf(1,"(%2d%% - %-3d%%] %d\n",{bins[i], bins[i+1],c})
end for
end procedure
constant data = {90, 90, 90, 91, 91, 92, 92, 92, 91, 91, 91, 90, 90, 90, 89, 89, 88, 87, 87, 87, 86, 86, 86, 85, 85,
86, 86, 87, 87, 88, 89, 89, 89, 90, 90, 91, 91, 91, 92, 92, 92, 92, 92, 92, 92, 92, 92, 91, 91, 90,
90, 90, 90, 90, 89, 89, 89, 89, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 89, 89, 89, 89, 89,
89, 90, 90, 90, 89, 89, 89, 89, 89, 89, 88, 88, 88, 88, 88, 88, 87, 88, 88, 88, 88, 88, 88, 88, 88,
88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 89, 89, 89, 89, 89, 88, 88, 88, 88, 88, 88, 89,
89, 89, 89, 89, 89, 89, 89, 88, 88, 88, 88, 88, 88, 88, 88, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87,
87, 87, 88, 88, 88, 88, 88, 88, 88, 88, 88, 89, 89, 89, 89, 89, 89, 89, 88, 88, 88, 88, 88, 88, 88,
88, 88, 88, 88, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 88, 88, 88, 87, 87, 87, 87, 86, 86, 86, 86,
86, 86, 87, 87, 87, 87, 87, 87, 87, 88, 88, 88, 88, 88, 88, 88, 88, 88, 89, 89, 89, 89, 89, 89, 89,
88, 88, 88, 88, 88, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 89, 89, 91,
94, 94, 95, 96, 96, 96, 97, 97, 96, 96, 96, 96, 95, 95, 94, 93, 93, 92, 92, 91, 91, 90, 89, 89, 88,
86, 86, 85, 83, 83, 81, 80, 80, 80, 79, 79, 79, 78, 78, 79, 81, 82, 82, 85, 89, 89, 91, 93, 93, 94,
95, 95, 95, 95, 95, 95, 95, 95, 95, 94, 94, 94, 94, 93, 93, 93, 92, 92, 91, 91, 91, 90, 90, 90, 88,
87, 87, 86, 85, 85, 84, 84, 84, 83, 84, 84, 84, 85, 86, 86, 87, 87, 87, 88, 88, 88, 89, 90, 90, 90,
91, 91, 92, 92, 92, 93, 94, 94, 94, 95, 95, 95, 95, 94, 94, 94, 93, 93, 93, 92, 92, 92, 91, 91, 90,
89, 89, 87, 86, 85, 85, 84, 83, 83, 82, 82, 82, 81, 81, 81, 81, 81, 81, 82, 85, 85, 86, 89, 89, 91,
92, 93, 93, 93, 94, 94, 94, 94, 94, 94, 94, 94, 94, 93, 93, 93, 92, 92, 92, 91, 91, 91, 90, 89, 89,
88, 88, 88, 87, 87, 87, 86, 86, 86, 85, 85, 85, 85, 85, 85, 86, 87, 87, 87, 88, 88, 88, 88, 88, 88,
89, 89, 89, 89, 89, 89, 90, 90, 90, 90, 91, 91, 92, 93, 93, 94, 94, 95, 95, 95, 96, 96, 96, 95, 95,
95, 94, 94, 93, 93, 93, 92, 90, 90, 89, 87, 87, 87, 85, 83, 83, 82, 81, 81, 81, 80, 80, 81, 81, 81,
81, 81, 81, 81, 81, 81, 81, 81, 81, 83, 86, 88, 88, 90, 91, 91, 91, 92, 92, 93, 93, 93, 94, 95, 95,
95, 96, 96, 96, 96, 96, 96, 96, 95, 95, 95, 95, 95, 94, 93, 93, 92, 92, 92, 91, 90, 90, 90, 90, 90,
91, 93, 93, 94, 94, 94, 94, 95, 94, 94, 94, 94, 94, 94, 93, 93, 93, 93, 93, 93, 92, 92, 92, 92, 92,
91, 91, 91, 91, 91, 91, 91, 91, 90, 90, 90, 90, 90, 90, 90, 90, 89, 89, 89, 89, 89, 89, 89, 89, 89,
89, 90, 90, 90, 90, 91, 91, 92, 93, 93, 93, 94, 94, 94, 94, 94, 94, 94, 94, 94, 95, 95, 95, 95, 95,
95, 95, 95, 95, 94, 93, 93, 93, 93, 93, 92, 92, 92, 91, 91, 91, 91, 90, 90, 90, 89, 89, 89, 88, 88,
88, 88, 88, 88, 88, 88, 88, 89, 89, 89, 89, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 91, 91, 91, 91,
91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 91, 92,
92, 93, 93, 93, 93, 94, 94, 94, 93, 93, 93, 93, 93, 93, 92, 92, 92, 91, 91, 91, 90, 90, 90, 89, 88,
88, 87, 87, 87, 86, 86, 85, 85, 85, 86, 86, 86, 87, 87, 88, 88, 88, 89, 90, 90, 90, 91, 91, 91, 91,
91, 91, 91, 91, 91, 92, 92, 92, 93, 93, 93, 93, 93, 93, 93, 92, 92, 92, 91, 91, 90, 90, 90, 89, 88,
87, 87, 87, 86, 86, 86, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 86, 86, 86, 86, 87, 88, 88, 88,
89, 89, 90, 91, 91, 92, 93, 93, 93, 94, 94, 94, 94, 94, 94, 94, 94, 94, 93, 93, 93, 92, 92, 92, 91,
90, 90, 90, 89, 89, 88, 88, 88, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 88, 88, 88,
90, 90, 91, 93, 93, 93, 93, 93, 94, 93, 93, 93, 93, 93, 93, 92, 92, 92, 91, 91, 91, 90, 90, 90, 89,
89, 89, 88, 87, 87, 87, 87, 87, 86, 87, 87, 87, 87, 87, 87, 87, 87, 87, 88, 88, 88, 88, 88, 88, 88,
89},
bins = {0, 4, 8, 12, 16, 25, 100}
test_decreasing(data,bins)
- Output:
Bin Count =================== ( 0% - 4 %] 7 ( 4% - 8 %] 6 ( 8% - 12 %] 4 (12% - 16 %] 2 (16% - 25 %] 2 (25% - 100%] 0
Python
"""Requires Python >= 3.10"""
import operator
from collections import Counter
from itertools import chain
from itertools import groupby
from itertools import pairwise
from typing import Iterable
# Example sequences is saved to data.py
from data import data
GROUPS = [
(0, 4),
(4, 8),
(8, 12),
(12, 16),
(16, 25),
(25, 100),
]
def decreasing_contiguous_subsequences(s: Iterable[int]) -> list[list[int]]:
subsequences = [t for t in contiguous_subsequences(s) if not is_flat(t)]
return [trim_plateaus(t) for t in subsequences]
def contiguous_subsequences(s: Iterable[int], op=operator.le) -> Iterable[list[int]]:
it = iter(s)
try:
subsequence = [next(it)]
except StopIteration:
return
for a, b in pairwise(it):
if op(b, a):
subsequence.append(b)
else:
yield subsequence
subsequence = [b]
def is_flat(s: list[int]) -> bool:
return len(s) < 2 or s[0] == s[-1]
def trim_plateaus(s: Iterable[int]) -> list[int]:
groups = [(k, list(g)) for k, g in groupby(s)]
if len(groups) < 2:
return list(s)
return (
[groups[0][0]]
+ list(chain.from_iterable(g[1] for g in groups[1:-1]))
+ [groups[-1][0]]
)
def percentage_change(s: list[int]) -> float:
return 100 - ((s[-1] / s[0]) * 100)
def subsequence_group(s: list[int]) -> tuple[int, int]:
change = percentage_change(s)
for start, end in GROUPS:
if change >= start and change < end:
return (start, end)
raise ValueError(f"subsequence out of range: {change}")
if __name__ == "__main__":
subsequences = decreasing_contiguous_subsequences(data)
dist = Counter(subsequence_group(s) for s in subsequences)
for group in GROUPS:
print(
f"{group[0]}% - {group[1]}%".rjust(10),
f"{dist[group]}",
)
- Output:
0% - 4% 7 4% - 8% 6 8% - 12% 4 12% - 16% 2 16% - 25% 2 25% - 100% 0
Raku
Since these are percentages, no need to specify a span. The span is automatically 0-100. The carat in the bin ranges mean "upto, but not including".
my @values =
90, 90, 90, 91, 91, 92, 92, 92, 91, 91, 91, 90, 90, 90, 89, 89, 88, 87, 87, 87, 86, 86, 86, 85, 85,
86, 86, 87, 87, 88, 89, 89, 89, 90, 90, 91, 91, 91, 92, 92, 92, 92, 92, 92, 92, 92, 92, 91, 91, 90,
90, 90, 90, 90, 89, 89, 89, 89, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 89, 89, 89, 89, 89,
89, 90, 90, 90, 89, 89, 89, 89, 89, 89, 88, 88, 88, 88, 88, 88, 87, 88, 88, 88, 88, 88, 88, 88, 88,
88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 89, 89, 89, 89, 89, 88, 88, 88, 88, 88, 88, 89,
89, 89, 89, 89, 89, 89, 89, 88, 88, 88, 88, 88, 88, 88, 88, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87,
87, 87, 88, 88, 88, 88, 88, 88, 88, 88, 88, 89, 89, 89, 89, 89, 89, 89, 88, 88, 88, 88, 88, 88, 88,
88, 88, 88, 88, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 88, 88, 88, 87, 87, 87, 87, 86, 86, 86, 86,
86, 86, 87, 87, 87, 87, 87, 87, 87, 88, 88, 88, 88, 88, 88, 88, 88, 88, 89, 89, 89, 89, 89, 89, 89,
88, 88, 88, 88, 88, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 89, 89, 91,
94, 94, 95, 96, 96, 96, 97, 97, 96, 96, 96, 96, 95, 95, 94, 93, 93, 92, 92, 91, 91, 90, 89, 89, 88,
86, 86, 85, 83, 83, 81, 80, 80, 80, 79, 79, 79, 78, 78, 79, 81, 82, 82, 85, 89, 89, 91, 93, 93, 94,
95, 95, 95, 95, 95, 95, 95, 95, 95, 94, 94, 94, 94, 93, 93, 93, 92, 92, 91, 91, 91, 90, 90, 90, 88,
87, 87, 86, 85, 85, 84, 84, 84, 83, 84, 84, 84, 85, 86, 86, 87, 87, 87, 88, 88, 88, 89, 90, 90, 90,
91, 91, 92, 92, 92, 93, 94, 94, 94, 95, 95, 95, 95, 94, 94, 94, 93, 93, 93, 92, 92, 92, 91, 91, 90,
89, 89, 87, 86, 85, 85, 84, 83, 83, 82, 82, 82, 81, 81, 81, 81, 81, 81, 82, 85, 85, 86, 89, 89, 91,
92, 93, 93, 93, 94, 94, 94, 94, 94, 94, 94, 94, 94, 93, 93, 93, 92, 92, 92, 91, 91, 91, 90, 89, 89,
88, 88, 88, 87, 87, 87, 86, 86, 86, 85, 85, 85, 85, 85, 85, 86, 87, 87, 87, 88, 88, 88, 88, 88, 88,
89, 89, 89, 89, 89, 89, 90, 90, 90, 90, 91, 91, 92, 93, 93, 94, 94, 95, 95, 95, 96, 96, 96, 95, 95,
95, 94, 94, 93, 93, 93, 92, 90, 90, 89, 87, 87, 87, 85, 83, 83, 82, 81, 81, 81, 80, 80, 81, 81, 81,
81, 81, 81, 81, 81, 81, 81, 81, 81, 83, 86, 88, 88, 90, 91, 91, 91, 92, 92, 93, 93, 93, 94, 95, 95,
95, 96, 96, 96, 96, 96, 96, 96, 95, 95, 95, 95, 95, 94, 93, 93, 92, 92, 92, 91, 90, 90, 90, 90, 90,
91, 93, 93, 94, 94, 94, 94, 95, 94, 94, 94, 94, 94, 94, 93, 93, 93, 93, 93, 93, 92, 92, 92, 92, 92,
91, 91, 91, 91, 91, 91, 91, 91, 90, 90, 90, 90, 90, 90, 90, 90, 89, 89, 89, 89, 89, 89, 89, 89, 89,
89, 90, 90, 90, 90, 91, 91, 92, 93, 93, 93, 94, 94, 94, 94, 94, 94, 94, 94, 94, 95, 95, 95, 95, 95,
95, 95, 95, 95, 94, 93, 93, 93, 93, 93, 92, 92, 92, 91, 91, 91, 91, 90, 90, 90, 89, 89, 89, 88, 88,
88, 88, 88, 88, 88, 88, 88, 89, 89, 89, 89, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 91, 91, 91, 91,
91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 91, 92,
92, 93, 93, 93, 93, 94, 94, 94, 93, 93, 93, 93, 93, 93, 92, 92, 92, 91, 91, 91, 90, 90, 90, 89, 88,
88, 87, 87, 87, 86, 86, 85, 85, 85, 86, 86, 86, 87, 87, 88, 88, 88, 89, 90, 90, 90, 91, 91, 91, 91,
91, 91, 91, 91, 91, 92, 92, 92, 93, 93, 93, 93, 93, 93, 93, 92, 92, 92, 91, 91, 90, 90, 90, 89, 88,
87, 87, 87, 86, 86, 86, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 86, 86, 86, 86, 87, 88, 88, 88,
89, 89, 90, 91, 91, 92, 93, 93, 93, 94, 94, 94, 94, 94, 94, 94, 94, 94, 93, 93, 93, 92, 92, 92, 91,
90, 90, 90, 89, 89, 88, 88, 88, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 88, 88, 88,
90, 90, 91, 93, 93, 93, 93, 93, 94, 93, 93, 93, 93, 93, 93, 92, 92, 92, 91, 91, 91, 90, 90, 90, 89,
89, 89, 88, 87, 87, 87, 87, 87, 86, 87, 87, 87, 87, 87, 87, 87, 87, 87, 88, 88, 88, 88, 88, 88, 88,
89;
my @bins = 0^..^4, 4..^8, 8..^12, 12..^16, 16..^25, 25..100;
my @subseqs;
@values.map: {
state $last = $_;
state $incr = 0;
++$incr if $_ > $last;
@subseqs[$incr].push: $_;
$last = $_;
};
sub bin (@items, @bins, :&as) {
my @classified;
for @items {
my $value = .&as;
for @bins {
state $index = 0;
@classified[$index]++ if $value ∈ $_;
++$index;
}
}
@classified
}
say "{.[0].gist}% : {.[1]}" for @bins Z flat @subseqs.&bin(@bins, :as{[R-] .minmax.bounds}), 0 xx *;
- Output:
0^..^4% : 7 4..^8% : 6 8..^12% : 4 12..^16% : 2 16..^25% : 2 25..100% : 0
Rust
const SEQ: [i32; 901] = [
90, 90, 90, 91, 91, 92, 92, 92, 91, 91, 91, 90, 90, 90, 89, 89, 88, 87, 87, 87, 86, 86, 86, 85,
85, 86, 86, 87, 87, 88, 89, 89, 89, 90, 90, 91, 91, 91, 92, 92, 92, 92, 92, 92, 92, 92, 92, 91,
91, 90, 90, 90, 90, 90, 89, 89, 89, 89, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 89, 89,
89, 89, 89, 89, 90, 90, 90, 89, 89, 89, 89, 89, 89, 88, 88, 88, 88, 88, 88, 87, 88, 88, 88, 88,
88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 89, 89, 89, 89, 89, 88, 88,
88, 88, 88, 88, 89, 89, 89, 89, 89, 89, 89, 89, 88, 88, 88, 88, 88, 88, 88, 88, 87, 87, 87, 87,
87, 87, 87, 87, 87, 87, 87, 87, 88, 88, 88, 88, 88, 88, 88, 88, 88, 89, 89, 89, 89, 89, 89, 89,
88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 88, 88, 88,
87, 87, 87, 87, 86, 86, 86, 86, 86, 86, 87, 87, 87, 87, 87, 87, 87, 88, 88, 88, 88, 88, 88, 88,
88, 88, 89, 89, 89, 89, 89, 89, 89, 88, 88, 88, 88, 88, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87,
87, 87, 87, 87, 87, 87, 87, 89, 89, 91, 94, 94, 95, 96, 96, 96, 97, 97, 96, 96, 96, 96, 95, 95,
94, 93, 93, 92, 92, 91, 91, 90, 89, 89, 88, 86, 86, 85, 83, 83, 81, 80, 80, 80, 79, 79, 79, 78,
78, 79, 81, 82, 82, 85, 89, 89, 91, 93, 93, 94, 95, 95, 95, 95, 95, 95, 95, 95, 95, 94, 94, 94,
94, 93, 93, 93, 92, 92, 91, 91, 91, 90, 90, 90, 88, 87, 87, 86, 85, 85, 84, 84, 84, 83, 84, 84,
84, 85, 86, 86, 87, 87, 87, 88, 88, 88, 89, 90, 90, 90, 91, 91, 92, 92, 92, 93, 94, 94, 94, 95,
95, 95, 95, 94, 94, 94, 93, 93, 93, 92, 92, 92, 91, 91, 90, 89, 89, 87, 86, 85, 85, 84, 83, 83,
82, 82, 82, 81, 81, 81, 81, 81, 81, 82, 85, 85, 86, 89, 89, 91, 92, 93, 93, 93, 94, 94, 94, 94,
94, 94, 94, 94, 94, 93, 93, 93, 92, 92, 92, 91, 91, 91, 90, 89, 89, 88, 88, 88, 87, 87, 87, 86,
86, 86, 85, 85, 85, 85, 85, 85, 86, 87, 87, 87, 88, 88, 88, 88, 88, 88, 89, 89, 89, 89, 89, 89,
90, 90, 90, 90, 91, 91, 92, 93, 93, 94, 94, 95, 95, 95, 96, 96, 96, 95, 95, 95, 94, 94, 93, 93,
93, 92, 90, 90, 89, 87, 87, 87, 85, 83, 83, 82, 81, 81, 81, 80, 80, 81, 81, 81, 81, 81, 81, 81,
81, 81, 81, 81, 81, 83, 86, 88, 88, 90, 91, 91, 91, 92, 92, 93, 93, 93, 94, 95, 95, 95, 96, 96,
96, 96, 96, 96, 96, 95, 95, 95, 95, 95, 94, 93, 93, 92, 92, 92, 91, 90, 90, 90, 90, 90, 91, 93,
93, 94, 94, 94, 94, 95, 94, 94, 94, 94, 94, 94, 93, 93, 93, 93, 93, 93, 92, 92, 92, 92, 92, 91,
91, 91, 91, 91, 91, 91, 91, 90, 90, 90, 90, 90, 90, 90, 90, 89, 89, 89, 89, 89, 89, 89, 89, 89,
89, 90, 90, 90, 90, 91, 91, 92, 93, 93, 93, 94, 94, 94, 94, 94, 94, 94, 94, 94, 95, 95, 95, 95,
95, 95, 95, 95, 95, 94, 93, 93, 93, 93, 93, 92, 92, 92, 91, 91, 91, 91, 90, 90, 90, 89, 89, 89,
88, 88, 88, 88, 88, 88, 88, 88, 88, 89, 89, 89, 89, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 91,
91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90,
90, 90, 91, 92, 92, 93, 93, 93, 93, 94, 94, 94, 93, 93, 93, 93, 93, 93, 92, 92, 92, 91, 91, 91,
90, 90, 90, 89, 88, 88, 87, 87, 87, 86, 86, 85, 85, 85, 86, 86, 86, 87, 87, 88, 88, 88, 89, 90,
90, 90, 91, 91, 91, 91, 91, 91, 91, 91, 91, 92, 92, 92, 93, 93, 93, 93, 93, 93, 93, 92, 92, 92,
91, 91, 90, 90, 90, 89, 88, 87, 87, 87, 86, 86, 86, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85,
86, 86, 86, 86, 87, 88, 88, 88, 89, 89, 90, 91, 91, 92, 93, 93, 93, 94, 94, 94, 94, 94, 94, 94,
94, 94, 93, 93, 93, 92, 92, 92, 91, 90, 90, 90, 89, 89, 88, 88, 88, 87, 87, 87, 87, 87, 87, 87,
87, 87, 87, 87, 87, 87, 87, 88, 88, 88, 90, 90, 91, 93, 93, 93, 93, 93, 94, 93, 93, 93, 93, 93,
93, 92, 92, 92, 91, 91, 91, 90, 90, 90, 89, 89, 89, 88, 87, 87, 87, 87, 87, 86, 87, 87, 87, 87,
87, 87, 87, 87, 87, 88, 88, 88, 88, 88, 88, 88, 89,
];
fn main() {
const BIN: [i32; 7] = [0, 4, 8, 12, 16, 25, 100];
let mut a = [0_i32; BIN.len()];
let mut grade_percent: Vec<f64> = vec![];
let (mut x, mut y) = (SEQ[0], SEQ[0]);
for i in 1..SEQ.len() {
if SEQ[i] > y {
if x != y {
grade_percent.push(100_f64 * (x - y) as f64 / x as f64);
}
(x, y) = (SEQ[i], SEQ[i]);
} else {
y = SEQ[i - 1];
}
}
for g in grade_percent {
a[(0..BIN.len() - 1).find(|i| g < BIN[*i] as f64).unwrap() - 1] += 1;
}
println!(" Interval Count\n===================");
for i in 0..BIN.len() - 1 {
println!("({:>2}% - {:>3}%] {}", BIN[i], BIN[i + 1], a[i]);
}
}
- Output:
Interval Count =================== ( 0% - 4%] 7 ( 4% - 8%] 6 ( 8% - 12%] 4 (12% - 16%] 2 (16% - 25%] 2 (25% - 100%] 0
Wren
import "./seq" for Lst
import "./fmt" for Fmt
var data = [
90, 90, 90, 91, 91, 92, 92, 92, 91, 91, 91, 90, 90, 90, 89, 89, 88, 87, 87, 87, 86, 86, 86, 85, 85,
86, 86, 87, 87, 88, 89, 89, 89, 90, 90, 91, 91, 91, 92, 92, 92, 92, 92, 92, 92, 92, 92, 91, 91, 90,
90, 90, 90, 90, 89, 89, 89, 89, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 89, 89, 89, 89, 89,
89, 90, 90, 90, 89, 89, 89, 89, 89, 89, 88, 88, 88, 88, 88, 88, 87, 88, 88, 88, 88, 88, 88, 88, 88,
88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 88, 89, 89, 89, 89, 89, 88, 88, 88, 88, 88, 88, 89,
89, 89, 89, 89, 89, 89, 89, 88, 88, 88, 88, 88, 88, 88, 88, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87,
87, 87, 88, 88, 88, 88, 88, 88, 88, 88, 88, 89, 89, 89, 89, 89, 89, 89, 88, 88, 88, 88, 88, 88, 88,
88, 88, 88, 88, 89, 89, 89, 89, 89, 89, 89, 89, 89, 89, 88, 88, 88, 87, 87, 87, 87, 86, 86, 86, 86,
86, 86, 87, 87, 87, 87, 87, 87, 87, 88, 88, 88, 88, 88, 88, 88, 88, 88, 89, 89, 89, 89, 89, 89, 89,
88, 88, 88, 88, 88, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 89, 89, 91,
94, 94, 95, 96, 96, 96, 97, 97, 96, 96, 96, 96, 95, 95, 94, 93, 93, 92, 92, 91, 91, 90, 89, 89, 88,
86, 86, 85, 83, 83, 81, 80, 80, 80, 79, 79, 79, 78, 78, 79, 81, 82, 82, 85, 89, 89, 91, 93, 93, 94,
95, 95, 95, 95, 95, 95, 95, 95, 95, 94, 94, 94, 94, 93, 93, 93, 92, 92, 91, 91, 91, 90, 90, 90, 88,
87, 87, 86, 85, 85, 84, 84, 84, 83, 84, 84, 84, 85, 86, 86, 87, 87, 87, 88, 88, 88, 89, 90, 90, 90,
91, 91, 92, 92, 92, 93, 94, 94, 94, 95, 95, 95, 95, 94, 94, 94, 93, 93, 93, 92, 92, 92, 91, 91, 90,
89, 89, 87, 86, 85, 85, 84, 83, 83, 82, 82, 82, 81, 81, 81, 81, 81, 81, 82, 85, 85, 86, 89, 89, 91,
92, 93, 93, 93, 94, 94, 94, 94, 94, 94, 94, 94, 94, 93, 93, 93, 92, 92, 92, 91, 91, 91, 90, 89, 89,
88, 88, 88, 87, 87, 87, 86, 86, 86, 85, 85, 85, 85, 85, 85, 86, 87, 87, 87, 88, 88, 88, 88, 88, 88,
89, 89, 89, 89, 89, 89, 90, 90, 90, 90, 91, 91, 92, 93, 93, 94, 94, 95, 95, 95, 96, 96, 96, 95, 95,
95, 94, 94, 93, 93, 93, 92, 90, 90, 89, 87, 87, 87, 85, 83, 83, 82, 81, 81, 81, 80, 80, 81, 81, 81,
81, 81, 81, 81, 81, 81, 81, 81, 81, 83, 86, 88, 88, 90, 91, 91, 91, 92, 92, 93, 93, 93, 94, 95, 95,
95, 96, 96, 96, 96, 96, 96, 96, 95, 95, 95, 95, 95, 94, 93, 93, 92, 92, 92, 91, 90, 90, 90, 90, 90,
91, 93, 93, 94, 94, 94, 94, 95, 94, 94, 94, 94, 94, 94, 93, 93, 93, 93, 93, 93, 92, 92, 92, 92, 92,
91, 91, 91, 91, 91, 91, 91, 91, 90, 90, 90, 90, 90, 90, 90, 90, 89, 89, 89, 89, 89, 89, 89, 89, 89,
89, 90, 90, 90, 90, 91, 91, 92, 93, 93, 93, 94, 94, 94, 94, 94, 94, 94, 94, 94, 95, 95, 95, 95, 95,
95, 95, 95, 95, 94, 93, 93, 93, 93, 93, 92, 92, 92, 91, 91, 91, 91, 90, 90, 90, 89, 89, 89, 88, 88,
88, 88, 88, 88, 88, 88, 88, 89, 89, 89, 89, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 91, 91, 91, 91,
91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 91, 92,
92, 93, 93, 93, 93, 94, 94, 94, 93, 93, 93, 93, 93, 93, 92, 92, 92, 91, 91, 91, 90, 90, 90, 89, 88,
88, 87, 87, 87, 86, 86, 85, 85, 85, 86, 86, 86, 87, 87, 88, 88, 88, 89, 90, 90, 90, 91, 91, 91, 91,
91, 91, 91, 91, 91, 92, 92, 92, 93, 93, 93, 93, 93, 93, 93, 92, 92, 92, 91, 91, 90, 90, 90, 89, 88,
87, 87, 87, 86, 86, 86, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 85, 86, 86, 86, 86, 87, 88, 88, 88,
89, 89, 90, 91, 91, 92, 93, 93, 93, 94, 94, 94, 94, 94, 94, 94, 94, 94, 93, 93, 93, 92, 92, 92, 91,
90, 90, 90, 89, 89, 88, 88, 88, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, 88, 88, 88,
90, 90, 91, 93, 93, 93, 93, 93, 94, 93, 93, 93, 93, 93, 93, 92, 92, 92, 91, 91, 91, 90, 90, 90, 89,
89, 89, 88, 87, 87, 87, 87, 87, 86, 87, 87, 87, 87, 87, 87, 87, 87, 87, 88, 88, 88, 88, 88, 88, 88,
89
]
var groups = [
[0, 4],
[4, 8],
[8, 12],
[12, 16],
[16, 25],
[25, 100]
]
var bb = ["()", "[)", "[)", "[)", "[)", "[]"]
var isFlat = Fn.new { |s| s.count < 2 || s[0] == s[-1] }
var percentageChange = Fn.new { |s| 100 - (s[-1] / s[0] * 100) }
// Assumes 'operator' is always less than or equal (<=).
var contiguousSubsequences = Fn.new { |s|
var subsequences = []
if (s.count == 0) return subsequences
var subsequence = [s[0]]
var i = 0
while (i < s.count - 1) {
if (s[i+1] <= s[i]) {
subsequence.add(s[i+1])
} else {
subsequences.add(subsequence)
subsequence = [s[i+1]]
}
i = i + 1
}
subsequences.add(subsequence)
return subsequences
}
var trimPlateaus = Fn.new { |s|
var indivs = Lst.individuals(s)
var res = [indivs[0][0]]
var i = 1
while (i < indivs.count - 1) {
for (j in 0...indivs[i][1]) res.add(indivs[i][0])
i = i + 1
}
res.add(indivs[-1][0])
return res
}
var nonIncreasingContiguousSubsequences = Fn.new { |s|
var subsequences = contiguousSubsequences.call(s).where { |t| !isFlat.call(t) }
return subsequences.map { |t| trimPlateaus.call(t) }
}
// Returns the index of the relevant group rather than the group itself.
var subsequenceGroupsIndex = Fn.new { |s|
var change = percentageChange.call(s)
if (change == 100) return groups.count - 1
for (i in 0...groups.count) {
if (change >= groups[i][0] && change < groups[i][1]) return i
}
Fiber.abort("Subsequence out of range: %(change)")
}
var subsequences = nonIncreasingContiguousSubsequences.call(data)
var dist = List.filled(groups.count, 0)
for (s in subsequences) {
var ix = subsequenceGroupsIndex.call(s)
dist[ix] = dist[ix] + 1
}
for (i in 0...groups.count) {
Fmt.print("$s$2d, $3d$s\% : $d", bb[i][0], groups[i][0], groups[i][1], bb[i][1], dist[i])
}
- Output:
( 0, 4)% : 7 [ 4, 8)% : 6 [ 8, 12)% : 4 [12, 16)% : 2 [16, 25)% : 2 [25, 100]% : 0