移至可打印的ASCII前端


19

背景

所述移动至前的变换(MTF)是一种数据编码算法旨在提高熵编码技术的性能。

bzip2压缩算法中,它是在Burrows-Wheeler变换(如Burrows,Wheeler和Back所示)之后应用的,目的是将重复的字符组转换为小的,易于压缩的非负整数。

定义

为了解决这一挑战,我们将定义MTF的可打印ASCII版本,如下所示:

给定输入字符串s,取空数组r,所有可打印ASCII字符(0x20至0x7E)的字符串d,并对s的每个字符c重复以下操作:

  1. 追加的索引Çdř

  2. c移到d的前面,即,从d移走c并将它放在其余的前面。

最后,我们将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输出,您的代码可能会打印尾随换行符。

  • 您的代码必须可以输入1000个或更少的可打印ASCII字符(0x20至0x7E)。

  • 适用标准代码高尔夫规则。以字节为单位的最短提交获胜。


1
“ Nanananana DDUP!” 只是不如“蝙蝠侠!”那么引人注目...
门把手

8
@Doorknob:但是蝙蝠侠不容易压缩。
丹尼斯

我们可以在函数返回中输出结果,而不是将其打印到STDOUT吗?
致命

@Fatalize:这是函数输出的最自然的形式,是的。顺便说一下,我们有I / O的默认值,因此,除非问题明确说明,否则始终允许这样做。
丹尼斯

Answers:


6

果酱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几乎相同。我创建它的唯一真实原因是:a。令人讨厌的GolfScript没有REPL,b。)缺少一些运算符/功能(浮点,I / O等)。语言设计仍然很有趣!
门把手

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版本必须是较新的版本之一,其中的反引号`代表代码字符串。"在旧版本中,代码字符串曾经用双引号表示。


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'7

你有e=d=,所以当你从弹出时,e你也从弹出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设置必要的列表并将其保存到JK~J+d-Jd执行列表更新,同时xL ... z将输入字符映射到它们在列表中的位置。最后,s@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"

工作原理:#是一个索引函数,返回ein 的位置selemIndex由于价格昂贵,因此无法使用Haskell的原生函数import)。main函数f遵循折叠模式,在该模式中,位置字符串d和结果字符串r在通过输入字符串时会更新。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.