Đảo ngược cực


12

Mục đích của thử thách này là viết một chương trình thỏa mãn các điều kiện sau:

  • Chương trình này không phải là palindromic, hoặc về cơ bản là palindromic (có nghĩa là có thể loại bỏ các ký tự để biến nó thành một palindrom mà không thay đổi các hiệu ứng của chương trình).

  • Chương trình không phải là một sự kết hợp (có nghĩa là nó không tạo ra đầu vào ban đầu của nó khi chạy trên đầu ra của nó)

  • Các phân cực ngược chương trình là nghịch đảo của chương trình bình thường; vì vậy khi chương trình đảo ngược được chạy trên đầu ra của chương trình bình thường, nó sẽ trả về đầu vào ban đầu.

Không đảo ngược có nghĩa là gì? Vâng, nó khác nhau giữa các ngôn ngữ.

  • Đối với hầu hết các phi esolang, điều này có nghĩa là đảo ngược thứ tự của các hoạt động phụ trong một hoạt động, đảo ngược thứ tự của các đối số và đảo ngược nội dung của các danh sách / mảng / tuples / từ điển / ngăn xếp / hàng đợi / v.v. như đảo ngược thứ tự các khối mã và các dòng độc lập (nhưng không phải các dòng trong các khối)

Ví dụ:

Haskell : x`mod`y-> y`mod`x; zipWith ((*3).(+)) [1,2,3] [4,5,6]->zipWith ((+).(*3)) [6,5,4] [3,2,1]

Con trăn : 2**3-> 3**2; for x,y in [(1,2),(3,4),(5,6)]->for y,x in [(6,5),(4,3),(2,1)]

  • Đối với các ngôn ngữ có chức năng 1 ký tự (như Pyth, APL), chỉ cần đảo ngược chuỗi hướng dẫn

  • Đối với các esolang 1 chiều như BF, đảo ngược các hướng dẫn hoặc hoán đổi cực tính; hoán đổi phân cực là []-> {}, +-> -, --> +, >-> <, <-> >, .->,,-> .(nhưng không phải cả hai)

  • Đối với các esolang 2 chiều như Befunge, bạn có thể thực hiện phản xạ trên các trục x hoặc y hoặc đường chéo, xoay 180 độ hoặc thực hiện kết hợp phản xạ và xoay

Các hoạt động giao hoán được cho phép, nhưng các hoạt động palindromic thì không: 2*xtốt, nhưng x+xlà xấu. Định nghĩa về đảo cực là khá lỏng lẻo, nhưng hãy sử dụng phán đoán của bạn để biết điều gì có ý nghĩa; đối tượng không phải là tìm kẽ hở thông minh nhất, mà là tìm ra giải pháp thông minh nhất.

Đây là một cuộc thi phổ biến, vì vậy một lỗ hổng rất thông minh có thể phổ biến, nhưng hãy cố gắng giữ vững tinh thần của thử thách này. Người chiến thắng sẽ được công bố khi có ít nhất 10 giải pháp với ít nhất 1 upvote và có ít nhất một giải pháp có nhiều upvote hơn so với các bài nộp với ít nhất 1 upvote; hoặc trong 1 tháng, tùy theo điều kiện nào đến trước. Đây là thử thách đầu tiên của tôi, vì vậy hãy cố gắng công bằng và cho tôi phản hồi mang tính xây dựng, nhưng cũng cho tôi biết nếu đây là một thử thách không hợp lý hoặc nó theo bất kỳ cách nào bị phân loại hoặc mơ hồ. Nếu bạn có câu hỏi về một ngôn ngữ không phù hợp với bất kỳ chuồng lợn nào tôi đã đặt ra ở đây, hãy bình luận và tôi sẽ uốn éo theo ý muốn của cộng đồng nếu có sự phản đối mạnh mẽ đối với việc làm rõ hoặc thay đổi quy tắc cụ thể.

CẬP NHẬT

Đã đúng 1 tháng kể từ khi cuộc thi này bắt đầu (tôi tình cờ kiểm tra nó một cách tình cờ, không biết rằng tôi đã thực sự đúng giờ). Vì đây là một cuộc thi phổ biến, người chiến thắng (bởi một trận lở đất) là Pietu1998-Befunge . Mặc dù các thành phần dưới cùng (bộ đảo ngược văn bản và bảng chữ cái ngược) đều là các tham gia, nhưng bộ mã hóa / giải mã thì không, vì vậy không có vấn đề gì ở đó. Điểm thưởng (trong tâm trí của tôi) để quản lý để viết "BEFUNGE" ở giữa. Cá nhân tôi thích sự mới lạ của giải pháp Theseus của Zgarb , vì ngôn ngữ có vẻ hay (nếu bị hạn chế). Cảm ơn tất cả mọi người đã tham gia, và trong khi người chiến thắng đã được chọn, tôi sẽ để cuộc thi này hoàn toàn mở và chào đón những bài dự thi trong tương lai.


1
Bạn có ý nghĩa gì bởi chương trình phân cực ngược là nghịch đảo của chương trình bình thường? Có đầu ra khác nhau theo một cách nào đó?
Sp3000

Nó thực hiện các hoạt động nghịch đảo; khi chương trình đảo ngược được chạy trên đầu ra của chương trình bình thường, nó sẽ trả về đầu vào ban đầu.
archaephyrryx

Xin lỗi vì lỗi; Tôi chưa từng nghe về nó trước đây và nó có vẻ hơi kỳ cục đối với tôi, vì vậy tôi phải cho rằng đó là một Esolang; Tôi sẽ thay đổi điều đó.
archaephyrryx

1
Chỉ cần một cái gì đó có lẽ nên được chỉ định - là ()palindromic? Về mặt kỹ thuật, điều ngược lại là )(.
Sp3000

1
Trong ví dụ Haskell tại sao đối số hàm không được xáo trộn đến cuối? Là sự đảo ngược được lựa chọn theo cách bảo tồn an toàn loại? Chúng ta có được phép chọn một số chi tiết của hoạt động đảo ngược cực không?
John Dvorak

Câu trả lời:


41

Befunge

Whoa, đó là một công việc, ngay cả với biên tập viên tôi đã thực hiện cho thử thách này. Đây là những gì tôi có, một khối 11x12 đẹp:

v$,g6<6g,$v
v,$ _^_ $,v
1W>v\B\v>L1
~T+:1E1:-O~
+F00-F-02L+
>:|6gUg6|:>
{a@>^N^>@z`
>1+|@G$| +>
:^9< E<  ^1
~>7^@_,#:>:
 xD>65 ^=P~
v,-\+**<  v

Nó làm một vài điều, đáng buồn chỉ cho chữ thường.

Những gì nó làm

Khi chạy bình thường, nó thực hiện một mật mã Caesar trên đầu vào.

abcxyz      -> bcdyza
exampletext -> fybnqmfufyu

Khi lật theo chiều ngang, nó đảo ngược mật mã nói. Đây là yêu cầu cho thử thách, nhưng nó không kết thúc ở đây.

bcdyza      -> abcxyz
fybnqmfufyu -> exampletext

Khi lật theo chiều dọc , nó mã hóa đầu vào với một bảng chữ cái ngược. Đây có thể được coi là cách tiếp cận ngược lại với mật mã Caesar.

abcxyz      -> zyxcba
exampletext -> vcznkovgvcg

Cuối cùng, khi xoay 180 độ, nó đảo ngược đầu vào. Tôi có cảm giác nó phải là một mặt trái của một cái gì đó (gợi ý: đầu vào).

abcxyz      -> zyxcba
exampletext -> txetelpmaxe

Làm thế nào nó hoạt động

Khối về cơ bản bao gồm bốn thuật toán bán chồng chéo.

Bộ mã hóa Caesar

v$,g6<
v,$ _^
1 >v\
~ +:1
+ 00-
>:|6g
{a@>^

Bộ giải mã mật mã Caesar (lật theo chiều ngang)

v$,g6<
v,$ _^
1 >v\
~ -:1
+ 20-
>:|6g
`z@>^

Mật mã bảng chữ cái ngược (lật theo chiều dọc)

v,-\+**<
   >65 ^
~>7^
:^9<
>1+|@
   >^

Đảo ngược văn bản (xoay 180 độ)

v  <
~      
:>:#,_@
1^  <
>+ |$
   >^

2
Tôi cho rằng Befunge có lợi thế hơn một chút ở đây, bởi vì bạn luôn có thể chỉ sử dụng góc phần tư phía trên bên trái và hoàn toàn bỏ qua những gì trong phần còn lại của mã. Mặc dù vậy công việc tốt
Martin Ender

1
Ồ Tôi phải nâng cao điều này, mặc dù điều đó có nghĩa là tôi rơi xuống vị trí thứ ba.
Cấp sông St

18

Brainfuck, 5

,+.-,

Có thể lần đầu tiên, Brainfuck đưa ra một câu trả lời cạnh tranh về độ dài mã. Xấu hổ không phải là một câu hỏi golf-code.

Nhập một byte (ký tự), tăng nó và xuất kết quả. Dấu phẩy ở cuối đang chờ một đầu vào khác, nếu được đưa ra sẽ bị bỏ qua. Không có gì trong thông số kỹ thuật về việc chấm dứt hợp lý: -) *

* (hoặc về việc làm một cái gì đó hữu ích với tất cả các mã theo cả hai hướng)

Kết quả điển hình (ký tự thứ hai nếu được bỏ qua).

Chuyển tiếp: B->C

Đảo ngược: B-> Ahoặc C->B


11

Tuyệt vời

Đây là một đơn giản để bắt đầu chúng tôi. Nó đọc một ký tự từ STDIN, tăng và in nó.

--
]]
00
]]
++

Nếu chúng ta xoay cái này 180 độ (không thay đổi dấu ngoặc) hoặc phản chiếu nó theo trục x, chúng ta sẽ nhận được

++
]]
00
]]
--

trong đó đọc một byte từ STDIN và giảm nó.

Bạn có thể kiểm tra nó ở đây .

Tôi có thể xem xét một số chương trình đáng tin cậy phức tạp hơn, nhưng tôi chắc chắn es1024 sẽ đánh bại tôi với nó. ;)

Giải trình

Đây 00là một viên bi có giá trị 0 (tùy ý). Các ]]thiết bị đọc một byte từ STDIN - nghĩa là, nếu một viên bi rơi qua chúng, giá trị của viên bi được thay đổi thành byte đọc. Các ++--các thiết bị đơn giản tăng hoặc giảm giá trị của đá cẩm thạch (mod 256) và để cho nó rơi qua. Khi một viên bi rơi ra khỏi bảng, byte được ghi vào STDOUT.

Do đó, hai thiết bị ở trên cùng chỉ đơn giản là bỏ qua vì luồng điều khiển không bao giờ chạm tới chúng.


Thay phiên, bạn có thể thay thế ba hàng giữa của mình bằng một thiết bị đầu vào.
overactor

@overactor Hay bạn muốn nói }0và sử dụng nó như một bảng con?
Martin Ender

}0như là một đầu vào dòng lệnh để được chính xác.
overactor

5

Tuyệt vời

Bảng này nhận một đối số ( x) và trả về (101 * x) mod 256.

.. @5 .. }0 }0 @1 .. @0 .. @2 .. 
.. /\ Dp << \\ .. &0 >0 &1 .. .. 
!! @3 .. << }0 .. \/ -- \/ .. }0 
@4 .. .. &0 @1 /\ &0 65 &1 /\ @2 
/\ Dp .. @4 .. .. @3 @0 @5 !! \\

Phản chiếu các ô dọc theo trục y sẽ dẫn đến một bảng nhận một đối số ( y) và trả về (101 * y + 8 * y) mod 256, đó là nghịch đảo của bảng đầu tiên.

.. @2 .. @0 .. @1 }0 }0 .. @5 ..
.. .. &1 >0 &0 .. \\ << Dp /\ ..
}0 .. \/ -- \/ .. }0 << .. @3 !!
@2 /\ &1 65 &0 /\ @1 &0 .. .. @4
\\ !! @5 @0 @3 .. .. @4 .. Dp /\

Kiểm tra điều này ở đây . Bảng hình trụ và thư viện Bao gồm cả hai nên được kiểm tra.

Ví dụ đầu vào / đầu ra :

Original Board:      Mirrored Board:
Input   Output       Input    Output
025     221          221      025
042     146          146      042
226     042          042      226

Xin lưu ý rằng Marbelous chỉ cho phép truyền các số nguyên dương làm đối số và các số nguyên này được chuyển vào chương trình modulo 256 bởi trình thông dịch.

101đã được chọn vì hai lý do: đó là một nguyên tố (và mọi đầu vào có thể có của chương trình này đều dẫn đến một đầu ra duy nhất) và hoạt động nghịch đảo có liên quan 109, đó là khoảng cách thuận tiện là 8 khoảng cách 101.

Giải thích ngắn gọn

Cột chứa các ô (từ trên xuống dưới) @0 >0 -- 65 @0chạy giống nhau trong cả hai bảng và vòng lặp 101lần trước khi đi sang phải. Ở hai bên của>0 chi nhánh là một bộ đồng bộ hóa khác nhau; cái nào được chọn tùy thuộc vào bảng có được nhân đôi hay không.

Ở mỗi bên, đồng bộ với vòng lặp trung tâm, đầu vào được lặp lại nhiều lần, do đó thu được 101*x mod 256. Trên bảng đảo ngược, hai bản sao của đầu vào cũng được dịch chuyển hai lần sang trái ( input * 4), sau đó được tóm tắt và để lại trong bộ đồng bộ hóa.

Khi vòng lặp trung tâm kết thúc, các viên bi tổng hợp được gửi để in, nằm ở bên cạnh của bảng (bên trái cho bảng gốc, bên phải để nhân đôi). Sau khi in, một !!ô được chạm tới, kết thúc bảng. Lưu ý rằng vòng lặp đã cho101 * x tiếp tục tự chạy cho đến khi bảng kết thúc.

Dp chỉ cần in ra kết quả dưới dạng số thập phân.


5

Những cái này

Điều này có thể được coi là một lỗ hổng, nhưng tôi thích ngôn ngữ, vì vậy ở đây đi. Chương trình này xác định một hàm ftrên các số tự nhiên ánh xạ 3n đến 3n + 1 , 3n + 1 đến 3n + 23n + 2 đến 3n , với mọi n .

data Num = Zero | Succ Num

iso f :: Num <-> Num
  | n                          <-> iter $ Zero, n
  | iter $ m, Succ Succ Succ n <-> iter $ Succ m, n
  | iter $ m, Succ Succ Zero   <-> back $ m, Zero
  | iter $ m, Succ Zero        <-> back $ m, Succ Succ Zero
  | iter $ m, Zero             <-> back $ m, Succ Zero
  | back $ Succ m, n           <-> back $ m, Succ Succ Succ n
  | back $ Zero, n             <-> n
  where iter :: Num * Num
        back :: Num * Num

Theseus là một ngôn ngữ có thể đảo ngược với cú pháp giống như Haskell, trong đó mọi chức năng đều không thể đảo ngược (các vấn đề giảm giá khi không kết thúc). Nó có tính thử nghiệm cao, và được thiết kế cho mục đích nghiên cứu. Đoạn mã trên xác định kiểu dữ liệu cho các số tự nhiên và hàm f. Cho một số đầu vào, bạn khớp mẫu với nó ở phía bên trái (nó luôn khớp n). Sau đó, bạn nhìn vào mô hình bên phải. Nếu mẫu đó có nhãn (ở đâyiter), bạn tiến hành khớp mẫu ở phía bên trái và một lần nữa lấy giá trị tương ứng ở phía bên phải. Điều này lặp lại cho đến khi bạn có một giá trị chưa được gắn nhãn ở bên phải và đó là đầu ra của bạn. Các mẫu ở bên trái và bên phải phải đầy đủ và không chồng chéo (riêng cho từng nhãn). Bây giờ, để "đảo ngược cực tính" của f, tôi làm như sau.

  • Hoán đổi hai giá trị của mỗi nhãn. Điều này không thay đổi ngữ nghĩa của f.
  • Hoán đổi bên phải và bên trái trong thân chức năng. Điều này xác định chức năng nghịch đảo của f thiết kế .

Kết quả:

iso f :: Num <-> Num
  | iter $ n, Zero             <-> n
  | iter $ n, Succ m           <-> iter $ Succ Succ Succ n, m
  | back $ Zero, m             <-> iter $ Succ Succ Zero, m
  | back $ Succ Succ Zero, m   <-> iter $ Succ Zero, m
  | back $ Succ Zero, m        <-> iter $ Zero, m
  | back $ Succ Succ Succ n, m <-> back $ n, Succ m
  | n                          <-> back $ n, Zero
  where iter :: Num * Num
        back :: Num * Num

3

tr

a b

Thí dụ:

$ echo "apple" | tr a b
bpple
$ echo "bpple" | tr b a
apple

Chỉ một nghịch đảo thực sự trên miền của các chuỗi không bao gồm cả 'a' và 'b'.


Bạn thực sự cần phải hạn chế tên miền nhiều hơn một chút. Ví dụ: nếu bạn bắt đầu với "bog", chương trình của bạn và ngược lại sẽ cho "bog" -> "bog" -> "aog". Vì vậy, bất kỳ chuỗi nào chứa 'b' là một vấn đề (hoặc chứa 'a', nếu bạn áp dụng chương trình đảo ngược trước).
user19057

Bạn có thể sử dụng tr abc bcavới phiên bản phân cực đảo ngược tr acb cba.
Christian Sievers

2

Một câu trả lời đáng tin cậy khác

Quyền ban đầu sẽ dịch chuyển đầu vào dòng lệnh (giá trị 8 bit), thêm đầu vào nếu 1 bị mất bằng cách dịch chuyển. ( 0000 0001 -> 1000 0000)

{0 ..
~~ ..
>> {0
-2 =0
.. ^0
\/ }0
}0 Sb
<< ..
\\ ..
:Sb
// ..
Sb >>
}0 ..
^7 }0
{0 \/

Xoay bảng này 180 ° (nhưng để nguyên nội dung của từng ô) Thay đổi chương trình để nó thay đổi ( 1000 0000 -> 0000 0001)

\/ {0
}0 ^7
.. }0
>> Sb
.. //
:Sb
.. \\
.. <<
Sb }0
}0 \/
^0 ..
=0 -2
{0 >>
.. ~~
.. {0

Bạn có thể kiểm tra nó ở đây . (bạn sẽ cần bật 'Hiển thị đầu ra dưới dạng số thập phân')

Giải trình

Cả hai chương trình bao gồm hai bảng, bảng chính (lấy đầu vào dòng lệnh) và Sb. Hãy xem xét cả hai phiên bản của bo mạch chính, chỉ nhìn vào các ô có thể đạt được theo hướng tương ứng của chúng (vì các viên bi thường không thể đi lên và các thiết bị đầu vào không ở trên cùng):

original:      flipped:
   }0          }0
}0 Sb          .. }0
<< ..          >> Sb
\\ ..          .. //

Đó là những bo mạch khá đơn giản, cả hai đều có hai bản sao của các đầu vào (mà chiếm chỗ của các }0tế bào. Các thức ăn ban đầu một phiên bản vào một thiết bị chuyển đổi trái <<phiên bản puts lật nó trong một thiết bị thay đổi ngay >>Những thực hiện một bitshift nhưng tiếc là loại bỏ bất kỳ Các bit bị mất. Đó là nơi các Sbbảng đến, họ kiểm tra xem việc bẻ khóa giá trị mà chúng được cung cấp có dẫn đến một bit bị mất hay không và trả về một giá trị được thêm vào kết quả để chống lại bit bị mất.

Đây là phần có liên quan của Sbbảng gốc cho chương trình gốc:

}0
^7
{0

Cái này cực kỳ dễ, `^ 7 'kiểm tra giá trị của bit đáng kể nhất. Nếu cái này là 1, thực hiện dịch chuyển trái sẽ khiến bit này bị mất. Vì vậy, bảng này đưa ra giá trị của bit này dưới dạng giá trị 8 bit được thêm vào kết quả của bithift.

Đối với phiên bản lật, Sbphải xem xét bit và trả về ít nhất, 128hoặc 0điều này phức tạp hơn một chút:

}0
^0 ..
=0 -2
{0 >>
.. ~~
.. {0

Nếu bit có ý nghĩa nhỏ nhất (như được kiểm tra bởi ^0) là 0, nó chỉ trả về 0. Nếu là một, ^0sẽ xuất ra 1. Điều này sẽ thất bại trong bài kiểm tra đẳng thức 0 =0và do đó được đẩy sang phải. Sau đó, chúng tôi trừ 2 -2để nhận 255, dịch chuyển trái >>để lấy 127 và thực hiện nhị phân không ~~nhận 128 (chúng tôi cũng có thể chỉ cần thêm một ++để nhận 128, nhưng đâu là niềm vui trong đó?)

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.