Jouer au golf avec mes tableaux Ada

10

Contexte

Ada est un langage de programmation qui n'est pas exactement connu pour sa lacune.

Cependant, sa syntaxe littérale de tableau peut en théorie permettre des spécifications de tableau assez laconiques. Voici une description EBNF simple de la syntaxe littérale du tableau (passable à 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'

Nous nous limiterons à des tableaux unidimensionnels d'entiers pour plus de simplicité. Cela signifie que nous n'utiliserons que des entiers pour les valeurs d'expression. Peut-être que dans un défi futur, nous pourrions essayer quelque chose de plus avancé (comme déclarer des variables et des tableaux multidimensionnels). Vous n'avez pas besoin de jouer au golf sur les littéraux entiers .

Voici quelques exemples de littéraux de tableau Ada et une représentation équivalente en python pour plus de clarté:

(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]

Défi

Le but de ce défi est de produire le littéral de tableau Ada le plus court pour un tableau d'entrée donné. Notez que les tableaux Ada peuvent commencer à partir de l'index souhaité, vous pouvez donc choisir ce que vous souhaitez que l'index de départ soit tant que chaque valeur est séquentielle. Dans cet exemple, je choisis de commencer à 1, ce qui est idiomatique pour Ada, mais vous pouvez choisir de commencer à n'importe quel autre entier.

Contribution

Votre entrée consistera en une liste d'entiers, sous la forme qui vous convient.

Production

Votre sortie sera une chaîne de texte représentant le littéral de tableau Ada valide le plus court qui représente la liste des entiers d'entrée. Vous pouvez utiliser n'importe quel index de départ que vous souhaitez sur ce tableau, mais votre choix (quel qu'il soit) doit être spécifié dans votre réponse (l'index de départ peut également être dynamique).

Les entiers doivent être représentés sous forme de nombres décimaux signés, comme dans les exemples. Ce défi ne couvre pas le golf de valeurs entières.

Exemples

Voici quelques exemples:

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)

Exigences minimales

  • Prend en charge au moins 100 numéros et entrées d'au moins 256 numéros.

  • Produire le résultat correct pour toutes ces entrées

    • Comprend mettre les «autres» à la fin
    • Comprend la mise en place d'un index pour les tableaux d'éléments uniques
  • Terminez (de préférence sur TIO) pour chacune des entrées ci-dessus en moins d'une minute.

La solution la plus courte en octets gagne!

Implémentation de référence

Essayez-le en ligne!

Cette implémentation utilise l'entrée comme tableau, chaque caractère étant un nombre. Les majuscules sont des constantes spéciales pour les grandes valeurs. L'argument du programme est l '«index de démarrage» à utiliser.

La section "code" du lien TIO est une solution correcte au problème, tandis que "l'en-tête" et le "pied de page" implémentent la structure de test.

LambdaBeta
la source
3
Le cas exist « Range Far » simplement pour indiquer que nous pouvons prendre entrée dans ce format si nous choisissons ou de mettre en évidence que nous devons être en mesure de gérer ce format d'entrée ainsi que les tableaux normaux? De plus, le dernier scénario de test ne devrait-il pas simplement sortir (-1)?
Shaggy
3
Le cas "Far Range" est simplement écrit de cette façon pour économiser de l'espace, l'entrée réelle serait un tableau plat composé de 110 entiers, mais la sortie est correcte. Son but est de démontrer les cas où le mot-clé «autres» devrait aller sur une plage plus courte qui a une représentation plus longue. ( 106..110=>3,others=>2serait plus long) Le dernier cas doit avoir un index, car la grammaire n'autorise pas les tableaux positionnels à élément unique ( positional_array ::= expression ',' expression (',' expression)*)
LambdaBeta
1
1(1=>1,others=>1)(1..100000000=>1)
2
Pourriez-vous s'il vous plaît confirmer qu'il (1|3=>1234567,2=>1)s'agit d'une autre sortie valide pour [1234567,1,1234567]?
Arnauld
1
Sommes-nous autorisés à utiliser Ada comme langue de notre choix?
Benjamin Urquhart

Réponses:

5

JavaScript (ES6),  307  304 octets

Enregistré 2 octets grâce à @KevinCruijssen

C'est d'une longueur embarrassante ...

a=>[b=([...a,m=''].map(o=(v,i)=>(i?p==v?!++n:m=o[(o[p]=[o[p]&&o[p]+'|']+(n?i-n+(n>1?'..':'|')+i:i))[m.length]?(x=i-n,j=p):j]:1)&&(p=v,M=n=0)),Object.keys(o).map(k=>j-k|!m[6]?o[k]+'=>'+k:O,O='others=>'+j).sort()),1/a[1]?[...a]:b,j-a.pop()?b:a.slice(0,x-1)+[,O]].map(a=>M=M[(s=`(${a})`).length]||!M?s:M)&&M

Essayez-le en ligne!

Arnauld
la source
305 octets (-2) en créant une variable pour le dupliqué 'others=>'.
Kevin Cruijssen
@KevinCruijssen Merci! (NB: dans votre version, test utilisé avant d'être défini; la raison pour laquelle il ne plante pas est que les 2 premiers cas de test ne l'utilisent pas du tout; cela peut être facilement réparé sans frais, cependant.)
Arnauld
Ah ok. Je n'ai pas vraiment dégoûté votre réponse pour voir ce qui a été utilisé où. J'ai simplement remarqué que vous aviez 'others'deux fois et essayé de créer une variable sans changer la sortie. ;) Merci de l'expliquer cependant, et bon golf de la virgule en utilisant [,O]. :)
Kevin Cruijssen
2

05AB1E , 136 134 132 octets

"',ý'(ì')«ˆ"©.V"θ…ˆ†=>쪮.V"Uγ¨D€gPi˜IX.V}\ÙεQƶ0KDāαγ€g£}D2Fε¾iεнyg≠iyθyg<i'|ë„..}ý}}ë˜}'|ý„=>«Iyнн<è«}Ю.VgFDN._ć'>¡X.V}\¼}¯éIgi¦}н

EDIT: corrigé pour tous les cas de test maintenant.

Essayez-le en ligne ou vérifiez tous les cas de test (sauf celui «Huge Input», car il est trop gros).

Explication:

"',ý'(ì')«ˆ"       # Push this string (function 1), which does:
 ',ý              '#  Join a list by ","
    '(ì           '#  Prepend a "("
       ')«        '#  Append a ")"
          ˆ        #  Pop and add it to the global array
            ©      # Store this string in the register (without popping)
             .V    # And execute it as 05AB1E code on the (implicit) input-list
"θ…ˆ†=>쪮.V"      # Push this string (function 2), which does:
 θ                 #  Pop and push the last element of the list
  …ˆ†=>ì           #  Prepend dictionary string "others=>"
        ª          #  Append that to the list which is at the top of the stack
         ®.V       #  And execute function 1 from the register     
             U     # Pop and store this string in variable `X`
γ                  # Get the chunks of equal elements in the (implicit) input-list
 ¨                 # Remove the last chunk
  D                # Duplicate the list of remaining chunks
   g              # Get the length of each
     Pi     }      # If all chunk-lengths are 1:
       ˜           #  Flatten the list of remaining chunks
        I          #  Push the input-list
         X.V       #  Execute function 2 from variable `X`
             \     # Discard the top of the stack (in case we didn't enter the if-statement)
Ù                  # Uniquify the (implicit) input-list
 ε                 # Map each unique value `y` to:
  Q                #  Check for each value in the (implicit) input-list if it's equal to `y`
                   #  (1 if truthy; 0 if falsey)
   ƶ               #  Multiply each by its 1-based index
    0K             #  Remove all 0s
      D            #  Duplicate it
       ā           #  Push a list [1, length] without popping the list itself
        α          #  Get the absolute difference at the same indices
         γ         #  Split it into chunks of the same values
          g       #  Get the length of each
            £      #  And split the duplicated indices-list into those parts
                   # (this map basically groups 1-based indices per value.
                   #  i.e. input [1,1,2,1,1,2,2,1,1] becomes [[[1,2],[4,5],[8,9]],[[3],[6,7]]])
 }D                # After the map: duplicate the mapped 3D list
   2F              # Loop 2 times:
     ε             #  Map the 3D list of indices to:
      ¾i           #   If the counter_variable is 1:
        ε          #    Map each list `y` in the 2D inner list to:
         н         #     Leave the first value
         ygi      #     And if there is more than one index:
             yθ    #      Push the last value as well
             yg<i  #      If there are exactly two indices:
              '|  '#       Push string "|"
             ë     #      Else (there are more than two indices)
              „..  #       Push string ".."
                 #      And join the first and last value by this string
        }}         #    Close the if-statement and map
      ë            #   Else:
       ˜           #    Flatten the 2D list
      }'|ý        '#   After the if-else: join by "|"
          „=>«     #   Append "=>"
       yнн         #   Get the very first index of this 2D list
          <        #   Decrease it by 1 to make it 0-based
      I    è       #   And index it into the input-list to get its value again
            «      #   Which is also appended after the "=>"
                 #  After the map: triplicate the result
       ®.V         #  Execute function 1 from the register
       g           #  Get the amount of items in the triplicated list
        F          #  Loop that many times:
         D         #   Duplicate the list
          N._      #   Rotate it the index amount of times
          ć        #   Extract the head; pop and push remainder and head
           '>¡    '#   Split this head by ">"
              X.V  #   And then function 2 is executed again from variable `X`
        }\         #  After the loop: discard the list that is still on the stack
          ¼        #  And increase the counter_variable by 1
                 # After looping twice: push the global array
     é             # Sort it by length
      Igi }        # If the input only contained a single item:
         ¦         #  Remove the very first item
           н       # And then only leave the first item
                   # (which is output implicitly as result)

Voir cette astuce de mes 05AB1E (section Comment chaînes Compresser ne font pas partie du dictionnaire? ) Pour comprendre pourquoi …ˆ†=>est "others=>".

Kevin Cruijssen
la source