Panjang-enkode string

18

Misalkan kita menggunakan aturan berikut untuk menarik satu string dari string lain, satu berisi hanya karakter ASCII yang dapat dicetak dan disebut *-string. Jika string habis sebelum proses berhenti, itu adalah kesalahan, dan hasil dari proses tidak ditentukan dalam kasus itu:

  1. Dimulai dari d=1, s=""
  2. Setiap kali Anda menemukan *, kalikan ddengan 2. Setiap kali Anda menemukan karakter lain, gabungkan hingga akhir sdan kurangi 1 dari d. Jika sekarang d=0, berhenti dan kembalis

Contoh yang Ditentukan :

d->d
769->7
abcd56->a
*abcd56->ab
**abcd56->abcd
*7*690->769
***abcdefghij->abcdefgh

Contoh tidak terdefinisi : (perhatikan bahwa string kosong juga akan menjadi salah satu dari ini)

*7
**769
*7*
*a*b
*

Tugas Anda adalah mengambil string dan mengembalikan *-string terpendek yang menghasilkan string itu.

Contoh Program :

7->7
a->a
ab->*ab
abcd->**abcd
769->*7*69

Program Anda harus menangani string yang mengandung setidaknya satu karakter dan hanya karakter yang tidak *dapat dicetak ASCII. Anda tidak pernah dapat mengembalikan string yang prosesnya tidak terdefinisi, karena menurut definisi mereka tidak dapat menghasilkan string APA PUN.

Berlaku celah standar dan aturan I / O.

Melon Fricative
sumber
Bisakah kita menganggap input tidak mengandung *?
Luis Mendo
3
@DonMuesli "hanya karakter non-* ASCII yang dapat dicetak"
FryAmTheEggman

Jawaban:

3

Pyth ( 36 27 bytes)

Terima kasih kepada Jakube untuk peningkatan 9 byte! Saat ini jawabannya tidak sebagus muddyfish , tapi terserahlah

KlzJ1VzWgKyJp\*=yJ)pN=tK=tJ

Test Suite

Terjemahan ke python:

                            | z=input() #occurs by default
Klz                         | K=len(z)
   J1                       | J=1
     Vz                     | for N in z:
       WgKyJ                |   while K >= J*2:
            p\*             |     print("*", end="")
               =yJ          |     J=J*2
                  )         |     #end inside while
                   pN       |   print(N, end="")
                     =tK    |   K=K-1
                        =tJ |   J=J-1
K Zhang
sumber
1
Muddyfish tampaknya telah mati ...
Rɪᴋᴇʀ
5

JavaScript (ES6), 61 byte

f=(s,d=2)=>s?d>s.length?s[0]+f(s.slice(1),d-2):'*'+f(s,d*2):s

Fungsi rekursif yang melakukan hal berikut:

  • Jika dkurang dari atau sama dengan panjang string yang tersisa dibagi 2:

    Tambahkan *ke keluaran dan kalikan ddengan 2

  • Lain:

    Geser string dan tambahkan ke output, kurangi 1 dari d.

Lihat dalam aksi:

f=(s,d=2)=>s?d>s.length?s[0]+f(s.slice(1),d-2):'*'+f(s,d*2):s

input.oninput = e => output.innerHTML = f(input.value);
<input id="input" type="text"/>
<p id="output"></p>

George Reith
sumber
1
Hemat 2 byte dengan bekerja dengan menggandakan nilai d ditambah byte lebih lanjut dengan membalikkan kondisinya:f=(s,d=2)=>s?d>s.length?s[0]+f(s.slice(1),d-2):'*'+f(s,d*2):s
Neil
4

Pyth, 29 27 ( Pemberitahuan rusak) 27 26 25 byte

+*\*sKllzXJ-^2.EKlzz?J\*k

Penjelasan yang akan datang.

Test Suite

Biru
sumber
2

C, 125 byte

main(int q,char**v){++v;int i=1,n=strlen(*v);while(n>(i*=2))putchar(42);for(i-=n;**v;--i,++*v)!i&&putchar(42),putchar(**v);}

Ini mengambil keuntungan dari pola posisi bintang yang sangat teratur untuk menghasilkan penyandian yang benar. Awalnya saya mencoba solusi rekursif bruteforce, tetapi dalam retrospeksi seharusnya sudah jelas bahwa ada solusi matematika yang lebih sederhana.

Pada dasarnya Anda akan selalu memiliki 2^floor(log_2(length))bintang pada awal output Anda, dan bintang akhir setelah 2^ceil(log_2(length)) - lengthkarakter (jika itu berhasil setidaknya 1 karakter).

Versi (sedikit) tidak diubah adalah sebagai berikut

main(int q,char**v){
   ++v;                         // refer to the first command line argument
   int i=1, n=strlen(*v);       // set up iteration variables

   while(n > (i*=2))            // print the first floor(log2(n)) '*'s
      putchar(42);

   for(i-=n;  **v;  --i, ++*v)  // print the string, and the final '*'
      !i&&putchar(42),putchar(**v);
}
Gordon Bailey
sumber
1

JavaScript (ES6), 88 77 byte

f=(s,l=s.length,p=2)=>l<2?s:p<l?"*"+f(s,l,p*2):s.slice(0,p-=l)+"*"+s.slice(p)

Pada awalnya saya pikir itu abcdeharus terjadi *a**bcdetetapi ternyata **abc*debekerja dengan baik. Ini berarti bahwa output siap dibangun menggunakan lantai (log₂ (s.length) terkemuka), ditambah bintang tambahan untuk string yang panjangnya bukan kekuatan dua.

Sunting: Disimpan 8 byte dengan menghitung jumlah bintang terkemuka secara rekursif. Menyelamatkan 3 byte lebih lanjut dengan string casing khusus panjang 1, sehingga saya dapat memperlakukan string yang panjangnya kekuatan 2 sebagai memiliki bintang tambahan.

Neil
sumber
0

Haskell, 68 byte

f d[]=""
f d xs|length xs>=d*2='*':f(d*2)xs
f d(x:xs)=x:f(d-1)xs

Sama seperti jawaban lainnya, sungguh. Jika EOF, output string kosong. Jika panjang yang tersisa lebih dari dua kali d, output bintang dan ganda d. Jika tidak, keluarkan karakter berikutnya dan kurangi satu dari d.

Tidak Disatukan:

f d (  [])                    = ""
f d (  xs) | length xs >= d*2 = '*' : f (d*2) xs
f d (x:xs)                    =  x  : f (d-1) xs
Matematika Matematika
sumber