Rosetta Stone Challenge: Run-Length Encoding v2.0


8

Tujuan dari Rosetta Stone Challenge adalah menulis solusi dalam bahasa sebanyak mungkin. Pamerkan multibahasa Anda dalam pemrograman!

Tantangan

Kami telah melakukan run-length encoding menjadi kedepan tetapi hanya dianggap berjalan dari satu karakter. Tentu saja, kadang-kadang kita dapat membuat penghematan lebih besar jika kita mempertimbangkan beberapa karakter.

Ambil aaaxyzxyzxyzddddcontoh. Ini dapat dikompresi ke 3a3{xyz}4d. Tugas Anda adalah menulis sebuah program fungsi yang, mengingat serangkaian huruf dan spasi peka huruf besar-kecil, kompres secara optimal menggunakan pengkodean run-length untuk menjalankan multi-karakter.

Anda dapat mengambil input melalui argumen fungsi, STDIN atau ARGV dan mengembalikan hasilnya atau mencetaknya ke STDOUT.

Berjalan tidak harus disarangkan, jadi aaabbbaaabbbharus 3a3b3a3b, tidak 2{3a3b} . Yaitu string harus dikodekan (atau didekodekan) dalam satu pass tunggal.

Konsekuensi Kompresi Optimal

Beberapa contoh di mana aplikasi naif pengkodean run-length dapat menyebabkan hasil yang kurang optimal:

  • abab tidak boleh "dikompresi" ke 2{ab}
  • aaaabcdeabcdetidak harus dikompresi 4abcdeabcdetetapi 3a2{abcde}sebaliknya.

Jika ada dua versi optimal (misalnya aadan 2aatau abcabcdan 2{abc}) hasilnya baik-baik saja.

Contohnya

Input              Output

aa                 aa -or- 2a
aaaaaAAAAA         5a5A
ababa              ababa
abababa            a3{ba} -or- 3{ab}a
foo foo bar        2{foo }bar
aaaabcdeabcde      3a2{abcde}
xYzxYz             xYzxYz -or- 2{xYz}
abcabcdefcdef      abcab2{cdef}
pppqqqpppqqq       3p3q3p3q
pppqqqpppqqqpppqqq 3{pppqqq}

Mencetak gol

Setiap bahasa adalah kompetisi terpisah untuk siapa yang dapat menulis entri terpendek, tetapi pemenang keseluruhan adalah orang yang memenangkan sebagian besar sub-kompetisi ini. Ini berarti bahwa seseorang yang menjawab dalam banyak bahasa yang tidak biasa dapat memperoleh keuntungan. Code golf sebagian besar tiebreak ketika ada lebih dari satu solusi dalam bahasa: orang dengan program terpendek mendapat pujian untuk bahasa itu.

Jika ada seri, pemenangnya adalah orang dengan kiriman tempat kedua (dan seterusnya).

Aturan, Batasan, dan Catatan

Harap simpan semua kiriman berbeda Anda yang terkandung dalam satu jawaban.

Juga, tidak ada shenanigans dengan jawaban yang pada dasarnya sama dalam dialek bahasa yang sedikit berbeda. Saya akan menjadi juri untuk pengajuan apa yang cukup berbeda.

Papan Peringkat Saat Ini

Bagian ini akan diperbarui secara berkala untuk menunjukkan jumlah bahasa dan siapa yang memimpin di masing-masing bahasa.

  • C # (265) - edc65
  • JavaScript (206) - edc65
  • Python (214) - Will
  • VB.NET (346) - edc65

Peringkat Pengguna Saat Ini

  1. edc65 (3)
  2. Will (1)

Jawaban:


1

JavaScript (E6) 206

Hampir yakin itu optimal. Saya mulai mencoba untuk menyandikan string terpanjang dengan gain maksimal, dan secara rekursif mengkodekan apa yang tersisa di kiri dan kanan. Setelah setiap percobaan saya menjaga hasil terpendek.

Catatan golf (khusus JS)

  • Argumen semu bukannya lokal (untuk rekursi)
  • Bandingkan panjang menggunakan indeks di luar batas yang memberikan 'tidak terdefinisi'
R=(s,n=s,d=s.length>>1,w,i,j,c)=>{
  for(;d;--d){
    for(i=-1;s[d+d+i++];){
      w=s.slice(i,j=i+d);
      for(r=1;w==s.substr(j,d);j+=d)++r;
      c=d>1?r+'{'+w+'}':r+w,
      // c[d*r-1]|| /* uncomment this line (+10 bytes) to have faster response
      n[(c=R(s.slice(0,i))+c+R(s.slice(j))).length]&&(n=c)
    }
  }
  return n
}

Uji di konsol FireFox / FireBug

;['aa','aaaaaAAAAA','ababa','abababa','foo foo bar', 'aaaabcdeabcde',
  'xYzxYz', 'abcabcdefcdef', 'pppqqqpppqqq','pppqqqpppqqqpppqqq']
.forEach(x=>console.log(x+' -> '+R(x)))

Keluaran

aa -> aa
aaaaaAAAAA -> 5a5A
ababa -> ababa
abababa -> 3{ab}a
foo foo bar -> 2{foo }bar
aaaabcdeabcde -> 3a2{abcde}
xYzxYz -> xYzxYz
abcabcdefcdef -> abcab2{cdef}
pppqqqpppqqq -> 3p3q3p3q
pppqqqpppqqqpppqqq -> 3{pppqqq}

C # (.NET 4.0) 265

Algoritma yang sama persis

string R(string s)
{
  string n=s,c,w;
  int l=s.Length,d=l/2,i,j,r;
  for(;d>0;--d)
  {
    for(i=0;d+d+i<=l;i++)
    {
      w=s.Substring(i,d);
      for(j=i+d,r=1;j+d<=l&&w==s.Substring(j,d);j+=d)++r;
      c=d>1?r+"{"+w+"}":r+w;
      // if(c.Length<d*r){ // uncomment this line for faster execution
        c=R(s.Substring(0,i))+c+R(s.Substring(j));
        n=c.Length<n.Length?c:n;
      //} // and this one of course
    }
  }
  return n;
}

Uji di LinqPad, mode 'C # program', tambahkan main setelah fungsi R.

void Main()
{
  string[] test = {"aa","aaaaaAAAAA","ababa","abababa","foo foo bar","aaaabcdeabcde",
  "xYzxYz","abcabcdefcdef","pppqqqpppqqq","pppqqqpppqqqpppqqq"};
  test.Select(x => new { x, r=R(x) }).Dump("Result");
}

Output yang sama

VB.Net (.NET 4) 346 (mungkin)

Algoritma yang sama dan perpustakaan yang sama, tetapi bahasanya cukup berbeda

Saya tidak yakin tentang jumlah byte, karena Visual Studio terus memformat ulang kode dan menambahkan spasi.

Catatan golf: lebih baik gunakan sesuatu yang lain

function R(s as string)

  dim n=s,c,w
  dim l=s.Length,i,j,d
  for d=l\2 to 1 step-1
    for i=0 to l-d-d
      w=s.Substring(i,d)
      j=i+d
      r=1
      do while (j+d<=l andalso w=s.Substring(j,d))
        r=r+1
        j=j+d
      loop
      c=if(d>1,r & "{" & w & "}",r & w)
      if(c.Length<d*r) then
        c=R(s.Substring(0,i))+c+R(s.Substring(j))
        if c.Length<n.Length then n=c
      end if
    next
  next
  return n

end function

Anda dapat membatalkan penambahan ruang. Jika Anda mengetik karakter yang membuatnya memformat ulang, tekan ctrl-z untuk hanya membatalkan pemformatan. Ini berarti dua karakter daripada satu setiap begitu sering tapi itu lebih baik daripada menghapus semua spasi dan umpan baris sesudahnya.
Jerry Jeremiah

3

Python 214

def t(s):
 b=s;l=len;r=range(1,l(s))
 for i in r:
  p=s[:i];b=min(b,p+t(s[i:]),key=l);x=1
  for j in r:k=i*j+i;x*=p==s[i*j:k];b=min(b,(b,''.join((`j+1`,"{"[i<2:],p,"}"[i<2:],t(s[k:]))))[x],key=l)           
 return b

(indentasi tingkat kedua adalah tab)

Karena ini adalah , ini adalah pendekatan rekursif yang naif tanpa keluar awal, jadi ini sangat lambat.

Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.