Buat Ciuman Melar Melar

57

Seekor ular melar terlihat seperti ini:

<||=|||:)~

Setiap urutan bar vertikal yang terpisah ( |) dalam ular melar, yang dikenal sebagai bagian melar , dapat diperpanjang secara individual hingga dua kali lebarnya, dan digambar dengan garis miring bergantian ( /, \) setelah diperpanjang.

Ular tertentu di atas memiliki dua bagian melar seperti itu, memberikannya empat kemungkinan pose:

<||=|||:)~

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

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

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

Bentuk umum ular melar dengan pose paling tidak melar ditentukan oleh regex ini :

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

Yang dapat dinyatakan dengan kata-kata sebagai:

<, Diikuti oleh sejumlah urutan |'s bergabung dengan =tanda-tanda, diikuti oleh :)~.

Jadi <|:)~dan <||:)~dan <|=|:)~dan <|=|=||=|||||=||:)~adalah ular melar, tetapi <=:)~dan <=|:)~dan <||=:)~dan <|==||:)~tidak.

Ular melar juga bisa menghadap ke kiri, bukan ke kanan, misalnya ~(:|||=||>. Bentuknya sama, hanya dicerminkan.

Tantangan

Tulis sebuah program yang mengambil satu baris string dari dua ular melar yang saling berhadapan, dengan beberapa ruang di antaranya. Kedua ular akan berada dalam posisi paling tidak melar (semua batang vertikal, tanpa garis miring). Tali akan mulai dengan ekor ular yang menghadap ke kanan dan diakhiri dengan ekor ular yang menghadap ke kiri (Anda dapat mengasumsikan ada juga baris baru yang tertinggal).

Misalnya, inilah input yang mungkin dengan lima spasi di antara ular:

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

Saya menggunakan titik ( .) alih-alih karakter spasi aktual untuk kejelasan.

Tanpa spasi antar ular juga merupakan input yang valid:

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

Kami mengatakan ular-ular itu berciuman ketika lidah mereka bersentuhan seperti ini.

Program Anda perlu memperpanjang beberapa kombinasi bagian melar dari kedua ular sehingga ular memiliki jumlah ruang paling sedikit di antara mereka (tanpa tumpang tindih), yaitu sedemikian rupa sehingga ular sedekat mungkin dengan ciuman .

Kedua ekor ular itu tetap tetapi kepala dan tubuhnya dapat bergerak - tepat untuk ular yang menghadap ke kanan, kiri untuk ular yang menghadap ke kiri - sesuai dengan bagian melar yang telah diperpanjang.

Output dari program Anda adalah string garis tunggal (plus baris tambahan opsional) yang menunjukkan ular sedekat mungkin dengan ciuman, dengan garis miring berganti-ganti di tempat garis vertikal untuk bagian melar yang telah diperpanjang.


Misalnya, output untuk <|=||:)~.....~(:||||>(dari atas) adalah:

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

Ini adalah satu - satunya solusi di sini karena dengan kombinasi lain dari bagian melar diperpanjang, ular akan tumpang tindih atau lebih jauh dari ciuman.


Jika ada beberapa solusi yang mungkin, hasilnya mungkin salah satunya.

Misalnya, jika inputnya

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

outputnya bisa

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

atau

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

Ingatlah bahwa ular tidak akan selalu bisa ciuman, tetapi Anda masih harus membuatnya sedekat mungkin.

Misalnya, jika inputnya

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

outputnya bisa

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

atau

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

Jika ular sudah berciuman, hasilnya akan sama dengan input. misalnya

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

Secara umum, output akan sama dengan input jika ekstensi dari setiap bagian melar akan membuat ular tumpang tindih. misalnya

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

Catatan

  • Mengambil input dari stdin atau baris perintah seperti biasa, atau menulis fungsi yang mengambil string. Cetak atau kembalikan hasilnya.
  • Anda dapat menggunakan titik ( .) pada input dan output sebagai ganti spasi ( ) jika diinginkan.
  • Ini hanya penting bahwa garis miring berganti dalam barisan vertikal yang mereka ganti. Pemesanan mereka pada ular pada umumnya atau apakah tebasan maju atau mundur datang pertama tidak masalah.
  • Bagian melar tidak dapat memanjang sebagian - persis dua atau tidak ada ekstensi sama sekali.

Mencetak gol

Ini adalah kode-golf . Pengajuan terpendek dalam byte menang. Tiebreaker adalah jawaban sebelumnya.

Hobi Calvin
sumber
17
Snex Education 101 - Cara berciuman dengan benar
Pengoptimal
45
"Kami mengatakan ular-ular itu berciuman ketika lidah mereka bersentuhan seperti ini." Apa yang saya baca ...
Fatalkan
8
Jadi Ular hanya melakukan Prancis?
Pengoptimal
3
@PeterTaylor Yah, "cermin", bukan "terbalik" (jika >tidak tidak akan menjadi <, sama untuk untuk (dan )), tetapi ia juga mengatakan "Hanya penting bahwa garis miring berganti dalam urutan bilah vertikal yang mereka ganti. Pemesanan mereka di ular pada umumnya atau apakah tebasan maju atau mundur datang pertama tidak masalah. "
Martin Ender
7
@qwr Imajinasi.
Hobi Calvin

Jawaban:

9

CJam, 87 71 70 68 byte

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

Cobalah online di juru bahasa CJam .

Bagaimana itu bekerja

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.
Dennis
sumber
19

Retina , 209 107 99 97 92 byte

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

Untuk tujuan penghitungan, setiap baris memiliki file terpisah, tetapi Anda dapat menjalankan kode dari satu file dengan -sflag.

Membawa fitur-fitur terbaik dari .NET regex dan Retina bersama-sama: menyeimbangkan kelompok, melihat panjang sewenang-wenang dan mengulangi penggantian regex.

Pada dasarnya, regex panjang mengkode solusi yang valid dan backtracker mesin regex menemukan salah satu yang optimal bagi saya.

Penjelasan

Pertama, mari kita pertimbangkan bagaimana kita dapat menemukan solusi yang valid (belum tentu menghasilkan output yang benar) dengan sebuah regex. Kita dapat menggunakan grup penyeimbang .NET untuk membantu kita menghitung bagian melar. Pertimbangkan regex sederhana berikut ini:

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

Kita bisa memotongnya.

\S+( )+.+

Ini cocok dengan seluruh string, mendorong satu tangkapan ke 1tumpukan kelompok untuk setiap ruang di input. Kami akan menggunakan tumpukan itu untuk memastikan bahwa bagian yang melar benar-benar mengisi ruang yang ditangkap ke dalam kelompok tersebut.

Selanjutnya adalah melihat di belakang. Tangkapannya adalah bahwa lookbehinds dicocokkan dari kanan ke kiri di .NET (jadi itulah bagaimana Anda harus membacanya). Ini memberi kita kesempatan untuk melintasi string untuk yang kedua kalinya, mencari tahu apakah ada subset bagian melar yang berjumlah jumlah ruang yang cocok. Melihat dari belakang ke kanan:

>

Ini hanya memastikan bahwa kita benar-benar mulai dari ujung tali (ekor ular).

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

Untuk setiap bagian melar, ini hanya cocok dengan seluruh bagian tanpa melakukan apa-apa ( \|+), atau cocok dengan seluruh bagian sambil muncul menangkap tumpukan 1( (?<-1>\|)*). Memiliki pergantian ini memastikan bahwa kami hanya dapat sepenuhnya memperpanjang bagian melar atau membiarkannya tidak berubah, dan tidak mendapatkan barang-barang seperti |/\|. Kemudian kita beralih ke bagian melar berikutnya dengan [^|]+.

(?(1)!)^

Akhirnya, kami memastikan bahwa kami telah melintasi seluruh string (keduanya ular), dan tumpukan 1itu benar-benar kosong. Yaitu bahwa kita telah menemukan subset dari bagian melar yang tepat jumlah jumlah ruang yang telah kita tangkap sebelumnya.

Pelacak mundur akan bolak-balik melalui string mencoba semua kombinasi bagian tidak berubah dan diperpanjang sampai masalah jumlah subset diselesaikan. Jika subset seperti itu tidak ada, tampilan di bawah akan gagal. Ini akan menyebabkan backtracker kembali ke \S+( )+.+bagian dan mencoba menangkap satu ruang lebih sedikit dengan ( )+(yang hanya akan ditutupi oleh .+sebagai gantinya). Karena keserakahan +kami berusaha mengisi ruang sebanyak mungkin.

Anda dapat memeriksa validitas pendekatan ini dengan substitusi yang sedikit dimodifikasi ini:

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

Yang akan memberi Anda string =spaces=dengan tepat jumlah ruang yang bisa diisi dengan ular yang diberikan.

Saya harus menambahkan beberapa tipu daya untuk benar-benar memperluas |s yang benar . Pada dasarnya, saya ingin mengganti semua |yang cocok menggunakan (?<-1>\|)+cabang. Idenya adalah untuk mencocokkan karakter individu, menempatkan solver di lookaround dan mengatur bendera jika pertandingan kebetulan berada di dalam cabang itu. Jika bendera itu tidak disetel, kami membatalkan pertandingan pada akhirnya untuk menghindari penggantian karakter lain.

Untuk melakukan ini, kami menggunakan banyak pencarian yang bersarang. Sekali lagi, tampilan variabel-panjang NET. Dicocokkan dari kanan ke kiri, jadi jika kita bersarang lookaheads dan lookbehinds, kita dapat membiarkan mesin regex melintasi string beberapa kali. Untuk alasan bermain golf, solver dibalik dalam solusi saya yang sebenarnya (mulai dari akhir, mengambil spasi dari kanan ke kiri, dan kemudian memecahkan jumlah himpunan bagian dari kiri ke kanan), tetapi sebaliknya struktur solver persis sama . Mari kita membedah regex lengkap:

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

Kami mencocokkan satu karakter, lalu menangkap sisa string dan memindahkan kursor ke ujung string. Kami akan menggunakan grup ini 1nanti untuk memeriksa solver apakah kami ada di posisi pertandingan.

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

Ini seperti bagian pertama dari pemecah sederhana di atas, kecuali bahwa kita mengambil spasi dari kanan ke kiri. Pengulangan jumlah ruang bekerja sama persis seperti sebelumnya, kecuali bahwa kami menggunakan grup 5sekarang.

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

Ini sama dengan sebelumnya, kecuali kita bergerak dari kiri ke kanan, dan setiap kali kita mencocokkan dengan |di cabang yang berkembang, kita memeriksa apakah itu yang cocok dengan

(?=\1())?

Ini adalah lookahead opsional. Ia mencoba untuk mencocokkan grup 1lagi (yang, di sini, hanya mungkin jika kita tepat setelah karakter dicocokkan), dan jika kita lakukan, kita menangkap string kosong ke dalam grup 4, yang menunjukkan bahwa kita memang menemukan karakter saat ini dalam satu bit diperluas. Jika \1tidak cocok, 4tidak akan menangkap apa pun, dan ?memastikan bahwa lookahead yang gagal tidak akan mempengaruhi pemecah sama sekali.

Akhirnya, setelah semua penyelesaian dilakukan, kami hanya memeriksa \4apakah lookahead ini digunakan. Jika demikian, kami ingin mengganti karakter saat ini dengan /\.

Satu kesulitan tetap: menghapus jumlah ruang yang tepat. Cara terpendek untuk melakukan ini yang saya temukan sejauh ini adalah menyisipkan spasi bersama dengan /\dan kemudian menyingkirkan satu ruang antara lidah untuk masing-masing ruang penanda tersebut dalam langkah terpisah:

+` (.*~|~.*) 
$1
Martin Ender
sumber
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}

Ini adalah fungsi yang mengambil string sebagai parameter dan mengembalikan string.

Tes online: http://ideone.com/uhdfXt

Ini versi yang bisa dibaca:

# 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
}

Dalam versi golf, fungsi utama adalah setara dengan KISSfungsi di atas, dan COMBINATIONSfungsi tersebut telah digariskan.

Cristian Lupascu
sumber
Gagal pada input <|=||:)~~(:||||>, yang menyebutkan spesifikasi adalah input yang valid.
Value Ink
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","/\\")

Memiliki satu lambda terlihat rapi, tapi saya hampir yakin ini bukan cara terbaik untuk melakukannya. Tapi saya memposting ini karena semua yang saya dapatkan sejauh ini terlihat cukup layak.

Ini adalah kekuatan kasar sederhana atas semua kemungkinan penggantian |dengan /\, memfilter konfigurasi yang tidak valid. Satu-satunya bit yang rapi saya kira adalah bahwa kita tidak benar-benar mengganti apa pun |dengan /\langsung - pertama kita ganti |dengan Xdan lepaskan a .dari tengah untuk setiap penggantian, ambil string panjang minimum di atas semua string yang valid, lalu ganti Xdengan /\.

Saya mencoba beberapa pendekatan lain, termasuk yang rekursif, tetapi mereka akhirnya cukup berantakan. Saya juga belajar bahwa re.splitsaat ini tidak terpecah pada string kosong, yang sangat disayangkan, karena salah satu ide saya melibatkan pemisahan pada \bbatas kata.

Sp3000
sumber
5

Mathematica, 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~"~"&

Fungsi murni mengambil string sebagai argumennya. Mengharapkan .daripada di antara ular.

Saya tidak berpikir itu akan seburuk ini ... Inilah yang saya miliki sebelum saya hancurkan bersama-sama dan melekatkan semuanya.

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[#, "~"] &

Berikut adalah contoh run-through dengan penjelasan:

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.
jcai
sumber
Mudah dikurangi menjadi 355 dengan mulai dengan a=StringReplace;b=StringSplit;c=StringLength;d=Total;dan kemudian menggantikan yang diperlukan di tempat lain di dalam: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

Jawaban saya yang lain adalah memecahkan masalah yang salah (maaf untuk kebisingan). Berikut adalah upaya lain dalam Prolog yang benar-benar menghormati semua aturan.

:-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).

Tes

(format: input, output, baris baru)

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

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

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

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

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

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

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

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

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

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

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

Penjelasan

  • Predikat utama adalah s/2, yang mengambil input sebagai argumen pertama dan tidak cocok dengan argumen kedua (kedua string). Input dikonversi ke daftar kode karakter E,.

  • Kemudian, s(E,Z,X,Y,L)rusak daftar menjadi elemen-elemen berikut:

    • Z jumlah spasi di antara ular
    • Xdan Y, representasi abstrak dari tubuh kiri dan kanan

      Format tubuh adalah daftar n:Natau s:Nekspresi, di mana Npanjangnya positif; nsarana normaldan ssarana stretched.

    • L total panjang daftar

Yang menariks/5 adalah bahwa ia berjalan dua arah , yaitu kita dapat membuat ular jika argumen lain dilemahkan:

    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.
  • Kami membangun tubuh kiri dan kanan yang dimodifikasi di mana setiap bagian normal atau membentang, sambil meminimalkan ruang Qyang memisahkan ular baru. Panjang total string yang dihitung dibatasi sehingga pencarian berakhir.
coredump
sumber
1

Python 2.7.3 427 421 400 371 Bytes

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))

Kode non-golf di sini -

#!/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)

Menguji solusi golf -

$ 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] =>  <|=||:)~~(:||||>

Tentunya ini bisa dilakukan dengan lebih baik (saya tidak tahu caranya :)).
Beri tahu saya jika saya melewatkan sesuatu yang jelas saat bermain golf (Ini codegolf pertama saya, saya mungkin melakukan sesuatu yang bodoh: P)

Kamehameha
sumber
@ Sp3000 Itu bagus. Diganti exituntuk sys.exit()(lupa exitada). Dan Anda benar, __import__dapat dihapus, yang dihilangkan seperti 20 karakter :)
Kamehameha
btw aturan praktis: untuk aliasing Anda perlu > 6karakter untuk bernilai aliasing jika Anda menggunakannya dua kali, > 3karakter jika Anda menggunakannya tiga kali. Saya tidak yakin f=' 'alias itu sepadan (saya hitung dua kali)
Sp3000
@ Sp3000 ya Anda benar. Dalam versi sebelumnya saya telah menggunakan variabel itu tiga kali. Menyelamatkan saya beberapa byte lagi :) :)
Kamehameha
1

05AB1E , 93 byte

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

Terlalu lama ..>.>

Cobalah secara online atau verifikasi semua kasus uji atau verifikasi semua hasil yang mungkin untuk semua kasus uji .

Penjelasan:

#õ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)
Kevin Cruijssen
sumber