Làm cho rắn co giãn hôn


57

Một con rắn co giãn trông giống như thế này:

<||=|||:)~

Mỗi chuỗi thanh dọc ( |) riêng biệt trong một con rắn co giãn, được gọi là phần co giãn , có thể mở rộng riêng lẻ thành hai lần chiều rộng của nó và được vẽ bằng các dấu gạch chéo xen kẽ ( /, \) sau khi được kéo dài.

Con rắn đặc biệt ở trên có hai phần co giãn như vậy, tạo cho nó bốn tư thế có thể:

<||=|||:)~

</\/\=|||:)~

<||=/\/\/\:)~

</\/\=/\/\/\:)~

Hình dạng chung của một con rắn co giãn trong tư thế ít duỗi nhất được xác định bởi biểu thức này :

<(\|+=)*\|+:\)~

Mà có thể được nói bằng các từ như:

<, theo sau là bất kỳ số lượng các chuỗi |được nối với =các dấu hiệu, theo sau là :)~.

Vì vậy, <|:)~<||:)~<|=|:)~<|=|=||=|||||=||:)~là rắn co giãn, nhưng <=:)~<=|:)~<||=:)~<|==||:)~không.

Rắn co giãn cũng có thể quay mặt sang trái thay vì phải, ví dụ ~(:|||=||>. Các hình thức là như nhau, chỉ cần nhân đôi.

Thử thách

Viết chương trình lấy một chuỗi dòng gồm hai con rắn co giãn đối diện nhau, với một số khoảng trống ở giữa. Cả hai con rắn sẽ ở trong tư thế kéo dài ít nhất của chúng (tất cả các thanh dọc, không có dấu gạch chéo). Chuỗi sẽ bắt đầu bằng đuôi của con rắn mặt phải và kết thúc bằng đuôi của con rắn mặt trái (bạn có thể tùy ý giả sử còn có một dòng mới).

Ví dụ: đây là một đầu vào có thể có năm khoảng cách giữa các con rắn:

<|=||:)~.....~(:||||>

Tôi đang sử dụng dấu chấm ( .) thay vì ký tự không gian thực tế cho rõ ràng.

Không có khoảng cách giữa các con rắn cũng là đầu vào hợp lệ:

<|=||:)~~(:||||>

Chúng tôi nói rằng những con rắn đang hôn nhau khi lưỡi của chúng chạm vào nhau như thế này.

Chương trình của bạn cần mở rộng một số kết hợp các phần co giãn của cả hai con rắn sao cho con rắn có số lượng khoảng trống ít nhất có thể giữa chúng (không chồng chéo), tức là con rắn càng gần nhau càng tốt .

Cả hai đuôi của rắn đều cố định nhưng đầu và cơ thể của chúng có thể di chuyển - phải cho rắn mặt phải, trái cho rắn mặt trái - theo những phần co giãn đã được mở rộng.

Đầu ra của chương trình của bạn là chuỗi dòng đơn (cộng với dòng mới theo dõi tùy chọn) cho thấy những con rắn càng gần nhau càng tốt, với các dấu gạch chéo xen kẽ được vẽ thay cho các thanh dọc cho các phần co giãn đã được mở rộng.


Ví dụ: đầu ra cho <|=||:)~.....~(:||||>(từ phía trên) sẽ là:

</\=||:)~~(:/\/\/\/\>

Đây là giải pháp duy nhất ở đây bởi vì với bất kỳ sự kết hợp nào khác của các phần co giãn được kéo dài, những con rắn sẽ chồng lên nhau hoặc cách xa nụ hôn.


Nếu có nhiều giải pháp khả thi, đầu ra có thể là một trong số chúng.

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

<|=||:)~.....~(:|||=|>

đầu ra có thể là

<|=/\/\:)~~(:/\/\/\=|>

hoặc là

</\=||:)~~(:/\/\/\=/\>

Hãy nhớ rằng sẽ không bao giờ có thể khiến những con rắn hôn nhau, nhưng bạn vẫn cần phải đưa chúng càng gần càng tốt.

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

<||=||||:)~...~(:||>

đầu ra có thể là

</\/\=||||:)~.~(:||>

hoặc là

<||=||||:)~.~(:/\/\>

Nếu những con rắn đã hôn nhau, đầu ra sẽ giống như đầu vào. ví dụ

<|=||:)~~(:||||>

Nói chung, đầu ra sẽ giống như đầu vào nếu phần mở rộng của bất kỳ phần co giãn nào sẽ làm cho các con rắn chồng lên nhau. ví dụ

<|||=|||:)~..~(:||||=|||||=||||||>

Ghi chú

  • Lấy đầu vào từ stdin hoặc dòng lệnh như bình thường hoặc viết một hàm lấy một chuỗi. In hoặc trả lại đầu ra.
  • Bạn có thể sử dụng dấu chấm ( .) trong đầu vào và đầu ra thay cho khoảng trắng ( ) nếu bạn thích.
  • Điều quan trọng duy nhất là các dấu gạch chéo xen kẽ trong chuỗi các thanh dọc mà chúng thay thế. Thứ tự của chúng ở con rắn lớn hay việc một nhát chém tiến hay lùi trước không thành vấn đề.
  • Các phần co giãn không thể kéo dài giữa chừng - chính xác là gấp đôi hoặc không có phần mở rộng nào cả.

Chấm điểm

Đây là mã golf . Đệ trình ngắn nhất tính bằng byte thắng. Tiebreaker là câu trả lời trước đó.


17
Snex Education 101 - Cách hôn đúng cách
Trình tối ưu hóa

45
"Chúng tôi nói rằng những con rắn đang hôn nhau khi lưỡi của chúng chạm vào nhau như thế này." Tôi đang đọc gì ...
Fatalize 24/07/2015

8
Vậy rắn chỉ làm tiếng Pháp?
Tối ưu hóa

3
@PeterTaylor Vâng, "nhân đôi", không "đảo ngược" (nếu không >sẽ trở thành <, tương tự cho ()), nhưng anh ấy cũng nói "Điều quan trọng là việc chém xen kẽ trong chuỗi các thanh dọc mà họ đã thay thế. con rắn lớn hay việc một nhát chém tiến hay lùi trước không thành vấn đề. "
Martin Ender

7
@qwr Tưởng tượng.
Sở thích của Calvin

Câu trả lời:


9

CJam, 87 71 70 68 byte

l:L"|"f&Qa%_,Y\m*\f{.{_,"/\\"*?}L'|%.\s" /"1$fe=:-\a+}${0a>}=~S%\S**

Hãy thử trực tuyến trong trình thông dịch CJam .

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

l:L        e# Read a line from STDIN and save it in L.
"|"f&      e# Intersect each character with the string "|".
           e# This pushes either "|" or "".
Qa%        e# Split the resulting array at runs of "".
_,         e# Compute the length of the resulting array (A).
           e# This yield K, the number of stretchy parts.
Y\m*       e# Push the array of all vectores in {0,1}^K.
\f{        e# For each vector V in {0,1}^K, push V and A; then:
  .{       e#   For each C in V and the corresponding P in A:
    _,     e#     Compute the length of the stretchy part P.
    "/\\"* e#     Repeat "/\" that many times.
    ?      e#     If C, select P; else, select "/\"*length(P).
  }        e#   This modifies A.
  L'|%     e#   Split L at runs of vertical lines.
  .\s      e#   Interleave the chunks of L and the modified A. Sringify.
           e#   In each iteration, this constructs a different modification of L,
           e#   with some stretched out stretchy parts.
  " /"1$   e#   Push " /" and a copy of the modified L.
  fe=      e#   Calculate the number of spaces and slashes in the modifed L.
  :-       e#   Subtract the number of occurrences.
  \a+      e#   Construct the array [difference modified-L].
}          e#
$          e# Sort the array (by final number of spaces).
{0a>}=     e# Find the first element greater than [0].
           e# This skips over too far stretched snakes, where the number of
           e# slashes is less than the number of spaces.
~          e# Dump the difference (D) and modified L on the stack.
S%         e# Split L at runs of spaces.
\S*        e# Construct a string of D spaces.
*          e# Join the split L, delimiting by D spaces.

19

Võng mạc , 209 107 99 97 92 byte

.(?=(.+)(?<=(?=<((\|+|(?<-5>\|(?=\1())?)+)[^|]+)+$(?(5)!)).+( )+\S+))\4
/ \
+` (.*~|~.*) 
$1

Đối với mục đích đếm, mỗi dòng đi trong một tệp riêng biệt, nhưng bạn có thể chạy mã từ một tệp duy nhất có -scờ.

Mang các tính năng tốt nhất của .NET regex và Retina lại với nhau: các nhóm cân bằng, các giao diện độ dài tùy ý và thay thế regex lặp đi lặp lại.

Về cơ bản, regex dài mã hóa một giải pháp hợp lệ và trình quay ngược của công cụ regex tìm thấy một trong những giải pháp tối ưu cho tôi.

Giải trình

Trước tiên, hãy xem xét làm thế nào chúng ta có thể tìm thấy một giải pháp hợp lệ (không nhất thiết phải tạo ra đầu ra chính xác) với biểu thức chính quy. Chúng tôi có thể sử dụng các nhóm cân bằng của .NET để giúp chúng tôi đếm các phần co giãn. Hãy xem xét regex đơn giản hơn sau đây:

\S+( )+.+(?<=(?(1)!)^([^|]+(\|+|(?<-1>\|)*))+>)

Chúng ta có thể loại bỏ điều đó.

\S+( )+.+

Điều này khớp với toàn bộ chuỗi, đẩy một lần chụp vào 1ngăn xếp nhóm cho từng khoảng trống trong đầu vào. Chúng tôi sẽ sử dụng ngăn xếp đó để đảm bảo rằng các phần co giãn chính xác lấp đầy không gian được chụp vào các nhóm đó.

Tiếp theo là một cái nhìn. Điều hấp dẫn là các lookbehind được ghép từ phải sang trái trong .NET (vì vậy đó là cách bạn nên đọc chúng). Điều này cho chúng ta cơ hội để đi qua chuỗi lần thứ hai, tìm hiểu xem liệu có một tập hợp con của phần co giãn tổng hợp với số lượng không gian phù hợp hay không. Đi qua cái nhìn từ phải sang trái:

>

Điều này chỉ đảm bảo rằng chúng ta thực sự bắt đầu từ cuối chuỗi (đuôi rắn).

(
  [^|]+
  (
    \|+
  |
    (?<-1>\|)+
  )
)+

Đối với mỗi phần co giãn, phần này chỉ khớp với toàn bộ phần mà không làm gì cả ( \|+) hoặc phù hợp với toàn bộ phần trong khi bật ra chụp ngăn xếp stack 1( (?<-1>\|)*). Có sự thay thế này đảm bảo rằng chúng ta chỉ có thể mở rộng hoàn toàn một phần co giãn hoặc giữ nguyên nó, và không có được những thứ như thế |/\|. Sau đó, chúng tôi chuyển sang phần co giãn tiếp theo với [^|]+.

(?(1)!)^

Cuối cùng, chúng tôi đảm bảo rằng chúng tôi đã duyệt qua toàn bộ chuỗi (cả hai con rắn) và ngăn xếp đó 1hoàn toàn trống rỗng. Tức là chúng tôi đã tìm thấy một tập hợp con của phần co giãn chính xác với số lượng không gian chúng tôi đã chụp trước đó.

Backtracker sẽ quay trở lại qua chuỗi thử tất cả các kết hợp của các phần không thay đổi và mở rộng cho đến khi vấn đề tổng hợp tập hợp con được giải quyết. Nếu một tập hợp con như vậy không tồn tại, giao diện sẽ thất bại. Điều này sẽ khiến backtracker quay trở lại \S+( )+.+phần đó và thử chụp một khoảng trống ít hơn ( )+(thay vào đó sẽ chỉ được che .+lại). Do sự tham lam của +chúng tôi do đó cố gắng lấp đầy càng nhiều khoảng trống càng tốt.

Bạn có thể kiểm tra tính hợp lệ của phương pháp này với sự thay thế được sửa đổi một chút này:

\S+(( )+).+(?<=(?(2)!)^([^|]+(\|+|(?<-2>\|)*))+>)
=$1=

Nó sẽ cung cấp cho bạn một chuỗi =spaces=với chính xác số lượng khoảng trống có thể được lấp đầy với những con rắn nhất định.

Tôi đã phải thêm một số mánh khóe nữa để thực sự mở rộng |s chính xác . Về cơ bản, tôi muốn thay thế tất cả các |s được khớp bằng (?<-1>\|)+nhánh. Ý tưởng là để khớp một nhân vật riêng lẻ, đặt người giải quyết trong một cái nhìn và đặt cờ nếu trận đấu xảy ra ở bên trong nhánh đó. Nếu cờ đó không được đặt, chúng tôi sẽ vô hiệu hóa trận đấu ở cuối để tránh thay thế các ký tự khác.

Để làm điều này, chúng tôi sử dụng một loạt các cái nhìn lồng nhau. Một lần nữa, các giao diện có độ dài thay đổi của .NET được khớp từ phải sang trái, vì vậy nếu chúng ta lồng các giao diện và giao diện, chúng ta có thể để công cụ regex đi qua chuỗi nhiều lần. Vì lý do chơi gôn, bộ giải được đảo ngược trong giải pháp thực tế của tôi (bắt đầu từ cuối, chọn khoảng trắng từ phải sang trái và sau đó giải tổng các tập con từ trái sang phải), nhưng nếu không thì cấu trúc của bộ giải hoàn toàn giống nhau . Hãy phân tích regex đầy đủ:

.(?=(.+)...)

Chúng tôi khớp một ký tự, sau đó bắt phần còn lại của chuỗi và di chuyển con trỏ đến cuối chuỗi. Chúng tôi sẽ sử dụng nhóm 1này sau để kiểm tra người giải quyết xem chúng tôi có ở vị trí của trận đấu hay không.

(?<=....+( )+\S+)

Đây giống như phần đầu tiên của bộ giải đơn giản ở trên, ngoại trừ việc chúng ta chọn các khoảng trắng từ phải sang trái. Việc quay lại số lượng không gian hoạt động chính xác như trước đây, ngoại trừ việc chúng tôi đang sử dụng nhóm 5bây giờ.

(?=<((\|+|(?<-5>\|(?=\1())?)+)[^|]+)+$(?(5)!))

Điều này cũng giống như trước đây, ngoại trừ chúng ta đi từ trái sang phải và bất cứ khi nào chúng ta khớp một |nhánh trong nhánh mở rộng, chúng ta sẽ kiểm tra xem nó có khớp với nhau không

(?=\1())?

Đây là một cái nhìn tùy chọn. Nó cố gắng khớp nhóm 1một lần nữa (điều này, ở đây, chỉ có thể nếu chúng ta đúng sau khi nhân vật được khớp) và nếu chúng ta làm như vậy, chúng ta sẽ bắt một chuỗi trống thành nhóm 4, điều đó cho thấy rằng chúng ta đã tìm thấy ký tự hiện tại trong một của các bit mở rộng. Nếu \1không khớp, 4sẽ không nắm bắt được bất cứ điều gì và ?đảm bảo rằng giao diện không thành công sẽ không ảnh hưởng đến người giải.

Cuối cùng, sau khi tất cả các giải quyết được thực hiện, chúng tôi chỉ cần kiểm tra \4xem liệu cái nhìn này đã được sử dụng. Nếu vậy, chúng tôi muốn thay thế nhân vật hiện tại bằng /\.

Một khó khăn vẫn còn: loại bỏ đúng số lượng không gian. Cách ngắn nhất để làm điều này tôi đã tìm thấy cho đến nay là chèn một /\khoảng trắng cùng với và sau đó loại bỏ một khoảng trống giữa các lưỡi cho mỗi không gian đánh dấu trong một bước riêng biệt:

+` (.*~|~.*) 
$1

6

Ruby 191 187 186 170 162

->t{s=r=t.size
i=m=t[o=/ +/].size
(0...2**t.scan(y=/\|+/).size).map{|n|q=-1
x=t.gsub(y){|r|n[q+=1]<1?r:'\/'*r.size}
d=i+s-x.size
d<0||d<m&&r=x.gsub(o,' '*m=d)}
r}

Đây là một hàm lấy một chuỗi làm tham số và trả về một chuỗi.

Kiểm tra trực tuyến: http://ideone.com/uhdfXt

Đây là phiên bản dễ đọc:

# enumerates the possible states for any string containing snakes
COMBINATIONS =-> snake {
  expandable_fragments = snake.scan /(\|+)/

  (0...2**(expandable_fragments.size)).map{ |i|
    x=-1
    snake.gsub(/\|+/){|r| i[x+=1]>0 ? '\/'*r.size : r}
  }
}

# finds the configuration in which snakes are closest to each other
KISS=
-> input {
  result = input
  s = input.size
  initial_distance = min_distance = input[/ +/].size

  COMBINATIONS[input].map{|c|
    distance = initial_distance + s - c.size
    if distance > -1 && distance < min_distance
      min_distance = distance
      result = c.gsub(/ +/,' '*distance)
    end
  }

  result
}

Trong phiên bản golf, chức năng chính tương đương với KISSchức năng trên và COMBINATIONSchức năng đã được nội tuyến.


Thất bại trong đầu vào <|=||:)~~(:||||>, mà thông số kỹ thuật đề cập là đầu vào hợp lệ.
Mực giá trị

6

Python, 205 byte

from itertools import*
f=lambda s:min([c.replace(".","",c.count("X"))for c in map("".join,product(*map({"|":"|X"}.get,s,s)))if{c.count("X")>c.count("."),"|X"in c,"X|"in c}=={0}],key=len).replace("X","/\\")

Có một lambda duy nhất trông gọn gàng và tất cả, nhưng tôi gần như chắc chắn đây không phải là cách tốt nhất để đi. Nhưng tôi đang đăng bài này bởi vì đó là tất cả những gì tôi đã có cho đến nay trông có vẻ khá nửa.

Đây là một lực lượng đơn giản trên tất cả các thay thế có thể |với /\, lọc ra các cấu hình không hợp lệ. Bit gọn gàng duy nhất mà tôi đoán là chúng ta không thực sự thay thế bất kỳ |với /\trực tiếp - lần đầu tiên chúng ta thay thế |với Xvà thả một .từ giữa cho mỗi thay thế, lấy chuỗi dài tối thiểu trên tất cả các chuỗi giá trị, sau đó thay thế Xs với /\.

Tôi đã thử một vài cách tiếp cận khác, bao gồm cả phương pháp đệ quy, nhưng cuối cùng chúng khá lộn xộn. Tôi cũng học được rằng re.splithiện tại không phân tách trên các chuỗi trống, điều này thật đáng tiếc, bởi vì một trong những ý tưởng của tôi liên quan đến việc phân tách trên các \branh giới từ.


5

Toán học, 381 byte

StringReplace[MapAt[StringReplace[#,"|"->"/\\"]&,StringSplit[#<>"="<>#2,"="],#3]~StringRiffle~"=",")="->")~"<>If[#4>0,"."~StringRepeat~#4,""]<>"~"]&[#1,#3,Sequence@@Function[{l,s},{#,#2-Total@Extract[l,#]}&[Flatten[l~Position~#~Take~#2&@@@Tally@#&@@Select[Subsets@l,Total@#<=s&]~MaximalBy~Total,1],s]][StringLength/@StringCases[#1<>#3,"|"..],StringLength@#2]]&@@#~StringSplit~"~"&

Hàm thuần túy lấy chuỗi làm đối số của nó. Mong đợi .hơn là giữa những con rắn.

Tôi không nghĩ nó sẽ tệ đến thế ... Đây là những gì tôi có trước khi đập vỡ nó và trộn lẫn mọi thứ.

f[lhs_, rhs_, 
  spaces_] := {StringLength /@ StringCases[lhs <> rhs, "|" ..], 
  StringLength@spaces}

g[barLens_, 
   spaceLen_] := {#, #2 - Total@Extract[barLens, #]} & @@ {Flatten[
     Take[Position[barLens, #], #2] & @@@ 
      Tally[First[
        MaximalBy[Select[Subsets[barLens], Total@# <= spaceLen &], 
         Total]]], 1], spaceLen};

h[lhs_, rhs_, partspec_, newSpaceLen_] := 
 StringReplace[
  StringRiffle[
   MapAt[StringReplace[#, "|" -> "/\\"] &, 
    StringSplit[lhs <> "=" <> rhs, "="], partspec], "="], 
  ")=" -> ")~" <> 
    If[newSpaceLen > 0, StringRepeat[".", newSpaceLen], ""] <> "~"]

 h[#1, #3, Sequence @@ g @@ f[#1, #3, #2]] & @@ 
     StringSplit[#, "~"] &

Dưới đây là một ví dụ chạy qua với lời giải thích:

Input: "<|=||:)~.....~(:||||>"
@Call StringSplit[#, "~"] &, yielding  {"<|=||:)", ".....", "(:||||>"}
@@Apply h[#1, #3, Sequence @@ g @@ f[#1, #3, #2]] &, but first
Set arguments: h["<|=||:)", "(:||||>", Sequence @@ g @@ f["<|=||:)", "(:||||>", "....."]]
@Call f, yielding {{1, 2, 4}, 5} = {# of bars in each segment, # of spaces}
@@Apply g, let's trace from the interior:
Subsets[barLens] = all subsets of {1, 2, 4}
Select those subsets whose sum is less than # of spaces {{},{1},{2},{4},{1,2},{1,4}}
MaximalBy Total, yielding a list of all subsets whose sum is maximal {{1, 4}}
First of these subsets, can be any of them {1, 4}
Tally the subset, yielding frequencies of each {{1, 1}, {4, 1}}
@@@Apply Take[Position[barLens, #], #2] & at the first level, yielding
    {Take[Position[{1, 2, 4}, 1], 1], Take[Position[{1, 2, 4}, 4, 1]]}
    which takes the first 1 positions of 1 and the first 1 positions of 4, yielding
    {{{1}},{{3}}}
Flatten at the first level, yielding {{1}, {3}}
Create a list {{{1}, {3}}, 5}
@@Apply {#, #2 - Total@Extract[barLens, #]} &, inserting arguments:
    {{{1}, {3}}, 5 - Total@Extract[{1, 2, 4}, {{1}, {3}}]} = {{{1}, {3}}, 0}
    where the second element becomes the # of spaces left over.
Done with g, it returned {{{1}, {3}}, 0}
@@Apply Sequence, splicing the return of g into h, yielding the
@Call, h["<|=||:)", "(:||||>", {{1}, {3}}, 0]; let's start from the interior
StringSplit the concatenated "<|=||:)=(:||||>" with delimiter "=", {"<|","||:)","(:||||>"}
MapAt the part specification {{1}, {3}} and StringReplace at those indices any | with /\
    yielding {"</\","||:)","(:/\/\/\/\>"}
StringRiffle together, inserting back the delimiter "=", yielding "</\=||:)=(:/\/\/\/\>"
StringReplace ")=" with ")~", concat the new number of spaces, concat "~"
Yields "</\=||:)~~(:/\/\/\/\>", done.

Dễ dàng giảm xuống 355 bằng cách bắt đầu a=StringReplace;b=StringSplit;c=StringLength;d=Total;và sau đó thay thế những thứ cần thiết ở nơi khác bên trong:a=StringReplace;b=StringSplit;c=StringLength;d=Total;a[MapAt[a[#,"|"->"/\\"]&,b[#<>"="<>#2,"="],#3]~StringRiffle~"=",")="->")~"<>If[#4>0,"."~StringRepeat~#4,""]<>"~"]&[#1,#3,Sequence@@Function[{l,s},{#,#2-d@Extract[l,#]}&[Flatten[l~Position~#~Take~#2&@@@Tally@#&@@Select[Subsets@l,d@#<=s&]~MaximalBy~d,1],s]][c/@StringCases[#1<>#3,"|"..],c@#2]]&@@#~b~"~"&
Alex Meiburg

3

Prolog (ECLiPSe), 438 byte

Các câu trả lời khác của tôi là giải quyết vấn đề sai (xin lỗi vì tiếng ồn). Đây là một nỗ lực khác trong Prolog thực sự tôn trọng tất cả các quy tắc.

:-lib(fd).
a([],[]).
a([H|T],L):-append(H,X,L),a(T,X).
s(E,Z,X,Y,L):-length(E,L),a([[60],M,[58,41,126],T,[126,40,58],W,[62]],E),checklist(=(32),T),length(T,Z),b(M,X-[]),b(W,Y-[]).
b(I,[K:M|R]-E):-(I:K=[47,92|L]:s;I:K=[124|L]:n),M#=N+1,N#>=0,b(L,[K:N|R]-E).
b([61|L],[_:0|R]-E):-b(L,R-E).
b([],[_:0|E]-E).
d(_:N,Y:N):-Y=s;Y=n.
s(W,P):-string_list(W,E),s(E,_,X,Y,L),minimize((maplist(d,X,U),maplist(d,Y,V),s(K,Q,U,V,L)),Q),string_list(P,K).

Xét nghiệm

(định dạng: đầu vào, đầu ra, dòng mới)

<===:)~         ~(:>
<===:)~         ~(:>

<|||:)~         ~(:||||=|>
</\/\/\:)~ ~(:/\/\/\/\=/\>

<=|=:)~         ~(:||||=|>
<=/\=:)~   ~(:/\/\/\/\=/\>

<===|:)~         ~(:||=|>
<===/\:)~     ~(:/\/\=/\>

<|=|=|||=|:)~         ~(:=|>
</\=/\=/\/\/\=/\:)~  ~(:=/\>

<||||||:)~         ~(:=|>
</\/\/\/\/\/\:)~  ~(:=/\>

<||||||:)~         ~(:||>
</\/\/\/\/\/\:)~ ~(:/\/\>

<||=||||:)~ ~(:||>
<||=||||:)~ ~(:||>

<||=||||:)~   ~(:||>
</\/\=||||:)~ ~(:||>

<||=||||:)~    ~(:||>
</\/\=||||:)~~(:/\/\>

<||=||||:)~~(:||>
<||=||||:)~~(:||>

Giải thích

  • Vị từ chính là s/2, lấy đầu vào làm đối số thứ nhất và hủy kết quả bằng đối số thứ hai (cả hai chuỗi). Đầu vào được chuyển đổi thành một danh sách mã ký tự , E.

  • Sau đó, s(E,Z,X,Y,L)hủy danh sách thành các thành phần sau:

    • Z số lượng khoảng cách giữa các con rắn
    • XY, đại diện trừu tượng của cơ thể trái và phải

      Định dạng của cơ thể là một danh sách n:Nhoặc s:Nbiểu thức, trong đó Ncó độ dài dương; nphương tiện normalsphương tiện stretched.

    • L tổng chiều dài của danh sách

Điều thú vịs/5 là nó đi cả hai chiều , tức là chúng ta có thể xây dựng một con rắn nếu các lập luận khác được đưa ra:

    s(E,5,[n:3],[s:2,n:7,s:1],_),string_list(S,E).

... unifies `S` with `"<|||:)~     ~(:/\\/\\=|||||||=/\\>"` (backslashes are quoted). This is due to how `b/2` is written, which can parse the character list or generate it.
  • Chúng tôi xây dựng các cơ thể trái và phải được sửa đổi trong đó mỗi phần là bình thường hoặc kéo dài, trong khi tối thiểu hóa không gian Qngăn cách những con rắn mới. Tổng chiều dài của chuỗi tính toán được giới hạn để tìm kiếm kết thúc.

1

Python 2.7.3 427 421 400 371 byte

import re,itertools as K
g,o,k='\|+',len,raw_input()
d=k.count(' ')
if d==0:exit(k)
p,x,y,s=re.sub,0,0,map(o,re.findall(g,k))
for e in [A for w in range(o(s)+1)for A in K.combinations(s,w)]:
 v=sum(e)
 if v==d or x<v<d:x,y=v,list(e)
print p(" +",' '*(d-x),p(g,lambda m:('/\\'*o(m.group(0))if y.remove(o(m.group(0)))or True else 1)if o(m.group(0))in y else m.group(0),k))

Mã không chơi gôn ở đây -

#!/usr/bin/env python
import sys
import re

def find_dist_combo(li, d):
    #Listing all combinations
    from itertools import combinations as c
    max_dist = -1
    max_dist_combo = []
    for p_len in xrange(1,len(li)+1):
        for e in c(li, p_len):
            e_sum = sum(e)
            cond1 = e_sum == d
            cond2 = max_dist < e_sum < d
            if cond1 or cond2:
                max_dist = e_sum
                max_dist_combo = list(e)
                if cond1:
                    return (max_dist, max_dist_combo)
    return (max_dist, max_dist_combo)

def snakes_foreplay(snakes):
    #find distance
    distance = snakes.count(" ")

    #already kissing
    if distance == 0:
        return snakes

    #find num_stretches
    stretch = map(len, re.findall("\|+", snakes))

    #find lowest combination of numbers
    (e_dist, res_stretch) = find_dist_combo(stretch, distance)

    def sub_callback(m):
        s = m.group(0)
        l = len(s) 
        if l in res_stretch:
            res_stretch.remove(l)
            return '/\\'*l
        return s

    #Resultant substitution
    res_snakes = re.sub("\s+", " "*(distance - e_dist), re.sub("\|+", sub_callback, snakes))

    return res_snakes

if __name__ == "__main__":
    for s in [ip.strip() for ip in sys.stdin]:
        print snakes_foreplay(s)

Thử nghiệm giải pháp đánh gôn -

$ python stretchy_snakes.py
[In]  <=  <|=||:)~     ~(:||||>
[Out] =>  </\=||:)~~(:/\/\/\/\>

$ python stretchy_snakes.py
[In]  <=  <|=||:)~             ~(:||||>
[Out] =>  </\=/\/\:)~      ~(:/\/\/\/\>

$ python stretchy_snakes.py
[In]  <=  <|=||:)~     ~(:|||=|>
[Out] =>  </\=||:)~~(:/\/\/\=/\>

$ python stretchy_snakes.py
[In]  <=  <||=||||:)~   ~(:||>
[Out] =>  </\/\=||||:)~ ~(:||>

$ python stretchy_snakes.py
[In]  <=  <|=||:)~~(:||||>
[Out] =>  <|=||:)~~(:||||>

Chắc chắn điều này có thể được thực hiện tốt hơn (tôi không thể hiểu làm thế nào :)).
Hãy cho tôi biết nếu tôi đã bỏ lỡ bất cứ điều gì rõ ràng trong khi chơi golf (Đó là codegolf đầu tiên của tôi, tôi có thể đang làm điều gì đó ngu ngốc: P)


@ Sp3000 Đó là một trong những tốt. Thay thế exitcho sys.exit()(quên exittồn tại). Và bạn đã đúng, __import__có thể được gỡ bỏ, loại bỏ như 20 ký tự :)
Kamehameha

Quy tắc btw của ngón tay cái: đối với răng cưa bạn cần > 6ký tự có giá trị răng cưa nếu bạn sử dụng hai lần, > 3ký tự nếu bạn sử dụng ba lần. Tôi không chắc f=' 'bí danh đó có giá trị không (tôi đếm hai lần)
Sp3000

@ Sp3000 yep bạn đúng. Trong một phiên bản trước đó, tôi đã sử dụng ba lần thay đổi đó. Tiết kiệm cho tôi một vài byte :) :)
Kamehameha

1

05AB1E , 93 byte

#õKDεγʒ'|å]©ε€gxøDgU`XG‘]`âDε˜ODI„| Ãg>‹*}ZQÏε˜ε®˜NèDgyÊi„/\y∍]н©J'/¢Ið¢αð×ý'|¡õK®.ιJIðå≠iI

Con đường quá dài ..>.>

Dùng thử trực tuyến hoặc xác minh tất cả các trường hợp thử nghiệm hoặc xác minh tất cả các kết quả có thể cho tất cả các trường hợp thử nghiệm .

Giải trình:

#õK                   # Split the (implicit) input by one or multiple adjacent spaces
                      # (we now have both snakes as separated items
                      #  - if any spaces were in the input-string)
   D                  # Duplicate this list
    ε                 # Map both snakes to:
     γ                #  Split the snake into chunks of the same character-type
      ʒ'|å]          '#  And only leave the chunks of "|" characters
    ©                 #  Store this list in variable `r` (without popping)
     ε                #  Map the "|" chunks of both snakes again:
      g              #  Get the length of each chunk of "|"
        xø            #  Pair each length with double itself
          DgU`XG‘   #  Create all possible combinations for the current snake
     ]`â              # After the map: create all possible combinations for both snakes
        ε             # Map over each possible combination
         ˜O           #  Get the flattened sum
            I„| Ãg    #  Count the amount of "|" and spaces in the input
                  >‹  #  Check if it's smaller than or equal to this sum
                      #  (1 if truthy; 0 if falsey)
           D        * #  And multiply it by the sum
        }ZQ           # After the map, get the positions of the largest flattened sum,
                      # still below (or equal to) the amount of "|" and spaces combined
       D   Ï          # And only keep those combinations
ε                     # Then map over the remaining combinations
 ˜ε                   #  Flatten it, and map over each value `y`
   ®˜Nè               #   Get the `N`'th part of the snakes
                      #   (where `N` is the index of the map for the current combination)
       D              #   Duplicate this "|"-part
        gyÊi          #   If the length of this "|"-part is not equal to the map-value:
            „/\       #    Push the string "/\"
               y     #    Extended to a size equal to the map-value
                      #   (implicit else:
                      #    use the duplicated value)
                    # After the map: only leave the first (since we don't have
                      # to output all possibilities)
 ©                    # Store it in variable `r` (without popping)
  J'/¢               '# Count the amount of "/" in it
      Ið¢             # Count the amount of spaces in the input
         α            # Get the difference between those
          ð×ý         # And join the list of snakes by that many spaces
'|¡õK                '# Then split by one or multiple adjacent "|"
     ®.ι              # Interleave it with the modified parts of variable` r`
        J             # And join everything together to a single string
Iðå≠i                 # If the input didn't contain any spaces:
     I                #  Output the input instead
                      # (implicit else:
                      #  output the top of the stack before this if)
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.