Tôi có thể xâu chuỗi tất cả các dây và bộ điều hợp của tôi lại với nhau không?


30

Giả sử một ngày nào đó bạn đang đào bới hộp lớn các dây và bộ điều hợp máy tính không sử dụng (USB sang USB mini, VGA sang DVI, v.v.). Có những dây bị rối ở khắp mọi nơi làm cho khá lộn xộn, và bạn tự hỏi liệu bạn có thể đơn giản hóa mọi thứ bằng cách gắn tất cả các dây với nhau trong một sợi dài, và sau đó chỉ cần cuộn nó lại.

Câu hỏi là, có thể kết nối tất cả các dây và bộ điều hợp của bạn trong một hàng dài như thế này không? Rõ ràng không phải lúc nào cũng có thể, ví dụ nếu bạn chỉ có hai dây với các phích cắm hoàn toàn khác nhau, chúng không thể được kết nối với nhau. Nhưng nếu bạn có một sợi dây thứ ba có thể kết nối với cả hai, thì bạn có thể xâu chuỗi tất cả các dây của bạn lại với nhau.

Bạn không quan tâm đến loại phích cắm nào ở hai đầu của sợi dây. Họ không cần phải cắm vào nhau để tạo thành một vòng lặp. Bạn chỉ muốn biết nếu làm cho tất cả các sợi dây là có thể, và nếu có, làm thế nào để làm điều đó.

Thử thách

Viết chương trình hoặc hàm có trong một chuỗi nhiều dòng trong đó mỗi dòng mô tả một trong các dây bạn sở hữu. Một dây được tạo thành từ một hoặc nhiều dấu gạch ngang ( -), với một đầu cắm ở hai đầu. Một phích cắm luôn là một trong 8 ký tự ()[]{}<>.

Vì vậy, đây là một số dây hợp lệ:

>->
(--[
}-{
<-----]
(---)

Nhưng đây không phải là:

-->
(--
)--
[{
---

Khi kết nối dây, chỉ các phích cắm có cùng loại khung chính xác mới có thể được kết nối với nhau.

Vì vậy, đây là một số kết nối dây hợp lệ:

...---((---...
...---))---...
...---]]---...
...---{{---...
...---<<---...

Và những điều này không hợp lệ:

...---()---...
...---)(---...
...---{]---...
...---{[---...
...---><---...
...--->)---...

Nếu tất cả các dây trong đầu vào có thể được sắp xếp lại và gắn với nhau thành một chuỗi dài, thì đầu ra chuỗi đó sẽ xuất ra trên một dòng (với một dòng mới theo dõi tùy chọn). Khi có nhiều giải pháp, bạn có thể chọn bất kỳ giải pháp nào để xuất. Nếu không thể tạo một chuỗi đơn, thì không xuất ra được gì (hoặc xuất ra một chuỗi trống với một dòng mới tùy chọn).


Ví dụ: nếu đầu vào là

[-->
{---]
>----{

đầu ra có thể là

[-->>----{{---]

nơi tất cả các dây được nối với nhau.

Tuy nhiên nếu đầu vào là

[-->
{---]

các dây không thể được kết nối nên sẽ không có đầu ra.


Lưu ý rằng dây có thể được lật xung quanh càng nhiều cần thiết để tạo kết nối. ví dụ [--><--]thực sự là cùng một dây bởi vì chúng có thể tạo ra cùng loại kết nối. Một số đầu ra có thể phụ thuộc vào việc lật các dây đầu vào.


Ví dụ

(-[
}--]

có thể có đầu ra

(-[[--{

nơi dây thứ hai được lật, hoặc

}--]]-)

nơi dây đầu tiên được lật.

(Lưu ý rằng nói chung việc lật toàn bộ đầu ra là hợp lệ vì nó giống như lần đầu lật từng dây riêng lẻ.)


Độ dài của dây trong đầu ra tất nhiên phải khớp với độ dài của dây đầu vào tương ứng. Nhưng các dây có thể được sắp xếp lại và lật xung quanh nhiều như bạn muốn để tạo ra các sợi dây. Đầu vào sẽ luôn chứa ít nhất một dây.

Mã ngắn nhất tính bằng byte thắng.

Các trường hợp thử nghiệm

Các trường hợp có đầu ra:

[-->
{---]
>----{
gives
[-->>----{{---]
or
[---}}----<<--]

(-[
}--]
gives
(-[[--{
or
}--]]-)

(-)
gives
(-)

[--{
gives
[--{
or
}--]

[-]
]-[
gives
[-]]-[
or
]-[[-]

[----->
)------------[
{--<
}---)
could give
[----->>--}}---))------------[
or
>--}}---))------------[[----->
or
}---))------------[[----->>--}
or
{--<<-----]]------------((---{
etc.

>-->
>->
>--->
could give
>-->>->>--->
or
>--->>-->>->
or
>->>-->>--->
or
<--<<---<<-<
etc.

(-]
]->
>-}
}-)
)-[
[-<
<-{
{-(
could give
(-]]->>-}}-))-[[-<<-{{-(
or
{-((-]]->>-}}-))-[[-<<-{
or
<-{{-((-]]->>-}}-))-[[->
etc.

Các trường hợp không có đầu ra:

[-->
{---]

[-]
[-]

(-]
]->
}-)

>->
>-->
]---]

[-------------------]
]-------------------[
[-----------------]
[-----------------]

{--[
]--}

6
hộp lớn của dây và bộ điều hợp máy tính không sử dụng Điều đó làm tôi cảm thấy tốt hơn - tôi không phải là người duy nhất. Trên thực tế tôi có một vài trong số các hộp này.
Chấn thương kỹ thuật số

Nhưng nếu bạn cắm một sợi dây vào chính nó thì sao?
anOKsquirrel 7/12/2015

Các dây được đảm bảo cho tất cả là hợp lệ?
R. Kap

@ R.Kap Đúng vậy
Sở thích của Calvin

Câu trả lời:


10

Không thể đọc được , 3924 byte

Đây là lần đầu tiên tôi triển khai phần nào cấu trúc giống như ngăn xếp cuộc gọi trong Không thể đọc được.

(Phiên bản đầu tiên của cái này là hơn 5300 byte, chỉ để đưa ra ý tưởng về việc tôi đã chơi golf này bao nhiêu.)

"" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" " "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" """" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" " "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" """ "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" " "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" """ "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" " "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" " "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" """" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" " "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" " "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" """" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" " "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" """" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" " "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" " "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" """" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" """" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" " "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" """" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" """ "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" " "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" " "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" """" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" """" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" """ "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" " "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" """ "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" " "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" """ "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" " "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" " "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" """" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" " "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" """ "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" " "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" " "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" """ "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" " "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" """" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" " "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" " "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" """" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" " "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" """ "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" " "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" """" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" " "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" " "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" """" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" """ "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" " "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" """ "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" " "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" " "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" """" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" " "" "" """" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" " "" "" "" "" "" "" """" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" " "" "" "" "" "" "" ""

Giải trình

Xem xét ví dụ đầu vào này:

>--{
[---}

Trong suốt phần lớn thời gian thực hiện, đoạn băng được trình bày như sau:

  • Các ô từ 0 đến 5 là các vị trí cho các biến khác nhau.

  • Ô 6 trở đi chứa tất cả thông tin về bộ cáp trong hộp của bạn:

    ví dụ bố trí băng

  • Các ô còn lại sau bộ kết thúc zero zero có chứa ngăn xếp. Mỗi stackframe của Cameron là một ô duy nhất trỏ đến ô đầu tiên của cáp (ô bắt đầu cắm cắm). Trong ví dụ trên, khi chương trình quyết định đã tìm ra giải pháp, ngăn xếp sẽ chứa 6 (tham chiếu đến >--{cáp thứ nhất) và 21 (tham chiếu đến {---]gương của cáp thứ hai).

Chương trình tiến hành theo ba giai đoạn chính:

  1. Đọc toàn bộ đầu vào và tạo cấu trúc trên, bao gồm tất cả các cáp được nhân đôi.
  2. Hãy thử tất cả các kết hợp (nhưng dừng lại nếu tìm thấy giải pháp).
  3. Nếu một giải pháp đã được tìm thấy, đầu ra nó.

Giai đoạn đầu tiên (đọc cấu trúc đầu vào và tạo cáp) chỉ sử dụng các ô số 1 (mà tôi sẽ gọi p) và # 2 (mà tôi sẽ gọi ch) và hoạt động theo vòng lặp while như sau:

  • Trong khi điều kiện: tăng thêm p6, hãy đọc ký tự tiếp theo (bắt đầu cắm) vào ô *pvà kiểm tra xem nó không -1(EOF).

  • Đọc các ký tự tiếp theo *(p+2)và đếm chúng *(p+1)cho đến khi chúng ta bắt gặp bất cứ thứ gì khác ngoài -(gạch nối). Tại thời điểm đó, *(p+1)sẽ chứa số lượng dấu gạch nối (chiều dài cáp) và *(p+2)ký tự không gạch nối cuối cùng (đầu cắm cuối). (Chúng tôi cũng sao chép các ký tự dấu gạch nối vào ô số 5 để chúng tôi có thể truy cập mã ASCII này sau trong giai đoạn đầu ra.)

  • Trong một vòng lặp while, tìm phích cắm gương và lưu trữ tại *(p+3), sau đó tăng thêm p2, cho đến khi *pbằng không. Vòng lặp trông như thế này trong mã giả:

    while (ch = *p) {
        *(p+3) = (ch -= 40) ? (ch -= 1) ? (ch -= 19) ? (ch -= 31) ? ch-32 ? *p-2 : *p+2 : *p+2 : *p+2 : *p-1 : *p+1
        p += 2
    }
    
  • Vòng lặp này sẽ luôn thực hiện hai lần lặp (phích cắm bắt đầu và phích cắm kết thúc) và lưu trữ kết quả trong ô thứ tư và thứ sáu của cáp này. Bây giờ, nếu bạn chú ý, bạn sẽ nhận ra rằng ô thứ sáu thực sự là vị trí chính xác cho đầu cắm được nhân đôi, nhưng phích cắm bắt đầu được nhân đôi nằm trong ô có nhãn Boolean chỉ ra cáp gốc. Điều này là ổn vì chúng ta chỉ cần ô này là giá trị khác không.

  • pmới được tăng tổng cộng 4, nên giờ nó chỉ vào ô có nhãn Cáp boolean được sử dụng. Đặt *(p+3)thành giá trị của *(p-1). Điều này đặt phích cắm bắt đầu nhân đôi ở đúng nơi.

  • Đọc (và loại bỏ) thêm một ký tự (mà chúng tôi dự kiến ​​là một dòng mới, nhưng chương trình không kiểm tra điều đó).

pban đầu bắt đầu từ 0 nhưng được tăng thêm 6 trong điều kiện while, do đó dữ liệu cáp bắt đầu từ ô số 6. pđược tăng thêm 4 bên trong thân vòng lặp, và do đó tổng cộng 10 cho mỗi cáp, đó chính xác là những gì chúng ta cần.

Trong giai đoạn thứ hai, các tế bào # 0-4 đang bị chiếm đóng bởi các biến mà tôi sẽ gọi a, p, q, m, và notdone. (Ô số 5 vẫn còn nhớ mã ASCII của dấu gạch nối.)

Để sẵn sàng cho giai đoạn 2, chúng ta cần đặt *plại về 0 (ô có nhãn Term zero terminator) để nó có thể đóng vai trò là đầu cuối cho danh sách các dây cáp; chúng tôi cũng đặt q(là con trỏ ngăn xếp của chúng tôi) thành p+1(tức là ô sau bộ kết thúc zero zero, đây là nơi ngăn xếp bắt đầu); *qđến 1 (mục đầu tiên trên ngăn xếp; tại sao 1 sẽ trở nên rõ ràng sau); và notdoneđến 1. Tất cả điều này được thực hiện trong một tuyên bố duy nhất:

*p = (notdone = *(q = p+1) = 1)-1

Giai đoạn thứ hai cũng là một vòng lặp while. Điều kiện của nó chỉ đơn giản là notdone. Trong mỗi lần lặp của vòng lặp while đó, bất kỳ một trong bốn điều sau đây đều có thể xảy ra:

  1. Chúng tôi thấy rằng tất cả các dây cáp đều được đánh dấu trên nền tảng sử dụng. Điều này có nghĩa là chúng tôi đã tìm thấy một giải pháp (được thể hiện bằng nội dung ngăn xếp hiện tại).
  2. Chúng tôi có thể chuyển *qsang một cáp đủ điều kiện khác (mà chúng tôi đã nhanh chóng đánh dấu là sử dụng trực tuyến cùng với bộ đôi của nó) và sau đó lặp lại (nghĩa là tạo một stackframe mới).
  3. Chúng tôi không thể tiến lên *qvì không còn cáp đủ điều kiện tồn tại nữa, vì vậy chúng tôi cần quay lại (xóa một stackframe và đánh dấu cáp trước đó và cáp đôi của nó là không còn sử dụng nữa).
  4. Chúng tôi không thể tiến lên *qvì không còn cáp đủ điều kiện tồn tại và chúng tôi không thể quay lại vì chúng tôi đã chạm đến đáy của ngăn xếp. Điều này có nghĩa là không có giải pháp.

Thân vòng lặp kiểm tra từng điều kiện trong bốn điều kiện này theo thứ tự này. Đây là những thông tin chi tiết:

  1. Đặt mpthành 1 và trong một vòng lặp while, tăng thêm p5 (do đó lặp qua các dây cáp) và kiểm tra xem *(p+4)(có sử dụng hay không). Nếu không, đặt mthành 0. Ở cuối vòng lặp đó, hãy mcho chúng tôi biết nếu tất cả các dây cáp đang được sử dụng. Nếu vậy, đặt notdonethành 0 để kết thúc vòng lặp chính. Nếu không, tiếp tục ở bước 2 bên dưới.

  2. Đặt pthành *q(cáp ở đầu ngăn xếp) và trong vòng lặp while tương tự như trên, tăng thêm p5 để lặp qua các cáp. Bắt đầu tại *qđảm bảo chúng tôi chỉ xem xét những người mà chúng tôi chưa xem xét trước đó; tuy nhiên, hãy nhớ rằng giá trị ban đầu cho stackframe mới là 1, do đó, cáp đầu tiên được xem là cáp ở ô 6, đây thực sự là cáp đầu tiên.

    Đối với mỗi hình cáp, chúng ta cần phải kiểm tra *(p+4)để đảm bảo rằng nó không phải là đã được sử dụng, và cũng là một trong hai *(q-1) là zero (có nghĩa là chúng ta đang ở dưới cùng của ngăn xếp, vì vậy không có hạn chế về các plug bắt đầu), hoặc *p (bắt đầu của cáp phích cắm) bằng *(*(q-1)+2)(đầu cắm cuối của cáp ngay bên dưới ngăn xếp). Chúng tôi kiểm tra sự bằng nhau bằng cách đặt athành *(*(q-1)+2)mđến *p+1và sau đó giảm cả hai trong một vòng lặp while. Các +1là vì mđược giảm đi trong khi điều kiện, vì vậy nó được giảm đi một lần hơn a. Nếu abằng 0 ở cuối này, hai phích cắm bằng nhau.

    Do đó, nếu *(q-1)bằng 0 hoặc so sánh đẳng thức thành công, cáp có đủ điều kiện. Đặt *qđể pthay thế cáp ở đầu ngăn xếp bằng cáp mới; được đặt mgiống nhau để chỉ ra rằng chúng tôi đã tìm thấy một cáp phù hợp; và sau đó giảm dần p. Sự suy giảm đó là một mẹo nhỏ để khiến vòng lặp while (lặp qua các dây cáp) kết thúc sớm; nó sẽ tăng thêm p5 lần nữa, do đó đưa nó đến ô có chứa cờ của Cáp này trong cờ sử dụng và chúng tôi biết đó là số 0 vì chúng tôi chỉ kiểm tra điều đó. Cuối cùng, sau vòng lặp lặp cáp, chúng tôi kiểm tra xem mcó khác không không. Nếu vậy, chúng tôi đã tìm thấy một dây cáp phù hợp và pđang chỉ vào cờ của người dùng đang sử dụng cho một loại cáp phù hợp. Đặt thành 1 để đánh dấu là đang sử dụng. Cũng đặt*(*(p-1) ? p+5 : p-5)đến 1 để đánh dấu sinh đôi của nó như đang sử dụng. Cuối cùng, tăng qvà đặt mới *qthành 1 để tạo một stackframe mới.

  3. Nếu, sau vòng lặp lặp trong khi lặp cáp, chúng ta thấy mbằng 0, không còn cáp nào khớp nữa, vì vậy chúng ta cần quay lại. Giảm qđể di chuyển xuống ngăn xếp và kiểm tra xem nó có còn chỉ vào cáp không (giá trị khác không). Nếu vậy, đánh dấu cáp và bộ đôi của nó là không sử dụng nữa. (Chúng tôi lưu trữ giá trị của *qin pđể làm cho biểu thức này ngắn hơn trong mã.)

  4. Nếu, sau khi giảm q, chúng ta thấy rằng nó trỏ đến một giá trị 0, thì đó là bộ kết thúc số 0 không có nghĩa, có nghĩa là chúng ta đã vượt qua ngăn xếp. Chúng tôi kết luận rằng không có giải pháp. Chúng tôi đặt notdonethành 0 để chấm dứt vòng lặp chính.

Giai đoạn thứ ba là giai đoạn đầu ra. Có hai điều có thể xảy ra:

  • vòng lặp chính tìm thấy một giải pháp mà chúng ta cần xuất ra, hoặc
  • vòng lặp chính kết luận không có giải pháp và chúng tôi không có kết quả.

Thuận tiện, nếu không có giải pháp, plà 0 vì chúng tôi đặt nó thành giá trị *qtrước khi kiểm tra giá trị đó bằng 0; và nếu có một giải pháp, pđược chỉ vào “zero terminator” bởi vì nó chỉ lặp thông qua cáp, vì vậy bây giờ chúng ta có thể sử dụng pđể lặp qua stack. Vì vậy, chỉ cần lặp qua ngăn xếp, xuất ra cho mỗi cáp đầu cắm ( *(*p)), dấu gạch nối (bằng cách giảm *(*p+1)trong vòng lặp while và sử dụng mã ASCII gạch nối được lưu trữ trong ô số 5) và đầu cắm cuối ( *(*p+2)). Đừng bận tâm rằng điều này sẽ phá hủy thông tin chiều dài cáp; chúng ta không cần điều đó nữa.


3

CJam, 67

qN%e!{_,2,m*\f{.{_{"()[]{}<>--"_@#1^=}%W%?}_2ew{~\W=#}%0-{;}&}~}%1<

Dùng thử trực tuyến

Lưu ý: liên kết đang sử dụng mã mới nhất từ ​​kho lưu trữ (đã đẩy nhưng chưa được phát hành), vì nó chứa một bản sửa lỗi.

Giải trình:

Chương trình chỉ đơn giản là thử tất cả các hoán vị và tất cả các định hướng của dây.

qN%             read the input and split into lines
e!              generate all permutations
{…}%            map each permutation of cords
  _,            get the number of cords (n)
  2,m*          generate all patterns of n bits (cartesian power of [0 1])
  \f{…}         for each bit pattern and the cord permutation
    .{…}        apply the block to each bit and cord (flipping cords for bit 0)
      _         duplicate the cord
      {…}%      map each character of the cord
        "…"_    push the string of all the plugs (and 2 dashes) and duplicate it
        @#      get the index of the character in the string
        1^      XOR with 1
        =       get the character at this new index (plugs get toggled)
      W%        reverse the cord
                 the stack now has the bit, the original cord and the flipped cord
      ?         if the bit is 1, use the original cord, else use the flipped one
    _           duplicate the array of cords
    2ew         get all pairs of adjacent cords
    {…}%        map each pair of cords
      ~\        dump the 2 cords on the stack and swap them
      W=        get the right plug of the first cord
      #         find its position in the second cord (if 0, we have a match)
    0-          remove all the zeros
    {…}&        if the array is not empty (i.e. we have a mismatch)
      ;         pop the array of cords
  ~             dump all the results for this permutation on the stack
                 (to avoid nested arrays)
1<              get the first result (if any) from the array of all results

Có lẽ một lời giải thích về cách nó hoạt động chính xác?
Timwi

@Timwi ok, tôi cũng đánh gôn thêm một chút
aditsu

Giải pháp này không hợp lệ vì nó không tạo ra bất kỳ đầu ra nào cho đầu vào (-] ]-> >-} }-) )-[ [-< <-{ {-(.
R. Kap

@ R.Kap nó giải quyết đầu vào đó, nhưng trình thông dịch trực tuyến cụ thể đó có thời gian chờ (và khá im lặng về nó). Bạn có thể thử nó ở đây thay vào đó (và cho nó vài phút) hoặc sử dụng trình thông dịch java (nhanh nhất)
aditsu

Trên thực tế, trình thông dịch mà tôi liên kết ở trên có thể sẽ mất nhiều thời gian để giải quyết đầu vào đó. Trình thông dịch java giải quyết nó trong chưa đầy 1,5 phút trên máy tính của tôi.
aditsu

2

JavaScript (ES6), 206

Hàm đệ quy

f=(l,a=l.pop(),x=x=>(z='<>[]{}()')[z.indexOf(x)^1])=>l[0]?l.some((b,i)=>r=[b,x([...b].pop())+b.slice(1,-1)+x(b[0])] .some(b=>r=a[0]==[...b].pop()?b+a:b[0]==[...a].pop()?a+b:0)&&(l=[...l],l[i]=r,f(l)))?r:'':a

Dễ đọc hơn

f=(l,a=l.pop(),x=x=>(z='<>[]{}()')[z.indexOf(x)^1])=>
  l[0]?
  l.some((b,i)=>
     r=[b,x([...b].pop())+b.slice(1,-1)+x(b[0])]
     .some(b=>r=a[0]==[...b].pop()?b+a:b[0]==[...a].pop()?a+b:0)
     &&(l=[...l],l[i]=r,f(l))
    )?r:''
 :a

Kiểm tra

f=(l,a=l.pop(),x=x=>(z='<>[]{}()')[z.indexOf(x)^1])=>l[0]?l.some((b,i)=>r=[b,x([...b].pop())+b.slice(1,-1)+x(b[0])] .some(b=>r=a[0]==[...b].pop()?b+a:b[0]==[...a].pop()?a+b:0)&&(l=[...l],l[i]=r,f(l)))?r:'':a

console.log=(...x)=>O.textContent+=x+'\n'

;[
 //OK
 ['[-->','{---]','>----{']
,['(-[','}--]']
,['(-)']
,['[--{']
,['[-]',']-[']
,['[----->',')------------[','{--<','}---)']
,['>-->','>->','>--->']
,['(-]',']->','>-}','}-)',')-[','[-<','<-{','{-(']
 //KO
,['[-->','{---]']
,['[-]','[-]']
,['(-]',']->','}-)']
,['>->','>-->',']---]']
,['[-------]',']-------[','[-------]','[---------]'] // shortened a little,
,['{--[',']--}']
].forEach(t=>{
  console.log(t+' : "'+f(t)+'"\n')
})
<pre id=O></pre>


1

Javascript, 800 byte

Khác xa với một giải pháp tối ưu hóa, nhưng đây là một bản hack nhanh trong javascript (không có ecma5 hay bất cứ thứ gì, vì tôi không biết nó).

function a(r){function t(r,t){var n=r.slice();return n.splice(t,1),n}function n(r){var t,n={"[":"]","]":"[",">":"<","<":">","(":")",")":"(","{":"}","}":"{"},e=r.split("").reverse();for(t=0;t<e.length;t++)n.hasOwnProperty(e[t])&&(e[t]=n[e[t]]);return e.join("")}function e(r,t){return r.unshift(t),r}var h,u,f=[];if(1==r.length)return r[0];for(h=0;h<r.length;h++){var l=r[h],i=t(r,h),c=l.charAt(0),g=l.charAt(l.length-1);for(u=0;u<i.length;u++){var o=i[u],s=o.charAt(0),p=o.charAt(o.length-1);c==p&&f.push(e(t(i,u),o+l)),g==s&&f.push(e(t(i,u),l+o)),o=n(o),s=o.charAt(0),p=o.charAt(o.length-1),c==p&&f.push(e(t(i,u),o+l)),g==s&&f.push(e(t(i,u),l+o))}}if(f.length<1)return!1;for(h=0;h<f.length;h++){if(1===f[h].length)return f[h][0];f[h]=a(f[h])}for(h=0;h<f.length;h++)if(f[h]!==!1)return f[h];return!1}

Ungolfed, đây là ... Tôi chắc chắn ít nhất 2 vòng lặp là không cần thiết ở đây và việc kiểm tra một yếu tố đầu vào ở trên cùng và một yếu tố phù hợp ở phía dưới là không ổn định ... nhưng có vẻ như nó hoạt động và xử lý các đầu vào thử nghiệm.

function a(inputs)
{
	var i, ii, matches = [];
	if (inputs.length == 1) {
		return inputs[0];
	}
	// For each of the elements in inputs (e1)
	for (i = 0; i < inputs.length; i++) {
		var e1 = inputs[i],
			others = except(inputs,i),
			e1s = e1.charAt(0),
			e1e = e1.charAt(e1.length-1);
		// Compare to each of the other elements in inputs (e2)
		for (ii = 0; ii < others.length; ii++) {
			// get the start and end of the elements to compare (e1s,e1e,e2s,e2e)
			var e2 = others[ii],
				e2s = e2.charAt(0),
				e2e = e2.charAt(e2.length-1);
			// if any of them match up (e1s == e2e || e1s == e2s || e1e == e2s || e1e = e2e)
			// Make a new array of inputs containing the joined elements (as a single element) and all other elements which might join with them
			if (e1s == e2e) {
				matches.push(addTo(except(others,ii),e2+e1));
			}
			if (e1e == e2s) {
				matches.push(addTo(except(others,ii),e1+e2));
			}
			e2 = flip(e2);
			e2s = e2.charAt(0);
			e2e = e2.charAt(e2.length-1);
			if (e1s == e2e) {
				matches.push(addTo(except(others,ii),e2+e1));
			}
			if (e1e == e2s) {
				matches.push(addTo(except(others,ii),e1+e2));
			}
		}
	}

	if (matches.length < 1) {
		return false;
	}

	for (i = 0; i < matches.length; i++) {
		if (matches[i].length  === 1) {
			return matches[i][0];
		} else {
			matches[i] = a(matches[i]);
		}
	};

	for (i = 0; i < matches.length; i++) {
		if (matches[i] !== false) {
			return matches[i];
		}
	};

	return false;

	function except(list,idx)
	{
		var newList = list.slice();
		newList.splice(idx,1);
		return newList;
	}
	function flip(s) {
		var replacements = {
			'[':']',
			']':'[',
			'>':'<',
			'<':'>',
			'(':')',
			')':'(',
			'{':'}',
			'}':'{'
		}, i, a = s.split('').reverse();
		for (i = 0; i < a.length; i++) {
			if (replacements.hasOwnProperty(a[i])) {
				a[i] = replacements[a[i]];
			}
		}

		return a.join('');
	}
	function addTo(arr,newEl)
	{
		arr.unshift(newEl);
		return arr;
	}
}


1
Bạn có thể đổi tên các hàm để lưu khá nhiều byte. stackoverflow.com/questions/6156319/ từ
noɥʇʎԀʎzɐɹƆ

1
tránh .charAt trong bất kỳ phiên bản JavaScript nào. s.charAt(x)===s[x]
edc65

1

Python 3, 217 byte

from itertools import*
a='()[]{}<>'
all(any(c[-1]!=d[0]for c,d in zip(q,q[1:]))or print(''.join(q))for p in permutations(open(0))for q in product(*[(c[:-1],a[a.find(c[-2])^1]+c[-3:0:-1]+a[a.find(c[0])^1])for c in p]))

( Bản demo trên Ideone )


Làm thế nào để có đầu vào này?
R. Kap

@ R.Kap Trên stdin, một dây trên mỗi dòng.
Anders Kaseorg

Nó dường như không, ít nhất là khi tôi chạy nó.
R. Kap

Ngoài ra, làm thế nào nhanh chóng nó có thể tìm thấy câu trả lời chính xác cho (-] ]-> >-} }-) )-[ [-< <-{ {-(?
R. Kap

@ R.Kap Xem bản demo trên Ideone để biết ví dụ về việc lấy đầu vào và sản xuất đầu ra. (Nó có thể không hoạt động trên Windows, nếu đó là những gì bạn đang cố gắng làm?) Nó chạy ~ ngay lập tức trên trường hợp thử nghiệm của bạn. Tất nhiên, có những trường hợp sẽ mất thời gian theo cấp số nhân.
Anders Kaseorg

0

Lua, 477 byte

function r(s)return s:reverse():gsub("[()%[%]{}<>]",{["("]=")",[")"]="(",["["]="]",["]"]="[",["{"]="}",["}"]="{",["<"]=">",[">"]="<"})end
function a(c,b)for i, v in next,b do
m=c:sub(-1,-1)n=v:sub(1,1)o=r(c):sub(-1,-1)p=r(v):sub(1,1)l=table.remove(b,i)if m==n then
return a(c..v,b)elseif o==n then
return a(r(c)..v,b)elseif m==p then
return a(c..r(v),b)elseif o==p then
return a(r(c)..r(v),b)end
table.insert(b,i,l)end
return#b>0 and""or c
end
print(a(table.remove(arg,1),arg))

Chấp nhận dây làm đối số dòng lệnh


0

Python 3.5, 448 432 427 424 286 311 byte:

( +25 do có một lỗi trong đó đầu ra có thể dài hơn so với một số đầu vào )

def g3(z):
 B=z.split();M='i[::-1].translate({41:40,40:41,125:123,123:125,62:60,60:62,93:91,91:93})';f=B+[eval(M)for i in B if eval(M)not in B];d=[f.pop(0)]
 for h in d:
  try:[d.append([f.pop(f.index(c))for c in f if h[-1]==c[0]][0])if len(d)<len(B)else E]
  except:break
 return''.join(d)if len(d)>=len(B)else''

Hoạt động hoàn hảo! ngoại trừ đầu vào có 7 giá trị trở lên. Phải mất một thời gian dài cho những người đó, rất có thể bởi vì nó phải trải qua tất cả những hoán vị của đầu vào cộng với đầu vào đảo ngược . Tôi sẽ cố gắng khắc phục điều này nếu và khi tôi có thể, nhưng bây giờ, điều này dường như là đủ tốt. Bây giờ tất cả đều tốt! Nếu chỉ bằng cách nào đó tôi có thể sử dụng try-exceptkhối đó trong việc hiểu danh sách, nó có thể ngắn hơn một chút và trông đẹp hơn nhiều . Tuy nhiên, bây giờ nó hoạt động cho tất cả các trường hợp thử nghiệm, và, tốt nhất, nó không sử dụng nhập khẩu! :)

Hãy thử trực tuyến! (Ideone) (284 byte ở đây)

(Mẹo: Để thử, chỉ cần chọn "ngã ba", sau đó nhập các lựa chọn của bạn, phân tách không gian và chọn "chạy")

Giải trình

Về cơ bản, những gì đang xảy ra là ...

  1. Một danh sách, Bđược tạo từ đầu vào bằng cách tách nó ở khoảng trắng thành các "dây" thành phần của nó.
  2. Mlà một chuỗi tôi đã tạo, khi được đánh giá, trả về một danh sách dựa trên Bđó chứa tất cả các dây, nhưng lần này ngược lại .
  3. Danh sách được tạo từ Mcuối cùng được nối với Bchính nó để tạo ra một danh sách f, với tất cả các định hướng có thể có của "dây".
  4. Một danh sách khác, dđược tạo, sẽ được khởi tạo với giá trị (giá trị f[0]) đầu tiên là f.
  5. Cuối cùng, tất cả các giá trị dđược lặp đi lặp lại và mỗi ký tự cuối cùng của mỗi giá trị được so sánh với ký tự đầu tiên của mỗi thành phần fvà khi tìm thấy kết quả khớp, ký tự đó được bật (hoặc xóa) và được trả về từ danh sách f. Điều này xảy ra cho đến khi a IndexErrorđược tăng hoặc độ dài của danh sách dvượt quá Bvà a NameErrorđược tăng sau khi cuộc gọi đến E, cả hai đều được xử lý và sau đó dnội dung của danh sách được nối vào một chuỗi và được trả về miễn là độ dài của danh sách dnhiều hơn hơn hoặc bằng độ dài của danh sách B. Mặt khác, một chuỗi rỗng được trả về ( ''), vì dkhông có cùng độ dài như Bbiểu thị rằng tất cả các "dây" trong danh sáchB không thể được nối vào một "dây" dài.

@KennyLau Bạn đã thay đổi điều gì? Từ những gì tôi có thể thấy, bạn vừa thêm vào. <!-- language: lang-python -->Điều đó thay đổi gì?
R. Kap

Điều đó có thể cho phép tô sáng cú pháp cho mã của bạn.
Leaky Nun

@KennyLau Wow, thật tuyệt. Tôi đã tự hỏi làm thế nào tôi sẽ làm điều đó trên PPCG. Bây giờ tôi biết! Cảm ơn bạn! :)
R. Kap
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.