เลื่อนไปที่หน้า ASCII ที่พิมพ์ได้


19

พื้นหลัง

การแปลงแบบย้ายไปด้านหน้า (MTF) เป็นอัลกอริทึมการเข้ารหัสข้อมูลที่ออกแบบมาเพื่อปรับปรุงประสิทธิภาพของเทคนิคการเข้ารหัสแบบเอนโทรปี

ในอัลกอริทึมการบีบอัด bzip2จะถูกนำไปใช้หลังจากการแปลง Burrows – Wheeler (ดังที่เห็นในBurrows, Wheeler และ Back ) โดยมีวัตถุประสงค์เพื่อเปลี่ยนกลุ่มของอักขระซ้ำเป็นจำนวนเต็มจำนวนน้อยที่ไม่บีบอัดได้ง่าย

คำนิยาม

สำหรับจุดประสงค์ของการท้าทายนี้เราจะกำหนดเวอร์ชัน ASCII ที่พิมพ์ได้ของ MTF ดังนี้:

รับสายป้อนsใช้อาร์เรย์ที่ว่างเปล่าRสตริงทุกตัวอักขระ ASCII (0x20 เพื่อ 0x7E) และทำซ้ำต่อไปนี้สำหรับตัวละครแต่ละตัวของs :

  1. ผนวกดัชนีของในdเพื่อR

  2. ย้ายcไปที่ด้านหน้าของdเช่นลบcจากdและเติมลงในส่วนที่เหลือ

สุดท้ายเราใช้องค์ประกอบของrเป็นดัชนีในd ต้นฉบับ และดึงอักขระที่เกี่ยวข้อง

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

INPUT: "CODEGOLF"

0. s = "CODEGOLF"
   d = " !\"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~"
   r = []
1. s = "ODEGOLF"
   d = "C !\"#$%&'()*+,-./0123456789:;<=>?@ABDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~"
   r = [35]
2. s = "DEGOLF"
   d = "OC !\"#$%&'()*+,-./0123456789:;<=>?@ABDEFGHIJKLMNPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~"
   r = [35 47]
3. s = "EGOLF"
   d = "DOC !\"#$%&'()*+,-./0123456789:;<=>?@ABEFGHIJKLMNPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~"
   r = [35 47 37]
4. s = "GOLF"
   d = "EDOC !\"#$%&'()*+,-./0123456789:;<=>?@ABFGHIJKLMNPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~"
   r = [35 47 37 38]
5. s = "OLF"
   d = "GEDOC !\"#$%&'()*+,-./0123456789:;<=>?@ABFHIJKLMNPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~"
   r = [35 47 37 38 40]
6. s = "LF"
   d = "OGEDC !\"#$%&'()*+,-./0123456789:;<=>?@ABFHIJKLMNPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~"
   r = [35 47 37 38 40 3]
7. s = "F"
   d = "LOGEDC !\"#$%&'()*+,-./0123456789:;<=>?@ABFHIJKMNPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~"
   r = [35 47 37 38 40 3 45]
8. s = ""
   d = "FLOGEDC !\"#$%&'()*+,-./0123456789:;<=>?@ABHIJKMNPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~"
   r = [35 47 37 38 40 3 45 41]

OUTPUT: "COEFH#MI"

งาน

เขียนโปรแกรมหรือฟังก์ชั่นที่ใช้งาน ASCII MTF ที่พิมพ์ได้ (ตามที่กำหนดไว้ด้านบน)

กรณีทดสอบ

Input:  Programming Puzzles & Code Golf
Output: Prpi"do lp%((uz rnu&3!P/o&$U$(p

Input:  NaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaN BATMAN!
Output: Na! !! !! !! !! !! !! !! !! !! !! !! !! !! !! !!"DDUP"%'

Input:  Two more questions and I have bzip2 in less than 100 bytes!
Output: Twp#o"si$sv#uvq(u$(l#o#W!r%w+$pz,xF%#,"x(. #0--'$GG ".z(**:

กฎเพิ่มเติม

  • คุณไม่สามารถใช้โอเปอเรเตอร์ในตัวที่คำนวณ MTF ของสตริงได้

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

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

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


1
"Nanananana DDUP!" ไม่เป็นลวงเหมือน "แบทแมน!" ...
Doorknob

8
@ Doorknob: แต่แบทแมนไม่สามารถบีบอัดได้ง่าย
Dennis

เราสามารถส่งออกผลลัพธ์เป็นฟังก์ชันส่งคืนแทนการพิมพ์ไปยัง STDOUT ได้หรือไม่?
เสียชีวิต

@ กระชับ: นั่นเป็นรูปแบบเอาต์พุตที่เป็นธรรมชาติที่สุดสำหรับฟังก์ชั่นดังนั้นใช่ โดยวิธีการที่เรามีค่าเริ่มต้นสำหรับ I / Oดังนั้นถ้าคำถามที่ระบุไว้เป็นอย่างอื่นอย่างชัดเจนว่าได้รับอนุญาตเสมอ
Dennis

คำตอบ:


6

CJam, 20

'¡,q{_C#c' ,C+@|}fC;

ลองออนไลน์

คำอธิบาย:

'¡,      make a string of characters with codes from 0 to 160 (a modified "d")
         could have been to 126 but stackexchange doesn't like the DEL character
q        read the input (s)
{…}fC    for each character C in s
  _      duplicate the d string
  C#     find the index of C in d
  c      convert to character (this is the result)
  ' ,    make a string of characters from 0 to 31
  C+     append C to the string
  @      bring d to the top
  |      set union, preserving order; effectively, C is moved to position 32
         this is the updated d string
;        pop the last d

6

นกกระจอกเทศ , 46 45 ตัวอักษร

อย่ามีหมายเลขรุ่นในส่วนหัวเพราะนี้เป็นจริงเพียงล่าสุดกระทำ ฉันเพิ่มตัวดำเนินการO(รหัส ascii ไปยังสตริง) หลังจากปล่อยรุ่นล่าสุด (แต่ยังก่อนที่จะโพสต์ความท้าทายนี้)

{a95,{32+O}%:d3@{:x\.3@?3@\+\x-x\+}/;{d=}%s*}

คำอธิบาย:

a             this is the "r" array (a is short for [], empty array)
95,{32+O}%:d  this is the "d" array
3@{...}/      for each character in the input (as an "argument")...
  :x            store in variable x (stack is now [r d c])
  \.3@?         find index in d     (stack is now [r d idx])
  3@\+          append index to r   (stack is now [d modified_r])
  \x-           remove char from d, and then...
  x\+           prepend char to d   (stack is now [modified_r modified_d])
;             throw away modified_d
{d=}%         map r to indices of (original) d
s*            join (s is short for ``, empty string)

ฉันสงสัยว่า PPCG กำลังเปลี่ยนจาก "รหัสงานนี้ด้วยวิธีที่สมานฉันท์ที่สุดในภาษาที่คุณโปรดปราน" เป็น "ออกแบบภาษาการเขียนโปรแกรมของคุณเองเพื่อแก้งานกอล์ฟรหัสทั่วไปที่สั้นกว่า golfscript"
John Dvorak

1
@AlexA ... เดี๋ยวก่อนเอ๋ยมันสะกดอย่างนั้นเหรอ? ชีวิตทั้งชีวิตของฉันเป็นเรื่องโกหก
Doorknob

@JanDvorak Ostrich เกือบจะเหมือนกับ GolfScript เหตุผลที่แท้จริงที่ฉันสร้างขึ้นนั้นเป็นเพราะก.) GolfScript น่ารำคาญไม่มี REPL และ b.) มีตัวดำเนินการ / คุณสมบัติที่หายไปสองสามอย่าง (จุดลอยตัว, I / O, ฯลฯ ) และการออกแบบภาษาก็สนุกดี!
Doorknob

3

Python 3, 88

*d,=range(127)
for c in input():y=d.index(ord(c));d[:32]+=d.pop(y),;print(chr(y),end='')

ใช้แนวคิดจากโซลูชัน CJam ของฉัน
-4 ไบต์เป็นของ Sp3000 :)


2

SWI-Prolog, 239 197 189 ไบต์

a(S):-l([126],X),a(S,X,[],R),b(R,X).
a([A|T],X,S,R):-nth0(I,X,A,Z),(a(T,[A|Z],[I|S],R);R=[I|S]).
b([A|T],X):-(b(T,X);!),nth0(A,X,E),put(E).
l([B|R],Z):-A is B-1,X=[A,B|R],(A=32,Z=X;l(X,Z)).

ตัวอย่าง: a(`Two more questions and I have bzip2 in less than 100 bytes!`).ผลลัพธ์:

Twp#o"si$sv#uvq(u$(l#o#W!r%w+$pz,xF%#,"x(. #0--'$GG ".z(**:

(และtrue .หลังจากนั้นแน่นอน)

หมายเหตุ:เวอร์ชัน SWI-Prolog ของคุณจะต้องเป็นหนึ่งในเวอร์ชันที่ใหม่กว่าซึ่ง backquote `แสดงถึงสตริงโค้ด สตริงโค้ดที่ใช้แสดงด้วยเครื่องหมายคำพูดคู่"ในเวอร์ชันที่เก่ากว่า


2

Python 2, 137 110 104

ไม่ยากที่จะนำไปใช้ แต่อาจจะยังสามารถเล่นกอล์ฟได้

ลองที่นี่

e=d=map(chr,range(32,127))
r=""
for c in raw_input():n=e.index(c);r+=d[n];e=[e[n]]+e[:n]+e[n+1:]
print r

1
ฉันคิดว่าคุณทำได้ดีกว่าในการทำรายการแผนที่e=d=map(chr,range(32,127))ใน Python 2 แม้ว่าคุณจะต้องปรับแต่งeเพื่อจัดการรายการ
xnor

@ xnor ขอบคุณ ฉันลองใช้e=[e.pop(n)]+eด้วย แต่ก็ใช้ไม่ได้ ทำไมถึงเป็นอย่างนั้น?
mbomb007

คุณได้e=d=ดังนั้นเมื่อคุณป๊อปจากeคุณยัง popping dจาก ลองd=e[:]ดู
Sp3000

1
แต่ ณ จุดนี้มันน่าจะดีกว่าที่จะทำn=e.index(ord(c));r+=chr(n+32);และปล่อยd
Sp3000

1

Pyth, 24 ไบต์

JK>95CM127s@LKxL~J+d-Jdz

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

บิตแรก JK>95CM127ชุดขึ้นรายการที่จำเป็นและบันทึกไปและJ ทำการอัปเดตรายการในขณะที่จับคู่อักขระอินพุตกับตำแหน่งในรายการ ในที่สุดแปลงดัชนีเหล่านั้นเป็นตัวละครในรายการต้นฉบับK~J+d-JdxL ... zs@LK


1

Haskell, 120 ไบต์

e#s=[b|(b,a)<-zip[0..]s,a==e]!!0
a=[' '..'~']
f=snd.foldl(\(d,r)e->(e:take(e#d)d++tail(drop(e#d)d),r++[a!!(e#d)]))(a,[])

ตัวอย่างการใช้: f "CODEGOLF"->"COEFH#MI"

มันทำงานอย่างไร: #เป็นฟังก์ชั่นดัชนีที่ส่งคืนตำแหน่งeในs(ไม่สามารถใช้ภาษาของ Haskell ได้elemIndexเพราะมีราคาแพงimport) ฟังก์ชั่นหลักfตามหลังรูปแบบการพับซึ่งจะอัพเดตสตริงตำแหน่งdและสตริงผลลัพธ์rขณะที่เดินผ่านสตริงอินพุต

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