游程长度解码


20

用您选择的语言编写最短的代码,以执行给定字符串的游程长度解码。

该字符串将以以下形式作为标准输入提供:

CNCNCNCNCNCNCNCN

其中每个C可以是任何可打印的ASCII字符和每N一个数字19(含)。

输入样例:

:144,1'1

对应的输出:

:4444,'

Answers:


28

Brainfuck,34个字符

,[>,>++++++[<-------->-]<[<.>-]<,]

5
哇。可以与其他解决方案竞争的头脑解决方案?
Johannes Kuhn

13

莎士比亚编程语言,406字节

.
Ajax,.
Ford,.
Act I:.
Scene I:.
[Enter Ajax and Ford]
Scene II:.
Ford:
Open your mind.Is sky nicer than you?If so, let us return to scene IV.
Ajax:
Open your mind.You is sum you and sum big big big big big big pig and big big big big cat!
Scene III:.
Ford:
Speak thy mind.
Ajax:
You is sum you and pig!Is you as big as zero?If so, let us return to scene II.Let us return to scene III.
Scene IV:.
[Exeunt]

非高尔夫版本:

The Decoding of the Lengths of Veronan Runs - A Drama of PPCG.

Romeo, quite a character.
Juliet, Romeo's lover and multiplicand.

Act I: In which the lengths of runs are decoded.

Scene I: A silent entrance.

[Enter Romeo and Juliet]

Scene II: In which neither Romeo nor Juliet believes the other open-minded.

Juliet:
  Open your mind. Is my mother jollier than thou? If so,
  we must proceed to scene IV.

Romeo:
  Open your mind. Thou art the sum of thyself and the sum of my good aunt and
  the difference between nothing and the quotient of the square of twice the sum
  of thy foul fat-kidneyed goat and thy death and thy evil variable!

Scene III: In which Romeo snaps and brutally insults Juliet.

Juliet:
  Speak thy mind.

Romeo:
  Thou art the sum of thyself and a hog! Art thou as rotten as nothing? If so,
  let us return to scene II. Let us return to scene III.

Scene IV: Finale.

[Exeunt]

我正在使用drsam94的Python SPL编译器,该编译器有一些错误(例如,这就是为什么我使用它Open your mind而不是Open thy mind高尔夫球版的原因)。

要运行此程序,请使用:

$ python splc.py rld.spl > rld.c
$ gcc rld.c -o rld.exe
$ echo -n ":144,1'1" | ./rld
:4444,'

怎么运行的

SPL是一种深奥的编程语言,旨在使程序看起来像莎士比亚的戏剧。它通过使用字符作为变量来执行此操作,并通过使字符彼此说出文字来执行处理。

The Decoding of the Lengths of Veronan Runs - A Drama of PPCG.

这是戏的标题;编译器会忽略它。

Romeo, quite a character.
Juliet, Romeo's lover and multiplicand.

在这里,我们声明程序其余部分中使用的变量。一切都在,并且.被编译器忽略。在这种情况下,我们声明Romeo,用于保存要解码的字符,而Juliet,用于保存字符的游程长度。

Act I: In which the lengths of runs are decoded.

在这里,我们声明程序中的第一个也是唯一一个动作。行为和场面就像标签;通过使用let us return to scene II或其中的一些变体,它们可以随时跳转到。我们只使用一种行为,因为它足以满足我们的需求。同样,:和之间的任何内容都.将被编译器忽略。

Scene I: A silent entrance.

在这里,我们声明第一个场景。场景以罗马数字编号:第一个是Scene I,第二个是,Scene II依此类推。

[Enter Romeo and Juliet]

这是一个阶段的方向;在其中,我们告诉RomeoJuliet变量进入“阶段”。一次只能有两个变量处于“阶段”;使用此阶段,以便编译器可以在讲话时找出哪个变量正在寻址哪个变量。由于我们只有两个变量,因此Romeo和Juliet将在整个程序过程中保持在舞台上。

Scene II: In which neither Romeo nor Juliet believes the other open-minded.

另一个场景声明。场景II将跳至以解码另一个游程长度。

Juliet:

这种形式的声明意味着朱丽叶将开始讲话。直到下一个Romeo:,舞台方向或场景/动作声明之前的所有内容都是朱丽叶所说的一行,因此“我”将指朱丽叶,“您” /“您”将指罗密欧,等等。

Open your mind.

此命令将STDIN中单个字符的序数值存储在中Romeo

Is my mother jollier than thou?

在SPL中,名词根据其是正数还是负数转换为1或-1。在这种情况下,my mother转换为1。形容词(正数或负数)将其名词乘以2。

这是一个问题;朱丽叶在其中询问my mother(AKA 1)是否比罗密欧更“傻”。比较器要么转换为less than(如果它们为负,如worse),要么转换为(如果greater than它们为正,如jollier)。因此,这个问题可以归结为Is 1 greater than you?

我们问这个问题的原因是检测输入的结束。由于EOF平台的值有所不同,但通常小于1,因此我们使用它来检测它。

If so, we must proceed to scene IV.

如果前面的问题评估为true,我们将跳至场景IV,这只是程序的结尾。简而言之,如果我们检测到EOF,则结束程序。

Romeo:

现在是罗密欧的台词:“我”和“你”分别指罗密欧和朱丽叶。

Open your mind.

同样,该语句将来自STDIN的单个字符的序数值放入Juliet,在这种情况下,该值是存储在中的字符的游程长度Romeo

Thou art the sum of thyself and the sum of my good aunt and the difference 
between nothing and the quotient of the square of twice the sum of thy foul
fat-kidneyed goat and thy death and thy evil variable!

这个时间太长,无法详细介绍,但是请相信我,因为它可以翻译为Juliet -= 48。我们这样做是因为Juliet拥有数字的ASCII值,并且ord('0') == 48; 在减去48时,我们将数字的ASCII值转换为数字本身。

Scene III: In which Romeo snaps and brutally insults Juliet.

另一个场景声明。这一个是循环中,我们反复打印的字符值RomeoJuliet倍。

Juliet:
  Speak thy mind.

这句话使罗密欧将自己的价值观印在了角色上。也就是说,现在输出以前存储在Romeo中的任何字符值。

Romeo:
  Thou art the sum of thyself and a hog!

猪是负名词,因此a hog翻译为-1;反之亦然。因此,此语句的计算结果为Juliet -= 1

Art thou as rotten as nothing?

罗密欧在这里询问朱丽叶是否“腐烂为”或等于0。

If so, let us return to scene II.

如果朱丽叶(Juliet)的值为0,我们循环回到场景II,以解码另一个角色的游程。

Let us return to scene III.

否则,我们循环回到场景III以再次输出罗密欧的角色。

Scene IV: Finale.

[Exeunt]

最后的场景声明只是程序结束的标记。该[Exeunt]阶段的方向是必要的,让编译器实际生成的最后一幕。



5

perl,27个字符

print<>=~s/(.)(.)/$1x$2/ger

这似乎是不必要的冗长:print<>=~s/(.)(.)/$1x$2/ger。我也很确定你的意思$1x$2,而不是相反。
2013年

@primo true-我不知道r标志,也找不到。谢谢。至于其他部分-对不起,我看错了规格。可以的时候我会编辑。
约翰·德沃夏克

BTW /rperlop中有记录,并在v5.14.0中添加-psxls
13年

使用该-p标志可以放下printand <>,因此答案将变得简单:s/(.)(.)/$1x$2/ge-> 17个字符+1表示-p-> 18
F. Hauri 2013年

4

R 67

x=strsplit(readline(),"")[[1]];cat(rep(x[c(T,F)],x[c(F,T)]),sep="")

+1我不知道reptimes自动将参数从字符强制转换为整数。辉煌。
plannapus

4

Python 3、52

Python 3使我可以合并两个python2解决方案的方法。

s=input()
t=''
while s:a,b,*s=s;t+=a*int(b)
print(t)

Python 2 raw_input与Python 3匹配input。所以第一行必须在s=input()
AMK 2013年

1
49:s=input() while s:a,b,*s=s;print(a*int(b),end='')
Cees Timmerman


3

APL(22)

,/{⍺/⍨⍎⍵}/↑T⊂⍨~⎕D∊⍨T←⍞

说明:

  • T←⍞:将输入存储在 T
  • T⊂⍨~⎕D∊⍨T: 分裂 T非数字字符
  • :把它变成一个 2 -by- N/2矩阵
  • {⍺/⍨⍎⍵}/:在矩阵(/)的每一行上,通过eval()复制(/)第一个字符(第二个字符())字符()
  • ,/:连接每行的输出

3

Ruby,30个字节

gsub!(/(.)(.)/){$1*$2.to_i}

27个字节的代码+ 3个字节来运行带有-p标志的代码:

$ ruby -p rld.rb <<< ":144,1'1"
:4444,'

2

8086汇编,106 98个字符

l:
mov ah,8
int 21h
mov bl,al
int 21h
sub al,48
mov cl,al
xor ch,ch
mov al,bl
mov ah,14
p:
int 10h
loop p
jmp l

如果数字在输入流中的字符之前,则可以省去两行(18个字符)。


刚刚删除了一个多余的“ mov ah,8”
Mike C

2
您应该发布已编译的字节数,而不是我们的汇编器字符数。规则滥用FTW
arrdem

怎么样dq 21cdc38821cd08b4 d888ed30c188482c e8ebfce210cd14b4为53个字符?我看不到它在哪里处理非大写字符或eof ...
Jason Goemaat 2013年

arrdem:好主意。我想知道如果我在十六进制编辑器中手工组装它是否违反了规则。我仍将直接编写代码,只是在比asm源代码低的级别上。:)杰森:我在规则中没有看到有关EOF的任何信息。它是标准输入,只需按ctrl-c即可停止。还有为什么它不处理小写字母呢?
Mike C

通常,与解释型或编译型语言的源代码计数相比,机器代码按字节计数进行计数,因为实际上没有合理的选择。
Joe Z.

2

GNU SED,122 + 2(-r)

#n
s/.*/\n&\a987654321\v\v\v\v\v\v\v\v\v/
:a
s/\n(.)(.)(.*\a.*\2.{9}(.*))/\1\n\4\3/
tb
bc
:b
s/(.)\n\v/\1\1\n/
tb
ba
:c
P

需要与运行-r标志
通过更换可减少到110 + 2 \v与不可打印0x0B\a0x07


+1(\2.{9}好主意)出色!
F. Hauri 2013年

2

C,65个字符

获取输入作为参数。

main(p,v)char*p,**v;{
    for(p=v[1];*p;--p[1]<49?p+=2:0)putchar(*p);
}

我无法通过gcc:克服这一点 error: first parameter of 'main' (argument count) must be of type 'int'。有命令行开关吗?
达伦·斯通

@DarrenStone,此代码不符合100%标准。我不使用第一个参数作为参数,因此其类型无关紧要。大多数编译器不太介意。
ugoren 2013年

好,谢谢。我很羡慕您的高尔夫友好编译器!:)
Darren Stone

2

Perl,19个 18个字符

perl -pe 's/(.)(.)/$1x$2/ge'

命令行上的开关计数规则在此处


2

第45个字符

BEGIN KEY KEY 48 - 0 DO DUP EMIT LOOP 0 UNTIL

在OS X上使用pforth测试。


2

Python,63 62个字符

print''.join([c*int(n)for c,n in zip(*[iter(raw_input())]*2)])

不错的窍门iter...我想我会自己使用的!
2013年

2

Windows PowerShell,55个字符

-join((read-host)-split'(..)'|%{(""+$_[0])*(""+$_[1])})

我觉得这可以进一步研究,尤其是从char到string和int的转换时,但我现在没有时间继续研究它。


2

C,68个字符

@ugoren在C中的答案略短,但此答案符合“字符串将作为输入在stdin上提供”的要求。

n;main(c){for(;;){c=getchar(),n=getchar()-48;while(n--)putchar(c);}}

您可以通过删除“ int”并声明c和n作为main参数来删除字符,通过使用for(;;)代替while(1)来删除字符,最后通过将括号放在最里面的while循环中删除另外两个字符。
Stuntddude

谢谢@Stuntddude!我应用了循环和花括号建议,但是我在“声明c和n为main参数”方面苦苦挣扎。尽管如此,这还是减少了3个字符。干杯。
达伦·斯通

由于main()是一个函数,因此您可以为其提供参数,例如:main(c,n){ ... }在程序运行时默认将传递1。
Stuntddude 2013年

谢谢@Stuntddude。我知道这一点,可以利用第一个intarg的优势,但是我使用的是编译器抱怨,error: second parameter of 'main' (argument array) must be of type 'char **'所以我无法摆脱main(c,n);我必须使用main(int c,char **n)。可能是平台或gcc之类的东西。
达伦·斯通

我的编译器允许我这样做,n;main(c)但不能main(n,c)-足够好!:)
Darren Stone

2

Haskell,58 56个字符

f[]=[]
f(x:y:s)=replicate(read[y])x++f s
main=interact$f

我第一次真正尝试打高尔夫球,所以这里可能需要做一些改进。


1
read[y]保存两个字符
MtnViewMark

@MtnViewMark谢谢。我把它英寸
西尔维奥Mayolo

我为此得到57个字节?您可以替换replicate x y[1..x]>>[y]。因此,您的第二行可以替换为f(x:y:s)=(['1'..y]>>[x])++f s,从而将其减少到53个字节。
2016年

2

Japt -P,8字节

输入为字符数组,输出为字符串。

ò crÈpY°

试试吧

ò crÈpYn     :Implicit input of character array
ò            :Groups of 2
   r         :Reduce each pair
    È        :By passing them through the following function as [X,Y]
     p       :  Repeat X
      Yn     :    Y, converted to an integer, times
             :Implicitly join and output

哦,C RèEPY!
Khuldraeseth na'Barya

@ Khuldraesethna'Barya,ò crÏ°îX如果您觉得它太令人毛骨悚然,也可以!
毛茸茸的

2

Malbolge Unshackled(20次旋转的变体形式),4,494e6字节

该答案的大小超过了可发布的最大程序大小(eh),因此代码位于我的GitHub存储库中

如何运行?

这可能是一个棘手的部分,因为幼稚的Haskell解释器将需要很长的时间才能执行此操作。TIO有不错的Malbogle Unshackled解释器,但可惜我无法使用它(限制)。

我能找到的最好的是固定的20-trit旋转宽度变体,该变体表现很好,每小时解压缩360字节

为了使口译员更快一些,我从Matthias Lutter的Malbolge Unshackled口译员中删除了所有支票。

我的修改版可以运行大约6.3%。

#include <malloc.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

const char* translation = "5z]&gqtyfr$(we4{WP)H-Zn,[%\\3dL+Q;>U!pJS72Fh"
        "OA1CB6v^=I_0/8|jsb9m<.TVac`uY*MK'X~xDl}REokN:#?G\"i@";

typedef struct Word {
    unsigned int area;
    unsigned int high;
    unsigned int low;
} Word;

void word2string(Word w, char* s, int min_length) {
    if (!s) return;
    if (min_length < 1) min_length = 1;
    if (min_length > 20) min_length = 20;
    s[0] = (w.area%3) + '0';
    s[1] = 't';
    char tmp[20];
    int i;
    for (i=0;i<10;i++) {
        tmp[19-i] = (w.low % 3) + '0';
        w.low /= 3;
    }
    for (i=0;i<10;i++) {
        tmp[9-i] = (w.high % 3) + '0';
        w.high /= 3;
    }
    i = 0;
    while (tmp[i] == s[0] && i < 20 - min_length) i++;
    int j = 2;
    while (i < 20) {
        s[j] = tmp[i];
        i++;
        j++;
    }
    s[j] = 0;
}

unsigned int crazy_low(unsigned int a, unsigned int d){
    unsigned int crz[] = {1,0,0,1,0,2,2,2,1};
    int position = 0;
    unsigned int output = 0;
    while (position < 10){
        unsigned int i = a%3;
        unsigned int j = d%3;
        unsigned int out = crz[i+3*j];
        unsigned int multiple = 1;
        int k;
        for (k=0;k<position;k++)
            multiple *= 3;
        output += multiple*out;
        a /= 3;
        d /= 3;
        position++;
    }
    return output;
}

Word zero() {
    Word result = {0, 0, 0};
    return result;
}

Word increment(Word d) {
    d.low++;
    if (d.low >= 59049) {
        d.low = 0;
        d.high++;
        if (d.high >= 59049) {
            fprintf(stderr,"error: overflow\n");
            exit(1);
        }
    }
    return d;
}

Word decrement(Word d) {
    if (d.low == 0) {
        d.low = 59048;
        d.high--;
    }else{
        d.low--;
    }
    return d;
}

Word crazy(Word a, Word d){
    Word output;
    unsigned int crz[] = {1,0,0,1,0,2,2,2,1};
    output.area = crz[a.area+3*d.area];
    output.high = crazy_low(a.high, d.high);
    output.low = crazy_low(a.low, d.low);
    return output;
}

Word rotate_r(Word d){
    unsigned int carry_h = d.high%3;
    unsigned int carry_l = d.low%3;
    d.high = 19683 * carry_l + d.high / 3;
    d.low = 19683 * carry_h + d.low / 3;
    return d;
}

// last_initialized: if set, use to fill newly generated memory with preinitial values...
Word* ptr_to(Word** mem[], Word d, unsigned int last_initialized) {
    if ((mem[d.area])[d.high]) {
        return &(((mem[d.area])[d.high])[d.low]);
    }
    (mem[d.area])[d.high] = (Word*)malloc(59049 * sizeof(Word));
    if (!(mem[d.area])[d.high]) {
        fprintf(stderr,"error: out of memory.\n");
        exit(1);
    }
    if (last_initialized) {
        Word repitition[6];
        repitition[(last_initialized-1) % 6] =
                ((mem[0])[(last_initialized-1) / 59049])
                    [(last_initialized-1) % 59049];
        repitition[(last_initialized) % 6] =
                ((mem[0])[last_initialized / 59049])
                    [last_initialized % 59049];
        unsigned int i;
        for (i=0;i<6;i++) {
            repitition[(last_initialized+1+i) % 6] =
                    crazy(repitition[(last_initialized+i) % 6],
                        repitition[(last_initialized-1+i) % 6]);
        }
        unsigned int offset = (59049*d.high) % 6;
        i = 0;
        while (1){
            ((mem[d.area])[d.high])[i] = repitition[(i+offset)%6];
            if (i == 59048) {
                break;
            }
            i++;
        }
    }
    return &(((mem[d.area])[d.high])[d.low]);
}

unsigned int get_instruction(Word** mem[], Word c,
        unsigned int last_initialized,
        int ignore_invalid) {
    Word* instr = ptr_to(mem, c, last_initialized);
    unsigned int instruction = instr->low;
    instruction = (instruction+c.low + 59049 * c.high
            + (c.area==1?52:(c.area==2?10:0)))%94;
    return instruction;
}

int main(int argc, char* argv[]) {
    Word** memory[3];
    int i,j;
    for (i=0; i<3; i++) {
        memory[i] = (Word**)malloc(59049 * sizeof(Word*));
        if (!memory) {
            fprintf(stderr,"not enough memory.\n");
            return 1;
        }
        for (j=0; j<59049; j++) {
            (memory[i])[j] = 0;
        }
    }
    Word a, c, d;
    unsigned int result;
    FILE* file;
    if (argc < 2) {
        // read program code from STDIN
        file = stdin;
    }else{
        file = fopen(argv[1],"rb");
    }
    if (file == NULL) {
        fprintf(stderr, "File not found: %s\n",argv[1]);
        return 1;
    }
    a = zero();
    c = zero();
    d = zero();
    result = 0;
    while (!feof(file)){
        unsigned int instr;
        Word* cell = ptr_to(memory, d, 0);
        (*cell) = zero();
        result = fread(&cell->low,1,1,file);
        if (result > 1)
            return 1;
        if (result == 0 || cell->low == 0x1a || cell->low == 0x04)
            break;
        instr = (cell->low + d.low + 59049*d.high)%94;
        if (cell->low == ' ' || cell->low == '\t' || cell->low == '\r'
                || cell->low == '\n');
        else if (cell->low >= 33 && cell->low < 127 &&
                (instr == 4 || instr == 5 || instr == 23 || instr == 39
                    || instr == 40 || instr == 62 || instr == 68
                    || instr == 81)) {
            d = increment(d);
        }
    }
    if (file != stdin) {
        fclose(file);
    }
    unsigned int last_initialized = 0;
    while (1){
        *ptr_to(memory, d, 0) = crazy(*ptr_to(memory, decrement(d), 0),
                *ptr_to(memory, decrement(decrement(d)), 0));
        last_initialized = d.low + 59049*d.high;
        if (d.low == 59048) {
            break;
        }
        d = increment(d);
    }
    d = zero();

    unsigned int step = 0;
    while (1) {
        unsigned int instruction = get_instruction(memory, c,
                last_initialized, 0);
        step++;
        switch (instruction){
            case 4:
                c = *ptr_to(memory,d,last_initialized);
                break;
            case 5:
                if (!a.area) {
                    printf("%c",(char)(a.low + 59049*a.high));
                }else if (a.area == 2 && a.low == 59047
                        && a.high == 59048) {
                    printf("\n");
                }
                break;
            case 23:
                a = zero();
                a.low = getchar();
                if (a.low == EOF) {
                    a.low = 59048;
                    a.high = 59048;
                    a.area = 2;
                }else if (a.low == '\n'){
                    a.low = 59047;
                    a.high = 59048;
                    a.area = 2;
                }
                break;
            case 39:
                a = (*ptr_to(memory,d,last_initialized)
                        = rotate_r(*ptr_to(memory,d,last_initialized)));
                break;
            case 40:
                d = *ptr_to(memory,d,last_initialized);
                break;
            case 62:
                a = (*ptr_to(memory,d,last_initialized)
                        = crazy(a, *ptr_to(memory,d,last_initialized)));
                break;
            case 81:
                return 0;
            case 68:
            default:
                break;
        }

        Word* mem_c = ptr_to(memory, c, last_initialized);
        mem_c->low = translation[mem_c->low - 33];

        c = increment(c);
        d = increment(d);
    }
    return 0;
}

工作正常!

It's working


2

05AB1E6 5 字节

2ι`ÅΓ

-1个字节感谢@Grimy

输出为字符列表。

在线尝试。

没有内置游程解码的旧6 字节答案:

2ôε`×?

在线尝试。

说明:

2ι      # Uninterleave the (implicit) input-string in two parts
        #  i.e. ":144,1'3" → [":4,'","1413"]
  `     # Push both separated to the stack
   ÅΓ   # Run-length decode
        #  i.e. ":4,'" and "1413" → [":","4","4","4","4",",","'","'","'"]
        # (after which the result is output implicitly)

2ô      # Split the (implicit) input-string into parts of size 2
        #  i.e. ":144,1'3" → [":1","44",",1","'3"]
  ε     # Loop over each of these pairs:
   `    #  Push both characters separated to the stack
    ×   #  Repeat the first character the digit amount of times as string
        #   i.e. "'" and "3" → "'''"
     ?  #  And print it without trailing newline

1
2ι`ÅΓ是5个字节。如果内置的RLE未能赢得RLE挑战,那将是可悲的。
Grimmy

@Grimy啊,那确实更好,谢谢!:)
凯文·克鲁伊森

1

Python,78 72 66个字符

d = raw_input()
打印“” .join([[x * int(d [i + 1])for i,x inumerate(d)if〜i&1])

s = raw_input()
打印“”。


1

J-24

;@(_2(<@#~".)/\])@1!:1 3

此提交的要点是使用中缀副词。


1

Befunge,49个字符

>~:25*-      v
$>\1-:v:-*68~_@
$^ ,:\_v
^      <


1

蟒蛇2,58

这是受到Darren Stone的python解决方案的启发-迭代器滥用!

x=iter(raw_input())
print''.join(a*int(next(x))for a in x)

这是我的原始解决方案(60个字符)

s=raw_input()
t=''
while s:t+=s[0]*int(s[1]);s=s[2:]
print t

另一种方法是将3个字符延长:

f=lambda a,b,*x:a*int(b)+(x and f(*x)or'')
print f(raw_input())

1

Java:285个字符

import java.util.Scanner;public class A{public static void main(String args[]){Scanner s = new Scanner(System.in);while(s.hasNext()){String t=s.next();for(int i=0;i<t.length();i++) {for(int j=0; j<(Byte.valueOf(t.substring(i+1,i+2)));j++){System.out.print(t.substring(i,i+1));}i++;}}}}

使用静态块代替主块,并使用Java6进行编译!
Fabinout


1

空格,135

LSSSLSSSSLSLSTLTSTTTSLSSSSTSSSSLTSSTLTTTTLSSSSLSLSTLTSTTTSSSTTSSSSLTSSTLSSSSLSLSLTSTLSSSTLTSSTSTSSTLTLSSLSLSSLLSSTLSLLSLLLSLSLLSSTTLLLL

(用空格,制表符,换行符替换S,T,L。)

在线尝试[这里]

说明:

"assembly"      whitespace                                      stack
----------      ----------                                      -----
s:              LSS SL      ;input loop                         []
    push 0      SS SSL                                          [0]
    dup         SLS                                             [0,0]
    getc        TLTS        ;input & store char c               [0]
    rcl         TTT         ;recall c                           [c]
    dup         SLS                                             [c,c]
    push 16     SS STSSSSL                                      [c,c,16]
    sub         TSST                                            [c,c-16]
    jlt  tt     LTT TTL     ;exit if ord(c) < 16                [c]       
    push 0      SS SSL                                          [c,0]
    dup         SLS                                             [c,0,0]
    getc        TLTS        ;input & store char n               [c,0]
    rcl         TTT         ;recall n                           [c,n]
    push 48     SS STTSSSSL ;convert n to m = ord(n)-ord('0')   [c,n,48]
    sub         TSST                                            [c,m]

ss:             LSS SSL     ;inner loop outputs c, m times      [c,m]
    dup         SLS                                             [c,m,m]
    jeq  t      LTS TL      ;if m==0, stop outputting this c    [c,m]
    push 1      SS STL      ;otherwise decr m                   [c,m,1]
    sub         TSST                                            [c,m-1]
    copy 1      STS STL     ;copy c to tos                      [c,m-1,c]
    putc        TLSS        ;output this c                      [c,m-1]
    jmp  ss     LSL SSL     ;loop back to output this c again   [c,m-1]

t:              LSS TL                                          [c,m]
    pop         SLL                                             [c]
    pop         SLL                                             []
    jmp  s      LSL SL      ;loop back to get the next c,n      []

tt:             LSS TTL                                         [c]
    end         LLL         ;exit

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.