Golf miei array Ada


10

sfondo

Ada è un linguaggio di programmazione che non è esattamente noto per la sua terseness.

Tuttavia, la sua sintassi letterale di array può in teoria consentire specifiche di array abbastanza concise. Ecco una semplice descrizione EBNF della sintassi letterale dell'array (passabile 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'

Ci limiteremo ad array monodimensionali di numeri interi per semplicità. Ciò significa che useremo solo numeri interi per i valori dell'espressione. Forse in una sfida futura potremmo provare qualcosa di più avanzato (come dichiarare variabili e array multidimensionali). Non , non è necessario il golf i letterali interi .

Ecco alcuni esempi di letterali array Ada e una rappresentazione equivalente in stile pitone per chiarezza:

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

Sfida

L'obiettivo di questa sfida è quello di produrre letteralmente l'array Ada conteggio dei byte più breve per un determinato array di input. Si noti che le matrici Ada possono iniziare da qualsiasi indice sia desiderato, quindi è possibile scegliere ciò che si desidera che l'indice iniziale sia purché ciascun valore sia sequenziale. In questo esempio ho scelto di iniziare da 1, che è idiomatico per Ada, tuttavia puoi scegliere di iniziare da qualsiasi altro numero intero.

Ingresso

Il tuo input sarà costituito da un elenco di numeri interi, in qualsiasi forma sia conveniente.

Produzione

L'output sarà una stringa di testo che rappresenta il valore letterale dell'array Ada più breve valido che rappresenta l'elenco di numeri interi di input. È possibile utilizzare qualsiasi indice iniziale desiderato su questo array, ma la scelta (qualunque essa sia) deve essere specificata nella risposta (l'indice iniziale può anche essere dinamico).

I numeri interi devono essere rappresentati come numeri decimali con segno, come negli esempi. Questa sfida non copre il golf dei valori interi.

Esempi

Ecco alcuni esempi:

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)

Requisiti minimi

  • Supporta almeno 100 numeri e input di almeno 256 numeri di lunghezza.

  • Produrre il risultato corretto per tutti questi input

    • Include mettere "altri" alla fine
    • Include l'inserimento di un indice per array di singoli elementi
  • Terminare (preferibilmente su TIO) per ciascuno degli ingressi sopra in meno di un minuto.

Vince la soluzione più breve in byte!

Implementazione di riferimento

Provalo online!

Questa implementazione utilizza l'input come array, con ogni carattere che è un numero. Le lettere maiuscole sono costanti speciali per valori di grandi dimensioni. L'argomento del programma è l '"indice iniziale" da utilizzare.

La sezione "codice" nel collegamento TIO è una soluzione corretta al problema, mentre "intestazione" e "piè di pagina" implementano la struttura del test.


3
Ha il caso esiste "Far Range" semplicemente per indicare che possiamo prendere in ingresso in quel formato, se scegliamo o per evidenziare che noi dobbiamo essere in grado di gestire tale formato di input, così come array normali? Inoltre, non dovrebbe essere prodotto solo l'ultimo caso di test (-1)?
Shaggy,

3
Il caso "Far Range" è semplicemente scritto in questo modo per risparmiare spazio, l'input effettivo sarebbe un array piatto composto da 110 numeri interi, ma l'output è corretto. Il suo scopo è dimostrare i casi in cui la parola chiave "altri" dovrebbe andare su un intervallo più breve con una rappresentazione più lunga. ( 106..110=>3,others=>2sarebbe più lungo) L'ultimo caso deve avere un indice, poiché la grammatica non consente matrici posizionali a singolo elemento ( positional_array ::= expression ',' expression (',' expression)*)
LambdaBeta,

1
In teoria, potrebbe (e dovrebbe) essere codificato un elenco di 100.000.000 di poiché poiché è più breve di ? 1(1=>1,others=>1)(1..100000000=>1)
Arnauld

2
Potresti confermare che (1|3=>1234567,2=>1)è un altro output valido per [1234567,1,1234567]?
Arnauld

1
È consentito utilizzare Ada come lingua preferita?
Benjamin Urquhart,

Risposte:


5

JavaScript (ES6),  307  304 byte

Salvato 2 byte grazie a @KevinCruijssen

Questo è imbarazzantemente lungo ...

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

Provalo online!


305 byte (-2) creando una variabile per il duplicato 'others=>'.
Kevin Cruijssen,

@KevinCruijssen Grazie! (NB: Nella tua versione, tviene utilizzato prima della definizione; il motivo per cui non si arresta in modo anomalo è che i primi 2 casi di test non lo usano affatto; ciò può essere facilmente risolto gratuitamente, tuttavia.)
Arnauld

Ah ok. Non ho davvero annullato la tua risposta per vedere cosa è stato usato dove. Ho semplicemente notato che hai avuto 'others'due volte e ho provato a creare una variabile per esso senza modificare l'output. ;) Grazie per averlo spiegato, e buon golf della virgola usando [,O]. :)
Kevin Cruijssen

2

05AB1E , 136 134 132 byte

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

EDIT: risolto per tutti i casi di test ora.

Provalo online o verifica tutti i casi di test (tranne quello "Input enorme", poiché è troppo grande).

Spiegazione:

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

Vedere questo 05AB1E punta del mio (sezione Come stringhe di comprimere che non fanno parte del dizionario? ) Per capire il motivo per cui …ˆ†=>è "others=>".

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.