Tôi đảo ngược mã nguồn, bạn phủ nhận đầu vào!


36

Trắng trợn rip-off của một rip-off . Đi lên những người!

Nhiệm vụ của bạn, nếu bạn muốn chấp nhận nó, là viết một chương trình / hàm xuất / trả về đầu vào / đối số nguyên của nó. Phần khó khăn là nếu tôi đảo ngược mã nguồn của bạn, đầu ra phải là số nguyên ban đầu bị phủ định.

Ví dụ

Giả sử mã nguồn của bạn là ABCvà đầu vào của nó là 4. Nếu tôi viết CBAthay thế và chạy nó, đầu ra phải được -4.

Giả sử mã nguồn của bạn là ABCvà đầu vào của nó là -2. Nếu tôi viết CBAthay thế và chạy nó, đầu ra phải được 2.

Đầu vào 0có thể cung cấp 0hoặc -0, tuy nhiên, nếu bạn hỗ trợ ký số 0, -0sẽ cung cấp 0.


5
Tại sao chúng ta cần một bản sao của cùng một câu hỏi?
Christian

5
@Christian Cái đó xuất ra một số không đổi (và phủ định của nó) trong khi cái này phải lấy đầu vào và trả về / phủ định nó. Một công việc rất khác nhau trong rất nhiều ngôn ngữ.
Adám

5
Có, bây giờ tôi thấy sự khác biệt. Một người cần đọc RẤT cẩn thận
Christian

Nếu sử dụng một ngôn ngữ có cấu trúc như C #, bạn chỉ đang đảo ngược các dòng?
PerpetualJ

@PerpetualJ Không, hãy xem nguồn như danh sách các ký tự, một số trong đó là ngắt dòng.
Adám

Câu trả lời:





11

mã máy x86, 3 byte

C3 D8 F7

Các byte mã trên xác định một hàm không có chức năng: nó chỉ đơn giản trả lại quyền điều khiển cho người gọi. Hàm đó được theo sau bởi hai byte rác sẽ không được thực thi, vì chúng xuất hiện sau khi quay trở lại, chúng nằm trong "vùng đất không có người". Trong mnemonics lắp ráp:

ret                     ; C3    
fdiv  st(0), st(7)      ; D8 F7

Được rồi, vì vậy bây giờ một số troll xuất hiện và đảo ngược thứ tự của các byte:

F7 D8 C3

Các byte này bây giờ xác định một hàm lấy một đối số nguyên trong thanh EAXghi, phủ định nó và trả lại quyền điều khiển cho người gọi. Trong mnemonics lắp ráp:

neg  eax     ; F7 D8
ret          ; C3

Thật đơn giản. :-)

Lưu ý rằng chúng ta có thể làm cho lệnh "phủ định" trở thành bất cứ thứ gì chúng ta muốn, vì nó không bao giờ được thực hiện theo hướng "chuyển tiếp" và chỉ được thực hiện theo hướng "đảo ngược". Do đó, chúng ta có thể theo cùng một mô hình để làm những thứ phức tạp hơn tùy ý. Ví dụ, ở đây chúng tôi lấy một đối số nguyên trong một thanh ghi khác (giả sử, EDIđể tuân theo quy ước gọi hệ thống V thường được sử dụng trên các hệ thống * nix), phủ định nó và trả về nó trong EAXthanh ghi thông thường :

C3      ret
D8 F7   fdiv  st(0), st(7)      ;  \ garbage bytes that
F8      clc                     ;  | never get executed,
89      .byte 0x89              ;  / so nobody cares

  ↓ ↓

89 F8   mov  eax, edi
F7 D8   neg  eax
C3      ret



6

Khoảng trắng , 48 byte

S S S N
S N
S T N
T   T   T   T   T   T   N
S T N
N
N
T   S N
T   N
S S T   N
T   T   S S T   T   T   T   T   N
T   S N
S N
S S S 

Chữ cái S(dấu cách), T(tab) và N(dòng mới) được thêm vào dưới dạng chỉ tô sáng.

Sửa đổi nhỏ câu trả lời Whitespace của tôi cho I đảo ngược mã nguồn, bạn phủ nhận đầu ra! thử thách .

Hãy thử trực tuyến hoặc thử đảo ngược trực tuyến (chỉ có khoảng trắng, tab và dòng mới).

Giải trình:

Sử dụng chương trình Thoát được xây dựng là một bảng màu ngắn NNN.
Chương trình thường xuyên sẽ:

SSSN   # Push 0 to the stack
SNS    # Duplicate it
TNTT   # Read STDIN as integer, and store it at heap address 0
TTT    # Retrieve the input from heap address 0, and push it to the stack
TNST   # Pop and print the top of the stack as number
NNN    # Exit the program, making everything after it no-ops

Chương trình đảo ngược sẽ:

SSSN   # Push 0 to the stack
SNS    # Duplicate it
TNTT   # Read STDIN as integer, and store it at heap address 0
TTT    # Retrieve the input from heap address 0, and push it to the stack
SSTTN  # Push -1 to the stack
TSSN   # Multiply the top two values on the stack together
TNST   # Pop and print the top of the stack as number
NNN    # Exit the program, making everything after it no-ops

Giải thích thêm về việc đẩy một số:

  • Đầu tiên S: Kích hoạt thao tác ngăn xếp
  • Thứ hai S: Đẩy một số vào ngăn xếp
  • Shoặc T: Tích cực / tiêu cực tương ứng
  • Một số S/ Ttheo sau là một dấu N: số ở dạng nhị phân, ở đâu S=0T=1

Tức là SSTTSTSNđẩy -10. Đối với 0chúng tôi không cần một rõ ràng S=0, vì vậy đơn giản SSSNhoặc SSTNlà đủ.




5

Brain-Flak , 7 byte

#)]}{[(

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

Đảo ngược:

([{}])#

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

Lưu ý: Chỉ hoạt động trong các thông dịch viên hỗ trợ nhận xét (ví dụ: hoạt động trong Rain-Flak, nhưng không hoạt động trong BrainHack)


Nếu chúng ta cũng trao đổi dấu ngoặc mở / đóng thay vì chỉ đảo ngược các byte, chúng ta có thể thực hiện việc này trong 8 byte mà không cần sử dụng nhận xét:

({}[{}])

Hãy thử trực tuyến!
Hãy thử nó đảo ngược!


Đây có phải là hành vi lạm dụng không xác định? Tôi không nghĩ rằng đặc tả Brain-Flak cho phép dấu ngoặc đơn như vậy.
Đánh giá cao hoạt động

@TwilightSparkle #Bắt đầu một nhận xét, vì vậy dấu ngoặc đơn trong phiên bản gốc bị bỏ qua.
Riley

Ồ vâng, tôi quên mất! Nhưng nó chỉ hoạt động trong Rain-Flak sau đó (Mặc dù đó là intepreter chính thức). Bạn có thể sẽ cần phải đề cập đến nó?
Đánh giá cao hoạt động

@TwilightSparkle đã thêm một ghi chú để làm rõ. Cảm ơn.
Riley

Thử thách nhỏ thú vị: Bạn có thể làm điều này mà không có ý kiến ​​nếu bạn cũng trao đổi dấu ngoặc mở / đóng thay vì chỉ đảo ngược?
DJMcMayhem




4

R , 23 byte

Tôi quyết định cho nó đi mà không có thủ thuật nhận xét.

Phía trước

`+`=scan;""+-0;nacs=`+`

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

Đảo ngược

`+`=scan;0-+"";nacs=`+`

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

Trong phiên bản chuyển tiếp +đang hoạt động một toán tử nhị phân, và- là một toán tử đơn nguyên.

Ngược lại, +trở thành đơn nguyên và -nhị phân. Vì vậy, chức năng quét lấy các đối số: file=""có nghĩa là stdin và what=0, cũng là mặc định. Vì vậy, khi+ unary là đối số đầu tiên ở bên phải, khi nó là nhị phân, đối số đầu tiên nằm ở bên trái.

Các

;nacs=`+`

một phần của mã không có gì thực sự hữu ích, vì vậy theo một nghĩa nào đó, mã của tôi không thực sự hợp lệ hơn nhiều so với sử dụng thủ thuật nhận xét.


1
Điều này rất thông minh (+1). Chúng tôi thường định nghĩa lại các toán tử R thành các byte golf, nhưng tôi nghĩ rằng đây là lần đầu tiên tôi thấy +định nghĩa lại được sử dụng như là đơn nguyên và nhị phân. Phải mất một phút để tôi hiểu cách thức phân tích cú pháp này Không có tên nhà khai thác nào khác thực hiện công việc.
Robin Ryder


4

Perl 5 ( -p), 7 6 byte

-1 cảm ơn @primo

$_*=$#

TIO

Một bình luận không thay đổi đầu vào

#1-=*_$

Phủ định đầu vào

$_*=-1#

TIO


-1: $_*=$# TIO . Lưu ý rằng #phải là byte cuối cùng của chương trình, nếu không nó sẽ được hiểu là biến $#, thay vì chỉ mục cuối cùng của mảng có tên <blank>.
Primo

1
tuy nhiên tôi không hiểu nó hoạt động như thế nào vì cố in $#sẽ gây ra lỗi (nếu # không phải là ký tự cuối cùng) hoặc không có gì
Nahuel Fouilleul

Có vẻ chỉ làm việc với -phoặc -n. Tôi nghi ngờ nồi hơi có liên quan đến nó ...
primo

2
@primo Nó hoạt động vì -p/-nthêm một ;mã sau. Điều đó có nghĩa $#là thực sự $#;: kích thước của mảng @;. Nếu kích thước @;thay đổi, kết quả không còn đúng nữa ( TIO ). Dù sao, đây là siêu thông minh, cũng được thực hiện! :)
Dada

đó là lời giải thích có thể được nhìn thấy perl -MO=Deparse -p <(echo -n '$_*=$#'), bởi vì nó dường như perl -MO=Deparse -pe '$_*=$#'thêm một dòng mới
Nahuel Fouilleul

4

Gaia , 2 byte

_@

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

_	| implicit push input and negate
 @	| push next input OR push last input (when all inputs have been pushed)
	| implicit print TOS

Đảo ngược:

@	| push input
 _	| negate
	| implicit print TOS

4

Trái tay , 6 5 byte

I@-Ov

Hãy thử trực tuyến! Hãy thử gấp đôi!

Tạo ra một chút phức tạp do bản chất của con trỏ trong Backhand. Tôi không nghĩ có thể rút ngắn được haha, hóa ra tôi đã sai. Điều này sao chép không có lệnh và sử dụng lại cả hai lệnh đầu vào, đầu ra và kết thúc giữa hai chương trình. Bây giờ tôi nghĩ rằng nó là tối ưu, vì bạn cần tất cảIO-@ lệnh để làm việc và trong chương trình 4 byte, bạn chỉ có thể thực hiện hai trong số các lệnh đó.

Giải trình:

Con trỏ trong Backhand di chuyển tại ba ô một dấu và bật ra khỏi ranh giới của ô, điều đó có nghĩa là logic chung bị chồng chéo. Tuy nhiên, bạn có thể điều khiển tốc độ này bằng v^ lệnh .

Chương trình ban đầu thực hiện các hướng dẫn IO-@, đó là đầu vào dưới dạng số, đầu ra là số, trừ, chấm dứt. Rõ ràng phép trừ là thừa. Trong mã này là:

I@-Ov
^  ^    Reflect
  ^     Reflect again
 ^

Chương trình đảo ngược thực thi v-I-vO-@. Việc vgiảm các bước con trỏ giữa các dấu tick và -phép trừ từ dưới cùng của ngăn xếp, hoàn toàn bằng không. Các -lệnh bổ sung không làm gì cả. Chương trình thực hiện như

vO-@I
v       Reduce pointer speed to 2
  -     Subtract zero from zero
    I   Get input as number and reflect off boundary
  -     Subtract input from zero
v       Reduce pointer speed to 1
 O      Output as number
  -     Subtract zero from zero
   @    Terminate



3

R , 14 byte

scan()#)(nacs-

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

Một chương trình đầy đủ đọc một số, hoặc đọc và phủ định một số. Các chức năng đảo ngược được bảo vệ bởi một bình luận nội tuyến


Dấu ngoặc của bạn là cách sai trong phần bình luận.
Aaron Hayman

@AaronHayman cảm ơn!
Nick Kennedy

3

Python 3 , 22 14 byte

int#__bus__. 0

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

Sử dụng hàm inttạo của lớp và một phương thức giả riêng được tích hợp sẵn.


Huh. Tại sao không gian trước thuộc tính bắt buộc?
Jo King

2
@JoKing 0.sẽ được hiểu là một số, theo sau là một biểu tượng
attinat



2

APL (Dyalog Unicode) , 13 3 byte

-∘0

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

Câu trả lời tầm thường. Trả về arghoặc¯arg .

Đã lưu 10 byte bằng cách không bị câm (cảm ơn Adám).

Đã thay đổi kết quả 3-byter thành một chức năng phù hợp hơn.


Whoa, điều này có thể được thực hiện tầm thường trong ba byte!
Adám

Thật thú vị, bạn đã có một câu trả lời 3 byte được nhúng dưới dạng một chuỗi con của điều này.
Adám

@ Adám yeah, tôi biết có một câu trả lời đơn giản ở đó đâu đó. Cảm ơn.
J. Sallé


2

> <> , 5 4 byte

n-r0

sử dụng khởi tạo ngăn xếp với -vtùy chọn, đặt biến đầu vào của bạn ở đó.

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

Hoặc thử đảo ngược

Giải trình

n       Prints whatever is on the stack as a number
 -      Subtract the top 2 elements on the stack.
        There aren't 2 elements, so it crashes.
  r0    Never gets executed

or reversed:

0       Push a 0 onto the stack
 r      reverse the stack (now 0, -v)
  -     Subtract top 2 elements and push result (0-v, ie negated)
   n    Print as number
        The code wraps around and executes again. 
        It crashes on the - as there is only one
        item on the stack: 0.

2

Mèo xếp chồng -mn , 2 byte

-X

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

Hãy thử ngược lại!

Giải trình

Hóa ra điều này thực sự dễ dàng hơn rất nhiều so với thử thách trước đây trong Stack Mèo. Chương trình đầy đủ (sau khi áp dụng -m) ở đây là -X-. Xđược sử dụng để hoán đổi các ngăn xếp bên trái và bên phải của đầu băng, nghĩa là nó hoàn toàn không ảnh hưởng đến ngăn xếp ban đầu, vì vậy chúng ta có thể bỏ qua nó. Nhưng sau đó, chương trình chỉ có hiệu quả-- (phủ định đỉnh của ngăn xếp hai lần), mà không làm gì cả.

Đối với chương trình nghịch đảo, áp dụng -mcho X-X. Một lần nữa, Xkhông làm gì cả, vì vậy chương trình chỉ có hiệu quả -, mà phủ nhận đỉnh của ngăn xếp.

Giải pháp 2 byte duy nhất khác là -=, nhưng nó hầu như giống nhau. Sự khác biệt duy nhất là =hoán đổi chỉ các ngọn của các ngăn xếp liền kề, không phải toàn bộ các ngăn xếp.

Nhưng một lần nữa, sử dụng -mcảm thấy hơi giống như gian lận, vì vậy dưới đây là một giải pháp sử dụng một chương trình nhân đôi hoàn toàn.


Mèo xếp chồng -n , 7 byte

:I<->I:

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

Hãy thử ngược lại!

Giải trình

Các cân nhắc từ câu trả lời trước vẫn được áp dụng : bất kỳ giải pháp hợp lệ nào cũng cần sử dụng các ký tự được ghép nối và I. Sáu giải pháp có thể (bao gồm trong liên kết TIO) hầu như giống nhau. -_tương đương trong chương trình này, và: có thể được thay thế bằng |hoặc T(hoạt động tương tự cho các đầu vào khác không và ngẫu nhiên cũng hoạt động cho các đầu vào bằng 0). Tôi vừa chọn cái này để giải thích vì nó dễ nhất.

Vì vậy, hãy nhớ rằng ngăn xếp ban đầu giữ đầu vào trên đầu trang của một -1 (trên đầu có vô số số không) trong khi tất cả các ngăn xếp khác dọc theo băng chỉ giữ các số không. Stack Mèo cũng có một đặc tính là bất kỳ chương trình dài chẵn nào cũng không có gì (miễn là nó chấm dứt, nhưng dù sao chúng ta cũng không thể sử dụng các vòng lặp cho thử thách này). Điều này cũng tương tự đối với bất kỳ chương trình có độ dài lẻ nào mà nhân vật trung tâm không làm gì cả ... hãy xem:

:    Swap the input with the -1 below.
I    Move the -1 one stack to the left and turn it into +1.
<    Move another stack left (without taking the value).
-    Negate the zero on top of that stack (i.e. do nothing).

Do đó, nửa sau của chương trình chính xác hoàn tác nửa đầu và chúng tôi kết thúc với đầu vào ở trên cùng của một -1 lần nữa.

Chương trình nghịch đảo là :I>-<I:. Hãy xem điều đó thay đổi mọi thứ như thế nào:

:    Swap the input with the -1 below.
I    Move the -1 one stack to the left and turn it into +1.
>    Move one stack right, i.e. back onto the initial stack which still holds the input.
-    Negate the input.
<    Move back to the left where we've parked the 1.
I    Move that 1 back onto the initial stack and turn it back into a -1.
:    Swap the -1 below the negated input to act as an EOF marker.

2

Mẻ, 34 byte

@ECHO.%1 2>MER@
@REM>2 1%=-aa/TES@

Tiếng vang ( ECHO.) đầu vào ( %1). Phần còn lại của dòng đầu tiên về mặt kỹ thuật chuyển hướng STDERRđến một tệp được gọi MER@, nhưng điều này không ảnh hưởng.
Dòng thứ hai được nhận xét ( REM...).

Đảo ngược

@SET/aa-=%1 2>MER@
@REM>2 1%.OHCE@

Sử dụng chế độ số học của lệnh set ( SET /a) để trừ ( -=) đầu vào ( %1) từ một biến không xác định ( a) tương đương với 0 - input. Một lần nữa, phần còn lại của dòng đầu tiên về mặt kỹ thuật chuyển hướng STDERRđến một tệp được gọi MER@, nhưng điều này không ảnh hưởng.
Dòng thứ hai được nhận xét ( REM...).


Điều này có vẻ thú vị. Quan tâm để giải thích?
Adám

@ Adám Đã thêm một lời giải thích, và cũng nhận ra rằng tôi có các chương trình xung quanh.
urous

2

Brachylog , 2 byte

&ṅ

Brachylog ngầm nhập từ bên trái và đầu ra từ bên phải.
&bỏ qua mọi thứ ở bên trái và chuyển đầu vào cho hàm bên phải.
ràng buộc mỗi bên của nó là phiên bản phủ định của nhau.

Dùng thử trực tuyến


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.