Background
Ada is a programming language that is not exactly known for its terseness.
However, its array literal syntax can in theory allow for fairly terse array specifications. Here is a simple EBNF description of the array literal syntax (passable to bottlecaps.de:
array ::= positional_array | named_array
positional_array ::= expression ',' expression (',' expression)*
| expression (',' expression)* ',' 'others' '=>' expression
named_array ::= component_association (',' component_association)*
component_association ::= discrete_choice_list '=>' expression
discrete_choice_list ::= discrete_choice ('|' discrete_choice)*
discrete_choice ::= expression ('..' expression)? | 'others'
We will limit ourselves to 1-dimensional arrays of integers for simplicity. This means that we will use only integers for the expression values. Perhaps in a future challenge we could try something more advanced (like declaring variables and multidimensional arrays). You do not have to golf the integer literals.
Here are some examples of Ada array literals and a python-esque equivalent representation for clarity:
(1, 2, 3) = [1, 2, 3]
(1, others => 2) = [1, 2, 2, ..., 2]
(others => 1) = [1, 1, ..., 1]
(1 => 1, 2 => 3) = [1, 3]
(1|2 => 1, 3 => 2) = [1, 1, 2]
(1 => 1, 3 => 2, others => 3) = [1, 3, 2, 3, 3, ..., 3]
Challenge
The goal of this challenge is to output the shortest byte-count Ada array literal for a given input array. Note that Ada arrays can start from whatever index is desired, so you can pick what you wish the starting index to be as long as each value is sequential. In this example I choose to start at 1, which is idiomatic for Ada, however you can choose to start at any other integer.
Input
Your input will consist of a list of integers, in whatever form is convenient.
Output
Your output will be a string of text representing the shortest valid Ada array literal that represents the list of input integers. You may use any starting index you wish on this array, but your choice (whatever it is) must be specified in your answer (the starting index may also be dynamic).
The integers are to represented as signed decimal numbers, as in the examples. This challenge does not cover golfing of integer values.
Examples
Here are some examples:
Simple: [1, 2, 3] -> (1,2,3)
Range: [1, 1, 1, 1, 1, 1, 1,] -> (1..7=>1)
Others: [1, 1, 1, 1, 1, 2, 1, 1, 1, 1, 1] -> (6=>2,others=>1)
Multiple Ranges: [1,1,1,1,1,2,2,2,2,2,1,1,1,1,1,2,2,2,2,2,1,1,1,1,1] -> (6..10|16..20=>2,others=>1)
Tiny Ranges: [1,1,2,2,1,1,1,1,1] -> (3|4=>2,others=>1)
Far Range: [[1]*5, [2]*100, [3]*5] -> (1..5=>1,6..105=>2,others=>3)
Alternation: [1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2] -> (1|3|5|7|9|11|13|15|17=>1,others=>2)
Big Number: [1234567890,1,1234567890] -> (2=>1,1|3=>1234567890)
Big-ish Number: [1234567,1,1234567] -> (1234567,1,1234567)
Solo: [-1] -> (1=>-1)
Huge Input: [[0],[1]*1000000000] -> (0,others=>1)
Positional Others: [1, 2, 3, 3, 3, 3, 3, 3] -> (1,2,others=>3)
Range and Choice, no Others: [1,1,1,12,12,3,3,3,3,3,3,3,3,3,3,4] -> (1..3=>1,4|5=>12,6..15=>3,16=>4)
Minimum Requirements
Support at least 100 numbers and inputs of at least 256 numbers in length.
Produce the correct result for all such inputs
- Includes putting 'others' at the end
- Includes putting an index for single item arrays
Terminate (preferably on TIO) for each of the above inputs in under a minute.
Shortest solution in bytes wins!
Reference Implementation
This implementation uses the input as its array, with each character being a number. Capital letters are special constants for large values. The program argument is the 'start index' to use.
The "code" section in the TIO link is a correct solution to the problem, while the "header" and "footer" implement the test structure.
(-1)
? \$\endgroup\$106..110=>3,others=>2
would be longer) The last case needs to have an index, as the grammar doesn't allow single element positional arrays (positional_array ::= expression ',' expression (',' expression)*
) \$\endgroup\$(1=>1,others=>1)
since it's shorter than(1..100000000=>1)
? \$\endgroup\$(1|3=>1234567,2=>1)
is another valid output for[1234567,1,1234567]
? \$\endgroup\$