ใช้การเข้ารหัสความยาวรันของ bzip2


14

พื้นหลัง

หลังจากใช้ BWT (เท่าที่เห็นในBurrows, Wheeler และ Back ) และ MTF (ดังที่เห็นในย้ายไปยังหน้า ASCII ที่พิมพ์ได้ ) คอมเพรสเซอร์bzip2ใช้รูปแบบการเข้ารหัสที่ค่อนข้างยาว

คำนิยาม

สำหรับวัตถุประสงค์ของการท้าทายนี้เราได้กำหนดการเปลี่ยนแปลง BRLE ดังนี้:

รับสตริงอินพุตsที่ประกอบด้วยอักขระ ASCII ที่มีจุดรหัสระหว่าง 0x20 ถึง 0x7A เท่านั้นให้ทำดังนี้:

  1. แทนที่การเรียกใช้อักขระที่เท่ากันแต่ละครั้งด้วยการเกิดขึ้นครั้งเดียวของตัวละครและจำนวนการจัดเก็บการทำซ้ำหลังจากครั้งแรก

  2. เข้ารหัสจำนวนการทำซ้ำ หลังจากที่เกิดขึ้นครั้งแรกของตัวละครโดยใช้bijective ฐานที่ 2 การคิดเลขและสัญลักษณ์และ{}

    จำนวนเต็มไม่เป็นลบnถูกเข้ารหัสเป็นสตริงb k … b 0เช่นนั้นn = 2 k i (b k ) + … + 2 0 i (b 0 )โดยที่i ({ ) = 1และi ( }) = 2 .

    โปรดทราบว่าการเป็นตัวแทนนี้ไม่ซ้ำกันเสมอ ตัวอย่างเช่นหมายเลข0ถูกเข้ารหัสเป็นสตริงว่าง

  3. แทรกสตริงของวงเล็บปีกกาที่เข้ารหัสจำนวนการทำซ้ำหลังจากการเกิดขึ้นครั้งเดียวของตัวละครที่เกี่ยวข้อง

ตัวอย่างทีละขั้นตอน

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{{{"

งาน

ใช้โปรแกรมหรือฟังก์ชั่นที่ไม่เกี่ยวข้องซึ่งอ่านสตริงเดี่ยวจาก STDIN หรือเป็นบรรทัดคำสั่งหรือฟังก์ชั่นอาร์กิวเมนต์และพิมพ์หรือส่งคืน BRLE หรืออินสแตนซ์ของสตริงอินพุต

หากอินพุตไม่มีวงเล็บปีกกาให้ใช้ BRLE หากอินพุตมีวงเล็บปีกกาให้ใช้ค่าผกผัน

ตัวอย่าง

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

กฎเพิ่มเติม

  • คุณไม่สามารถใช้บิวด์อินใด ๆ ที่คำนวณ BRLE หรืออินสแตนซ์ของสตริงได้

  • คุณสามารถใช้บิวด์อิน:

    • คำนวณ RLE หรือ RLD ของสตริงตราบใดที่จำนวนการทำซ้ำไม่ได้เก็บไว้ใน bijective base-2

    • ทำการแปลงพื้นฐานทุกชนิด

  • รหัสของคุณอาจพิมพ์ขึ้นบรรทัดใหม่หากคุณเลือก STDOUT สำหรับเอาท์พุท

  • รหัสของคุณจะใช้งานได้กับอินพุตที่มีอักขระ ASCII น้อยกว่า 1,000 ตัวในช่วงตั้งแต่ 0x20 ถึง 0x7A รวมถึงเครื่องหมายปีกกา (0x7B และ 0x7D)

  • หากอินพุตมีวงเล็บปีกกาคุณอาจสมมติว่าเป็นผลลัพธ์ที่ถูกต้องของการใช้ BRLE กับสตริง

  • บังคับใช้กฎกอล์ฟมาตรฐาน การส่งที่สั้นที่สุดในหน่วยไบต์ชนะ


ทำไมไม่สร้างบิลด์อิน
MilkyWay90

คำตอบ:


4

CJam, 50 48 ไบต์

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

ขอบคุณสำหรับ Dennis ที่ช่วยประหยัด 2 ไบต์

ลองออนไลน์

คำอธิบาย

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ไบต์

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

2 ไบต์ขอบคุณ @Maltysen

สาธิต. สายรัดทดสอบ

คำอธิบาย:

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. 

แทนการ"{}"ที่คุณสามารถใช้`Hผูกกับ CJam :)
Maltysen

@Jakube ขออภัยสำหรับการผสมผสาน
isaacg

2

OCaml, 252

t เป็นฟังก์ชันที่ทำการแปลงรูป

#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

ตอนแรกฉันคิดว่าฉันต้องตรวจสอบการปรากฏตัวของเครื่องมือจัดฟันหยิก แต่มันก็ไม่จำเป็น การถอดรหัสชัดเจนไม่มีผลกับสตริงที่ถอดรหัสไปแล้วและส่วนการเข้ารหัสพิสูจน์แล้วว่าไม่เป็นอันตรายต่อส่วนที่เข้ารหัสแล้ว


the encoding part proved equally harmlessทำมัน? 4{{8{{{G{{{{W{{{{{คุณไม่ได้รับการเข้ารหัส4{{8{}G{{{W{{}?
edc65

@ edc65 ไม่ฉันได้รับคำตอบที่ระบุในตัวอย่าง คุณทดสอบมันยังไง?
feersum

"4 {{8 {{G {{{{{{{{{}]] เนื่องจากอินพุตไม่ใช่หนึ่งในตัวอย่าง คุณลองแล้วหรือยัง
edc65

@ edc65 มันเป็นสิ่งที่ตรงกันข้ามของหนึ่งในตัวอย่างและฉันทดสอบพวกเขาทั้งสอง ใช่ฉันลองทั้งก่อนโพสต์และหลังจากความคิดเห็นของคุณ
feersum

OK ดี. ฉันชี้ให้เห็นประโยคที่ยกมาว่าการเข้ารหัส "ตรงไปตรงมา" (ของฉัน) จะไม่เป็นอันตรายกับทุกกรณีทดสอบที่กำหนดชัดเจนว่าส่วนการเข้ารหัสของคุณนั้นฉลาดกว่า
edc65

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>

คำอธิบายบางอย่าง

หมายเลขnถึง BB2 โดยใช้ 0 และ 1:(n+1).toString(2).slice(1)

สตริงใน BB2 เป็นตัวเลข: to_number ("0b1" + สตริง) - นั่นคือเพิ่มเลขฐานสองที่ 1 ซ้ายสุดและแปลงจากเลขฐานสอง (และลดลง 1 ไม่จำเป็นในอินสแตนซ์เฉพาะนี้)

นิพจน์ทั่วไปเพื่อค้นหาอักขระตามด้วย{หรือ}:/[^{}][{}]+/g

นิพจน์ทั่วไปเพื่อค้นหาอักขระซ้ำ: /(.)\1*/g

การใช้ regexp ในการแทนที่ param แรกคือ char "repeat" (ในที่สุดทำซ้ำเพียง 1 ครั้ง), param ที่สองคือสตริงซ้ำทั้งหมดซึ่งความยาวคือจำนวนที่ฉันต้องการเข้ารหัสใน BB2 เพิ่มขึ้น 1 แล้ว

... จากนั้นรวบรวมทั้งหมด ...

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.