Temukan representasi nomor terpendek di SNUSP Modular

10

Latar Belakang

Banyak bahasa pemrograman esoterik tidak memiliki angka bawaan pada literal, jadi Anda harus menghitungnya saat runtime; dan dalam banyak kasus ini, representasi angka bisa sangat menarik. Kami sudah memiliki tantangan tentang mewakili angka untuk Underload. Tantangan ini adalah tentang mewakili angka dalam SNUSP Modular . (Perhatikan bahwa Anda tidak perlu mempelajari SNUSP untuk menyelesaikan tantangan ini - semua informasi yang Anda butuhkan ada dalam spesifikasi - tetapi Anda mungkin menemukan latar belakangnya menarik.)

Tugas

Untuk tujuan tantangan ini, nomor SNUSP Modular adalah string yang terbentuk dari karakter @,, +dan =, kecuali bahwa karakter terakhir adalah a #, dan bahwa karakter kedua dari belakang harus +atau =(tidak mungkin @). Misalnya, nomor yang valid termasuk @+#, ==#dan @@+@=#; contoh nomor yang tidak valid termasuk +=, @@#, dan +?+#.

Nilai nomor SNUSP Modular dihitung secara rekursif sebagai berikut:

  • # memiliki nilai 0 (ini adalah kasus dasar).
  • Jika angka memiliki bentuk =x, untuk string apa pun x, nilainya sama dengan nilai x.
  • Jika angka memiliki bentuk +x, untuk string apa pun x, nilainya sama dengan nilai x, ditambah 1.
  • Jika angka memiliki bentuk @cx, untuk karakter tunggal cdan string apa pun x, nilainya sama dengan nilai x, ditambah nilai cx.

Untuk tantangan ini, Anda harus menulis sebuah program yang mengambil bilangan bulat non-negatif sebagai input, dan menghasilkan string yang merupakan nomor SNUSP Modular tersingkat yang memiliki nilai sama dengan input.

Klarifikasi

  • Sangat mungkin bahwa akan ada lebih dari satu string dengan nilai yang sama, dan khususnya, untuk beberapa bilangan bulat akan ada ikatan untuk nomor SNUSP Modular terpendek dengan nilai itu. Dalam kasus seperti itu, Anda dapat menampilkan nomor apa pun yang terkait dengan seri.
  • Tidak ada batasan pada algoritma yang Anda gunakan untuk menemukan nomornya; misalnya, string kasar dan mengevaluasinya adalah taktik hukum, tetapi begitu juga melakukan sesuatu yang lebih pintar untuk mengurangi ruang pencarian.
  • Seperti biasa di PPCG, kiriman Anda bisa berupa program lengkap atau fungsi (pilih mana yang lebih ringkas dalam bahasa Anda).
  • Ini bukan masalah tentang penanganan format input dan output, sehingga Anda dapat menggunakan cara apa pun yang masuk akal untuk memasukkan bilangan bulat negatif dan mengeluarkan string. Ada panduan lengkap tentang meta , tetapi metode hukum yang paling umum digunakan meliputi argumen fungsi / pengembalian, argumen baris perintah, dan input standar / output standar.

Uji kasus

Berikut adalah representasi terpendek dari beberapa angka pertama:

  • 0 :#
  • 1 :+#
  • 2 :++#
  • 3 : +++#atau@++#
  • 4 : ++++#atau +@++#atau@=++#
  • 5 : @+++#atau@@++#
  • 6 : +@+++#atau +@@++#atau @=+++#atau @=@++#atau@@=++#
  • 7 : @++++#atau@+@++#
  • 8 : @@+++#atau@@@++#
  • 9 : +@@+++#atau +@@@++#atau @+++++#atau @++@++#atau @+@=++#atau @@=+++#atau@@=@++#
  • 10 : @=@+++#atau @=@@++#atau @@@=++#( ini adalah kasus uji yang cukup penting untuk diperiksa , karena semua jawaban yang mungkin termasuk =)
  • 11 : @+@+++#atau @+@@++#atau @@++++#atau@@+@++#
  • 12 : +@+@+++#atau +@+@@++#atau +@@++++#atau +@@+@++#atau @=+@+++#atau @=+@@++#atau @=@=+++#atau @=@=@++#atau @=@@=++#atau @@=++++#atau @@=+@++#atau@@=@=++#
  • 13 : @@@+++#atau@@@@++#
  • 14 : +@@@+++#atau +@@@@++#atau @=@++++#atau @=@+@++#atau @@+++++#atau @@++@++#atau@@+@=++#
  • 15 : @+@++++#atau @+@+@++#atau @@=@+++#atau @@=@@++#atau @@@=+++#atau@@@=@++#

Sebagai kasus uji yang lebih besar, output dari input 40 harus @@@=@@+++#, @@@=@@@++#, @@@@=@+++#, atau @@@@=@@++#.

Kondisi kemenangan

Sebagai tantangan , pemenangnya adalah entri terpendek, diukur dalam byte.

Komunitas
sumber
1
=hanya akan terjadi secara optimal @=, kan?
orlp
3
Ngomong-ngomong, tantangan semacam ini biasanya paling baik diposting sebagai metagolf , karena hampir tidak akan ada jawaban yang menarik (hanya mengevaluasi string dan loop atas semua string yang mungkin).
orlp
3
@ orlp: Saya tidak setuju, tantangan ini akan terlalu mudah sebagai metagolf, karena menemukan jawaban yang optimal relatif mudah, dan metagolf tidak menempatkan batasan lain pada penilaian. Saya berharap sebagian besar jawaban di sini adalah brute-force, tetapi spesifikasinya cukup kompleks sehingga brute force a) mungkin tidak terpendek, dan b) cenderung menarik untuk bermain golf dengan caranya sendiri. Jika Anda menginginkan perubahan dalam kondisi kemenangan, kemungkinan satu-satunya yang menarik adalah kode tercepat , dan itu lebih masuk akal sebagai tantangan yang berbeda.
Kami juga memiliki sejumlah tantangan golf untuk Brain-flak
hanya ASCII

Jawaban:

3

Oracle SQL 11.2, 341 262 byte

WITH e AS(SELECT DECODE(LEVEL,1,'=',2,'@','+')e FROM DUAL CONNECT BY LEVEL<4),n(s,v,p,c,i)AS(SELECT'#',0,0,e,1 FROM e UNION ALL SELECT c||s,DECODE(c,'+',1,'@',p,0)+v,v,e,i+1 FROM n,e WHERE i<11)CYCLE s SET y TO 1 DEFAULT 0 SELECT s FROM n WHERE:1=v AND rownum=1;

Versi lama

WITH e AS(SELECT DECODE(LEVEL,1,'=',2,'@','+')e FROM DUAL CONNECT BY LEVEL<4),n(s,v,p,c) AS(SELECT'#',0,0,e FROM e UNION ALL SELECT s||c,CASE c WHEN'+'THEN 1 WHEN'='THEN 0 WHEN'@'THEN p ELSE 0 END+v,v,e FROM n,e WHERE LENGTH(s)<10)CYCLE s SET y TO 1 DEFAULT 0 SELECT MIN(REVERSE(s))KEEP(DENSE_RANK FIRST ORDER BY LENGTH(s))FROM n WHERE v=:1;

: 1 angka untuk diwakili dalam SNUSP Modular

Tidak golf:

WITH e AS (SELECT DECODE(LEVEL,1,'=',2,'@','+')e FROM DUAL CONNECT BY LEVEL<4),  
n(s,v,p,c,i) AS                   
(
  SELECT '#',0,0,e,1 FROM e
  UNION ALL
  SELECT s||c
       , DECODE(c,'+',1,'@',p,0)+v 
       , v
       , e
       , i+1
  FROM n,e
  WHERE i<11
) CYCLE s SET y TO 1 DEFAULT 0
SELECT s FROM n WHERE:1=v AND rownum=1;

Pertama buat tampilan dengan 3 baris, satu untuk setiap simbol yang digunakan untuk mewakili angka, minus # yang hanya digunakan di akhir string:

SELECT DECODE(LEVEL,1,'=',2,'@','+')e FROM DUAL CONNECT BY LEVEL<4;    

Kemudian tampilan rekursif dan menghasilkan setiap string yang mungkin dengan 3 simbol tersebut, menggabungkannya menjadi # dan mengevaluasinya.

Parameternya adalah:

s: representasi SNUSP Modular dari angka yang dievaluasi
v: nilai desimal dari s yang dihitung oleh iterasi sebelumnya
p: v dihitung dengan iterasi i-2
c: simbol berikutnya untuk digabungkan ke s
i: panjang s, hanya s diperlukan untuk menyingkirkan dua LENGTH () untuk tujuan bermain golf

DECODE(c,'+',1,'@',p,0)+v 

Jika simbol terakhir adalah + lalu tambahkan 1
Jika itu adalah @ tambahkan nilai dari iterasi i-2
Lain simbol tersebut adalah # atau =. v diinisialisasi dengan 0 di bagian init dari tampilan rekursif, sehingga v baru sama dengan v sebelumnya dalam kedua kasus.

WHERE i<11

Setiap string yang mungkin dengan 3 simbol dihitung, bagian ini memastikan bahwa permintaan tidak berjalan sampai krisis besar.

CYCLE s SET y TO 1 DEFAULT 0

Karena tidak ada aturan untuk konstruksi string, duplikat pasti akan muncul. Berada dalam pandangan rekursif, Oracle menginterpretasikan duplikat-duplikat itu sebagai siklus dan melemparkan kesalahan jika kasus tidak secara eksplisit ditangani.

SELECT s FROM n WHERE:1=v AND rownum=1;

Mengembalikan representasi SNUSP Modular pertama yang mengevaluasi ke angka desimal yang dimasukkan sebagai parameter: 1

Dalam tes saya, baris pertama selalu merupakan salah satu representasi terpendek.

Jika database Anda tidak akan bertindak dengan cara yang sama, maka klausa terakhir harus diganti

SELECT MIN(s)KEEP(DENSE_RANK FIRST ORDER BY i)FROM n WHERE:1=v
Jeto
sumber
2

JavaScript (ES6), 100 byte

n=>eval("for(a=[['#',0,0]];[[s,t,p],...a]=a,t-n;)a.push(['='+s,t,t],['+'+s,t+1,t],['@'+s,t+p,t]);s")

Algoritme pencarian luas pertama brute-force.

Neil
sumber
Untuk 40 ia mengembalikan "@@@@@@ = ​​++ #" yang dievaluasi menjadi 42
aditsu berhenti karena SE adalah JAHAT
Bahkan untuk 12 ia memberikan "@@@ +++ #" yang dievaluasi menjadi 13
aditsu berhenti karena SE adalah JAHAT
Hmm, saya pikir berubah t<nmenjadi t-nmungkin bekerja ...
Neil
2

Pyth, 41 byte

L?b+ytb@[yttb001)Chb0+hfqQyTs^L"+@="UhQ\#

Suite uji

Bagaimana itu bekerja:

Ada dua bagian. Fungsi rekursif yang menghitung nilai ekspresi SNUSP tanpa trailing #, dan rutin brute force.

Evalutaion:

L?b+ytb@[yttb001)Chb0
L                        Define the function y(b) as follows
 ?b                      If b is nonempty
   +ytb                  The sum of y(tail(b)) and   # tail(b) = b[1:]
   @[       )            The element in the list at location
   Chb                   Character values of the first character.
                         Modular indexing means that 
                         + -> 3
                         @ -> 0
                         = -> 1
                         Index 2 is filler.
    [yttb001)            @ adds y(tail(tail(b)). Tail suppresses the error when
                         called on an empty list, so this treats @# as zero, but
                         this can't lead to problems because removing the @ will
                         always make the expression shorter.
                         + adds 1, = adds 0.
 0                       If b is the empty string, return 0

Kasar:

+hfqQyTs^L"+@="UhQ\#
               UhQ      0 ... Q     # Q is the input
        ^L"+@="         Map that list to all strings formed from the characters
                        "+@=", with that many characters.
       s                Concatenate
  fqQyT                 Filter for strings which evaluate to the input
 h                      Take the first success, which is the shortest due to
                        the order the strings were generated.
+                 \#    Add a '#' and output
isaacg
sumber
1

CJam, 58

ri:M;'#0_]]{_{M&}#_)!}{;{~[2,+1$f+"@=+"\]z\f+\af.+~}%}w=0=

Brute force, dengan sedikit inspirasi dari jawaban Neil. Cobalah online

Versi efisien, 107

ri0"#"a{_{:B\:A={'=A0j+}{A(B={'+B0j+}{AB>{BAB-j_N={'@\+}|}N?}?}?}{;_(0j'+\+a\,1>_W%.{j}Na-'@\f++{,}$0=}?}2j

Cobalah online

Ini menggunakan pemrograman dinamis.

aditsu berhenti karena SE adalah JAHAT
sumber
1

Haskell , 89 86 byte

EDIT:

  • -3 byte: zipping lebih pendek dari pengindeksan.

Solusi brute force lain yang berakhir dengan banyak inspirasi dari jawaban Neil. (Meskipun itu bekerja lebih seperti Pyth isaacg sebelum golf memperkenalkan l.)

f n=[s|(a,_,s)<-l,a==n]!!0
l=(0,0,"#"):[(a+c,a,d:s)|(a,b,s)<-l,(c,d)<-zip[0,1,b]"=+@"]

Cobalah online!

  • f adalah fungsi utama, yang mengambil integer dan mengembalikan sebuah string.
  • ladalah daftar tuple yang tak terbatas (a,b,s), representasi terpendek spertama, bersama dengan nilainya adan nilai brepresentasi dengan char pertama dilucuti. (seperti orang lain juga perhatikan / perhatikan, tidak ada salahnya memperlakukan yang terakhir sebagai 0 untuk #.)
  • Unsur-unsur lselain yang pertama dihasilkan secara rekursif dengan pemahaman daftar. dadalah karakter yang harus diawali untuk smenghasilkan representasi baru dalam daftar, dan 'c' adalah kenaikan yang sesuai untuk a.
Ørjan Johansen
sumber