Làm cho ngôn ngữ của bạn * chủ yếu là * không sử dụng được (chủ đề của Robber)


31

Lấy cảm hứng từ bình luận này ...

Cảm ơn người dùng Step Hen , Wheat-WizardDennis đã giúp tôi củng cố đặc điểm kỹ thuật của thử thách này trước khi đăng nó!

Đây là chủ đề của Robber! Đối với chủ đề của Cảnh sát, hãy vào đây


Trong thử thách này , bạn có nhiệm vụ chạy một số mã khiến cho ngôn ngữ của bạn không còn thỏa mãn tiêu chí của chúng tôi là ngôn ngữ lập trình. Trong thử thách đó, điều đó có nghĩa là làm cho nó để ngôn ngữ không còn ...

  • Lấy đầu vào số và đầu ra

  • Cộng hai số lại với nhau

  • Kiểm tra nếu một số nhất định là một số nguyên tố hay không.

Đây là một thử thách , trong đó có hai thử thách khác nhau với hai mục tiêu khác nhau: Cảnh sát sẽ cố gắng viết một số mã khiến ngôn ngữ hầu như không sử dụng được và bọn cướp sẽ cố gắng tìm ra cách giải quyết ẩn cho phép cảnh sát để phục hồi ngôn ngữ của họ.

Cảnh sát sẽ viết hai đoạn mã:

  1. Một ngôn ngữ làm cho ngôn ngữ của họ hầu như không sử dụng được, ví dụ bằng cách loại bỏ các hàm tích hợp để thực hiện các thao tác nhập / xuất và số. Mã này không được phép để sập hoặc thoát. Có thể thêm mã vào cuối đoạn mã này và mã đó sẽ được đánh giá . Và

  2. Một đoạn mã lấy hai số làm đầu vào, cộng chúng lại với nhau và xuất tổng của chúng. Đoạn mã này vẫn phải hoạt động chính xác ngay cả sau khi chạy đoạn mã đầu tiên. Khi hai đoạn mã được kết hợp với nhau, chúng phải tạo thành một chương trình đầy đủ có thêm hai số hoặc xác định hàm thêm hai số. Đoạn trích này có thể sẽ dựa vào hành vi tối nghĩa và khó tìm.

Cảnh sát cũng sẽ chọn bất kỳ phương pháp tiêu chuẩn đầu vào và đầu ra . Tuy nhiên, họ phải tiết lộ chính xác định dạng (đầu vào và đầu ra) mà họ đang sử dụng. Để bạn bẻ khóa câu trả lời của họ, bạn phải tuân theo cùng một định dạng đầu vào / đầu ra, hoặc vết nứt của bạn không được tính.

Một câu trả lời của cảnh sát sẽ luôn luôn tiết lộ

  • Đoạn đầu tiên (rõ ràng không phải là đoạn thứ hai).

  • Ngôn ngữ (bao gồm cả phiên bản nhỏ, vì hầu hết các bài nộp có thể sẽ dựa vào các trường hợp cạnh lạ)

  • Định dạng IO, bao gồm cả chức năng hay chương trình đầy đủ. Kẻ cướp phải sử dụng định dạng tương tự để trở thành một vết nứt hợp lệ.

  • Bất kỳ trường hợp cạnh lạ cần thiết cho câu trả lời của họ để làm việc. Ví dụ: chỉ chạy trên linux hoặc yêu cầu kết nối Internet .

Là một tên cướp, bạn phải nhìn vào một trong những đệ trình của cảnh sát và cố gắng bẻ khóa nó. Bạn có thể bẻ khóa nó bằng cách viết bất kỳ đoạn mã hợp lệ nào có thể hoạt động như đoạn 2 (cộng hai số lại với nhau sau khi ngôn ngữ được tạo ra hầu hết không sử dụng được). Đây không phải là đoạn trích giống như cảnh sát ban đầu đã viết. Khi bạn có câu trả lời bị bẻ khóa, hãy đăng mã của bạn dưới dạng câu trả lời trên chuỗi này và gửi liên kết đến câu trả lời của bạn dưới dạng nhận xét về câu trả lời của cảnh sát. Sau đó, bài đăng đó sẽ được chỉnh sửa để chỉ ra đã bị bẻ khóa.

Đây là một ví dụ. Đối với đoạn mã đầu tiên, bạn có thể xem chương trình python 3 sau đây dưới dạng câu trả lời của cảnh sát:

Con trăn 3

print=None

Đưa đầu vào từ STDIN và đầu ra sang STDOUT

Một đoạn mã thứ hai hợp lệ có thể là

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

Điều này hợp lệ vì sẽ lấy hai số làm đầu vào và xuất tổng của chúng ngay cả khi bạn nối hai đoạn mã với nhau, ví dụ:

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

Đây là một vết nứt hợp lệ cho câu trả lời của họ.

Nếu câu trả lời của cảnh sát vẫn không bị theo dõi trong cả tuần, họ có thể chỉnh sửa trong đoạn trích thứ hai và cho biết câu trả lời của họ hiện đã an toàn . Một khi nó được chỉnh sửa để an toàn, bạn có thể không còn cố gắng bẻ khóa nó nữa. Nếu họ không chỉnh sửa nó là an toàn, bạn có thể tiếp tục cố gắng bẻ khóa cho đến khi họ làm điều đó.

Người chiến thắng trong chủ đề của tên cướp là người dùng đã bẻ khóa nhiều câu trả lời nhất, với kẻ phá vỡ là thời điểm chúng đạt đến N vết nứt. (vì vậy, nếu hai người dùng khác nhau, mỗi người có 5 vết nứt, thì người dùng đã đăng lần bẻ khóa thứ 5 của họ trước là người chiến thắng) Sau khi đủ thời gian trôi qua, tôi sẽ chấp nhận câu trả lời của người chiến thắng với nhiều phiếu nhất.

Chúc vui vẻ!

Làm rõ quy tắc

  • Đoạn mã đầu tiên phải chạy chính xác mà không cần bất kỳ đầu vào nào . Nó có thể xuất bất cứ thứ gì bạn thích, và đầu ra này sẽ bị bỏ qua. Miễn là sau khi đoạn mã được thực hiện, đoạn mã thứ hai chạy chính xác.

  • Đoạn mã thứ hai thực sự phải được thực thi để câu trả lời của bạn có giá trị. Điều này có nghĩa là một câu trả lời như

    import sys
    sys.exit()
    

    không hợp lệ vì nó không phá vỡ ngôn ngữ. Nó chỉ đơn giản là thoát.

  • Sau khi an toàn, điểm của bạn là số byte của cả hai đoạn .

  • Điều này quay trở lại Vui lòng tiết lộ bất kỳ trường hợp cạnh lạ nào cần thiết để câu trả lời của bạn hoạt động ... Nội dung gửi của bạn phải chứa đủ thông tin trước khi được tiết lộ để có thể sao chép lại sau khi được tiết lộ. Điều này có nghĩa là nếu câu trả lời của bạn trở nên an toàn, và sau đó bạn chỉnh sửa: Đây là câu trả lời của tôi. Oh ya, BTW này chỉ hoạt động nếu bạn chạy nó trên Solaris, đùa bạn! câu trả lời của bạn không hợp lệ và sẽ bị xóa và không được coi là đủ điều kiện để chiến thắng.

  • Đoạn mã thứ hai được phép gặp sự cố sau khi xuất tổng. Miễn là đầu ra vẫn đúng (ví dụ: nếu bạn chọn xuất ra STDERR, và sau đó bạn nhận được một loạt thông tin sự cố, điều này không hợp lệ)

Bảng xếp hạng

Dưới đây là danh sách của mỗi người dùng có ít nhất một vết nứt, được sắp xếp theo điểm số và sau đó đặt tên (theo bảng chữ cái). Nếu bạn gửi một vết nứt, xin vui lòng cập nhật điểm số của bạn cho phù hợp.

#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

Câu trả lời:


3

Java 8 của Olivier Grégoire

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

Hãy thử trực tuyến!

Do Olivier rõ ràng cho phép chuyển đầu vào qua các thuộc tính được đặt bằng các đối số VM, tôi sẽ chỉ định rằng đầu vào phải được đưa ra trong đối số VM -Dline.separator=X,Y, trong đó XYlà các số được thêm vào. Nghĩa là, ví dụ, thêm các số 17 và 25, chương trình sẽ được gọi là:

java -Dline.separator=17,25 Main

Tôi tin rằng điều này sẽ hoạt động trên bất kỳ hệ thống nào hơn là có thể chạy các chương trình Java trên dòng lệnh. Ngay cả trên các hệ thống không có dòng lệnh, bất kỳ cơ chế tương đương nào khác để thiết lập các thuộc tính hệ thống đều có thể được sử dụng để chuyển đầu vào cho VM.


Thi thiên Đây là nỗ lực bẻ khóa trước đây của tôi, được coi là không hợp lệ do sử dụng các tính năng dành riêng cho 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);
  }
}

Hãy thử trực tuyến!

Điều này hóa ra ít dài dòng hơn so với trước đây . Phần khó là tìm một lớp con SecurityManagerkhông sống trong không gian tên bắt đầu bằng " java.". Tôi nghi ngờ đây vẫn không phải là giải pháp dự định, nhưng nó hoạt động. *

*) Trên TIO, ít nhất; các sun.awt.AWTSecurityManagerlớp học và các sun.java.commandtài sản dường như không được chính thức ghi nhận, và có thể không có trên tất cả các JVM.


Công việc tốt! Tôi đã thử điều này, nhưng không thể tìm thấy một SecurityManagercái trong phạm vi ... Tuy nhiên, bạn cũng có thể đọc từ System.inlúc này, vì nó chưa bị đóng.
zbw

Xin lỗi, đây là câu trả lời phụ thuộc vào nền tảng trên hai khía cạnh: cả hai sun.awt.SecurityManager"sun.awt.command"đều phụ thuộc vào nền tảng và không phải là một phần của Java .
Olivier Grégoire

Đúng, nứt! :) Giải pháp dự định là thông qua System.getProperties().get("blah")(vì tôi chỉ chặn truy cập System.getPropertychứ không phải System.getProperties), nhưng điều này là đủ tốt! Làm tốt!
Olivier Grégoire

22

C (GCC / Linux) của Sisyphus

Đoạn mã này đóng chức năng được cung cấp và bắt đầu một chức năng mới (tiêm mã cổ điển), chính nó xác định lại closeđể thay vì đóng fd, chạy mã mong muốn của chúng tôi.

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

  exit(0);

20

Python, giải pháp của Wheat Wizard ở đây

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()))

Ý tôi là, bạn chỉ có thể đặt lại giới hạn đệ quy và không có gì xấu xảy ra ...

Hoạt động trên TIO

chú thích

Đây là lần gửi CnR đầu tiên của tôi, vì vậy nếu điều này vi phạm bất kỳ quy tắc nào, vui lòng cho tôi biết và tôi sẽ xóa nội dung này.


4
Tôi thật ngu ngốc vì đã bỏ lỡ điều này
Thuật sĩ lúa mì

@WheatWizard :)
HyperNeutrino

@wheatwizard Đừng tiết lộ giải pháp dự định của bạn. Tôi muốn looove để xem một cảnh sát tốt hơn với giải pháp ban đầu của bạn mà sửa chữa vấn đề này.
DJMcMayhem

@Djmcmayhem Có lẽ tôi sẽ đăng lại với một del sys.
Phù thủy lúa mì

@WheatWizard Hãy nhớ rằng os.sys, nếu điều đó tạo ra sự khác biệt: P
HyperNeutrino

15

Haskell của Ben

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)

Tôi vẫn có số lượng đen và chars (tôi sử dụng 0, '0''-'), và [a..][a..b]đó là rất hữu ích. Và tôi có unary -, nhưng tôi có thể làm mà không cần.

Tôi tạo lại ++để hiện thực r( reverse) và định nghĩa ttsđó là tailtails. x a btrả về nphần tử thứ của b, trong đó nđộ dài atrừ đi một. xthường có thể được định nghĩa là snd.last.zip. Hàm dlấy một danh sách và trả về một danh sách với các phần tử từ các vị trí đó là bội số của mười. l!!strả về nphần tử thứ của l, trong đó sbiểu diễn chuỗi đảo ngược của n. +trả về dưới dạng số nguyên tổng của hai số tự nhiên được cho dưới dạng chuỗi đảo ngược, tương tự như vậy -cho sự khác biệt. addtrả về dưới dạng số nguyên tổng của hai số nguyên âm có thể được cho dưới dạng chuỗi.

Tôi tự hỏi nếu điều này là hơi giống với những gì Ben có trong tâm trí.


Đúng, khá nhiều ý tưởng tương tự. Kết hợp mẫu với chữ để có các bài kiểm tra đẳng thức và phân nhánh, liệt kê cú pháp liệt kê để có được một hình thức gia tăng. Tôi khá ngạc nhiên khi thấy :nó nằm trong phạm vi ngay cả khi có NoImplicitPreludevà không nhập bất cứ thứ gì.
Ben


7

Python 2 bởi Wheat Wizard (lần lặp thứ tư)

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

Hãy thử trực tuyến!

Không khai thác, chỉ là một chức năng để thêm chỉ sử dụng các ký tự ' &)(,.:[]a`cdfijmonrt~', như dự định (thực tế chỉ '(),.:[]`acdfijmnort').

Tôi đã không cố gắng để làm cho nó ngắn; Tôi chỉ viết các biểu thức con cho các giá trị trung gian như 0 và chuỗi rỗng và chuỗi thay thế các giá trị trong.

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

Hãy thử trực tuyến!

Ý tưởng cốt lõi là định dạng chuỗi '{0:5}'.format('1')đệm từ số 0 đến độ dài 5thích '1 '. Bằng cách nối hai chuỗi như vậy bằng cách sử dụng ''.join, tổng độ dài của chúng là tổng của các số đầu vào. Sau đó, chúng tôi giải quyết từ đầu 0đến cuối và gọi .find()đến vị trí cuối cùng, đó là tổng.

Chuỗi '{0:5}'định dạng được tạo ra bằng cách trích xuất các {:}ký tự từ chuỗi reprs của từ điển, được tạo bằng dict. Chuỗi repr của mỗi triệu hồi liên tiếp được đặt ở vị trí 5. Tôi muốn sử dụng một dict như {0:5}chính nó, nhưng repr của nó bao gồm một không gian làm cho nó rối tung lên.

Các đầu vào của 0 làm xáo trộn quá trình vì chuỗi con có độ dài tối thiểu là 1. Chúng ta có những đầu and/orvào để cung cấp chuỗi trống trong trường hợp này.


1
Điều này khá khác so với những gì tôi dự định, tôi rất muốn xem một lời giải thích.
Phù thủy lúa mì

Bạn có thể chơi golf tất cả int([]in[])chỉ đơn giản int()vì cả hai sẽ xuất 0.
Ink Ink


5

x86 lắp ráp chế độ thực 16 bit, bởi Joshua

    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

ảnh chụp màn hình của Debug dump mã, cùng với đầu ra ở góc trên bên trái

Giải trình:

"Sự cố" được giới thiệu bởi mã của Joshua là cài đặt cờ bẫy (TF), đưa CPU vào chế độ một bước. Điều này có nghĩa là chỉ một lệnh duy nhất sẽ được thực thi tại một thời điểm, trước khi CPU dừng (bẫy) với ngắt loại 1. Đây là những gì cho phép trình gỡ lỗi thực hiện một bước mã đơn giản khá tiện lợi ở đó, nhưng là một PITA thực sự nếu bạn muốn chạy mã bên ngoài bối cảnh của trình gỡ lỗi!

Đây là phần mã sau đây bật cờ bẫy:

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

Việc thực hiện cờ bẫy có nghĩa là chúng ta có cơ hội thực hiện chính xác một lệnh trước khi CPU bẫy bẫy, đó là lệnh xuất hiện ngay sau POPFđây. Vì vậy, chúng ta cần phải thực hiện điều này.

Thủ thuật là INT 3hướng dẫn, gọi ngắt số 3. Có hai lý do tại sao điều này hoạt động để "phá vỡ" mã:

  1. Cờ bẫy được xóa trong xử lý ngắt. Đây chỉ là một phần trong thiết kế của Intel, nhưng có lẽ nó được thực hiện vì lý do vệ sinh cơ bản. Hãy nhớ rằng việc thực hiện cờ bẫy là một ngắt loại 1 được gọi sau khi thực hiện từng lệnh, vì vậy nếu TF không bị xóa, chính nóINT 1 sẽ kích hoạt một ngắt gián đoạn, nó sẽ bị gián đoạn. Ngoài ra, việc ngắt TF rõ ràng chỉ giúp gỡ lỗi mã dễ dàng hơn, giống như một IDE tự động chuyển qua các cuộc gọi đến các chức năng của thư viện.

  2. Cách làm việc gián đoạn về cơ bản là giống như xa CALL. Chúng gọi trình xử lý ngắt có địa chỉ được lưu trữ tại vị trí tương ứng trong bảng vectơ ngắt toàn cầu. Vì bảng này bắt đầu tại địa chỉ 0x0000:0000và được lưu trữ ở segment:offsetđịnh dạng 4 byte , việc tính toán địa chỉ đơn giản như nhân 4 với vectơ / số ngắt. Trong trường hợp này, chúng tôi gọi ngắt 3, do đó sẽ là 4 × 3 = 12.

    Nhiều và bạn sẽ nhận thấy Joshua chu đáo thiết lập điều này cho chúng tôi. Trước khi bật cờ bẫy, anh ta có mã sau:

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

    mà thiết lập 0x0000:000C(trình xử lý ngắt cho INT 3) thành BP:SI. Điều đó có nghĩa là bất cứ khi nào INT 3được gọi, nó sẽ đẩy thanh ghi FLAGS lên ngăn xếp, theo sau là địa chỉ trả về và sau đó các nhánh tới BP:SI, cho phép chúng ta bắt đầu thực thi lại mã, trong bối cảnh cờ bẫy bị tắt.

Tất cả đều xuống dốc sau đó INT 3. Tất cả những gì chúng ta cần làm là cộng hai số lại với nhau và in kết quả. Ngoại trừ việc điều này không đơn giản trong ngôn ngữ lắp ráp như trong các ngôn ngữ khác, vì vậy đây là nơi dành phần lớn mã.

Joshua đang cho phép tên cướp chỉ định bất kỳ cơ chế I / O nào anh ta muốn , vì vậy tôi đang sử dụng cách tiếp cận đơn giản giả định rằng các giá trị được truyền vào DXvà các CXthanh ghi. Điều đó là hợp lý, vì những thứ này không bị ghi đè ở bất cứ đâu bởi mã "prologue" của anh ta.

Đầu ra sau đó được thực hiện bằng cách lưu trữ byte ASCII trực tiếp vào bộ nhớ video. Bộ đệm video bắt đầu ở 0xB800:0000chế độ văn bản CGA, EGA và / hoặc VGA, vì vậy chúng tôi bắt đầu in ở đó. Định dạng là: ký tự trong byte thấp và thuộc tính màu trong byte cao. Điều đó có nghĩa là mỗi ký tự nằm trên offset 2 byte. Chúng tôi chỉ lặp đi lặp lại qua từng chữ số trong số (cơ số 10), chuyển đổi chúng thành ASCII và in từng chữ số ra màn hình. Vâng, đây là rất nhiều mã. Không có chức năng thư viện để giúp chúng tôi trong ngôn ngữ lắp ráp. Điều này gần như chắc chắn có thể được tối ưu hóa hơn nữa, nhưng tôi cảm thấy mệt mỏi khi làm việc với nó ...

Sau khi đầu ra được hiển thị, mã được phép sập hoặc làm bất cứ điều gì, vì vậy chúng tôi chỉ cần xóa các ngắt và tạm dừng CPU.


Tôi hoang mang; Tôi không thể hiểu làm thế nào điều này vượt qua hướng dẫn hlt tại BP: SP + 1.
Joshua

@Joshua Hmm, đó là một điểm tốt. Tôi thậm chí không nghĩ về điều đó. Bước qua mã trong Debug, tôi thực thi INT 3và kết thúc ngay lập tức theo hướng dẫn theo nó, vì vậy tôi chỉ đi với nó. Có lẽ có một cái gì đó để làm với môi trường thử nghiệm của tôi? CLIsẽ chỉ vô hiệu hóa các ngắt phần cứng, nhưng ngay cả khi nó đã vượt qua HLT, bạn sẽ nghĩ rằng nó sẽ vượt qua và thực thi mã lngay sau đó.
Cody Grey

Oh, bạn đã từng bước. Vâng, điều đó sẽ làm điều đó. Tôi sẽ kiểm tra lại nhưng tôi nghĩ rằng tôi đã tải lên mã bị đánh.
Joshua

Tôi cũng đã thử nghiệm mà không cần bước đơn. Không khác nhau. Đây là trên FreeDOS mới nhất trong VM Virtualbox. Tôi có sẵn phần cứng thực sự, nhưng không cảm thấy muốn tăng sức mạnh cho nó. @Joshua
Cody Grey

Vâng, bạn rõ ràng đã crack nó sau đó. Có lẽ bạn đã tìm thấy một cách để nâng cao NMI đó.
Joshua


4

Python 3 , Thử thách thứ 2 của ppperry

Wow, thật là vui! Tôi rất thích giải quyết điều này.

Chỉnh sửa: OK, tôi đã sửa nó. Có vẻ như các lớp ở một chỉ mục khác trong danh sách lớp con trên TIO so với trên máy tính của tôi, vì vậy tôi đã làm cho nó hoạt động cho cả hai và thêm 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()

Hãy thử trực tuyến!


Tôi nhận được một lỗi. sys.excepthook is missing?
Rɪᴋᴇʀ

Hmm ... làm việc cho tôi. Lỗi thực sự của bạn là gì? (Điều đó xảy ra vì mã của ppperry đã phá hủy khá nhiều thứ, bao gồm cả việc biết cách hiển thị ngoại lệ, vì vậy sys.excepthook, nhưng sẽ có một nguyên nhân thực sự được liệt kê ở đâu đó trong đó.)
zbw 21/07/17

Nevermind, lỗi thực sự là IndexError('list index out of range',). Đó là trên dòng với định nghĩa của _io_RawIOBase.
Rɪᴋᴇʀ

Vấn đề là thứ tự của các lớp con không cố định. _io_IOBase = [cls for cls in object.__subclasses__() if cls.__name__ == '_IOBase'][0]Nên làm việc ở mọi nơi.
Dennis

@Dennis Yep, tôi nhận ra điều đó và chỉ sửa nó. Nó hoạt động trên TIO ngay bây giờ!
zbw

4

Haskell bởi 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 )

Không thể chạy mã vào thời gian chạy? Chạy nó vào thời gian biên dịch!

Điều này thật thú vị, tôi không biết mẫu haskell trước thử thách này.




3

Java của LordFarquaad

Chặn quyền truy cập vào các đối tượng ở cấp nguồn thực sự rất thông minh (và gây khó chịu khi thử nghiệm), được thực hiện tốt!

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

Tốt đẹp! Điều gì nếu ClassLoaderđã bị che khuất?
Jakob

1
@JakobCornell "".getClass().getClassLoader(). Shadowing thường chỉ là một vấn đề bạn phải suy nghĩ một lần và sau đó nó ổn. Bạn thậm chí có thể bóng Object, tôi vẫn có thể giải quyết điều này. Ok, bạn có thể buộc tôi vào giải pháp 1kb, nhưng điều đó là có thể.
Olivier Grégoire


3

Thông báo 7, bởi Ilmari Karonen

Lạm dụng trắng trợn các danh từ mơ hồ ... Mã của tôi bắt đầu bằng factory is a room. Dòng trước là mã của cảnh sát. Nhập add 1 and 1để có được 2, ví dụ.

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, La Mã

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

Đặt stdoutstderrtrở lại giá trị ban đầu của họ.

Tôi tin rằng tôi có thể sử dụng tên đủ điều kiện thay vì nhập, nếu tôi sai xin vui lòng sửa cho tôi (đây là bài đăng đầu tiên của tôi ở đây.) Điều này có thể cũng được thực hiện bằng cách sử dụng sự phản chiếu.

Chỉnh sửa: đây là một giải pháp phản chiếu chỉ sử dụng 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) {
        }
    }
}

Yep, stdin, stdoutstderrđược lưu trữ ở nơi khác! Bạn thậm chí không cần sử dụng setOutsetErrđơn giản là bạn có thể sử dụng PrintStreamtrực tiếp.
Olivier Grégoire

Đã thêm giải pháp phản chiếu cũng như tôi cảm thấy đây là những gì được mong đợi ban đầu
Moira

2

JavaScript của Daniel Franklin

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

Đây có thể được coi là một giải pháp gian lận một chút, nhưng nó hoạt động với tôi trên Chromium 59 / Linux, ngay cả khi tôi cũng nhận được một cảnh báo:

Các phiên bản sắp tới sẽ chặn điều hướng khung hình hàng đầu được khởi tạo nội dung đối với dữ liệu: URL. Để biết thêm thông tin, hãy xem https://goo.gl/BaZAea .

Thi thiên Đây là một vết nứt khác, lần này không có cảnh báo:

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

Tôi nghĩ prompt()- -prompt()tiết kiệm hai byte
Marie

2

Java 8 của Olivier Grégoire

Một vết nứt dài vô tận cho một thách thức cực kỳ dài. :) Nỗi đau của việc làm việc gián tiếp với các lớp mà bạn không thể đặt tên là có thể sờ thấy được.

    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;

Hãy thử trực tuyến!

Thi thiên Đây là nỗ lực trước đây của tôi, được viết trước khi Olivier làm rõ rằng đầu vào có nghĩa là được thực hiện thông qua các đối số dòng lệnh. Không giống như bản crack ở trên, bản này không dành riêng cho 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;

Hãy thử trực tuyến!


Nếu bạn sẵn sàng, đây là thử thách mới của tôi .
Olivier Grégoire

Chỉ vì mục đích viết nó ở đây: vì tôi không có quyền nói "Gotcha! Nó chỉ hoạt động trên một hệ thống", câu trả lời này không hoàn toàn phá vỡ thách thức vì nó chỉ hoạt động trên Linux.
Olivier Grégoire

@ OlivierGrégoire: FWIW, tôi đã đưa ra một giải pháp thay thế bằng cách sử dụng String[] args = ((String) system.getMethod("getProperty", String.class).invoke(null, "sun.java.command")).split(" ");không dành riêng cho Linux, nhưng sử dụng những gì dường như là một thuộc tính không có giấy tờ do một số JVM thiết lập.
Ilmari Karonen

Điều đó vẫn không thể di động. Nó sẽ không hoạt động trên IBM Java, ví dụ. Tuy nhiên, đó là một ý tưởng tốt! :)
Olivier Grégoire

2

C # (.NET Core) bởi raznagul

Tôi cho rằng đây không phải là giải pháp dự định.

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

Thủ thuật hay /dev/std*đấy. Ban đầu tôi nhắm đến một cách tiếp cận tương tự, nhưng không thể tìm thấy bất kỳ cách dễ dàng nào để mở luồng cho stdin / out mà không truy cập vào System.Console, vì vậy tôi đã chọn phản ánh thay thế. Tất nhiên, giải pháp của bạn có lẽ chỉ hoạt động trên Linux và các hệ thống Unixish khác với các /devmục phù hợp , nhưng raznagul không nói rõ ràng rằng nó phải hoạt động trên Windows. Và nó hoạt động trên TIO.
Ilmari Karonen

@IlmariKaronen: Thật vậy; và kế hoạch của tôi nếu đó là Windows sẽ thất bại trên TIO.
Joshua

1

Java, bởi racer290

Đây là một bỏ qua cơ bản mà các trình statickhởi tạo được gọi trước mainphương thức. Đó là một cố gắng tốt đẹp: ban đầu tôi đã mất tinh thần throw new Error(), nhưng cuối cùng đã tìm được đường đi;)

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!");Không thêm hai số nguyên? .. " 2. Một đoạn mã lấy hai số làm đầu vào, cộng chúng lại với nhau và xuất tổng của chúng. Đoạn mã này vẫn phải hoạt động chính xác ngay cả sau khi chạy đoạn mã đầu tiên. Khi hai đoạn mã được kết hợp với nhau, chúng phải tạo thành một chương trình đầy đủ có thêm hai số hoặc xác định hàm thêm hai số. Đoạn mã này có thể sẽ dựa vào hành vi tối nghĩa và khó tìm thấy. "
Kevin Cruijssen

@KevinCruijssen Tôi có thể nói gì? Nếu cảnh sát không làm công việc của họ, tại sao tôi phải làm việc của họ? : P
Olivier Grégoire

1
@KevinCruijssen Ở đó, tôi đặt một bổ sung trong đó.
Olivier Grégoire

@ OlivierGrégoire toàn bộ vấn đề là ngăn chặn việc thêm số, cho dù bằng cách loại bỏ khả năng nhập, thêm hoặc đầu ra.
Stephen

@StepHen Yep, tôi đã hiểu nó thêm một chút sau đó. Kiểm tra 3 vết nứt khác của tôi để thấy rằng cuối cùng tôi đã hiểu điều đó;)
Olivier Grégoire

1

Java của Kevin Cruijssen

Xây dựng tốt. Rất nhiều mã để làm cho bất cứ ai suy nghĩ đúng cách để giải quyết thách thức này. Tôi đoán "đặt mã của bạn sau đó" là một gợi ý lớn, lớn.

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) {}
}

Hãy thử nó ở đây.


Đó là nhanh chóng .. Đó thực sự là giải pháp dự định chính xác của tôi! Làm tốt. :) EDIT: Mất tự do để thêm liên kết TIO nếu bạn không phiền.
Kevin Cruijssen

Chà, tôi thực sự đang thực hiện ý tưởng đó với thử thách của tay đua 290 khi bạn đăng bài của bạn. Và, không, tôi không phiền.
Olivier Grégoire

1

JavaScript của Grant Davis

document.body.innerHTML='<iframe/>'
w=frames[0]
w.console.log(1*w.prompt()+1*w.prompt())

Hoạt động trong bảng điều khiển JS trên about:blanktrang (như được chỉ định trong bài đăng cảnh sát) trên Chromium 59 / Linux.


Điều đó đã không mất nhiều thời gian. Làm tốt lắm.
Cấp Davis

1

cQuents , Bước Hen , 3 byte

+BC

Hãy thử trực tuyến!

Đã nói chuyện rất nhiều với Step Hen để tìm hiểu làm thế nào ngôn ngữ kỳ lạ của anh ta hoạt động, nhưng tóm lại:

Mã của anh ấy là #|1,1:A. #|1,1là đầu vào mặc định, nghĩa là bất kỳ đầu vào nào được cung cấp cho chương trình đều được nối thêm bởi 2 1. (IE nếu bạn vượt qua 47 và 53, đầu vào của bạn là [47, 53, 1, 1].

:chỉ cần đặt chế độ, sẽ xuất ra nmục thứ trong chuỗi nếu nđược đặt và nếu không thì xuất toàn bộ chuỗi.

Cuối cùng cũng Anhận được đầu vào đầu tiên.

Bởi vì chúng tôi có 4 đầu vào [47, 53, 1, 1], thêm BCvào cuối cũng sẽ tìm nạp đầu vào thứ 2 và thứ 3, và đầu vào thứ 4 hoàn toàn trở thành n.

Bởi vì trình tự của chúng tôi là ABC, nó được phân tích theo đại số, có nghĩa là nó trở thành A*B*C. Chúng tôi không muốn điều đó, nhưng nếu chúng tôi chèn a +giữa A và B, nó sẽ trở thành A+B*C, ở đâu ABlà đầu vào của chúng tôi và Clà 1.


how the hell his weird language workscó lẽ một khi tôi hoàn thành nó có thể có ý nghĩa hơn
Stephen

@StepHen đừng hiểu lầm tôi đó là một ngôn ngữ gọn gàng, nhưng kỳ lạ như địa ngục
Skidsdev

1

C # (.NET Core) bởi raznagul

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

Hãy thử trực tuyến!

Điều này có lẽ sẽ mất ít thời gian hơn nếu tôi thực sự biết bất kỳ C # nào. Tuy nhiên, với một số duyệt tài liệu và một chút giúp đỡ từ Jon Skeet , tôi đã xoay sở để cùng nhau làm một cái gì đó hoạt động.


1

Thử thách Vim của @DJMcMayhem

Đã được một thời gian kể từ khi tôi không thể thoát vim , đây là giải pháp của tôi (lưu ý rằng nó nhiều hơn nhiều so với 23byte - vì vậy nó có thể không phải là giải pháp dự định):

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

Hãy thử trực tuyến!

Ý tưởng là đơn giản chỉ để ống hai số nguyên để awkthông qua bash, kể từ =+bị tàn tật tôi đã phải sử dụng một nhỏ công việc xung quanh. Các awkdòng mở rộng để:

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

Chỉnh sửa : Ý định ban đầu là đầu vào đã có trong bộ đệm, nhưng điều đó sẽ không khó khăn hơn - khó khăn chính là để hoạt động bổ sung.

Đây là bản sửa lỗi được đề xuất bởi @DJMcMayhem: Dùng thử trực tuyến!


Tôi nghĩ đừng nghĩ rằng bạn có thể làm [insert your number here]trong chế độ chèn. Thay vào đó, nó đã có trong bộ đệm. Nhưng bạn có thể vượt qua điều đó với Oecho "<esc>Go"|awk..., vì vậy tôi nghĩ rằng điều này có giá trị. Làm tốt lắm! Đây không phải là vết nứt mà tôi có trong đầu (tôi đã hy vọng có một câu trả lời thuần túy vim) vì vậy tôi có thể sẽ đăng một câu trả lời mới vá các lệnh bên ngoài và !.
DJMcMayhem

1
Đây là một ví dụ đưa đầu vào đúng cách: Hãy thử trực tuyến!
DJMcMayhem

Vâng, tôi không chắc chắn về đầu vào. Nhưng cách giải quyết thực sự sẽ dễ dàng. Tôi sẽ chỉnh sửa theo cách chính thức .
ბიმო

BTW, cách tiếp cận được vá của tôi là ở đây: codegolf.stackexchange.com/a/133441/31716
DJMcMayhem

1

Java 7 của Poke

  }
  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) {

Hãy thử trực tuyến!

Không cần các thủ thuật dành riêng cho Linux, chỉ cần che giấu đơn giản các tên lớp Stringvà không đủ tiêu chuẩn System. Đây có lẽ không phải là giải pháp dự định, nhưng nó hoạt động.



1

RProgN2 bởi @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|}"+"=

Hãy thử trực tuyến!

Đây không phải là câu trả lời hay nhất mà tôi có thể đưa ra, nhưng nó cho phép thêm các số lại với nhau. Nếu tôi thực sự đã trải qua và thực hiện xử lý ngăn xếp thích hợp, tôi có thể chơi golf này khá nhiều, nhưng đến bây giờ tôi rất vui với câu trả lời.

Trong bài viết gốc của ATaco, ông thực sự chỉ định lại tất cả các toán tử số học chính để phá hủy đầu vào của chúng. Để khắc phục vấn đề này, tôi đã xác định lại sự bổ sung nào về các hoạt động nhị phân của nó, điều này thật khó khăn vì RProgN2 không có toán tử phủ định nhị phân hoặc xor.

Lưu ý: Nếu bạn muốn kiểm tra đầu vào, các số có nhiều hơn một chữ số cần phải ở dạng "XX..." nđể được chuyển đổi thành số thực do RProgN2 lấy mỗi ký tự trừ khi đó là khái niệm hoặc chuỗi. Chỉnh sửa: @ATaco lưu ý rằng việc thêm '$' trước số nhiều chữ số sẽ làm điều tương tự.

EDIT: Đây là logic cho giải pháp của tôi. Như bạn có thể thấy, chắc chắn không phải là mã tinh chỉnh nhất, nhưng nó hoạt động.

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

Cung cấp một đô la trước một số lượng cũng nhóm nó thành một số, ví dụ: 56$46$12sẽ đẩy các số 5, 6, 46 và 12. Tôi sẽ đăng giải pháp thực tế của mình và như vậy
ATaco

Không biết điều đó. Tôi chỉ nhìn qua các thiết bị gọi của bạn để tìm hiểu xem mọi thứ là gì.
Arnold Palmer

Tôi thực sự có thể viết một số tài liệu vì thách thức này.
ATaco

Điều đó thật tuyệt vời. Tôi đã tìm được danh sách các lệnh cho RProgN, nhưng đã mất nó ... Và nó chỉ giúp ích rất nhiều vì các chức năng đều khác nhau. Tôi đã phải học các chức năng của bạn thông qua trang hướng dẫn RProgN cũ của bạn và các lớp có thể gọi được của bạn. Thật vui khi chơi xung quanh ngay cả khi mọi thứ không hoạt động ngay lập tức.
Arnold Palmer

1

JavaScript (Node.js) bởi jrich , 298 byte

Tôi cảm thấy như đây không phải là giải pháp dự định, nhưng nếu nó được thực hiện tốt, tôi đã dành một thời gian để cố gắng tìm ra cách lấy tên của hàm khai báo! :)

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])));

Hãy thử trực tuyến!


1
Không phải là giải pháp dự định nhưng rất thông minh! Đẹp crack +1
jrich 20/07/17

@jrich Vâng, tôi hiểu rồi, cứ thoải mái vá nó đi, tôi chắc chắn sẽ có một giải pháp khác!
Dom Hastings

Rất tiếc ... quá muộn! Tôi hài lòng với sự sáng tạo của giải pháp của bạn mặc dù!
jrich
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.