Bzip2'nin çalışma uzunluğu kodlamasını uygulayın


14

Arka fon

BWT ( Burrows, Wheeler ve Back'de görüldüğü gibi) ve MTF'yi ( yazdırılabilir ASCII cephesine taşı bölümünde görüldüğü gibi ) uyguladıktan sonra, bzip2 kompresörü oldukça benzersiz bir çalışma uzunluğu kodlaması biçimi uygular.

Tanım

Bu zorluğun amacı için BRLE dönüşümünü şu şekilde tanımlarız:

Bir giriş dizesi Verilen s aşağıdakileri yapın sadece 0x20 ve 0x7A arasındaki kod noktaları ile ASCII karakterlerden oluştuğundan:

  1. Eşit karakterlerin her bir çalışmasını, karakterin tek bir oluşumuyla değiştirin ve birinciden sonra tekrar sayısını depolayın.

  2. Tekrar sayısını kodlama karakter ilk geçtiği sonra kullanarak örten baz-2 sayılandırma ve sembolleri {ve }.

    Bir negatif olmayan bir tamsayı , n dize olarak kodlanan b k b ... 0 , öyle ki , n = 2 k ı, (b k ) + ... + 2 0 ı (b , 0 ) , ı ( {) 1 = ve i ( }) = 2 .

    Bu sunumun her zaman benzersiz olduğunu unutmayın. Örneğin, 0 sayısı boş bir dize olarak kodlanır.

  3. Karşılık gelen karakterin tek bir tekrarından sonra tekrar sayısını kodlayan kıvırcık parantez dizesini ekleyin.

Adım adım örnek

Input:  "abbcccddddeeeeeffffffggggggghhhhhhhh"
Step 1: "abcdefgh" with repetitions 0, 1, 2, 3, 4, 5, 6, 7
Step 2: "" "{" "}" "{{" "{}" "}{" "}}" "{{{"
Step 3: "ab{c}d{{e{}f}{g}}h{{{"

Görev

STDIN'den veya komut satırı veya işlev bağımsız değişkeni olarak tek bir dize okuyan ve BRLE'yi veya giriş dizesinin tersini yazdıran veya döndüren ilgili bir program veya işlev uygulayın.

Giriş kıvrımlı parantez içermiyorsa, BRLE uygulayın. Giriş kıvırcık köşeli ayraç içeriyorsa, tersini uygulayın.

Örnekler

INPUT:  CODEGOLF
OUTPUT: CODEGOLF

INPUT:  PROGRAMMING
OUTPUT: PROGRAM{ING

INPUT:  PUZ{LES
OUTPUT: PUZZLES

INPUT:  444488888888GGGGGGGGGGGGGGGGWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWW
OUTPUT: 4{{8{{{G{{{{W{{{{{

INPUT:  y}}}{{
OUTPUT: yyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyy

Ek kurallar

  • Sen olamaz Brle veya dize onun tersini hesaplamak herhangi yerleşik ins kullanın.

  • Yerleşikleri aşağıdakileri kullanabilirsiniz:

    • Yineleme sayısı iki temelli taban-2'de saklanmadığı sürece, bir dizenin RLE veya RLD'sini hesaplayın.

    • Herhangi bir tür temel dönüşüm gerçekleştirin.

  • Çıktı için STDOUT'u seçerseniz kodunuz bir satırsonu yazdırabilir.

  • Kodunuz, 0x20 ila 0x7A aralığındaki 1000 veya daha az ASCII karakteri ve ayrıca küme parantezleri (0x7B ve 0x7D) için çalışmalıdır.

  • Girdi köşeli parantez içeriyorsa, bunun bir dizeye BRLE uygulanmasının geçerli bir sonucu olduğunu varsayabilirsiniz.

  • Standart kod golf kuralları geçerlidir. Bayt cinsinden en kısa gönderim kazanır.


Yerleşiklere neden izin verilmiyor?
MilkyWay90

Yanıtlar:


4

CJam, 50 48 bayt

l_{}`:T&1${_T#)_(@a?)+}%{(\2b)*}%@e`{(2b1>Tf=}%?

Dennis'e 2 bayt kazandığı için teşekkürler.

Çevrimiçi deneyin.

açıklama

l_              e# Read and duplicate input.
{}`:T           e# T = "{}"
&               e# If the input has '{ or '}:
    1$          e# Input.
    {           e# For each character:
        _T#)    e# If it is '{ or '}:
            _(  e# Return 0 for '{ or 1 for '}.
            @a  e# Otherwise, convert the character itself to an array (string).
        ?
        )+      e# If it is a number, increment and append to the previous array.
                e# If it is a string with at least 1 character, do nothing.
    }%
    {(\         e# For each character and bijective base 2 number:
        2b)*    e# Repeat the character 1 + that many times.
    }%
                e# Else:
    @           e# Input.
    e`          e# Run-length encoding.
    {(          e# For each character and length:
        2b1>    e# Convert the length to base 2 and remove the first bit.
        Tf=     e# Map 0 to '{ and 1 to '}.
    }%
?               e# End if.

3

Pyth, 48 50 bayt

J`Hs?m*hdi+1xLJtd2tczf-@zTJUz@Jzsm+ed@LJtjhd2rz8

@Maltysen sayesinde 2 bayt.

Gösteri. Kablo demetini test edin.

Açıklama:

J`Hs?m*hdi+1xLJtd2tczf-@zTJUz@Jzsm+ed@LJtjhd2rz8
                                                    Implicit: z = input()
                                                    H is empty dict.
J`H                                                 J = repr(H) = "{}"
   s                                                Print the concatenation of
    ?                        @Jz                    If z and J share any chars:
                     f     Uz                       Filter range(len(z))
                      -@zTJ                         On the absence of z[T] in J.
                   cz                               Chop z at these indices.
                                                    just before each non '{}'.
                  t                                 Remove empty initial piece.
     m*hd                                           Map to d[0] *
         i       2                                  the base 2 number                             
            xLJtd                                   index in J mapped over d[:-1]
          +1                                        with a 1 prepended.
                                             rz8    Otherwise, run len. encode z
                                 m                  map over (len, char)
                                         jhd2       Convert len to binary.
                                        t           Remove leading 1  
                                     @LJ            Map to element of J.
                                  +ed               Prepend char.
                                s                   Concatenate. 

yerine "{}"kullanabileceğiniz `H, CJam ile bağlı :)
Maltysen

@ Jakube Karışıklık için özür dilerim.
isaacg

2

OCaml, 252

t dönüşümü yapan işlevdir.

#load"str.cma"open Str
let rec(!)=group_beginning and
g=function|1->""|x->(g(x/2)^[|"{";"}"|].(x mod 2))and($)i s=if g i=s then i else(i+1)$s and
t s=global_substitute(regexp"\(.\)\1*\([{}]*\)")(fun s->String.make(1$matched_group 2 s)s.[!1]^g(!2- !1))s

İlk başta kıvırcık parantezlerin varlığını kontrol etmek zorunda olduğumu düşünüyordum, ancak gereksiz olduğu ortaya çıktı. Kod çözmenin, halihazırda kodu çözülmüş olan dizeler üzerinde net bir etkisi yoktur ve kodlama kısmının, halihazırda kodlanmış olanlara eşit derecede zararsız olduğu kanıtlanmıştır.


the encoding part proved equally harmlessyapar? Kodlama 4{{8{{{G{{{{W{{{{{anlamıyor 4{{8{}G{{{W{{}musunuz?
edc65

@ edc65 Hayır, örneklerde belirtilen yanıtı alıyorum. Nasıl test ediyorsunuz?
feersum

"4 {{8 {{{G {{{{W {{{{{") girdi olarak örneklerden biri değildir. Denedin mi?
edc65

@ edc65 Örneklerden birinin tersi ve onları her iki şekilde de test ettim. Evet, hem göndermeden önce hem de yorumunuzdan sonra denedim.
feersum

Tamam iyi. Alıntılanan cümleye işaret ettim, çünkü "açık" bir kodlama (benimki gibi) verilen test
senaryosuyla

1

JavaScript ( ES6 ), 162

f=s=>
(t=s[R='replace'](/[^{}][{}]+/g,n=>n[0].repeat('0b'+n[R](/./g,c=>c!='{'|0))))==s
?s[R](/(.)\1*/g,(r,c)=>c+r.length.toString(2).slice(1)[R](/./g,c=>'{}'[c])):t

// TEST
out=x=>O.innerHTML += x + '\n';

test=s=>O.innerHTML = s+' -> '+f(s) +'\n\n' + O.innerHTML;

[['CODEGOLF','CODEGOLF']
,['PROGRAMMING','PROGRAM{ING']
,['PUZ{LES','PUZZLES']
,['444488888888GGGGGGGGGGGGGGGGWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWW','4{{8{{{G{{{{W{{{{{']
,['y}}}{{','yyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyy']]
.forEach(v=>{
  w=f(v[0])  
  out('Test ' + (w==v[1]?'OK':'Fail')+'\nInput:    '+v[0]+'\nExpected: '+v[1]+'\nResult:   '+w)
})  
Your test: <input id=I style='width:300px'><button onclick='test(I.value)'>-></button>
<pre id=O></pre>

Bazı açıklamalar

Sayı n BB2 için 0 ve 1 kullanılarak:(n+1).toString(2).slice(1)

BB2'de sayı: to_number ("0b1" + dize) - yani, en soldaki 1 ikili rakamı ekleyin ve ikili dosyadan dönüştürün (ve bu özel örnekte gerekli değildir, 1 azaltın).

{Veya ifadesini izleyen herhangi bir karakteri bulmak için normal ifade }:/[^{}][{}]+/g

Tekrarlanan karakterleri bulmak için normal ifade: /(.)\1*/g

Onun yerine bu regexp kullanarak, ilk param "tekrarlanan" char (sonunda sadece 1 kez tekrar), ikinci param toplam tekrarlanan dize, uzunluğu BB2 kodlamak için gereken sayı olan 1

... sonra hepsini bir araya getirin ...

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.