Golf mis matrices Ada

10

Antecedentes

Ada es un lenguaje de programación que no es exactamente conocido por su brevedad.

Sin embargo, su sintaxis literal de matriz puede, en teoría, permitir especificaciones de matriz bastante concisas. Aquí hay una descripción simple EBNF de la sintaxis literal de la matriz (pasable a 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'

Nos limitaremos a conjuntos de enteros unidimensionales por simplicidad. Esto significa que solo usaremos enteros para los valores de expresión. Quizás en un desafío futuro podríamos intentar algo más avanzado (como declarar variables y matrices multidimensionales). Usted no tiene que campo de los literales enteros .

Estos son algunos ejemplos de literales de matriz Ada y una representación equivalente a Python esque para mayor claridad:

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

Desafío

El objetivo de este desafío es generar el literal de matriz Ada de recuento de bytes más corto para una matriz de entrada dada. Tenga en cuenta que las matrices Ada pueden comenzar desde el índice que desee, por lo que puede elegir cuál desea que sea el índice inicial siempre que cada valor sea secuencial. En este ejemplo, elijo comenzar en 1, lo cual es idiomático para Ada, sin embargo, puede elegir comenzar en cualquier otro número entero.

Entrada

Su entrada consistirá en una lista de enteros, en cualquier forma que sea conveniente.

Salida

Su salida será una cadena de texto que representa el literal de matriz de Ada válido más corto que representa la lista de enteros de entrada. Puede usar cualquier índice inicial que desee en esta matriz, pero su elección (sea cual sea) debe especificarse en su respuesta (el índice inicial también puede ser dinámico).

Los enteros deben representarse como números decimales con signo, como en los ejemplos. Este desafío no cubre el golf de valores enteros.

Ejemplos

Aquí hay unos ejemplos:

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)

Requerimientos mínimos

  • Admite al menos 100 números e entradas de al menos 256 números de longitud.

  • Produzca el resultado correcto para todas esas entradas

    • Incluye poner 'otros' al final
    • Incluye poner un índice para conjuntos de elementos individuales
  • Termine (preferiblemente en TIO) para cada una de las entradas anteriores en menos de un minuto.

¡La solución más corta en bytes gana!

Implementación de referencia

Pruébalo en línea!

Esta implementación utiliza la entrada como su matriz, con cada carácter como un número. Las letras mayúsculas son constantes especiales para valores grandes. El argumento del programa es el 'índice de inicio' a usar.

La sección "código" en el enlace TIO es una solución correcta al problema, mientras que el "encabezado" y el "pie de página" implementan la estructura de prueba.

LambdaBeta
fuente
3
¿Tiene el caso de que existan "Lejos Rango" simplemente para indicar que podemos tomar de entrada en ese formato si elegimos o para resaltar que tenemos para poder manejar ese formato de entrada, así como matrices normales? Además, ¿no debería salir el último caso de prueba (-1)?
Shaggy
3
El caso "Far Range" se escribe simplemente de esa manera para ahorrar espacio, la entrada real sería una matriz plana que consta de 110 enteros, pero la salida es correcta. Su propósito es demostrar casos en los que la palabra clave 'otros' debe ir en un rango más corto que tenga una representación más larga. ( 106..110=>3,others=>2sería más largo) El último caso debe tener un índice, ya que la gramática no permite matrices posicionales de un solo elemento ( positional_array ::= expression ',' expression (',' expression)*)
LambdaBeta
1
En teoría, ¿podría (y debería) codificarse una lista de 100,000,000 ya que es más corta que ? 1(1=>1,others=>1)(1..100000000=>1)
Arnauld
2
¿Podría confirmar que (1|3=>1234567,2=>1)es otra salida válida para [1234567,1,1234567]?
Arnauld
1
¿Se nos permite usar Ada como nuestro idioma de elección?
Benjamin Urquhart

Respuestas:

5

JavaScript (ES6),  307  304 bytes

Guardado 2 bytes gracias a @KevinCruijssen

Esto es vergonzosamente largo ...

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

Pruébalo en línea!

Arnauld
fuente
305 bytes (-2) creando una variable para los duplicados 'others=>'.
Kevin Cruijssen
@KevinCruijssen ¡Gracias! (Nota: en su versión, tse usa antes de que se defina; la razón por la que no falla es que los primeros 2 casos de prueba no lo usan en absoluto; sin embargo, eso se puede solucionar fácilmente sin costo alguno).
Arnauld
Ah ok Realmente no descifré tu respuesta para ver qué se usaba y dónde. Simplemente noté que tenía 'others'dos veces e intenté crearle una variable sin cambiar la salida. ;) Gracias por explicarlo, y buen golf de la coma usando [,O]. :)
Kevin Cruijssen
2

05AB1E , 136 134 132 bytes

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

EDITAR: Corregido para todos los casos de prueba ahora.

Pruébelo en línea o verifique todos los casos de prueba (excepto el 'Entrada enorme', ya que es demasiado grande).

Explicación:

"',ý'(ì')«ˆ"       # 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)

Ver este consejo 05AB1E mío (sección Cómo comprimir cadenas que no forman parte del diccionario? ) Para entender por qué …ˆ†=>es "others=>".

Kevin Cruijssen
fuente