Golf array Ada saya

10

Latar Belakang

Ada adalah bahasa pemrograman yang tidak dikenal karena kekasarannya.

Namun, sintaks literal arraynya secara teori memungkinkan spesifikasi array yang cukup singkat. Berikut ini adalah deskripsi EBNF sederhana dari sintaks literal array (lumayan untuk 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'

Kami akan membatasi diri pada array bilangan 1 dimensi untuk kesederhanaan. Ini berarti bahwa kami hanya akan menggunakan bilangan bulat untuk nilai ekspresi. Mungkin dalam tantangan di masa depan kita bisa mencoba sesuatu yang lebih maju (seperti mendeklarasikan variabel dan array multidimensi). Anda tidak harus bermain golf bilangan bulat literal .

Berikut adalah beberapa contoh literal array Ada dan representasi setara python-esque untuk kejelasan:

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

Tantangan

Tujuan dari tantangan ini adalah untuk menghasilkan byte array count-byte terpendek yang ada untuk array input yang diberikan. Perhatikan bahwa array Ada dapat mulai dari indeks apa pun yang diinginkan, sehingga Anda dapat memilih apa yang Anda inginkan sebagai indeks awal selama masing-masing nilai berurutan. Dalam contoh ini saya memilih untuk memulai pada 1, yang merupakan idiomatis untuk Ada, namun Anda dapat memilih untuk mulai dari bilangan bulat lainnya.

Memasukkan

Masukan Anda akan terdiri dari daftar bilangan bulat, dalam bentuk apa pun yang nyaman.

Keluaran

Output Anda akan berupa string teks yang mewakili literal array Ada terpendek valid yang mewakili daftar bilangan bulat input. Anda dapat menggunakan indeks awal apa pun yang Anda inginkan pada larik ini, tetapi pilihan Anda (apa pun itu) harus ditentukan dalam jawaban Anda (indeks awal mungkin juga dinamis).

Bilangan bulat harus direpresentasikan sebagai angka desimal yang ditandatangani, seperti pada contoh. Tantangan ini tidak mencakup golf dari nilai integer.

Contohnya

Berikut ini beberapa contohnya:

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)

Persyaratan minimum

  • Mendukung setidaknya 100 angka dan panjangnya sedikitnya 256 angka.

  • Menghasilkan hasil yang benar untuk semua input tersebut

    • Termasuk menempatkan 'orang lain' di bagian akhir
    • Termasuk menempatkan indeks untuk array item tunggal
  • Hentikan (sebaiknya pada TIO) untuk masing-masing input di atas dalam waktu kurang dari satu menit.

Solusi terpendek dalam byte menang!

Implementasi Referensi

Cobalah online!

Implementasi ini menggunakan input sebagai lariknya, dengan setiap karakter menjadi angka. Huruf kapital adalah konstanta khusus untuk nilai besar. Argumen program adalah 'indeks awal' untuk digunakan.

Bagian "kode" di tautan TIO adalah solusi yang tepat untuk masalah tersebut, sedangkan "header" dan "footer" menerapkan struktur pengujian.

LambdaBeta
sumber
3
Apakah ada kasus "Kisaran Jauh" hanya untuk menunjukkan bahwa kami dapat mengambil input dalam format itu jika kami memilih atau menggarisbawahi bahwa kami harus dapat menangani format input tersebut serta array normal? Juga, bukankah test case terakhir hanya output (-1)?
Shaggy
3
Kasus "Far Range" hanya ditulis dengan cara itu untuk menghemat ruang, input sebenarnya akan berupa array datar yang terdiri dari 110 bilangan bulat, tetapi hasilnya benar. Tujuannya adalah untuk mendemonstrasikan kasus di mana kata kunci 'orang lain' harus berada pada rentang yang lebih pendek yang memiliki representasi yang lebih panjang. ( 106..110=>3,others=>2akan lebih lama) Kasus terakhir perlu memiliki indeks, karena tata bahasa tidak mengizinkan array posisi elemen tunggal ( positional_array ::= expression ',' expression (',' expression)*)
LambdaBeta
1
Secara teori, dapatkah (dan seharusnya) daftar 100.000.000 dikodekan karena lebih pendek dari ? 1(1=>1,others=>1)(1..100000000=>1)
Arnauld
2
Bisakah Anda mengonfirmasi bahwa (1|3=>1234567,2=>1)ini adalah keluaran lain yang valid untuk [1234567,1,1234567]?
Arnauld
1
Apakah kami diizinkan menggunakan Ada sebagai bahasa pilihan kami?
Benjamin Urquhart

Jawaban:

5

JavaScript (ES6),  307  304 byte

Disimpan 2 byte berkat @KevinCruijssen

Ini memalukan lama ...

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

Cobalah online!

Arnauld
sumber
305 byte (-2) dengan membuat variabel untuk digandakan 'others=>'.
Kevin Cruijssen
@KevinCruijssen Terima kasih! (NB: Dalam versi Anda, tdigunakan sebelum didefinisikan; alasan mengapa tidak macet adalah karena 2 kasus uji pertama tidak menggunakannya sama sekali; yang dapat dengan mudah diperbaiki tanpa biaya, meskipun.)
Arnauld
Ah baiklah. Saya tidak benar-benar ungolf jawaban Anda untuk melihat apa yang digunakan di mana. Saya hanya memperhatikan Anda telah 'others'dua kali dan mencoba membuat variabel untuk itu tanpa mengubah output. ;) Terima kasih telah menjelaskannya, dan golf yang bagus dengan menggunakan koma [,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: Tetap untuk semua kasus uji sekarang.

Cobalah secara online atau verifikasi semua test case (kecuali untuk yang 'Input Besar', karena terlalu besar).

Penjelasan:

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

Lihat ini 05AB1E ujung tambang (bagian Cara string kompres bukan bagian dari kamus? ) Untuk memahami mengapa …ˆ†=>adalah "others=>".

Kevin Cruijssen
sumber