Đảo ngược thuật toán khối Rubik


19

Bất cứ khi nào bạn thực hiện một di chuyển trên Rubik's Cube, sẽ có một động thái ngược lại hoàn tác bước di chuyển đầu tiên. Bởi vì điều này, mọi thuật toán (tập hợp các bước di chuyển) có một thuật toán đảo ngược để hoàn tác thuật toán đầu tiên.

Mục tiêu của thử thách này là tìm ra mặt trái của một thuật toán nhất định.

Đặc điểm kỹ thuật:

Đầu vào bao gồm một loạt các di chuyển cá nhân. Mỗi lần di chuyển là một chuỗi có độ dài 1 hoặc 2. Tất nhiên, bạn có thể sử dụng bất kỳ định dạng đầu vào nào có ý nghĩa nhất trong ngôn ngữ của bạn. Mỗi di chuyển bao gồm cấu trúc Xhoặc X'hoặc X2, trong đó Xlà một chữ cái viết hoa hoặc chữ thường.

Để đảo ngược X, chỉ cần thay thế nó bằng X'. Tương tự như vậy, X'trở thành X. X2mặt khác không được thay đổi.

Để tạo đầu ra, đảo ngược từng di chuyển, và sau đó đảo ngược mảng.

Ví dụ (các chuỗi được phân tách bằng dấu cách):

R => R'

D U' => U D'

S T A C K => K' C' A' T' S'

A2 B2 => B2 A2

Ghi điểm:

Đây là môn đánh gôn, vì vậy số lượng byte ít nhất sẽ giành chiến thắng. Sơ hở tiêu chuẩn không được phép.


Được R2-> R2'hay B-> B3được phép?
Máy

2
Phải xử lý X3hoặc X1sẽ là một bổ sung tốt đẹp cho thử thách.
Shaggy

1
"Bởi vì điều này, mọi thuật toán (tập hợp các bước di chuyển) có một thuật toán đảo ngược hoàn tác thuật toán đầu tiên" điều này có đúng với mọi thuật toán không ?? Vì tôi nghĩ các thuật toán băm là một cách. Có nghĩa là nó không có bất kỳ thuật toán đảo ngược nào, phải không? xin vui lòng cho tôi biết
Avishek Saha

4
@AvishekSaha: Đối với các sự cố Cube của Rubik, "thuật toán" bị giới hạn theo nghĩa "một chuỗi các động tác bạn có thể thực hiện trên Cube". Theo nghĩa này, không có thứ gọi là thuật toán băm một chiều trên Cube.
Ross Presser

5
Đáng lẽ phải có D2R2một trường hợp thử nghiệm ...
Neil

Câu trả lời:



7

V , 13 10 byte

æGÇä/á'Ó''

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

3 byte được lưu nhờ @nmjmcman chỉ ra tính năng yêu thích của tôi. Giải trình:

æG          " Revere the order of every line
  Ç         " On every line not containing...
   ä/       " a digit:
     á'     "   Append an '
       Ó    "   Remove every instance on this line
        ''  "     Of two single quotes

äthích đại diện cho một regex khi biên dịch sang vim không?
Hạ cấp

@Downgoat Vâng! Nó làm. Được dịch sang vim, giải pháp này là :g!/\d/norm A'<CR>:%s/''//g<CR>gg:g/^/m0<CR>Thông tin thêm về cách V nén các biểu thức thông thường có thể được tìm thấy ở đây
DJMcMayhem

@DJMcMayhem Không phải là kết thúc ngầm như tính năng yêu thích của bạn? Hãy thử trực tuyến!
nmjcman101

3
Tôi biết điều này là khá muộn, nhưng điều này không làm việc cho tôi. Nó biến R2 thành 2R, không hợp lệ
Jamie Sanborn

7

Võng mạc 0.8.2 , 27 26 byte

\w
$&'
''

'2'
2
O$^`.'?2?

Hãy thử trực tuyến! Liên kết bao gồm các trường hợp thử nghiệm. Giải thích: Giai đoạn đầu tiên thêm dấu nháy đơn sau mỗi chữ số. Điều này dẫn đến các dấu nháy đơn (có hoặc không bao gồm 2) cần được loại bỏ. Giai đoạn cuối cùng đảo ngược các động thái.


Điều này có thể được cải thiện với việc phát hành Retina 1.0 không?
MD XF

@MDXF Có vẻ như O$^trên thực tế vẫn là cách tốt nhất để đảo ngược danh sách các trận đấu, vì vậy số byte thực sự không thay đổi trong Retina 1.
Neil

5

JavaScript (ES6), 45 byte

s=>s.map(([a,b])=>b?+b?a+b:a:a+"'").reverse()

Giải pháp ngắn nhất là lấy Array IO. Sử dụng đơn giản và thích hợp của phá hủy đối số.

Đầu ra chuỗi là +8 byte cho .join` `.

Đầu vào chuỗi, đầu ra mảng: 69 byte

(s,k=[])=>s.replace(/\S\S?/g,([a,b])=>k.unshift(b?+b?a+b:a:a+"'"))&&k

f=

(s,k=[])=>s.replace(/\S\S?/g,([a,b])=>k.unshift(b?+b?a+b:a:a+"'"))&&k

;

console.log(["R", "D U'", "S T A C K", "A2 B2"].map(e => `${e} => ${f(e)}`));
<textarea oninput="out.value=(f(this.value)||[]).join` `" placeholder="input here"></textarea>
<textarea id="out" readonly></textarea>


Đẹp một. Tại sao tôi không bao giờ nghĩ đến việc phá hủy các tham số chức năng?! :(
Xù xì

Bạn sẽ có thể thay thế .reverse()bằng cách ::reversetiết kiệm 1 byte nhưng tạo ES7
Downgoat

@Downgoat Bất cứ nơi nào tôi có thể kiểm tra ES7?
Conor O'Brien

@ ConorO'Brien bạn có thể sử dụng REPL trực tuyến của babel (đánh dấu vào thực thi và tất cả các hộp đặt sẵn cho tất cả các tính năng): babeljs.io/repl
Downgoat

4

Thạch , 11 byte

ḟ;ċ?”'ḣ2µ€Ṛ

Một liên kết đơn âm lấy một danh sách các danh sách các ký tự (một "mảng" của "chuỗi").

Hãy thử trực tuyến! (Chân trang tránh việc phá vỡ đầu ra, hiển thị phân chia danh sách với khoảng trắng.)

Làm sao?

ḟ;ċ?”'ḣ2µ€Ṛ - Link: list of lists of characters             e.g. ["F'", "D2" , "R"]
        µ€  - perform the chain to the left for €ach turn instruction:
    ”'      -   literal "'" character
   ?        -   if:
  ċ         -     count (number of "'" in the instruction) i.e.:  1   , 0    , 0
ḟ           -   then: filter out                                  "F"
 ;          -   else: concatenate                                       "D2'", "R'"
      ḣ2    -   head to index 2                                   "F" , "D2" , "R'"
          Ṛ - reverse                                            ["R'", "D2" , "F"]

10 byte với Jelly mới.
dùng202729

4

JavaScript (ES6), 46 byte

Đưa đầu vào như một mảng di chuyển.

a=>a.map(m=>m[1]?+m[1]?m:m[0]:m+"'").reverse()

Kiểm tra nó

Nhập một danh sách di chuyển được phân tách bằng dấu phẩy.

o.innerText=(f=
a=>a.map(m=>m[1]?+m[1]?m:m[0]:m+"'").reverse()
)((i.value="S,T,A,C,K").split`,`);oninput=_=>o.innerText=f(i.value.split`,`)
<input id=i><pre id=o>


Giải trình

a=>

Hàm ẩn danh lấy mảng di chuyển làm đối số thông qua tham số a.

a.map(m=>                       )

Ánh xạ qua mảng, chuyển từng chuỗi qua một hàm, trong đó mlà chuỗi hiện tại.

 m[1]?

Kiểm tra xem chuỗi có chứa ký tự thứ hai thứ hai ( "'"hoặc "2") không.

+m[1]?

Nếu nó cố gắng truyền chuỗi ký tự đó thành một số nguyên. Nếu chuỗi là "2", nó trở thành 2, đó là sự thật. Nếu chuỗi là "'", nó trở thành NaN, đó là falsey.

m

Nếu bài kiểm tra trước là trung thực, chỉ cần quay lại m.

:m[0]

Nếu không, trả lại ký tự đầu tiên của m.

:m+"'"

Nếu chuỗi không chứa ký tự thứ hai thì trả về được mnối với a '.

.reverse()

Đảo ngược mảng sửa đổi.


Xin lỗi, tôi chỉ thấy điều này. Câu trả lời của riêng tôi tương tự như của bạn: P
Conor O'Brien

2

Python ,  51  48 byte

lambda a:[(v+"'")[:2-("'"in v)]for v in a[::-1]]

Một hàm không tên lấy và trả về danh sách các chuỗi.

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

Đảo ngược danh sách đầu vào với a[::-1]; nối thêm 'vào mỗi mục với v+"'"; đứng đầu mỗi một đến 1 hoặc 2 ký tự tùy thuộc vào việc bản gốc có 'in hay không [:2-("'"in v)].


2

Python 3 , 91 89 72 70 69 65 byte

lambda s:[i[0]+(len(i)-2and"'"or"2"*("2"==i[1]))for i in s[::-1]]

Hãy thử trực tuyến! (Có tủ thử)

Bạn không cần phải lấy đầu vào và đầu ra dưới dạng chuỗi, vì vậy giải pháp 69 byte là có thể


AFAIK bạn có thể xóa khoảng trắng saulen(i)==1
Stephen

@StepHen Huh, không biết rằng được phép (Biết rằng một số thông dịch viên cho phép nó, chỉ không biết nó cho phép trong codegolf)
sagiksp

2
Các ngôn ngữ được định nghĩa bởi các thông dịch viên của họ ở đây vì vậy, nếu nó hoạt động trong bất kỳ một trình thông dịch nào, thì nó hợp lệ.
Xù xì

Nếu thông dịch viên cho phép nó, bạn có thể làm điều đó. Đó là tất cả sự quan tâm của golf-code;)
Stephen

len(i)-2ngắn hơn len(i)==1(nhớ 0 là falsey)
Stephen



1

05AB1E , 13 byte

RεÐ1èQ''si«ëK

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

Giải trình

RεÐ1èQ''si«ëK
R             # Reverse input array
 ε            # Map over each element...
  Ð1èQ         # Is the second char in the element the first one? (Uses the fact that in python indexing loops)
      ''       # Push '
        s      # Swap top items of stack
         i     # If the question above is true...
          «     # Concatenate
           ë   # Else
            K   # Push element without '  

1

J, 25 byte

J xử lý tốt điều này, ngoài chuỗi thoát đáng tiếc cần thiết để thể hiện một trích dẫn:

|.,&''''`}:@.(''''={:)&.>

Chúng ta cần thể hiện danh sách bằng cách sử dụng dữ liệu được đóng hộp, vì đó là sự pha trộn của một và hai mục ký tự, do đó:

  • &.> - "trong unbox", có nghĩa là bỏ hộp từng phần tử, thực hiện thao tác theo sau (nghĩa là các ký hiệu được giải thích bên dưới) và sau đó rebox khi hoàn tất
  • (''''={:) "nếu ký tự thứ 2 là một trích dẫn" ....
  • @. (Động từ chương trình nghị sự của J, một loại tuyên bố ternary tổng quát hoặc tuyên bố trường hợp) "sau đó thực hiện mục thứ 2 trong danh sách chương trình nghị sự, nếu không thì thực hiện đầu tiên"
  • }: (mục thứ 2 trong danh sách chương trình nghị sự), "xóa ký tự cuối cùng", nghĩa là trích dẫn đơn
  • `(Động từ tie của J) Bạn có thể coi đây là dấu phân tách mục chương trình nghị sự
  • ,&'''' (mục đầu tiên trong danh sách chương trình nghị sự) "thêm một trích dẫn vào cuối"
  • |. "đảo ngược"

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




0

Java 8, 141 128 126 byte

a->new StringBuffer(a.replaceAll("(.)","$1'").replace("'''","").replaceAll("(.)'","'$1").replaceAll("'(.)'2","2$1")).reverse()

Đưa đầu vào dưới dạng đơn Stringkhông có khoảng trắng (nghĩa là RUR'URU2R'U).

Giải trình:

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

a->new StringBuffer(           // Method with String parameter and StringBuffer return-type
  a.replaceAll("(.)","$1'")    //1  Add an apostrophe after every character
   .replace("'''","")          //2  Remove all occurrences of three adjacent apostrophes
   .replaceAll("(.)'","'$1")   //3  Reverse letter+apostrophe to apostrophe+letter
   .replaceAll("'(.)'2","2$1") //4  Reverse letter+2 to 2+letter and remove aphostrophes
  ).reverse()                  //5 Reverse everything

Ví dụ về các bước trên, với đầu vào như đã cho: RUR'URU2R'U

  1. RUR'URU2R'UR'U'R'''U'R'U'2'R'''U'
  2. R'U'R'''U'R'U'2'R'''U'R'U'RU'R'U'2'RU'
  3. R'U'RU'R'U'2'RU''R'UR'U'R'U'2R'U
  4. 'R'UR'U'R'U'2R'U'R'UR'U'R2UR'U
  5. 'R'UR'U'R2UR'UU'RU2R'U'RU'R'
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.