使您的语言*大部分*不可用(强盗的线程)


31

受到此评论的启发...

感谢用户Step HenWheat-WizardDennis帮助我在发布挑战之前确定了挑战的规格!

这是强盗的线索!有关警察的线索,请转到此处


这个挑战中,您需要运行一些代码来使您的语言不再满足我们成为编程语言的条件。在这一挑战中,这意味着要做到这一点,以便不再能使用该语言...

  • 进行数字输入和输出

  • 将两个数字相加

  • 测试某个数字是否为质数。

这是一个挑战,其中有两个不同的挑战,其目标是两个不同:警察将尝试编写一些使该语言几乎不可用的代码,并且强盗将尝试找到允许警察使用的隐藏变通方法恢复他们的语言。

警察将编写两个代码段:

  1. 一种使其语言几乎无法使用的方法,例如,通过删除用于进行输入/输出和数字运算的内置函数。此代码是不是允许崩溃或退出。应该可以在此代码段的末尾添加代码,并且该代码将得到评估。和

  2. 一小段代码,将两个数字作为输入,将它们加在一起,然后输出它们的和。即使运行第一个代码段后,该代码段也必须仍然能够正常运行。当两个代码片段组合在一起时,它们必须形成一个将两个数字相加的完整程序,或者定义一个将两个数字相加的函数。此代码段可能依赖于晦涩的行为,并且很难找到。

警察还将选择任何标准的输入和输出方法。但是,他们必须准确显示他们正在使用哪种格式(输入和输出)。要破解他们的答案,您必须遵循相同的输入/输出格式,否则您的破解就不算在内。

警察的答案将永远揭示

  • 一个摘要(显然不是第二个)。

  • 语言(包括次要版本,因为大多数提交可能都依赖于奇怪的情况)

  • IO格式,包括功能或完整程序。强盗必须使用相同的格式才能有效破解。

  • 任何奇怪的情况下,他们的答案才能起作用。例如,仅在linux上运行,或者需要Internet连接

作为强盗,您必须查看其中一个警察提交的内容,然后尝试对其进行破解。您可以编写任何可以用作代码段2的有效代码段(在使该语言几乎不可用之后将两个数字加在一起)来破解它。但这不是必须是相同的片段,警察最初编写。破解答案后,将代码发布为该线程的答案,并发布指向您答案的链接,作为对警察答案的评论。然后,该帖子将被编辑以指示已被破解。

这是一个例子。对于第一个代码段,您可能会看到以下python 3程序作为警察的答案:

Python 3

print=None

从STDIN接收输入并输出到STDOUT

有效的第二个片段可能是

import sys
a,b=int(input()),int(input())
sys.stdout.write(a+b)

这是有效的,因为它将两个数字作为输入,并且即使您将两个摘要合并在一起也可以输出它们的总和,例如

print=None
import sys
a,b=int(input()),int(input())
sys.stdout.write(a+b)

这是对他们答案的有效破解。

如果警察的答案整整一个星期没有变化,他们可以在第二个片段中进行编辑,并指出他们的答案现在是安全的。一旦安全起见,就不能再尝试破解了。如果他们不安全地编辑它,则可以继续尝试对其进行破解,直到他们这样做为止。

强盗线索的胜利者是破解最多答案的用户,而决胜局是他们达到N条裂缝的时间。(例如,如果两个不同的用户各自有5个裂纹,则第5个裂纹首先发布的用户就是获胜者。)经过足够的时间后,我将以最高票数接受获胜者的回答。

玩得开心!

规则澄清

  • 第一个代码段必须正确运行而不需要任何输入。它可能会输出您喜欢的任何内容,并且该输出将被忽略。只要代码段完成后,第二个代码段就可以正确运行。

  • 为了使您的答案有效,实际上必须执行第二个代码段。这意味着答案像

    import sys
    sys.exit()
    

    无效,因为它不会破坏语言。它只是退出。

  • 安全后,您的得分就是两个代码段的字节数。

  • 这可以回溯到“ 请揭示工作答案所需的任何奇怪的情况 ……”。您提交的内容必须包含足够的信息,然后才能显示出来,以便显示出来之后可以重现。这意味着,如果您的答案变得安全,然后您输入:这是我的答案。哦,是的,BTW仅在您在Solaris上运行时有效,请您开玩笑!您的答案无效,将被删除,不符合获奖资格。

  • 输出总和后,第二个代码段将允许崩溃。只要输出仍然正确(例如,如果您选择输出到STDERR,然后您获得大量崩溃信息,则此信息无效)

排行榜

这是每个至少有一个裂纹的用户的列表,按分数和名称(字母顺序)排序。如果您提交裂缝,请相应地更新您的分数。

#User                       #Score
Ilmari Karonen              8

Dennis                      5

Olivier Grégoire            4

Sisyphus                    3
Veedrac                     3

Arnold Palmer               2
Bruce Forte                 2
DJMcMayhem                  2
Dom Hastings                2
ppperry                     2

1bluston                    1
2012rcampion                1
Ben                         1
BlackCap                    1
Christian Sievers           1
Cody Gray                   1
HyperNeutrino               1
Joshua                      1
Kaz                         1
Mark                        1
Mayube                      1
Xnor                        1
zbw                         1

Answers:


3

OlivierGrégoire的Java 8

class A {
  public A() {
    String[] args = System.lineSeparator().split(",");
    System.out.print(Integer.parseInt(args[0]) + Integer.parseInt(args[1]));
  }
}

在线尝试!

由于Olivier 明确允许通过使用VM参数设置的属性传递输入,因此我将指定输入应在VM参数中给出-Dline.separator=X,Y,其中XY是要添加的数字。也就是说,例如将数字17和25相加,应将该程序调用为:

java -Dline.separator=17,25 Main

我相信,这可以在任何可以在命令行上运行Java程序的系统上运行。即使在没有命令行的系统上,也可以使用任何其他等效的机制来设置系统属性,以将输入传递给VM。


附言 这是我之前的破解尝试,由于使用了JVM特定的功能而被认为是无效的:

class SecurityManager extends sun.awt.AWTSecurityManager {
  static {
    String[] args = System.getProperty("sun.java.command").split(" ");
    int a = Integer.parseInt(args[args.length-2]);
    int b = Integer.parseInt(args[args.length-1]);
    System.out.println(a+b);
  }
}

在线尝试!

事实证明,它比以前的冗长得多。困难的部分是找到一个SecurityManager不在“ java.” 开头的命名空间中的子类。我怀疑这仍然不是预期的解决方案,但是它可以工作。*

*)至少在TIO上;在sun.awt.AWTSecurityManager类和sun.java.command财产似乎并没有正式记录在案,并可能并不适用于所有JVM。


不错的工作!我试过了,但是找不到SecurityManager范围内的东西... System.in不过,您现在也可以阅读,因为它尚未关闭。
zbw

抱歉,这是基于平台的两个方面的答案:sun.awt.SecurityManager和都与"sun.awt.command"平台有关,并且不是Java的一部分
奥利维尔·格雷戈尔

是的,破解!:)预期的解决方案是通过System.getProperties().get("blah")(因为我只阻止了对System.getProperty,而不是System.getProperties)的访问,但这已经足够了!做得好!
奥利维尔·格雷戈尔

22

Sisyphus编写的C(GCC / Linux)

此代码段关闭了提供的功能,并启动了一个新功能(经典代码注入),该功能本身重新定义,close以便运行所需的代码而不是关闭fd。

}
int close(int x) {
  int a, b;
  scanf("%d %d", &a, &b);
  printf("%d\n", a + b);

  exit(0);

20

Python中,小麦向导的解决方案在这里

import sys
c="".join(open(__file__).read().split('\n')[4:])
if set(c)-set(' &)(,.:[]a`cdfijmonrt~')or"import"in c:sys.setrecursionlimit(1)
f=lambda\
:[]                                                      # my code starts here
sys.setrecursionlimit(1000)
print(int(input())+int(input()))

我的意思是,您只需将递归限制设置回去,就不会发生任何不好的事情...

在TIO上工作

注意

这是我第一次提交CnR,因此,如果这违反了任何规则,请告诉我,我将其删除。


4
我因错过了这个内容而感到傻了
Wheat Wizard

@WheatWizard :)
HyperNeutrino

@wheatwizard暂时不要透露您想要的解决方案。我很乐意看到与您解决该问题的原始解决方案更好的解决方案。
DJMcMayhem

@Djmcmayhem我可能要用del sys重新发布。
小麦巫师

@WheatWizard记住os.sys,如果有所不同:P
HyperNeutrino

15

本·Haskell

import Prelude(getLine,print)
a=a
[]++s=s
(a:as)++s=a:(as++s)
r""=""
r(c:s)=(r s)++[c]
t(_:r)=r
ts l=l:ts(t l)
x[_](v:_)=v
x(_:r)(_:s)=x r s
d(a:_:_:_:_:_:_:_:_:_:r)=a:d r
(a:_)!!""=a
l!!(n:m)=d(x['0'..n](ts l))!!m
a+b=[[0..]!!a..]!!b
a-b=let n=[0..]!!a;m=[0..]!!b in
    case [n..m] of
      [] ->   x[m..n][0..]
      l  -> -(x l    [0..])
add('-':x)('-':y)= -(r x+r y)
add('-':x)y=r y-r x
add x('-':y)=r x-r y
add x y=x+y
main=do a<-getLine;b<-getLine;print(add a b)

我仍然有文字数字和字符(我用的0'0''-'),以及[a..][a..b]这是非常有用的。而且我有一元-,但是我可以没有。

我重新++实现rreverse),并定义tts它们是tailtailsx a b返回的n第th个元素b,其中n的长度为a负1。x通常可以定义为snd.last.zip。该函数d获取一个列表,并返回一个列表,其中包含来自那些位置的元素(是十的倍数)。l!!s返回的n第th个元素l,其中s是的反向字符串表示形式n+以整数形式返回两个自然数之和,即以相反的字符串形式给出的两个自然数之和-add以整数形式返回以字符串形式给出的两个可能为负的整数之和。

我想知道这是否与Ben的想法有些相似。


是的,几乎相同的想法。对文字进行模式匹配以获取相等性测试和分支,列出枚举语法以获取递增形式。我很惊讶地发现:,即使NoImplicitPrelude没有导入任何东西,它的范围也是如此。


7

Wheat Wizard编写的Python 2(第四次迭代)

import sys
if set("".join(open(__file__).read().split('\n')[4:]))-set(' &)(,.:[]a`cdfijmonrt~'):sys.setrecursionlimit(1)
for m in sys.modules:sys.modules[m]=None
del sys;f=lambda\
c,d:(`int([]in[])`[:[]in[]]).join([((c)and`dict([((int([]in[])),(int([]in[])))])`[(int([]in[[]])):][(int([]in[[]]))].join([`dict([((int([]in[])),(int([]in[])))])`[(int([]in[]))],`dict([((int([]in[])),c)])`[(int([]in[[]])):][(int([]in[[]])):][(int([]in[[]])):][(int([]in[[]])):]])or`int([]in[])`[:[]in[]]).format((int([]in[]))),((d)and`dict([((int([]in[])),(int([]in[])))])`[(int([]in[[]])):][(int([]in[[]]))].join([`dict([((int([]in[])),(int([]in[])))])`[(int([]in[]))],`dict([((int([]in[])),d)])`[(int([]in[[]])):][(int([]in[[]])):][(int([]in[[]])):][(int([]in[[]])):]])or`int([]in[])`[:[]in[]]).format((int([]in[]))),`(int([]in[]))`]).rfind(`(int([]in[]))`)

在线尝试!

没有漏洞利用,只是一个仅使用characters ' &)(,.:[]a`cdfijmonrt~'(实际上是'(),.:[]`acdfijmnort')添加的功能。

我没有试图使它简短。我只是为中间值(如0和空字符串)编写了子表达式,并用字符串替换了这些表达式。

def f(c,d):
	FALSE = []in[]
	TRUE = []in[[]]
	ZERO = int([]in[])
	ONE = int(TRUE)
	EMPTY = `int([]in[])`[:[]in[]]
	ZERO_STR = `ZERO`
	ONE_STR = `ONE`

	ZERO_DICT = dict([(ZERO,ZERO)])
	ZERO_DICT_STR = `ZERO_DICT`

	OPEN_BRACE = ZERO_DICT_STR[ZERO]
	COLON = ZERO_DICT_STR[ONE:][ONE]
	CLOSE_BRACE = ZERO_DICT_STR[ONE:][ONE:][ONE:][ONE:][ONE]

	C_STR = `c`
	D_STR = `d`

	FORMAT_STR_C = ''.join([OPEN_BRACE, ZERO_STR, COLON, C_STR, CLOSE_BRACE])
	FORMAT_STR_D = ''.join([OPEN_BRACE, ZERO_STR, COLON, D_STR, CLOSE_BRACE])

	LENGTH_C_STR = c and FORMAT_STR_C.format(ONE_STR) or EMPTY
	LENGTH_D_STR = d and FORMAT_STR_D.format(ONE_STR) or EMPTY

	TOTAL_STR = EMPTY.join([LENGTH_C_STR, LENGTH_D_STR, ZERO_STR])
	RESULT = TOTAL_STR.find(ZERO_STR)

	return RESULT

在线尝试!

核心思想是字符串格式'{0:5}'.format('1')将数字零填充为5like 的长度'1 '。通过使用连接两个这样的字符串''.join,它们的长度总和就是输入数字的总和。然后,我们将a拖到0末尾并调用.find()最终位置,即总和。

'{0:5}'要格式化的字符串是通过{:}从用创建的字典的字符串reprs中提取字符来产生的dict。每个连续被加数的字符串repr放置在5所在的位置。我想使用像{0:5}自己一样的字典,但是它的代表包括一个使它混乱的空间。

输入0会弄乱整个过程,因为字符串sub的最小长度为1。and/or在这种情况下,我们使用带有的子字符串来提供空字符串。


1
这与我的初衷完全不同,我希望看到一个解释。
小麦巫师

您可以打高尔夫球所有int([]in[])简单地int()因为他们所输出0
价值油墨


5

x86 16位实模式汇编,作者约书亚

    int  0x3                  ; <---  this is the "robber" portion

    ; -- begin code to print numbers in real-mode asm using ROM BIOS video interrupts --
    add  dx, cx               ; add input values together
    mov  ax, dx               ; move result into AX
    push WORD 0xB800
    pop  ds                   ; DS == starting address of text-mode video buffer
    xor  cx, cx               ; digit counter
    xor  di, di               ; position counter
    mov  bx, 0xA              ; divisor

    test ax, ax               ; is number negative?
    jns  .GetDigits
    neg  ax                   ; convert negative number to positive
    mov  WORD ds:[di], 0x4F2D ; output leading negative sign, in white-on-red
    add  di, 2                ; increment position counter

.GetDigits:
    xor  dx, dx
    div  bx                   ; divide DX:AX by 10 (AX == quotient, DX == remainder)
    push dx                   ; push digit onto stack
    inc  cx                   ; increment digit counter
    test ax, ax
    jnz  .GetDigits           ; keep looping until we've got 'em all

.PrintDigits:
    pop  dx                   ; get digit off of stack
    dec  cx                   ; decrement digit counter
    mov  dh, 0x4F             ; high byte: color attribute (white-on-red)
    add  dl, 0x30             ; low  byte: convert to ASCII
    mov  WORD ds:[di], dx     ; output digit
    add  di, 2                ; increment position counter
    test cx, cx
    jnz  .PrintDigits         ; keep looping until we've printed 'em all

    cli
    hlt

调试转储代码的屏幕截图,以及左上角的输出

说明:

约书亚代码引入的“损坏”是陷阱标志(TF)的设置,该标志使CPU进入单步模式。这意味着在CPU以1类中断停止(陷阱)之前,一次只能执行一条指令。这就是允许调试器实现代码的单步执行的功能—在那里很方便,但是如果您想在调试器的上下文之外运行代码,则可以使用真正的PITA!

下面的代码部分打开了陷阱标志:

pushf               ; push the FLAGS register onto the top of the stack
mov bp, sp          ; load the pointer to the top of the stack into BP
or word [bp], 256   ; bitwise-OR the WORD at the top of the stack (the copy of FLAGS)
                    ;  with 0x100, which turns on bit 8 (TF)
popf                ; pop the modified flags back off the stack into FLAGS

陷阱标志的实现意味着我们有机会在CPU陷阱之前恰好执行一条指令,即在POPF此之后立即执行的一条指令。因此,我们需要计算这一数字。

窍门是INT 3调用中断号3 的指令。有两个原因可以使代码“中断”代码:

  1. 陷阱标志在中断处理程序中被清除。这只是英特尔设计的一部分,但是大概是出于基本的理智考虑。请记住,陷阱标志的实现是在执行每条指令后调用类型1中断,因此,如果清除TF ,则其本身INT 1将触发中断-它将一直向下中断。另外,将中断清除为TF只会使调试代码更容易,就像IDE自动将对函数的调用移开一样。

  2. 中断的工作方式与far基本上相同CALL。它们调用其地址存储在全局中断向量表中相应位置的中断处理程序。由于该表从address开始0x0000:0000,并以4字节segment:offset格式存储,因此计算地址的过程非常简单,只需将中断向量/中断数乘以4。在这种情况下,我们调用中断3,因此它将为4×3 = 12。

    …您会注意到,约书亚为我们精心设置了此设置。在启用陷阱标志之前,他具有以下代码:

    mov  di, 12
    mov  [di], si
    mov  [di + 2], bp
    

    0x0000:000C(的中断处理程序INT 3)设置为BP:SI。那意味着每当INT 3调用,它都会将FLAGS寄存器压入堆栈,后跟返回地址,然后跳转到BP:SI,这使我们可以在陷阱标志关闭的情况下再次开始执行代码。

之后都下坡了 INT 3。我们要做的就是将两个数字加在一起并打印结果。除了在汇编语言中不像在其他语言中那样简单之外,这是花费大量代码的地方。

约书亚允许强盗指定他想要的任何I / O机制,因此我采用了一种简单的方法,即假定将值传递给DXand CX寄存器。这是合理的,因为这些都不会被他的“序言”代码所淹没。

然后通过将ASCII字节直接存储到视频存储器中来完成输出。视频缓冲区始于0xB800:0000文本模式CGA,EGA和/或VGA,因此我们从那里开始打印。格式为:低字节为字符,高字节为color属性。这意味着每个字符的偏移量均为2字节。我们只需要遍历数字(以10为基数)中的每个数字,将它们转换为ASCII,然后一次将它们打印到屏幕上。是的,这是一个很多代码。没有库函数可以帮助我们使用汇编语言。几乎可以肯定,这可以进一步优化,但是我对它的工作感到厌倦了。

显示输出后,允许代码崩溃或执行任何操作,因此我们只需清除中断并暂停CPU。


我很困惑;我无法弄清楚它是如何通过BP:SP + 1的hlt指令的。
约书亚记

@Joshua Hmm,这是一个好点。我什至没有想到。逐步执行Debug中的代码,我执行INT 3并立即返回到它后面的指令,因此我随手进行了。也许与我的测试环境有关?CLI只会禁用硬件中断,但是即使它超过HLT,您也会认为它会失败并在l此后立即执行代码。
科迪·格雷

哦,你只是一步。是的,可以做到。我要仔细检查,但我认为我上传了乱码。
约书亚

我还进行了单步测试。没有不同。这是在VM Virtualbox中最新的FreeDOS上。我有可用的真实硬件,但不想上电。@Joshua
Cody Gray

好吧,那您显然已经破解了。也许您找到了提高NMI的方法。
约书亚


4

Python 3中ppperry第二个挑战

哇,这很有趣!我很喜欢解决这个问题。

编辑:好的,我修复了它。看来这些类在TIO上的子类列表中的索引与在我的计算机上的索引不同,因此我使这两种方法都适用,并添加了一个TIO。

import sys
for mod in sys.modules.values():mod.__dict__.clear()
1+1

# My code begins here
str = "Hello!".__class__
int = (37).__class__
object = str.__base__

def find_subclass(superclass, name):
	for cls in superclass.__subclasses__():
		if cls.__name__ == name:
			return cls

_io_IOBase      = find_subclass(object, '_IOBase')        # <class '_io._IOBase'>
_io_RawIOBase   = find_subclass(_io_IOBase, '_RawIOBase') # <class '_io._RawIOBase'>
_ioFileIO       = find_subclass(_io_RawIOBase, 'FileIO')  # <class '_io.FileIO'>
stdout = _ioFileIO('stdout', mode='w', opener=lambda name,flags: 1) # FD for stdout is 1
stdin  = _ioFileIO('stdin',  mode='r', opener=lambda name,flags: 0) # FD for stdin is 0
nums = str(stdin.read(), encoding='utf-8').split()
stdout.write(str(int(nums[0]) + int(nums[1])).encode('utf-8') + b'\n')
stdout.flush()

在线尝试!


我得到一个错误。sys.excepthook is missing
Rɪᴋᴇʀ

嗯...为我工作。您得到的真正错误是什么?(发生这种情况是因为ppperry的代码破坏了几乎所有东西,包括知道如何显示异常,所以这是sys.excepthook,但是其中确实有一个真正的原因。)
zbw

没关系,真正的错误是IndexError('list index out of range',)。与的定义一致_io_RawIOBase
Rɪᴋᴇʀ

问题在于子类的顺序不固定。_io_IOBase = [cls for cls in object.__subclasses__() if cls.__name__ == '_IOBase'][0]应该到处工作。
丹尼斯,

@Dennis Yep,我意识到这一点,并对其进行了修复。现在可以在TIO上使用!
zbw

4

Haskellzbw

{-#OPTIONS_GHC -fth -w#-}
module M where

import Language.Haskell.TH.Syntax
import System.IO.Unsafe

a = $( runIO $ TupE[] <$
              do x <- readLn :: IO Integer
                 y <- readLn
                 print $ x + y )

无法在运行时运行代码?在编译时运行它!

这很有趣,在挑战之前我还不知道模板haskell。



3

Wheat Wizard编写的Python 2

import sys
c="".join(open(__file__).read().split('\n')[4:])
if set(c)-set(' &)(,.:[]a`cdfijmonrt~')or"import"in c:sys.setrecursionlimit(1)
sys.modules['sys'],sys.modules['os']=None,None;del sys;f=lambda\
a,b:a+b
__import__('sysconfig').__dict__['os'].__dict__['sys'].setrecursionlimit(1000)
print(f(1,2))

在线尝试!


事实证明,这比我想象的要难。
小麦巫师

3

Java by LordFarquaad

在源代码级别上阻止对对象的访问确实很聪明(测试时很烦人),做得好!

public class java {
  public static void main(String[] s) {
    //there is no executable code in snippet one.
    //your code here.
    try {
      ClassLoader cl = ClassLoader.getSystemClassLoader();
      Object in = cl.loadClass("java.lang.System").getDeclaredField("in").get(null);
      Object out = cl.loadClass("java.lang.System").getDeclaredField("out").get(null);
      Object scanner = cl.loadClass("java.util.Scanner").getConstructor(cl.loadClass("java.io.InputStream")).newInstance(in);
      int i = (Integer)cl.loadClass("java.util.Scanner").getMethod("nextInt").invoke(scanner);
      int j = (Integer)cl.loadClass("java.util.Scanner").getMethod("nextInt").invoke(scanner);
      cl.loadClass("java.io.PrintStream").getMethod("println", Object.class).invoke(out, i+j);
    } catch (Exception e) {
      e.printStackTrace();
    }
  }
  class Class {}
  class Method {}
  class System {}
  class FileDescriptor {}
  class Logger {}
  class Runtime {}
  class Scanner {}
}

真好!如果ClassLoader被遮盖了怎么办?
雅各布

1
@JakobCornell "".getClass().getClassLoader()。阴影通常只是您必须考虑一次的问题,然后就可以了。您甚至可以遮蔽Object,我仍然可以解决此问题。好的,您可能会强迫我进入1kb的解决方案,但这是可能的。
奥利维尔·格雷戈尔


3

通知7,Ilmari Karonen

am昧滥用歧义名词...我的代码以factory is a room。上一行是警察的代码。键入add 1 and 1拿到2,例如。

For reading a command: Rule fails

factory is a room.
The adder one is a thing. The adder two is a thing. The adder one is in factory. The adder two is in factory.
Before reading a command: change the text of the player's command to "examine adder"

For printing a parser error: 
    if the player's command includes "add [number] ":
        let N be the number understood;
        if the player's command includes "and [number]":
            say the number understood plus N;

2

爪哇,罗马·格拉夫

public class Main {
    public static void main(String... args){
        System.setOut(null);
        System.setErr(null);

        System.setOut(new java.io.PrintStream(new java.io.FileOutputStream(java.io.FileDescriptor.out)));
        System.setErr(new java.io.PrintStream(new java.io.FileOutputStream(java.io.FileDescriptor.err)));
        System.out.println("This");
        System.err.println("works");
    }
}

设置stdoutstderr返回其初始值。

我相信我可以使用完全限定的名称而不是导入的名称,如果我错了,请纠正我(这是我在这里的第一篇文章。)这也可以使用反射来完成。

编辑:这是仅使用的反射解决方案java.lang.reflect.*

import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.Modifier;

public class Test {
    public static void main(String... args) {
        System.setOut(null);
        System.setErr(null);

        try {
            Class<?> psClass = Class.forName("java.io.PrintStream");
            Class<?> fsClass = Class.forName("java.io.FileOutputStream");
            Class<?> osClass = Class.forName("java.io.OutputStream");
            Class<?> fdClass = Class.forName("java.io.FileDescriptor");
            Class<System> sClass = System.class;
            Constructor psCtor = psClass.getConstructor(osClass);
            Constructor fsCtor = fsClass.getConstructor(fdClass);

            Field modifiersField = Field.class.getDeclaredField("modifiers");
            modifiersField.setAccessible(true);

            Object sout = psCtor.newInstance(fsCtor.newInstance(fdClass.getDeclaredField("out").get(null)));
            Field outField = sClass.getDeclaredField("out");
            modifiersField.setInt(outField, outField.getModifiers() & ~Modifier.FINAL);
            outField.set(null, sout);

            Object serr = psCtor.newInstance(fsCtor.newInstance(fdClass.getDeclaredField("err").get(null)));
            Field errField = sClass.getDeclaredField("err");
            modifiersField.setInt(errField, outField.getModifiers() & ~Modifier.FINAL);
            errField.set(null, serr);

            System.out.println("This");
            System.err.println("works");
        } catch (Exception ignore) {
        }
    }
}

是的,stdinstdoutstderr存储在别处!您甚至不需要使用setOutsetErr因为您可以简单地使用PrintStream Direct。
奥利维尔·格雷戈尔(OlivierGrégoire)

添加了反射解决方案,以及我认为这是最初的预期
Moira

2

Daniel Franklin撰写的JavaScript

location="data:text/html;base64,PHNjcmlwdD5jb25zb2xlLmxvZygxKnByb21wdCgpKzEqcHJvbXB0KCkpPC9zY3JpcHQ+"

这可能被认为是一个有点欺骗的解决方案,但是即使我也收到警告说,它在Chromium 59 / Linux上也确实适用于我:

即将发布的版本将阻止内容发起的顶部框架对数据URL的导航。有关更多信息,请参见https://goo.gl/BaZAea

附言 这是另一个裂缝,这次没有警告:

Node.prototype.removeChild=function(){}
document.body.innerHTML='<iframe src="data:text/html;base64,PHNjcmlwdD5jb25zb2xlLmxvZygxKnByb21wdCgpKzEqcHJvbXB0KCkpPC9zY3JpcHQ+"/>'

我认为prompt()- -prompt()可以节省两个字节
Marie

2

OlivierGrégoire的Java 8

一个非常冗长的破解,可以应对一个非常冗长的挑战。:)间接处理无法命名的类的痛苦是显而易见的。

    try {
      Class loader = Class.class.getMethod("getClassLoader").getReturnType();
      Object sysLoader = loader.getMethod("getSystemClassLoader").invoke(null);
      Class integer = (Class) loader.getMethod("loadClass", String.class).invoke(sysLoader, "java.lang.Integer");
      Class system  = (Class) loader.getMethod("loadClass", String.class).invoke(sysLoader, "java.lang.System");
      Class filein  = (Class) loader.getMethod("loadClass", String.class).invoke(sysLoader, "java.io.FileInputStream");

      InputStream cmd = (InputStream) filein.getConstructor(String.class).newInstance("/proc/self/cmdline");
      byte[] buf = new byte[65536];
      int len = cmd.read(buf);
      String[] args = new String(buf, 0, len).split("\0");
      
      int a = (int) integer.getMethod("parseInt", String.class).invoke(null, args[args.length-2]);
      int b = (int) integer.getMethod("parseInt", String.class).invoke(null, args[args.length-1]);

      Object out = system.getField("out").get(null);
      out.getClass().getMethod("println", String.class).invoke(out, ""+(a+b));
    } catch (Exception e) {
      throw new Error(e);
    }
  }
}
class ClassLoader {
  public static ClassLoader getSystemClassLoader() { return new ClassLoader(); }
  public ClassLoader loadClass(String s) { return this; }
  public ClassLoader getDeclaredField(String s) { return this; }
  public ClassLoader getMethod(String s) { return this; }
  public ClassLoader getMethod(String s, Class c) { return this; }
  public InputStream get (Object o) { return new FakeInputStream(); }
  public void invoke(Object o, SecurityManager sm) {}
}
class FakeInputStream extends InputStream {
  public int read() {
    return -1;

在线尝试!

附言 这是我以前的尝试,写在Olivier澄清输入是通过命令行参数进行之前。与上面的破解不同,该破解不是特定于Linux的。

    try {
      Class loader = Class.class.getMethod("getClassLoader").getReturnType();
      Object sysLoader = loader.getMethod("getSystemClassLoader").invoke(null);
      Class integer = (Class) loader.getMethod("loadClass", String.class).invoke(sysLoader, "java.lang.Integer");
      Class system  = (Class) loader.getMethod("loadClass", String.class).invoke(sysLoader, "java.lang.System");
      Class scanner = (Class) loader.getMethod("loadClass", String.class).invoke(sysLoader, "java.util.Scanner");

      InputStream in = (InputStream) system.getField("in").get(null);
      Object scanIn = scanner.getConstructor(InputStream.class).newInstance(in);

      int a = (int) scanner.getMethod("nextInt").invoke(scanIn);
      int b = (int) scanner.getMethod("nextInt").invoke(scanIn);

      Object out = system.getField("out").get(null);
      out.getClass().getMethod("println", String.class).invoke(out, ""+(a+b));
    } catch (Exception e) {
      throw new Error(e);
    }
  }
}
class ClassLoader {
  public static ClassLoader getSystemClassLoader() { return new ClassLoader(); }
  public ClassLoader loadClass(String s) { return this; }
  public ClassLoader getDeclaredField(String s) { return this; }
  public ClassLoader getMethod(String s) { return this; }
  public ClassLoader getMethod(String s, Class c) { return this; }
  public InputStream get (Object o) { return new FakeInputStream(); }
  public void invoke(Object o, SecurityManager sm) {}
}
class FakeInputStream extends InputStream {
  public int read() {
    return -1;

在线尝试!


如果您愿意,这是我的新挑战
奥利维尔·格雷戈尔

只是为了在此处编写它:由于我无权说“ Gotcha!它仅在一个系统上工作”,因此,此答案不能完全解决挑战,因为它仅在Linux上工作。
奥利维尔·格雷戈尔

@OlivierGrégoire:FWIW,我确实提出了一个替代解决方案,该解决方案String[] args = ((String) system.getMethod("getProperty", String.class).invoke(null, "sun.java.command")).split(" ");不是特定于Linux的,但是确实使用了某些JVM设置的未记录属性。
Ilmari Karonen

那仍然不是便携式的。例如,它不适用于IBM Java。但是,这是一个好主意!:)
OlivierGrégoire17年

2

raznagul的C#(.NET Core)

我认为这不是预期的解决方案。

int a;
int b;

using (var f = new System.IO.FileStream("/dev/stdin", System.IO.FileMode.Open, System.IO.FileAccess.Read))
{
using (var fs = new System.IO.StreamReader(f))
{
a = int.Parse(fs.ReadLine());
b = int.Parse(fs.ReadLine());
}
}
using (var f = new System.IO.FileStream("/dev/stdout", System.IO.FileMode.Open, System.IO.FileAccess.Write))
{
using (var fs = new System.IO.StreamWriter(f))
{
fs.WriteLine((a + b).ToString());
}
}

/dev/std*那里不错的把戏。我最初的目标是采用类似的方法,但是在没有访问System.Console的情况下找不到任何简单的方法来打开流以进行stdin / out,因此我选择了反射。当然,您的解决方案大概只能在具有适当/dev条目的Linux和其他Unixish系统上运行,但是raznagul并未明确表示必须在Windows上运行。它确实适用于TIO。
Ilmari Karonen

@IlmariKaronen:确实;而我的计划是Windows是否会在TIO上失败。
约书亚记

1

Java,由racer290

这是一个基本的忽略,即staticmain方法之前调用初始化程序。这是一个不错的尝试:一开始我很沮丧throw new Error(),但是最后找到了路;)

public static void main(String[] args) throws IllegalArgumentException, IllegalAccessException, NoSuchFieldException, SecurityException, NoSuchMethodException {

    try {

        System.class.getField("in").set(null, null);
        System.class.getField("out").set(null, null);
        System.class.getField("err").set(null, null);

        System.class.getMethod("getSecurityManager", new Class[0]).setAccessible(false);

        File.class.getField("fs").set(null, null);

        for (Method m : Class.class.getMethods()) {

            m.setAccessible(false);

        }

        SecurityManager mngr = new SecurityManager() {

            @Override
            public void checkPermission(Permission p) {

                throw new Error("Muahaha!");

            }

            @Override
            public void checkLink(String s) {

                throw new Error("Not this way, my friend!");

            }

        };

        System.setSecurityManager(mngr);

    } catch (Throwable t) {

    }
    // My code here, I guess...
} static {
  java.util.Scanner s = new java.util.Scanner(System.in);
  System.out.println(s.nextInt()+s.nextInt());

    // End of my code
}

System.out.println("Hello World!");不添加两个整数吗?..“ 2.一个将两个数字作为输入的代码片段,将它们加在一起并输出它们的和。即使运行第一个片段,该片段也必须正确运行。将它们组合在一起,必须形成一个将两个数字相加的完整程序,或者定义一个将两个数字相加的函数。此
摘要

@KevinCruijssen我能说什么?如果警察不履行职责,我为什么要履行职责?:P
OlivierGrégoire17年

1
@KevinCruijssen在这里,我在其中添加了一个内容。
奥利维尔·格雷戈尔(OlivierGrégoire),

@OlivierGrégoire的全部要点是防止相加,无论是通过取消输入,相加还是输出的功能。
斯蒂芬,

@StepHen Yep,之后我了解了一点。检查我的其他3条裂缝,看看我终于明白了;)
OlivierGrégoire17年

1

Java by Kevin Cruijssen

结构良好。许多代码可以使任何人正确地思考如何解决这一挑战。我想“事后输入代码”是一个很大的暗示。

import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.FileDescriptor;
import java.io.FilePermission;
import java.io.PrintStream;
import java.lang.reflect.Field;
import java.lang.reflect.Modifier;

public class Main {

  // Put everything in a static block so it is run before the static main method 
  // and any trailing (static) initializer-blocks:
  static {
    try {
      initializing();
    } catch (final Exception e) {
    }
  }

  static void initializing() throws Exception {
    // Overwrite System.out, System.err and System.in:
    System.setOut(new PrintStream(new ByteArrayOutputStream()));
    System.setErr(new PrintStream(new ByteArrayOutputStream()));
    System.setIn(new ByteArrayInputStream(new byte[0]));

    // Enable reflection for System.out, System.err and System.in:
    final Field modifiersField = Field.class.getDeclaredField("modifiers");
    modifiersField.setAccessible(true);
    final Class<?> fdClass = java.io.FileDescriptor.class;
    final Field outField = fdClass.getDeclaredField("out");
    outField.setAccessible(true);
    modifiersField.setInt(outField, outField.getModifiers() & ~Modifier.FINAL);
    final Field errField = fdClass.getDeclaredField("err");
    errField.setAccessible(true);
    modifiersField.setInt(errField, errField.getModifiers() & ~Modifier.FINAL);
    final Field inField = fdClass.getDeclaredField("in");
    inField.setAccessible(true);
    modifiersField.setInt(inField, inField.getModifiers() & ~Modifier.FINAL);

    // Replace existing System.out FileDescriptor with a new (useless) one:
    outField.set(null, new FileDescriptor());
    // Replace existing System.err FileDescriptor with a new (useless) one:
    errField.set(null, new FileDescriptor());
    // Replace existing System.in FileDescriptor with a new (useless) one:
    inField.set(null, new FileDescriptor());

    // Disable reflection for System.out, System.err, System.in again:
    modifiersField.setInt(outField, outField.getModifiers() & ~Modifier.FINAL);
    modifiersField.setInt(errField, errField.getModifiers() & ~Modifier.FINAL);
    modifiersField.setInt(inField, inField.getModifiers() & ~Modifier.FINAL);
    inField.setAccessible(false);
    errField.setAccessible(false);
    outField.setAccessible(false);
    modifiersField.setAccessible(false);

    // Overwrite the SecurityManager:
    System.setSecurityManager(new SecurityManager() {

      private boolean exitAllowed = false;

      @Override
      public void checkExec(final String cmd) {
        throw new SecurityException();
      }

      @Override
      public void checkPermission(final java.security.Permission perm) {
        final String name = perm.getName();
        // You're not allowed to read/write files:
        if (name.equals("setIO") || name.equals("writeFileDescriptor")
            || name.equals("readFileDescriptor")
            || ((perm instanceof FilePermission) && name.startsWith("/proc/self/fd/"))) {
          throw new SecurityException();
        }
        // You're not allowed to overwrite the Security settings:
        if (name.equals("setSecurityManager") || name.equals("suppressAccessChecks")) {
          throw new SecurityException();
        }
        // You're not allowed to use reflection anymore:
        if (name.equals("getModifiers") || name.equals("get") || name.equals("set")
            || name.equals("setBoolean") || name.equals("setByte")
            || name.equals("setChar") || name.equals("setShort") || name.equals("setInt")
            || name.equals("setLong") || name.equals("setFloat") || name.equals("setDouble")
            || name.equals("setFieldAccessor") || name.equals("setFieldAccessor")) {
          throw new SecurityException();
        }
        // When you try to leave the current VM it will stop the program:
        if (name.startsWith("exitVM") && !this.exitAllowed) {
          this.exitAllowed = true;
          System.exit(0);
        }

        // You know what, nothing is allowed!
        throw new SecurityException("Mhuahahahaha!");
      }
    });
  }

  public static void main(String[] args) {
    // Overwritting all given arguments:
    args = new String[0];

    // Exit the program before you can do anything!
    System.exit(0);
  }
}

class System {
  static void exit(int n) {}
  static void setSecurityManager(SecurityManager sm) {
    java.util.Scanner scanner =new java.util.Scanner(java.lang.System.in);
    java.lang.System.out.println(scanner.nextInt() + scanner.nextInt());
  }
  static void setIn(Object o) {}
  static void setOut(Object o) {}
  static void setErr(Object o) {}
}

在这里尝试。


速度很快。那确实是我确切的解决方案!做得好。:)编辑:随意添加TIO链接,如果您不介意的话。
凯文·克鲁伊森

好吧,当您发布赛车时,我实际上是在与Racer 290的挑战一起工作的。而且,不,我不介意。
奥利维尔·格雷戈尔(OlivierGrégoire),


1

cQuentsStep Hen,3个字节

+BC

在线尝试!

进行了很多与Step Hen的交谈以弄清楚他的奇怪语言是如何工作的,但总之:

他的密码是#|1,1:A#|1,1是默认输入,表示给程序的任何输入都附加2 1。(即,如果您通过47和53,则输入为[47, 53, 1, 1]

:只需设置模式,n如果n已设置,它将输出序列中的第一个项目,否则输出整个序列。

最终A获得第一个输入。

因为我们有4个输入[47, 53, 1, 1],所以添加BC到末尾也将获取第二个和第三个输入,第四个输入隐式变为n

因为我们的序列是ABC,所以它是代数解析的,这意味着它变为A*B*C。我们不想要那样,但是如果我们+在A和B之间插入a ,它将变为A+B*C,其中AB是我们的输入,并且C是1。


how the hell his weird language works也许一旦我完成它,它可能会更有意义
Stephen

@StepHen不要误会我的意思,这是一种简洁的语言,但是像地狱一样很奇怪
Skidsdev '17

1

raznagul的C#(.NET Core)

var console = typeof(System.ConsoleCancelEventArgs).Assembly.GetType("System.Console");
var readLine = console.GetMethod("ReadLine");
var writeLine = console.GetMethod("WriteLine", new Type[] { typeof(int) });
int a = Int32.Parse((string) readLine.Invoke(null, null));
int b = Int32.Parse((string) readLine.Invoke(null, null));
writeLine.Invoke(null, new object[] {a+b});

在线尝试!

如果我实际上知道任何C#,这本来可以花费更少的时间。但是,通过浏览文档和Jon Skeet的帮助,我设法将一些有用的东西拼凑在一起。


1

Vim挑战@DJMcMayhem

已经有一段时间了,因为我无法退出vim,这是我的解决方案(请注意,它远远超过23字节,因此可能不是预期的解决方案):

i
echo "
12
39
"|awk '{s'$(python -c "print(''.join([chr(43),chr(61)]))")'$1} END {print s}'<Esc>vgg!bash

在线尝试!

这个想法只是将两个整数awk通过管道传递给via bash,因为=+被禁用,我不得不使用一个小的解决方法。该awk行扩展为:

"|awk '{s'+='} END {print s}

编辑:最初的意图是输入已经在缓冲区中,但这并不困难-主要困难是使加法有效。

这是@DJMcMayhem建议的解决方案:在线尝试!


我认为您无法[insert your number here]在插入模式下进行操作。相反,它已经在缓冲区中了。但是您可以使用解决该问题Oecho "<esc>Go"|awk...,因此我认为这很重要。做得很好!这不是我想到的(我希望获得一个纯vim的答案),所以我可能会发布一个新的答案来修补外部命令和!
DJMcMayhem

1
这是一个采用正确输入方式的示例:在线尝试!
DJMcMayhem

是的,我不确定输入内容。但是解决方法确实很容易。我将以官方方式进行编辑。
ბიმო

顺便说一句,我的补丁方法在这里:codegolf.stackexchange.com/a/133441/31716
DJMcMayhem

1

Poke Java 7

  }
  public static void main(java.lang.String[]a) throws Exception {
    int x = Integer.parseInt(a[0]);
    int y = Integer.parseInt(a[1]);
    java.lang.System.out.println(x+y);
  }
}
class String {
}
class System {
  public static java.io.InputStream in = new java.io.ByteArrayInputStream(new byte[0]), out = in, err = in;
  public static void setProperties (Object o) {

在线尝试!

没有Linux特有的技巧需要,只是简单的不合格的掩蔽StringSystem类名。这可能不是预期的解决方案,但它可以工作。



1

RProgN2,来自@ATaco

"+-/*÷^"{²[[\=};
{"D"=11{‹1D&¬\D›]"D"=}:]1\2\Š1{[\D‹|"D"=};D¬{1"D"=1\2\Š1{[D‹"D"=};}{[}?D}"~"={"d"="g"=g~d&gd~&|}"±"={"H"="I"=11{‹H1&I1&±\H›"H"=I›"I"=H¬¬I¬¬|}:1\2\Š1{[H‹|"H"=};H}"×"={"J"="K"=1{JK&‹JK×"K"=]"J"=}:JK|}"+"=

在线尝试!

到目前为止,这并不是我能给出的最佳答案,但是它允许再次将数字相加。如果我确实经过了适当的堆栈处理,我可能会打高尔夫球很多,但是到目前为止,我对答案很满意。

在ATaco的原始职位上,他实际上只是重新分配了所有主要的算术运算符以销毁其输入。为了解决这个问题,我重新定义了二进制操作中的加法,这很麻烦,因为RProgN2,没有二进制取反运算符或xor。

注意:如果要测试输入,则必须采用多于一位数字的形式 "XX..." n将其转换为实际数字,因为RProgN2会按原样使用每个字符,除非它是概念或字符串。编辑:@ATaco指出,在多位数数字之前添加“ $”将执行相同的操作。

编辑:这是我的解决方案的逻辑。如您所见,绝对不是最完善的代码,但是它可以工作。

{"D"=11{‹1D&¬\D›]"D"=}:]1\2\Š1{[\D‹|"D"=};D¬{1"D"=1\2\Š1{[D‹"D"=};}{[}?D}"~"= # Defines the ~ operator which negates a number
{"D"=                                                                   }     # Remove the top of the stack and assign D with the popped value
     11                                                                       # Push 2 1's to the stack.  The first is used as a counter, the second if the initial truthy value for the loop
       {             }:                                                       # Start a while loop if the top of the stack (popped) is truthy (removes final falsey value)
        ‹                                                                     # Left shift the counter variable
         1D&¬                                                                 # Push negation of last bit of D
             \                                                                # Swap the counter (index 1) and the negated bit (index 0)
              D›]"D"=                                                         # Push D, right shift it, duplicate the value on the stack, then pop and assign the top to D
                       ]1\                                                    # Duplicate the counter, push 1, and swap the counter to the top of the stack
                          2\Š                                                 # Push 2, swap with the counter, then take the log (log_2(counter))
                             1{         };                                    # Run the for loop "for (i=1;i<=log_2(counter);i+=1)"
                               [\                                             # Pop off i, then swap the original counter with the next bit to append
                                 D‹|"D"=                                      # Left shift D, or it with the next bit, then assign D the new value
                                          D¬                                  # Need to check if D was 0 or not (in the case of 0b11...1~)
                                            {                     }{ }?       # Conditional on the truthiness of not D
                                             1"D"=                            # If D was 0, we assign it as 1, then start to bit shift it up
                                                  1\2\Š1{       };            # Same for loop as earlier since the original counter is still on the top of the stack
                                                         [D‹"D"=              # Pop off i, left shift D, then reassign it
                                                                    [         # Else D was non-zero, so just pop off the counter we've been carrying around
                                                                       D      # Push the final value to the top of the stack as a return
                                                                         "~"= # Assign the function between the {}'s to the character '~'

{"d"="g"=g~d&gd~&|}"±"=                                                       # Defines the ± operator which performs a single bit xor
{"d"="g"=         }                                                           # Assign d and g the first and second values on the stack respectively
         g~d&                                                                 # Push ~g&d to the top of the stack
             gd~&                                                             # Push g&~d to the top of the stack
                 |                                                            # Or the top 2 values giving us (~g&d)|(g&~d)
                   "±"=                                                       # Assign this function to the ± operator

{"H"="I"=11{‹H1&I1&±\H›"H"=I›"I"=H¬¬I¬¬|}:1\2\Š1{[H‹|"H"=};H}"×"=             # Defines the × operator which performs a full number xor
{"H"="I"=                                                   }                 # Store the top 2 stack values in H and I (in that order)
         11{                            }:                                    # Another while loop with the first one being a counter for later, and the second is our truthy value to start the loop
            ‹H1&I1&±                                                          # Left shift the counter, then push the bit xor of H's and I's lowest bit ((H&1)±(I&1) in infix notation)
                    \                                                         # Swap the calculated bit and the counter
                     H›"H"=I›"I"=                                             # Right shift both variables and store the values back in them
                                 H¬¬I¬¬|                                      # Effectively pushing the value (H!=0 | I != 0)
                                          1\2\Š1{        };                   # Same for loop as the ones above
                                                 [H‹|"H"=                     # Pop off the for loop counter, left shift H, or it with the next bit, and reassign
                                                           H                  # Push the final computed xor value to the top of the stack
                                                             "×"=             # Assign this whole function to the × operator

{"J"="K"=1{JK&‹JK×"K"=]"J"=}:JK|}"+"=                                         # Finally, a function redefining addition as the "+" operator
{"J"="K"=                       }                                             # Store the top 2 stack values in J and K respectively
         1{                }:                                                 # An initial truthy value to start the while loop and the loop itself
           JK&‹                                                               # Push (J&K)<<1 to the stack
               JK×                                                            # Compute the full xor of J and K (J^K in Python)
                  "K"=                                                        # Assign K the value of J xor K
                      ]"J"=                                                   # Duplicate (J&K)<<1 and assign 1 copy to J, leaving (J&K)<<1 as our while check (while ((J&K)<<1))
                             JK|                                              # Finally push the value J|K to the stack to get the addition
                                 "+"=                                         # Assign this function to the "+" operator, restoring it

56$46$12在数字

不知道 我只是看了看你的可调用对象,以弄清是什么东西。
阿诺德·帕尔默

由于这一挑战,我可能实际上写了一些文档。
ATaco

那太好了。我设法找到了RProgN的命令列表,但是却丢失了……而且它的作用很大,因为功能各不相同。我必须通过旧的RProgN教程页面和可调用的类来学习您的函数。即使现在还不清楚一切如何工作,还是很有趣。
阿诺德·帕尔默

1

的JavaScript(Node.js的)jrich,298个字节

我觉得这不是预期的解决方案,但如果做得很好,我花了一段时间试图弄清楚如何获得已声明函数的名称!:)

var p=process,f;(_=>{var w=p.stdout.write,n='f'+(Math.random()*1e7|0),l=1
f=p.stdout.write=a=>eval(`(function ${n}(a){while(l&&((typeof a)[0]!='s'||'f'+a!=n));a=l?l="":a;w.apply(p.stdout,arguments);})`)(a)})();
process.stderr.write.call(process.stdout,''+((0|process.argv[2])+(0|process.argv[3])));

在线尝试!


1
不是预期的解决方案,但是非常聪明!不错的+1破解
jrich,

@jrich是的,我想,可以随时进行修补,以确保我可以在预期的解决方案中再做一次!
Dom Hastings

哎呀……来不及了!我对您的解决方案的创造力感到满意!
jrich
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.