制作;#解释器


62

我最近创建了一种新语言;#(发音为“ Semicolon Hash”),它只有两个命令:

; 向累加器加一

#对累加器乘以127,对ASCII字符进行转换,然后输出而不带换行符。此后,将累加器重置为0。是的,正确的是127。

其他任何字符都将被忽略。它对累加器没有影响,什么也不做。

您的任务是为这种强大的语言创建一个解释器!

它应该是完整程序,也可以是将;#程序作为输入并产生正确输出的函数。

例子

Output: Hello, World!
Program: ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;#;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;#;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;#;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;#;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;#;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;#;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;#;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;#;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;#;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;#;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;#;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;#;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;#

Output: ;#
Program: ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;#;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;#

Output: 2d{ (unprintable characters here; should have 4 `\000` bytes between the `d` and the `{` and 3 after the `{`)
Program: ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;#;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;hafh;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;f;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;#;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;###ffh#h#;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;ffea;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;aa;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;#au###h;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;h;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;o

Output: Fizz Buzz output
Program: link below

Output: !
Program: ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;#

嘶嘶声达100


1
如果解释器没有在输入的末尾终止执行,而是无限期地循环而不产生额外的输出,是否可以接受?
狮子座

5
第二个示例使我想知道一个程序,该程序对程序进行编码以产生输出...递归编译!
frarugi87

@Leo是的,这很好
Caird coinheringaahing

1
@iamnotmaynard分号哈希
凯尔德coinheringaahing

2
也许Wink Hash会更容易说
James Waldby-jwpat7

Answers:



17

JavaScript(ES6),76 82 80字节

s=>s.replace(/./g,c=>c=='#'?String.fromCharCode(a%(a=127)):(a+=(c==';'),''),a=0)

演示版

递归版本,82 77字节

由于尼尔节省了5个字节

对于大量输入(例如Fizz Buzz示例),此选项可能会崩溃。

f=([c,...s],a=0)=>c?c=='#'?String.fromCharCode(a%127)+f(s):f(s,a+(c==';')):""

我认为f(s,a+(c==';'))可能会使递归版本减少3个字节。
尼尔,

@Neil实际上节省5个字节。:-)
Arnauld

我现在真的很傻。我最初有一个错误版本,并减去2个字节来修复错误。但是我算错了,这个错误的版本实际上节省了7个字节……
尼尔(Neil)

12

Retina336 63 67 65 66 62 59字节

T`;#-ÿ`¯_
;{127}|;+$

(^|¯)
¯
+T`-~`_-`[^¯]
T\`¯`

在线尝试!

使用假设的转义语法的可读版本:

T`;#\x01-ÿ`\x01¯_
;{127}|;+$

(^|¯)\x01\x01
¯\x02
+T`\x01-~`_\x03-\x7f`[^\x01¯]\x01
T\`¯`

不打印NUL字节,因为TIO不允许在源代码中使用它们。在末尾还会打印一个额外的换行符,但是我想它不能这样做。尾随换行符由于@Leo而受到抑制。

-273(!)字节感谢@ETHproductions

-2个字节,感谢@ovs

-3个字节,感谢@Neil。看看他们出色的34字节解决方案


1
哦,我的话。但是您不能用保存一千个字节+T`\x01-~`_\x03-\x7f`[^\x01¯]\x01吗?(当然包括不可打印的字符)
ETHproductions '17

@ETHproductions当然可以。谢谢!:)
eush77

1
当前,即使#输入中没有尾部,最后一个字母也始终位于输出中。您可以通过将第二阶段更改为(;{127}|;+$)
ovs,将于

1
您是否需要在第三行加上+`?当您删除整个匹配项时,在第二个迭代中应该没有什么可以替换。
ovs '17

1
我想我可以用34个字节来做到这一点:(T`;#\x01-ÿ`\x80\x7F_ \x80+$空行)\+T`\x7Fo`\x01-\x80_`\x80[^\x80](使用十六进制转义符表示不可打印的字符)。输出\ x7F而不是null。
尼尔

12

Java 8,100字节

s->{int i=0;for(byte b:s.getBytes()){if(b==59)i++;if(b==35){System.out.print((char)(i%127));i=0;}}};

在线尝试!


3
欢迎光临本站!:)
DJMcMayhem

我为您添加了带有FizzBu​​zz示例的在线解释器的链接(链接文本太长而无法在评论中显示)
Jonathan Allan

Java将UTF-16用于其程序。因此,这些不是100个字节,而是100个字符
Gerold Broser

5
@GeroldBroser Unicode是一个字符集:UTF-8和UTF-16是该字符集的两种编码。ASCII源作为Java程序是完全有效的,并且我有很多用ASCII编码的Java源文件(这也是有效的UTF-8,因此也是Unicode编码)。

1
完全打高尔夫球,占81字节,是Consumer<char[]>s->{char i=0;for(int b:s){if(b==59)i++;if(b==35){System.out.print(i%=127);i=0;}}}
奥利维尔·格雷戈雷(

11

Japt,18个字节

®è'; %# d}'# ë ¯J

之后有一个不可打印的\ x7f字符%#在线测试!

这个怎么运作

®   è'; %#   d}'# ë ¯  J
mZ{Zè'; %127 d}'# ë s0,J
                         // Implicit: operate on input string
mZ{           }'#        // Split the input at '#'s, and map each item Z to
   Zè';                  //   the number of semicolons in Z,
        %127             //   mod 127,
             d           //   turned into a character.
m              '#        // Rejoin the list on '#'. At this point the Hello, World! example
                         // would be "H#e#l#l#o#,# #W#o#r#l#d#!#" plus an null byte.
                  ë      // Take every other character. Eliminates the unnecessary '#'s. 
                    ¯J   // Slice off the trailing byte (could be anything if there are
                         // semicolons after the last '#').
                         // Implicit: output result of last expression

1
D'oh,应该检查一下答案!只是花了一些时间才发现你打败了我。q'# ®è'; u# dì¯J也适用于相同的分数。
毛茸茸的

11

Python,65个字节

这是一个高尔夫球这种早期的答案。

lambda t:''.join(chr(x.count(';')%127)for x in t.split('#')[:-1])

在线尝试!Python2

在线尝试!Python3

说明

这是一个非常简单的答案,我们可以确定;每个之间有多少s #并打印chrmod127。唯一可能有点奇怪的是[:-1]。我们需要删除最后一组,因为之后将没有#

例如

;;#;;;;#;;;;;#;;;

将被分成

[';;',';;;;',';;;;;',';;;']

但是我们不想要最后一个,;;;因为#在它之后没有可打印的值。


1
我正忙于在一个TIO链接中进行所有测试。除了t和以外,都是chr x
乔纳森·艾伦

9

> <>,35个字节

>i:0(?;:'#'=?v';'=?0
^   [0o%'␡'l~<

在线尝试!替换为0x7F,^?或“删除”。

主循环

>i:0(?;:'#'=?v      
^            <

它采用输入(i)的字符,检查其是否小于零,即EOF(:0(),如果为(?;),则终止程序。否则,请检查输入是否等于#:'#'=)。如果是,请分支并重新启动循环(?v... ^ ... <)。

计数器逻辑

              ';'=?0
              

检查输入是否等于;';'=)。如果是,请按0。否则,什么都不做。这将重新启动主循环。

打印逻辑

>       '#'=?v      
^   [0o%'␡'l~<

当输入字符#为时,将输入弹出堆栈(~),获取堆栈上的成员数(l),按127('␡'),然后取模数(%)。然后,将其输出为字符(o)并开始新的堆栈([0)。这会将计数器“置零”。然后,循环重新开始。


3
> <>较差。很:0(
可惜

9

Python 3,69字节

借助@Wheat向导,@ Uriel进行了改进

print(''.join(chr(s.count(';')%127)for s in input().split('#')[:-1]))

3
欢迎来到编程难题和Code Golf!此处的目的是使代码尽可能短(以字节为单位),因此您需要在标头中包括字节数:)。
阿德南

感谢您的解释,不知道。那我会处理。
MrGeek '17

2
您可以在:s 后删除空格。
帕维尔

1
我数了74个字节。tio.run/nexus/…–
丹尼斯

2
同样,';'==c可以节省空间,但是根本不使用if语句会更短。
丹尼斯,

9

Röda44 39 38字节

@fergusq节省了5个字节

{(_/`#`)|{|d|d~="[^;]",""chr #d%127}_}

在线尝试!

从流中获取输入的匿名函数。


如果不必忽略其他字符,我得到以下信息:

Röda,20个字节

{(_/`#`)|chr #_%127}

8

Ruby,41 35 34个字符

40 34 33个字符的代码+ 1个字符的命令行选项)

gsub(/.*?#/){putc$&.count ?;%127}

谢谢:

  • Jordan建议使用putc不需要显式转换.chr(6个字符)
  • Kirill L.查找不必要的括号(1个字符)

样品运行:

bash-4.4$ ruby -ne 'gsub(/.*?#/){putc$&.count ?;%127}' < '2d{.;#' | od -tad1
0000000    2  etb    d  nul  nul  nul  nul    {  nul  nul  nul
          50   23  100    0    0    0    0  123    0    0    0
0000013

在线尝试!


h 尽管我早年做过C,但是我完全忘记了putc()。谢谢@Jordan
manatwork

1
令我惊讶的是,您实际上可以在计数后添加括号以保存一个字节
Kirill L.

不错,@ KirillL。,谢谢。
manatwork '18 / 08/10

7

05AB1E16 15 14字节

码:

'#¡¨ʒ';¢127%ç?

说明:

'#¡              # Split on hashtags
   ¨             # Remove the last element
    ʒ            # For each element (actually a hacky way, since this is a filter)
     ';¢         #   Count the number of occurences of ';'
        127%     #   Modulo by 127
            ç    #   Convert to char
             ?   #   Pop and print without a newline

使用05AB1E编码。在线尝试!


7

果冻,13个字节

ṣ”#Ṗċ€”;%127Ọ

在线尝试!

这个怎么运作

ṣ”#Ṗċ€”;%127Ọ  Main link. Argument: s (string)

ṣ”#            Split s at hashes.
   Ṗ           Pop; remove the last chunk.
    ċ€”;       Count the semicola in each chunk.
        %127   Take the counts modulo 127.
            Ọ  Unordinal; cast integers to characters.

1
这个词semicola不存在,是semicolons
暴民埃里克(Erik the Outgolfer)


嗯,奇怪的话。
暴民埃里克(Erik the Outgolfer)

@EriktheOutgolfer Wiktionary上的某人可能试图使拉丁文复数在英语中有效,但应禁止可乐可乐的拼写。
心教堂

7

MS-DOS上的x86机器代码-29个字节

00000000  31 d2 b4 01 cd 21 73 01  c3 3c 3b 75 06 42 80 fa  |1....!s..<;u.B..|
00000010  7f 74 ed 3c 23 75 eb b4  02 cd 21 eb e3           |.t.<#u....!..|
0000001d

评论程序集:

bits 16
org 100h

start:
    xor dx,dx       ; reset dx (used as accumulator)
readch:
    mov ah,1
    int 21h         ; read character
    jnc semicolon
    ret             ; quit if EOF
semicolon:
    cmp al,';'      ; is it a semicolon?
    jne hash        ; if not, skip to next check
    inc dx          ; increment accumulator
    cmp dl,127      ; if we get to 127, reset it; this saves us the
    je start        ; hassle to perform the modulo when handling #
hash:
    cmp al,'#'      ; is it a hash?
    jne readch      ; if not, skip back to character read
    mov ah,2        ; print dl (it was choosen as accumulator exactly
    int 21h         ; because it's the easiest register to print)
    jmp start       ; reset the accumulator and go on reading

6

05AB1E25 21 19字节

-2个字节感谢Adnan

Îvy';Q+y'#Qi127%ç?0

说明:

Î                       Initialise stack with 0 and then push input
 v                      For each character
  y';Q+                 If equal to ';', then increment top of stack
       y'#Qi            If equal to '#', then
            127%        Modulo top of stack with 127
                ç       Convert to character
                 ?      Print without newline
                  0     Push a 0 to initialise the stack for the next print

在线尝试!


1
我想你可以替换i>}+
阿德南

6

视网膜,34字节

T`;#-ÿ`_
\+T`o`-_`[^]|$

在线尝试!包括测试用例。编辑:在@MartinEnder的帮助下保存了2个字节。注意:代码包含不可打印的内容,并且使用&#x;代码会生成错误的结果,因为浏览器使用Windows-1252而不是ISO-8859-1。说明:第一行清理输入:(由于TIO限制);更改为\x80#\x7F,其他所有内容均被删除。然后,只要我们看到一个\x80不在另一个\x80字符之前的,就将其删除并循环增加下一个字符的代码。反复进行此操作,直到没有\x80剩余的字符为止。支持空字节的原始代码基本上从不可打印的字节中减去1,但在第一行中\xFF不变并\x7F变为\x00。使用转义符以提高可读性:

T`;#\x00-\xFF`\x7F\x00_
\+T`\x7Eo`\x00-\x7F_`\x7F[^\x7F]|\x7F$

您可以通过将最后两个阶段与\x80([^\x80]|$)最后一个阶段组合在一起来保存字节。
Martin Ender

@MartinEnder谢谢!恼人的是,\s+T`\x7Fo`\x01-\x80_`\x80(?!\x80).?也只保存一个字节。
尼尔,2017年

嗯,但是[^\x80]|\x80$我想节省了两个字节。
尼尔

很好,是的,最后一个有效。我也尝试过否定的前瞻性,但是s很烦人。
Martin Ender

6

R,97 90 86 84字节

功能:

function(s)for(i in utf8ToInt(s)){F=F+(i==59);if(i==35){cat(intToUtf8(F%%127));F=0}}

当R开始时,F定义为FALSE(数值0)。

取消高尔夫:

function (s)
    for (i in utf8ToInt(s)) {
        F = F + (i == 59)
        if (i == 35) {
            cat(intToUtf8(F%%127))
            F = 0
        }
    }

这不是R + pryr吗?
L3viathan '17

@ L3viathan由于pryr是R包,因此它仍然是R代码。
Sven Hohenstein

它是R代码,但需要安装其他库。
L3viathan '17

@ L3viathan您认为我的答案无效吗?我应该避免使用其他软件包吗?
Sven Hohenstein

2
@BLT没有区别。我认为使用挑战之前创建的其他程序包没有问题。所有语言都适用。在Python中,您必须使用importR;而在R中,您可以使用::它直接访问包中的函数。您经常可以在这里看到其他软件包的使用(例如,对于Python和Java)。但是,我更改了以前的帖子,因为我不想参与讨论。
Sven Hohenstein

5

Python,82个字节

lambda t:''.join(chr(len([g for g in x if g==';'])%127)for x in t.split('#')[:-1])

1
@WheatWizard,因为您已经将其发布为答案,所以我认为对我来说正确的行动是对其进行投票,而不是进行更新
Uriel

4

普通TeX,156字节

\newcount\a\def\;{\advance\a by 1\ifnum\a=127\a=0\fi}\def\#{\message{\the\a}\a=0}\catcode`;=13\catcode35=13\let;=\;\let#=\#\loop\read16 to\>\>\iftrue\repeat

可读的

\newcount\a

\def\;{
  \advance\a by 1
  \ifnum \a=127 \a=0 \fi
}
\def\#{
  \message{\the\a}
  \a=0
}

\catcode`;=13
\catcode35=13

\let;=\;
\let#=\#

\loop
  \read16 to \> \>
  \iftrue \repeat

它可以象征性地打印字符吗?
eush77


4

Perl,25个字节

$_=chr(y%;%%%127)x/#/

运行perl -043pe(计数为4个字节,因为perl -e是标准的)。

说明:-043将行终止符设置为#(ASCII 043)。-p遍历输入的“行”(现在实际上是#分隔的字符串)。y%;%%计算;每个“行”中的数量。x/#/确保对于不以#结尾的程序,我们不打印多余的字符(例如第三个测试用例)。%127应该很明显。$_=是通常的样板。


令人印象深刻的是,尽管有故障:因为;;#;;;它输出#5而不是#2。
manatwork '17

您是怎么得到这个结果的?在我的机器上echo -n ';;#;;;' | perl -043pe '$_=chr(y%;%%%127)x/#/' | xxd正确输出00000000: 02。如果您不使用043,或者使用的代码页#不是ASCII 043,则可以解释您的结果。
肮脏的

1
哎呀。抱歉,我的考试有错字。您的代码可以完美运行。
manatwork '17

4

CJam,27个字节

0q{";#"#") 127%co0 "S/=~}%;

说明:

0                            e# Push 0
 q                           e# Push the input
  {                          e# For each character in the input:
   ";#"#                     e#   Index of character in ";#", -1 if not found
        ") 127%co0 "S/       e#   Push this string, split on spaces
                      =      e#   Array access (-1 is the last element)
                       ~     e#   Execute as CJam code. ")" increments the accumulator,
                             e#     and "127%co0" preforms modulo by 127, converts to character, pops and outputs, and then pushes 0.
                        }%   e# End for
                          ;  e# Delete the accumulator

替代解决方案,18字节

q'#/);{';e=127%c}%

说明:

q                   e# Read the whole input
 '#/                e# Split on '#'
    );              e# Delete the last element
      {             e# For each element:
       ';e=         e#   Count number of ';' in string
           127%     e#   Modulo by 127
               c    e#   Convert to character code
                }%  e# End for

不忽略无效字符的商务猫。
硕果累累

为什么需要;删除累加器?
caird coinheringaahing

@RandomUser因此,最终不会在字符串末尾输出。
ETHproductions's

4

F#,79 91 93字节

let rec r a=function|[]->()|';'::t->r(a+1)t|'#'::t->printf"%c"(char(a%127));r 0 t|_::y->r a y

不打高尔夫球

let rec run acc = function
    | [] -> ()
    | ';'::xs ->
        run (acc + 1) xs
    | '#'::xs ->
        printf "%c" (char(acc % 127))
        run 0 xs
    | x::xs -> run acc xs

在线尝试!

编辑:正在处理除';'以外的任何其他字符 为“#”。对其进行了更改,以使其忽略无效字符。

另类

F#,107104字节

let r i=
 let a=ref 0
 [for c in i do c|>function|';'->a:=!a+1|'#'->printf"%c"(!a%127|>char);a:=0|_->()]

使用参考单元可节省3个字节

不打高尔夫球

let run i =
    let a = ref 0;
    [for c in i do
        match c with
        | ';' -> a := !a + 1
        | '#' ->
            printf "%c" (char(!a % 127))
            a := 0
        |_->()
    ]

在线尝试


4

Processing.js(Khanacademy版本),118字节

var n="",a=0;for(var i=0;i<n.length;i++){if(n[i]===";"){a++;}if(n[i]==="#"){println(String.fromCharCode(a%127));a=0;}}

在线尝试!

由于所使用的处理版本没有任何输入方法,因此将输入放置在n中。


从技术上讲,您可以使用keyTyped=function(){ ... }:P
ETHproductions

@ETHproductions这令人厌恶。
克里斯托弗·

@RandomUser是的!我已经做了!我喜欢在处理中回答(请检查我的回答)
Christopher

2
@RandomUser不仅是1000代表。而是2 ^ 10代表((°

@Midnightas Ohhh yeah
Christopher

4

迷宫61 47字节

_36},)@
;    {
; 42_-
"#-  1
_ ; 72
_ ) %
"""".

在线尝试!

说明

解决方案代码的彩色图像

代码执行从左上角开始,第一个分号从堆栈中丢弃一个隐式零,然后继续向右。

橙子

  • _36将36推入堆栈。这是为了将输入与#
  • } 将堆栈顶部移动到辅助堆栈
  • , 将字符的整数值压入堆栈
  • )增加堆栈(如果它是输入的末尾,则将使堆栈为0,并且程序流将继续进行到@并退出)
  • { 将辅助堆栈的顶部移至主要堆栈的顶部
  • -弹出y,弹出x,按x-y。这是为了将输入与#(ascii中的35)进行比较。如果输入是#代码,则代码将继续到紫色部分(因为堆栈的顶部为0,因此IP沿其之前的移动方向继续前进),否则它将继续至绿色部分。

紫色

  • 127 将127推入堆栈
  • % 弹出x,弹出y,按下x%y
  • . 弹出堆栈的顶部(累加器)并作为字符输出

从这里开始,灰色代码将我们带到程序的左上角,堆栈上没有任何内容。

绿色

  • _24 将24推入堆栈
  • -弹出x,弹出y,按下xy。#和之间是24的差,;因此它检查输入是否为;。如果是;,代码将继续直接向)。否则,它将转向#推动堆栈高度的。(始终为正数,迫使程序在下一个交叉点向右转,并错过使累加器递增的代码)
  • ; 丢弃栈顶
  • ) 递增栈顶,它是隐式零或它是先前递增的零,用作输出的累加器

从这里开始,灰色代码将我们带到仅带有累加器的堆栈的程序的左上角。

灰色

引号是无操作的,_将0压入堆栈,并;丢弃堆栈的顶部。所有这些仅仅是以正确的方式强制控制流并从堆栈顶部丢弃任何多余内容的代码。


出于好奇,您是如何生成解释图像的?您是自己创建的吗?
Stefnotch

2
@Stefnotch,我使用文本编辑器在每个字符之间放置一个选项卡,然后将代码粘贴到Microsoft Excel中,从而将每个字符放入其自己的单元格中。我选择了所有单元格以使其具有相等的宽度和高度。然后,我调整了颜色和边框并拍摄了屏幕截图。
罗伯特·希克曼

3

MATL,29个字节

';#'&mXz!"@o?T}vn127\c&YD]]vx

输入是用单引号引起来的字符串。

在线尝试!

FizzBu​​zz程序对于在线口译员来说太长了。看到它在此gif中脱机工作:

在此处输入图片说明

说明

累加器值实现为堆栈中元素的数量。这使程序比累加器值是堆栈中的单个数字时要慢,但是却节省了一些字节。

';#'       % Push this string
&m         % Input string (implicit). Pushes row vector array of the same size with 
           % entries 1, 2 or 0 for chars equal to ';', '#' or others, respectively
Xz         % Remove zeros. Gives a column vector
!          % Transpose into a row vector
"          % For each entry
  @        %   Push current entry
  o?       %   If odd
    T      %     Push true. This increases the accumulator (number of stack elements)
  }        %   Else
    v      %     Concatenate stack into a column vector
    n      %     Number of elements
    127\   %     Modulo 127
    c      %     Convert to char
    &YD    %     Display immediately without newline
  ]        %   End
]          % End
vx         % Concatenate stack and delete. This avoids implicit display

3

爱丽丝,22字节

I!?';-n+?h$'@u%?'#-n$O

在线尝试!

说明

我们只在堆栈中保留;已遇到的计数器。当堆栈为空时(例如,在程序开始时),它隐式为0。

I!?';-n+?h$'@u%?'#-n$O
I                      Push codepoint of next char from input
 !?                    store it on the tape and reload it right away
   ';-n+               add 1 to the counter if this char is a semicolon,
                       0 otherwise
        ?h$'           If the input char was -1 (EOF) execute the next command,
                       otherwise push its codepoint
            @          Terminate the program (or push 64)
             u         Set all bits up to the most significant as equal to 1
                       this turns 64 (1000000b) into 127 (1111111b)
              %        Compute modulo
               ?       reload the input char from the tape
                '#-n$O if it is a hash, pop the counter and print
                       the corresponding character
                       wrap back to the start of the line

您可以在此处找到该程序的较短但不终止的版本。



抱歉,格式不正确,我已经从手机中发布了此信息,一旦接触到PC,便会立即修复
-Leo

程序必须终止,除非挑战中另有说明。
Martin Ender

您可以通过使用原义0x7F代替字节来保存字节~h
Martin Ender

@MartinEnder使它终止。我无法在代码中插入0x7F,但我认为无论如何,这种替代的修改还是比较有趣的:)
Leo

3

JS(ES6),97 92字节

c=>(a=0,y="",c.split``.map(x=>x=="#"?(a%=127,y+=String.fromCharCode(a),a=0):x==";"?a++:0),y)

试图采取与Shaggy的答案不同的方法。那好吧。


3

;#+,59字节,非竞争

语言是在挑战之后做出的。

;;;;;~+++++++>~;~++++:>*(~<:-+!(<-;->(;))::<+-::!(<#>)-:-*)

在线尝试!输入以空字节终止。

说明

生成与我的Generate;#代码答案相同。唯一的区别是迭代。

迭代

*(~<:-+!(<-;->(;))::<+-::!(<#>)-:-*)
*(                                *)   take input while != 0
  ~                                    swap
   <                                   read value from memory (;)
    :                                  move forward to the accumulator memory spot (AMS)
     -                                 flip Δ
      +                                subtract two accumulators into A
       !                               flip A (0 -> 1, else -> 0)
        (     (;))                     if A is nonzero, or, if A == ';'
         <                             read from AMS
          -;-                          increment
             >                         write to AMS
                  ::                   move to cell 0 (#)
                    <                  read value from memory (#)
                     +                 subtract two accumulators into A
                      -                flip Δ
                       ::              move to AMS
                         !(   )        if A == '#'
                           <           read from AMS
                            #          output mod 127, and clear
                             >         write to AMS
                               -:-     move back to initial cell

3

Bash + coreutils,46个 39字节

tr -dc \;#|sed 'y/;/1/;s/#/.ZC7%P/g'|dc

在线尝试!

说明

(感谢Cows Quack提供-7个字节!)

tr部分删除了所有多余的字符(我可以将其放在sed完全相同的字节数中,但是由于它sed留在dc了第一个换行符中,因此无法正确处理换行符?

sed剩下的并构建一个dc程序:

字符串;变成1(长文字)的字符串

#变成.ZC7%P(如果它跟在一个字符串之后1,则.是无操作的小数点。但是,如果它在程序的开头,或者在另一个之后#,则是一个文字0。然后,它会取数字的长度,对其进行修改,并打印相应的ASCII。)


您无需逃脱;内部操作'...',只需更改dc -ez?为即可dc。除此之外;,您可以将它们分组在一起并使用Z到达此tio.run/##S0oszvj/…的长度,而不是将其加到堆栈中。
Kritixi Lithos

@Cowsquack很好,谢谢!(这dc -ez?是启动程序需要额外的零的结果),但是您的程序stderr在连续#或输入不以结尾结尾的情况下都向其添加了附加输出#(在两种情况下,我的意思是删除了多余的字符之后) 。我不知道是否达成共识,但是我觉得多余的输出使解决方案无效。但是,我适应了您的想法,并且比您的建议仅增加了一个字节,而没有dc抛出错误!
Sophia Lechner '18

根据这个标准,除非挑战明确指出,否则可以忽略stderr,因此对于dc非常方便。还要注意,此当前解决方案#因为is 的原因而Z导致连续s 失败,因此它输出0x01而不是0x00(我也陷入了相同的陷阱,但是我的浏览器将不可打印的内容显示为其十六进制代码,所以我抓住了它)。01
Kritixi Lithos

3

C, 65 64 60字节

(-2感谢ceilingcat)

c;f(char*s){for(c=0;*s;s++)c+=*s-35?*s==59:-putchar(c%127);}

您需要将其初始化c为零以使该函数可重用
科纳·奥布赖恩

@ ConorO'Brien固定。不幸的是,我没有想出比添加短的任何东西c=0,而且我不想从丹尼斯的答案中抄袭作弊。
hvd

@ceilingcat再次感谢,之后我又可以摘下三个字节。这确实在Dennis的答案中使用了一个技巧(在编辑后检查),但是这次已经过去了太多的时间,以至于我忘记了所有内容,而是自己提出了。
hdv
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.