字符串操作解释器


11

摘要

制作了一种新的字符串操作语言,仅使用字符$+#-!*|@>!您的任务是在尽可能少的字节中为其实现一个解释器。

输入值

字符串,是此语言的一行。可以采用任何合理的方式(标准输入,函数参数,命令行参数等)或将其用作预定义变量。如果程序要求用户输入,请接受它从stdin要求的所有用户输入,仅此而已,请参见下文。您可能会认为它是一个有效程序。

输出量

无论使用哪种语言输出,以下说明。您必须以任何合理的方式(标准输出,函数输出等)输出字符串或变量值。语言明确输出后,必须转到stdout。禁止出现标准漏洞。

语言规格

处理和语法

该语言具有非常简单的处理形式,因为它仅执行字符串操作:它以空字符串("")开头,并随每个术语进行更改。一个术语由一个或两个部分组成:一个函数(在下面),然后可能是一个参数(在下面),用于编辑其行为。术语用竖线(|)分隔。您可能会认为它不会是一个空程序,并且任何条件都不会是空的。您应该在程序末尾输出该值。

功能

该语言只有6种功能,如下所示。每个函数都接受一个或零个参数。

  • + 连接字符串(采用一个字符串参数,将其连接到当前值)
  • ! 反转当前值的字符顺序(无参数)
  • * 重复字符串(采用一个整数参数,将当前值重复多次)
  • - 删除所有出现的值(采用一个字符串参数,从当前值删除所有出现的值)
  • $ [pseudo-]随机改组当前值(无参数)
  • <将当前值输出到stdout(无参数)

价值观

这些是可以传递给函数的值,由匹配它们的正则表达式表示:

  • @[^|]*字符串文字,包括除管道以外的任何字符。它可能是空的。
  • #[0-9]+ 整数文字
  • >下一行stdin。如果与一起使用*,则转换为整数。

测试用例

╔════════════════════════╤═════════════╤══════════════╗
║code                    │input        │output        ║
╟────────────────────────┼─────────────┼──────────────╢
║+>|!|+@hello|*>         │13           │31hello31hello║
║                        │2            │              ║
╟────────────────────────┼─────────────┼──────────────╢
║+>|+@abcdefg|$          │hello        │hcloeebafdlg  ║
╟────────────────────────┼─────────────┼──────────────╢
║+@how areyou|-@o|->     │w            │h areyu       ║
╟────────────────────────┼─────────────┼──────────────╢
║+@out|<|*#3             │             │out           ║
║                        │             │outoutout     ║
╟────────────────────────┼─────────────┼──────────────╢
║+>                      │what ever 345│what ever 345 ║
╟────────────────────────┼─────────────┼──────────────╢
║+@$pe<i@l|<|-@$pe<i@l|+>│A|$o $pe<!@| │$pe<i@l       ║
║                        │             │A|$o $pe<!@|  ║
╟────────────────────────┼─────────────┼──────────────╢
║<|+>|!|<                │input text   |              ║
║                        │             │txet tupni    ║ 
║                        │             │txet tupni    ║
╟────────────────────────┼─────────────┼──────────────╢
║+@>#                    │             |>#            ║
╚════════════════════════╧═════════════╧══════════════╝

请注意,测试用例2是随机的,因此其中的所有字符排列都是有效的。另外,表中的输出用换行符分隔,但是您的程序不必这样做。每种情况下的最后一个值是最终输出。

范例(Un-golfed)python解释器

在线尝试!如果通过IDLE或其他方式运行IMO,则效果更好。(之后,我将其压缩到424字节,但我敢肯定,您可以做得更好)。


2
允许输入已经包含在变量中是非标准的,允许输出包含在一个变量中也是非标准的。
乔纳森·艾伦,

您的示例似乎每次<遇到时都会换行。这是强制性的吗?
无知的体现,

该程序中是否包含换行符?因为如果可以的话,它会使查斯·布朗的答案无效
无知的体现

2
对于您将来的问题,请考虑避免使用繁琐的I / O格式。在某些语言中,将输入限制为stdin会花费额外的字节,并且带来的挑战并不多。
阿纳尔德

1
@digEmAll我刚刚添加的那个怎么样+@>#?我也用过#
Artemis仍然不信任

Answers:


3

红宝石 -palF\|146个 142字节

r='';$F.map{|i|x=i[1]!=?>?i[2..-1]:gets.chomp;eval %w[r.reverse! r*=x.to_i 0 $><<r r=r.chars.shuffle*'' r.gsub!x,'' r+=x][i[0].ord*5%11]};$_=r

在线尝试!

Chas Brown的Python解答端口。输出后不打印换行符。

与往常一样,Ruby 2.6版本将使用无限范围索引(i[2..])缩短2个字节。


6

[R 287 286 273 269字节

function(C,x='',`[`=gsub,`!`=intToUtf8,`?`=utf8ToInt){for(k in el(strsplit(C,'\\|'))){B=eval(parse(t='^.'['','(?<=.)>$'['readLines(,1)','[@#](.+)'['"\\1"',k],,T]]));x=switch((?substr(k,1,1))%%13-2,strrep(x,B),paste0(x,B),,B['',x,f=T],!rev(?x),print(x),,!sample(?x))};x}

在线尝试!

  • -1感谢@Kirill L.
  • -4感谢@Giuseppe

展开代码和说明:

function(C){                                      # C is the string manipulation expression
  x = ''                                          # initialize x = ''
  tokens = el(strsplit(C,'\\|'))                  # split C by pipe '|'
  for(k in tokens){                               # for each token k
    arg2 = k
    arg2 = gsub('[@#](.+)','"\\1"',k)             # replace @X or #X with "X" (in quotes)
    arg2 = gsub('(?<=.)>$','"readLines(,1)"',
                 arg2,perl=T)                     # replace > with readLines(,1)
    arg2 = gsub('^.','',arg2)                     # remove the first character
    B = eval(parse(t=arg2))                       # evaluate the string : this will be our 
                                                  # second argument B
    A = substr(k,1,1)                             # take the first character : 
                                                  # i.e. the main command (+,-,! etc)
    x = switch(A,                                 # switch on the main command, execute the 
            '+'=paste0(x,B),                      # corresponding expression and 
            '!'=intToUtf8(rev(utf8ToInt(x))),     # store the result into x
            '*'=strrep(x,B),                      # Note: in the actual code we switch on
            '-'=B['',x,f=T],                      # the utf8 value MOD 13-2 of the command
            '$'=intToUtf8(sample(utf8ToInt(x))),
            '<'=print(x)
        )
    }
    x                                             # return x (and print it implicitly)
}

3

Python 2中215个 219 209 208字节

from random import*
I=raw_input;o=''
for t in I().split('|'):p=t[1:]=='>'and I()or t[2:];exec"o=o[::-1] o*=int(p) 0 print(o) o=''.join(sample(o,len(o))) o=o.replace(p,'') o+=p".split()[ord(t[0])*5%11]
print o

在线尝试!

-4,因为raw_input是必需的。

由于无知的体现, 9个字节; 1个字节(仅来自Ascii)


如问题所指定,程序以外的输入必须来自stdin。
Artemis仍然不相信

我使用的是Python 3,但据我所知,input的使用需要raw_input。纠正我,如果我错了..
阿蒂米斯仍然不相信SE

根据Py 2.7 docs:input([prompt])等效于eval(raw_input(prompt))。此功能不会捕获用户错误。如果输入在语法上无效,则将引发SyntaxError。
Artemis仍然不相信

因此,您提出的问题类似于此处,其中需要对输入字符串加引号-而不是在“真实” stdin情况下不加引号。同样,通常I / O规则有点松懈;但我会修改。
Chas Brown

感谢您的更改。您可以通过更改为Python 3并使用旧代码+ 3个字节作为括号来节省一些字节,但是……+1
仍然如此

2

C#(Visual C#交互式编译器),305个字节

a=>{string s="",d,g;foreach(var c in a.Split('|')){g=$"{c,2}";d=g[1]==62?ReadLine():g.Substring(2);var z=c[0]%14;s=z<1?string.Concat(Enumerable.Repeat(s,int.Parse(d))):z<2?s+d:z<4?s.Replace(d,""):z<5?s:z<6?string.Concat(s.Reverse()):string.Concat(s.OrderBy(_=>Guid.NewGuid()));Write(z==4?s:"");}return s;}

在线尝试!


1

Perl 5中 -MList::Util=shuffle -pF/\|/220个 217 210 183字节

map{$,=s/..//r;$\=reverse$\if/^!/;$,ne""||chomp($,=<>),$\=~s/\Q$,//g if/^-/;say$\if/^</;$\=join"",shuffle$\=~/./g if/^\$/;$\.=$,eq""?<>=~s/\n//r:$,if/^\+/;$\x=$,eq""?<>:$,if/^\*/}@F}{

在线尝试!


1

Javascript,292,267字节

f=(p)=>{c='';p.split`|`.map(l=>{v=l.substr(2);v=l[1]=='#'?parseInt(v):l[1]=='>'?prompt():v;c={'+':_=>c+v,'-':_=>c.split(v).join``,'*':_=>c.repeat(v),'$':_=>[...c].sort(_=>.5-Math.random()).join``,'!':_=>[...c].reverse().join``,'<':_=>alert(c)||c}[l[0]]();});return c}

JSFiddle


测试用例6不太起作用...
Artemis仍然不相信SE

1
@ArtemisFowl,谢谢,正则表达式无法正常工作,切换到split..join保存了几个字节。
约翰·杜托伊
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.