あなたの言語を*ほとんど*使用不可にします(強盗のスレッド)


31

このコメントに触発された...

投稿する前にこのチャレンジの仕様を固めるのを手伝ってくれたユーザー、Step HenWheat-Wizard、およびDennisに感謝します!

これが強盗のスレッドです!警官のスレッドについては、こちらをご覧ください


、この挑戦、あなたはそのようにプログラミング言語であることの満たし、当社の基準をあなたの言語は、もはやことになり、いくつかのコードを実行する使命を帯びています。その挑戦では、それは言語がもはやできないようにすることを意味します...

  • 数値の入出力を行う

  • 2つの数字を一緒に追加します

  • 特定の数が素数かどうかをテストします。

これは、 2つの異なる目的を持つ2つの異なる課題がある挑戦、警官は言語が作るいくつかのコードを記述しようとするほとんど使用不可能にし、強盗は警官を可能に隠された回避策を見つけようとします言語を回復します。

警官は2つのコードスニペットを記述します。

  1. 入出力や数値演算を行うための組み込み関数を削除するなど、言語をほとんど使用できなくするもの。このコードは、クラッシュまたは終了することはできません。このスニペットの最後にコードを追加することが可能であるべきであり、そのコードは評価されます。そして

  2. 2つの数値を入力として受け取り、それらを加算して合計を出力するコードスニペット。このスニペットは、最初のスニペットを実行した後でも正しく機能する必要があります。2つのスニペットを組み合わせる場合、2つの数字を追加する完全なプログラムを形成するか、2つの数字を追加する関数を定義する必要があります。このスニペットは、あいまいな動作に依存している可能性が高く、見つけるのは困難です。

警官は、入力および出力の標準的な方法も選択します。ただし、使用している形式(入力および出力)を正確に明らかにする必要があります。回答を解読するには、同じ入力/出力形式に従う必要があります。そうしないと、亀裂はカウントされません。

警官の答えは常に明らかにします

  • 最初のスニペット(明らかではない第二)。

  • 言語(マイナーバージョンを含む、ほとんどの提出物はおそらく奇妙なエッジケースに依存するため)

  • 関数か完全なプログラムかを含むIO形式。強盗、有効なクラックになるために同じ形式を使用する必要があります。

  • 答えが機能するために必要な奇妙なエッジケース。たとえば、Linuxのみ実行される、インターネット接続が必要です。

強盗として、警官の提出物の1つを見て、それを解読しようとする必要があります。スニペット2として機能する有効なスニペットを記述することにより、それをクラックすることができます(言語がほとんど使用できなくなった後、2つの数字を加算します)。これは、警官が最初に書いたものと同じスニペットである必要はありませ。回答をクラックしたら、このスレッドに回答としてコードを投稿し、警官の回答に対するコメントとして回答へのリンクを投稿します。次に、その投稿が編集され、クラックされていることを示します。

以下に例を示します。最初のスニペットでは、警官の答えとして次のpython 3プログラムが表示される場合があります。

Python 3

print=None

STDINから入力を受け取り、STDOUTに出力します

有効な2番目のスニペットは

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

これは、入力として2つの数値を受け取り、2つのスニペットを結合した場合でも合計を出力するため、有効です。たとえば、

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

これは彼らの答えに対する有効なクラックです。

警官の答えが1週間ひび割れていない場合、2番目のスニペットを編集して、答えが安全であることを示すことができます。安全に編集されたら、クラックを試みることはできなくなります。彼らが安全であると編集しない場合は、編集するまで続けようとするかもしれません。

強盗のスレッドの勝者は、最も多くの回答をクラックしたユーザーです。タイブレーカーは、Nクラックに達した時間です。(たとえば、2人の異なるユーザーがそれぞれ5つのひびを持っている場合、5番目のひびを最初に投稿したユーザーが勝者です)十分な時間が経過した後、私は勝者の回答を最も多く投票して受け入れます。

楽しむ!

ルールの説明

  • 最初のスニペットは、入力なしで正しく実行する必要があります。好きなものを出力できますが、この出力は無視されます。スニペットが完了すると、2番目のスニペットが正しく実行されます。

  • 回答を有効にするには、2番目のスニペットを実際に実行する必要があります。これは次のような答えを意味します

    import sys
    sys.exit()
    

    言語を壊さないので無効です。単に終了します。

  • 安全になった後、スコアは両方のスニペットのバイト数になります

  • これは、バックに行く仕事へのあなたの答えのために必要な任意の奇妙なエッジケースを明らかにしてくださいあなたの提出が十分な情報を含んでいなければなりません... 前に再現性があることが明らかにされた後に明らかにされています。これは、あなたの答えが安全になったら、あなたが編集することを意味します:ここに私の答えがあります。ああ、ところで、これはSolarisで実行した場合にのみ機能します。あなたの答えは無効であり、削除され、勝利の資格があるとはみなされません。

  • 2番目のスニペットは、合計を出力した後にクラッシュすることができます。出力がまだ正しい限り(たとえば、STDERRに出力することを選択し、クラッシュ情報を大量に取得する場合、これは無効です)

リーダーボード

これは、スコアと名前(アルファベット順)の順に並べられた、少なくとも1つのクラックを持つすべてのユーザーのリストです。クラックを送信する場合は、それに応じてスコアを更新してください。

#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

回答:


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。ここでXおよびYは追加する数値です。つまり、たとえば番号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

両方:申し訳ありませんが、これは2つの点にプラットフォーム依存の答えであるsun.awt.SecurityManager"sun.awt.command"プラットフォームに依存しているとされないのJavaの一部
オリビエグレゴワール

うん、割れた!:)意図された解決策はを通過することでしたSystem.getProperties().get("blah")(私はへのアクセスをブロックしただけなのでSystem.getProperty、ではありませんSystem.getProperties)が、これで十分です!よくやった!
オリビエグレゴワール

22

C(GCC / Linux)by Sisyphus

このスニペットは提供された関数を閉じ、新しい関数を開始します(クラシックコードインジェクション)。これcloseはfdを閉じる代わりに目的のコードを実行するように再定義します。

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

  exit(0);

20

Python、Wheat Wizardのソリューションはこちら

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
私はこれを見逃して愚かです
小麦ウィザード

@WheatWizard :)
HyperNeutrino

@wheatwizard目的のソリューションをまだ公開しないでください。私は思いますloooveこの問題を修正し、あなたの元の溶液とのより良い警官を見て。
DJMcMayhem

@Djmcmayhem私はおそらくデルシスで再投稿するつもりです。
小麦ウィザード

@WheatWizard覚えておいてos.sys、それが違いを生むなら:P
HyperNeutrino

15

ベンによるハスケル

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)と定義tしてtsいるされているtailtailsx a bn番目の要素を返します。bここでnは、aマイナス1の長さです。x通常はとして定義できsnd.last.zipます。この関数dはリストを取り、10の倍数である位置からの要素を含むリストを返します。l!!sはのnth要素を返します。lここでsはの逆の文字列表現ですn。差について+も同様-に、逆の文字列として与えられた2つの自然数の合計を整数として返します。add文字列として指定された2つの負の整数の合計を整数として返します。

これは、ベンが念頭に置いていたものにいくらか似ているのだろうか。


うん、ほぼ同じアイデア。リテラルに対するパターンマッチングは、等価性テストと分岐を取得し、列挙構文をリストして増分の形式を取得します。何をインポートしてもインポートしなく:てもスコープ内にあることに驚いたNoImplicitPrelude
ベン


7

Wheat WizardによるPython 2(4回目の反復)

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[]))`)

オンラインでお試しください!

悪用はなく、' &)(,.:[]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')が数字のゼロをの5ような長さまで埋め込むこと'1 'です。を使用してこのような2つの文字列を連結する''.joinと、その長さの合計は入力数の合計になります。次に、0最後にaを追加し.find()、最終的な位置、つまり合計を呼び出します。

文字列'{0:5}'の形式には、抽出によって生成される{:}と作成された辞書の列reprs、から文字をdict。連続する各被加数の文字列reprは、5が置かれる場所に配置されます。私は{0:5}それ自体のような辞書を使いたかったのですが、そのレプラにはそれを台無しにするスペースが含まれています。

文字列subの最小長は1であるため、0の入力はプロセスを台無しにします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

screenshot of Debug dump of code, along with output in upper-left corner

説明:

Joshuaのコードによって導入された「破損」は、CPUをシングルステップモードにするトラップフラグ(TF)の設定です。これは、CPUがタイプ1割り込みで停止(トラップ)する前に、一度に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がトラップする前に1つの命令、つまりPOPFここの直後に来る命令を実行する機会を得ることを意味します。したがって、これを1つに数える必要があります。

トリックは、INT 3割り込み番号3を呼び出す命令です。これがコードを「解除」するために機能する理由は2つあります。

  1. トラップフラグは割り込みハンドラでクリアされます。これはIntelの設計の一部にすぎませんが、おそらく基本的な健全性の理由で行われたものです。トラップフラグの実装は、タイプ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です。必要なのは、2つの数値を加算して結果を出力することだけです。これは、アセンブリ言語では他の言語ほど単純ではないことを除けば、コードの大部分が費やされる場所です。

Joshuaは、強盗が望むI / Oメカニズムを指定できるようにしているため、値がDXand CXレジスタに渡されると仮定するという単純なアプローチを取っています。これらは彼の「プロローグ」コードによってどこにも破壊されないので、それは合理的です。

出力は、ASCIIバイトをビデオメモリに直接保存することにより行われます。ビデオバッファは0xB800:0000、テキストモードのCGA、EGA、VGAのいずれか、または両方で開始されるため、そこで印刷を開始します。形式は、下位バイトの文字、上位バイトの色属性です。つまり、各文字は2バイトのオフセット上にあります。数字の各桁(10進数)を反復処理して、ASCIIに変換し、一度に1つずつ画面に出力します。はい、これは大量のコードです。アセンブリ言語を支援するライブラリ関数はありません。これはほぼ確実にさらに最適化できますが、作業にうんざりしました...

出力が表示された後、コードはクラッシュするか、何でもすることができます。そのため、割り込みをクリアしてCPUを停止します。


私は困惑しています。これがBP:SP + 1のhlt命令をどのように通過するかわかりません。
ジョシュア

@ジョシュアフム、それは良い点です。私もそれについて考えませんでした。デバッグでコードをステップ実行するINT 3と、実行してすぐに次の命令に戻るため、そのまま実行しました。私のテスト環境に何か関係があるのでしょうか?CLIハードウェア割り込みのみを無効にしますがHLT、を超えても、lすぐにコードが実行されて実行されると思われます。
コーディグレー

ああ、あなたはシングルステップでした。ええ、それはそれをするでしょう。再確認しますが、ハックされたコードをアップロードしたと思います。
ジョシュア

また、シングルステップなしでテストしました。変わりはない。これは、VM Virtualboxの最新のFreeDOS上にあります。実際のハードウェアは入手可能ですが、電源を入れたくはありませんでした。@ジョシュア
コーディ・グレイ

さて、あなたは明らかにそれをクラックしました。たぶん、あなたはそのNMIを上げる方法を見つけました。
ジョシュア


4

Python 3ppperry2番目のチャレンジ

うわー、これは楽しかったです!これを解決できて楽しかったです。

編集:OK、修正しました。クラスは、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

Haskell by zbw

{-#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

LordFarquaadによるJava

ソースレベルでオブジェクトへのアクセスをブロックするのは本当に賢明で(テストするときは面倒です)、よくできました!

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、私はまだこれを解決することができます。[OK]を、あなたは私を1kbのソリューションに強制するかもしれませんが、それは可能です。
オリヴィエグレゴワール


3

通知7、イルマリ・カロネン

あいまいな名詞の不当な乱用...私のコードはで始まります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

Java、RomanGräf

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");
    }
}

初期値に設定stdoutしてstderr戻します。

インポートの代わりに完全修飾名を使用できると信じています。間違っている場合は修正してください(これが最初の投稿です)。これもおそらくリフレクションを使用して行うことができます。

編集:ここでのみを使用して反射ソリューションです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) {
        }
    }
}

うん、stdinstdoutおよびstderr他の場所に保存されます!あなたも、使用する必要はありませんsetOutし、setErrあなたが簡単に使用できるようPrintStreamに直接。
オリヴィエグレゴワール

反射ソリューションを追加し、これが当初予想されていたものだと感じた
モイラ

2

ダニエル・フランクリンによる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()2バイトを節約すると思います
マリー

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!1つのシステムでしか動作しない」と言う権利がないので、この答えはLinuxでのみ動作するため、完全に課題を解決するわけではありません。
オリビエグレゴワール

@OlivierGrégoire:FWIW、String[] args = ((String) system.getMethod("getProperty", String.class).invoke(null, "sun.java.command")).split(" ");Linux固有ではないが、いくつかのJVMによって設定された文書化されていないプロパティのように見えるものを使用する代替ソリューションを思い付きました。
イルマリカロネン

それはまだ移植性がありません。たとえば、IBM Javaでは機能しません。しかし、それはいいアイデアです!:)
オリヴィエグレゴワール

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でも機能します。
イルマリカロネン

@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つの整数を追加しませんか?。 " 2. 2つの数値を入力として受け取り、それらを加算し、合計を出力するコードのスニペット。一緒に組み合わせ、彼らは2つの数値を追加し、完全なプログラムを形成する、または2つの数値を追加する機能を定義する必要があります。このスニペットは、おそらく無名の行動に依存している、と見つけるのは難しいだろう。
ケビンCruijssen

@KevinCruijssen何と言えますか?警官が彼らの仕事をしないなら、なぜ私は彼らのものをする必要がありますか?:P
オリヴィエグレゴワール

1
@KevinCruijssenそこに追加しました。
オリビエグレゴワール

@OlivierGrégoireは、入力、追加、または出力の機能を削除するかどうかに関係なく、数値の追加を防ぐことです。
スティーブン

@StepHenうん、あとでもう少し理解しました。他の3つのクラックをチェックして、最終的にそれを理解したことを確認してください;)
オリビエグレゴワール

1

Kevin CruijssenによるJava

よくできています。誰もがこの課題を解決する方法を熟考するための多くのコード。「後でコードを置く」ということは、大きな、大きなヒントだったと思います。

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リンクを追加してください。
ケビンCruijssen

さて、実際にレーサー290のチャレンジでそのアイデアに取り組んでいたのは、あなたがあなたのポストを投稿したときです。そして、いや私は気にしません。
オリビエグレゴワール


1

cQuentsStep Hen、3バイト

+BC

オンラインでお試しください!

Step Henと多くの話をして、彼の奇妙な言語がどのように機能するかを理解しましたが、要するに:

彼のコードはでした#|1,1:A#|1,1はデフォルトの入力です。つまり、プログラムに与えられた入力には2 1が付加されます。(つまり、47と53を渡すと、入力はになり[47, 53, 1, 1]ます。

:モードを設定するだけで、設定さnれている場合nはシーケンスのth番目の項目を出力し、そうでない場合はシーケンス全体を出力します。

最後Aに最初の入力を取得します。

4つの入力があるため、最後[47, 53, 1, 1]に追加BCすると2番目と3番目の入力もフェッチされ、4番目の入力は暗黙的にになりnます。

シーケンスはABCであるため、代数的に解析され、になりA*B*Cます。これは望ましくありませんが、+AとBの間にa を挿入すると、になりますA+B*C。ここでAおよびBは入力で、C1です。


how the hell his weird language works多分それを終えたら、もう少し理にかなっているかもしれません
スティーブン

@StepHenは誤解しないでください、それはきちんとした言語ですが、地獄のように奇妙
です-Skidsdev

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

@DJMcMayhemによるVimチャレンジ

vim終了できなかったのでしばらく経ちましたが、ここに私の解決策があります(23バイトよりもはるかに多いことに注意してください-したがって、おそらく意図した解決策ではありません)。

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

オンラインでお試しください!

アイデアは、単に2つの整数をawkvia にパイプすることです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固有のトリック、非修飾の単純なマスキングStringおよびSystemクラス名。これはおそらく意図した解決策ではありませんが、機能します。



1

@ATacoによるRProgN2

"+-/*÷^"{²[[\=};
{"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がない。

注:入力をテストする場合は、2桁以上の数字を入力する必要があります "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

それは例えば、1つの番号としてグループも数字の刺し傷の前に$を提供することが56$46$12、私は私の実際のソリューションや、明日投稿します番号5、6、46および12をプッシュします
ATaco

知らなかった。私はあなたの呼び出し可能オブジェクトを調べて、物事が何であるかを把握しました。
アーノルドパーマー

この挑戦のために実際にいくつかのドキュメントを書くかもしれません。
ATaco

それは素晴らしいことです。私はRProgNのコマンドのリストを見つけることができましたが、それを失いました...そして、機能がすべて異なるので、それは非常に役立ちました。古いRProgNチュートリアルページと呼び出し可能なクラスを介して関数を学習する必要がありました。すべてがどのように機能するかがすぐに明らかでなかったとしても、いじってみるのは楽しかったです。
アーノルドパーマー

1

jrichによるJavaScript(Node.js)、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
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.