Sıkı Bir Yılan Öpücüğü Yap


57

Bir esnek yılan şöyle görünür:

<||=|||:)~

|Bir esnek kısım olarak bilinen esnek bir yılandaki dikey çubukların ( ) her ayrı dizisi , genişliğinin iki katı kadar ayrı ayrı genişletilebilir ve bir kez uzatılmış alternatif eğik çizgilerle ( /, \) çizilir .

Yukarıdaki özel yılan, dört olası poz vererek, bu gibi iki esnek kısma sahiptir:

<||=|||:)~

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

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

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

Esnek bir yılanın en az gerilmiş pozundaki genel formu bu regex ile tanımlanır :

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

Kelimelerde şu şekilde ifade edilebilir:

<, Dizilerin herhangi bir sayıda ve ardından |'s birleştirilmiş ile =, ardından işaretler :)~.

Yani <|:)~ve <||:)~ve <|=|:)~ve <|=|=||=|||||=||:)~esnek yılan vardır, ama <=:)~ve <=|:)~ve <||=:)~ve <|==||:)~değillerdir.

Esnek yılanlar ayrıca sağ yerine sola da bakabilir, örn ~(:|||=||>. Formlar aynı, sadece yansıtılmış.

Meydan okuma

Aralarında bazı boşluklar olacak şekilde birbirine bakan iki esnek yılandan oluşan tek bir satır dizgisine geçen bir program yazın. Her iki yılan da en az gerilmiş pozunda olacaktır (tüm dikey çubuklar, eğik çizgi yok). İp, sağa bakan yılanın kuyruğuyla başlayacak ve sola bakan yılanın kuyruğuyla sona erecektir (isteğe bağlı olarak ayrıca izleyen bir yeni satır olduğunu da varsayabilirsiniz).

Örneğin, yılanlar arasında beş boşluk bulunan olası bir girdi:

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

.Netlik için gerçek boşluk karakterleri yerine perioları ( ) kullanıyorum.

Yılanlar arasındaki sıfır boşluklar da geçerli girişlerdir:

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

Dilleri böyle dokunurken yılanların öpüştüğünü söylüyoruz .

Programınızın, her iki yılanın esnek kısımlarının bir birleşimini genişletmesi gerekir; böylece yılanlar, aralarında mümkün olan en az sayıda boşluğa sahip olur (örtüştürmeden), yani yılanlar, mümkün olduğunca öpmeye yakındır .

Her iki yılanın ucu da sabit ancak başları ve gövdeleri, hangi esnek bölümlerin uzatıldığına göre - sağa bakan yılan için sağa, sola bakan yılan için sağa doğru - hareket edebiliyor.

Programınızın çıktısı, uzatılmış kısımlar için dikey çubukların yerine çizilen alternatif eğik çizgileri olan yılanları mümkün olduğunca öpmeye yakın gösteren tek satır dizisidir (artı isteğe bağlı izleyen yeni satır).


Örneğin, <|=||:)~.....~(:||||>(yukarıdan) için çıktı şöyle olacaktır:

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

Buradaki tek çözüm bu çünkü uzatılmış esnek kısımların başka bir kombinasyonu ile yılanlar üst üste gelecek veya öpüşmekten daha uzakta olacaklardır.


Mümkün olan birden fazla çözüm varsa, çıktı bunlardan herhangi biri olabilir.

Örneğin, giriş olsaydı

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

çıktı olabilir

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

veya

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

Yılanların öpüşmesini sağlamak her zaman mümkün olmayacak, ama yine de onları mümkün olduğunca yaklaştırman gerek.

Örneğin, giriş olsaydı

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

çıktı olabilir

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

veya

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

Yılanlar zaten öpüşüyorsa, çıkış girişle aynı olacaktır. Örneğin

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

Genel olarak, herhangi bir esnek bölümün uzatılması yılanların üst üste binmesine neden olacaksa, çıktı, girişle aynı olacaktır. Örneğin

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

notlar

  • Her zamanki gibi stdin'den veya komut satırından girdi alır veya dize alan bir işlev yazar. Çıktıyı yazdırın veya iade edin.
  • İsterseniz .giriş ve çıkışta boşluk ( ) yerine bölümler ( ) kullanabilirsiniz.
  • Sadece eğik çizgilerin değiştirdikleri dikey çubuk dizisi içinde dönüşümlü olması önemlidir. Yılandaki büyük sıraları veya öne veya arkaya eğik çizginin gelip gelmediği önemli değil.
  • Sıkı kısımlar kısmen uzayamaz - bu tam olarak iki katıdır veya uzaması yoktur.

puanlama

Bu kod golfü . Bayt cinsinden en kısa gönderme kazanır. Tiebreaker daha erken bir cevaptı.


17
Snex Education 101 - Düzgün öpüşmek için
Doktor

45
"Dilleri böyle dokunurken yılanların öpüştüğünü söylüyoruz." Ne okuyorum ...
Fatalize

8
Yani yılanlar sadece Fransızca mı?
Doktor,

3
@PeterTaylor Eh, "aynalı" değil (aksi takdirde "ters" >haline olmaz <, biri için aynı (ve )), ama aynı zamanda Onların yerini dikey çubukların dizisi içinde alternatif eğik olduğunu sadece önemli" diyor. Onların sipariş içinde büyük ya da ileri ya da geri eğik çizginin gelip gelmediği önemli değil. ”
Martin Ender

7
@ qwr Hayal gücü.
Calvin'in Hobileri

Yanıtlar:


9

CJam, 87 71 70 68 bayt

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

CJam tercümanında çevrimiçi olarak deneyin .

Nasıl çalışır

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

Retina , 209 107 99 97 92 bayt

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

Sayma amacıyla, her satır ayrı bir dosyaya gider, ancak kodu -sbayrakla birlikte tek bir dosyadan çalıştırabilirsiniz .

.NET regex ve Retina'nın en iyi özelliklerini bir araya getirme: Dengeleme grupları, isteğe bağlı uzunluk görünüşleri ve tekrarlanan regex ikamesi.

Temel olarak, uzun regex geçerli bir çözümü kodlar ve regex motorunun arka izleyicisi benim için en uygun çözümlerden birini bulur.

açıklama

Öncelikle, bir regex ile geçerli bir çözümü nasıl bulacağımızı (mutlaka doğru çıktıyı üretmek zorunda değiliz) düşünelim. Sıkı parçaları saymamıza yardımcı olması için .NET'in dengeleme gruplarını kullanabiliriz. Aşağıdaki daha basit regex'i düşünün:

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

Bunu disekte edebiliriz.

\S+( )+.+

Bu, dizgenin tamamıyla eşleşir 1ve girişteki her alan için bir kümeyi grup yığınına iter . Esnek yığını, bu gruplara yakalanan alanı tam olarak doldurmasını sağlamak için bu yığını kullanacağız.

Sırada bir göz atıyor. Yakalama, gözbebeklerinin .NET'te sağdan sola doğru eşleştirilmesidir (bu yüzden onları okumalısınız). Bu bize ipi ikinci kez çaprazlama ve eşleştirilen boşluk sayısına tekabül eden bir esnek bölüm alt kümesinin bulunup bulunmadığını bulma fırsatı verir. Soldan sağa sola bakarken:

>

Bu sadece dizgenin sonundan (yılanın kuyruğu) başladığımızdan emin olmaktır.

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

Her esnek parça için bu, ya hiçbir şeyi ( \|+) yapmadan sadece tüm parçayla eşleşir ya da haşhaş yığını 1( (?<-1>\|)*) yakalarken, tüm parçayla eşleşir . Bu değişime sahip olmak, sadece esnek bir parçayı tamamen genişletebilmemizi veya değiştirmeden bırakmamızı ve benzeri şeyler alamamamızı sağlar |/\|. Sonra bir sonraki gergin kısma geçiyoruz [^|]+.

(?(1)!)^

Son olarak, tüm dizgiyi (her iki yılanı da) geçtik ve o yığının 1tamamen boş olduğundan emin olduk . Yani, daha önce yakaladığımız alanların toplamına tekabül eden bir esnek kısım alt kümesi bulduk.

Backtracker, alt küme toplamı sorunu çözülene kadar değiştirilmemiş ve uzatılmış parçaların tüm kombinasyonlarını deneyen dizi içerisinde ileri geri gidecektir. Eğer böyle bir alt küme mevcut değilse, gözetleme başarısız olur. Bu, arka izleyicinin \S+( )+.+parçaya geri dönmesine ve bununla daha az bir alan yakalamaya çalışmasına ( )+neden olur (bunun .+yerine sadece kapak olur ). +Bu nedenle açgözlülüğümüzden dolayı mümkün olduğunca fazla boşluk doldurmaya çalışıyoruz.

Bu yaklaşımın geçerliliğini, bu hafifçe değiştirilmiş ikame ile kontrol edebilirsiniz:

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

Bu, size =spaces=verilen yılanlarla doldurulabilecek boşlukların tam olarak bulunduğu bir dize verecektir .

Doğru olanı genişletmek için biraz daha kandırmaca eklemek zorunda kaldım |. Temel olarak, dalı |kullanarak eşleşen tüm s değiştirmek istiyorum (?<-1>\|)+. Buradaki fikir, bireysel bir karakterle eşleşmek, çözücü bir aramaya koymak ve eğer maç o dalın içinde olursa bir bayrak koymaktır. Bu bayrak ayarlanmadıysa, diğer karakterlerin değiştirilmesini önlemek için sonunda eşleşmeyi geçersiz kılıyoruz.

Bunu yapmak için, bir sürü iç içe görünüm kullanırız. Yine, .NET'in değişken uzunluktaki gözbebekleri sağdan sola eşleştirilir, böylece gözbebekleri ve gözbebeklerini yerleştirirsek, regex motorunun dizgiyi birkaç kez geçmesine izin verebiliriz. Golf nedeniyle, çözücüm gerçek çözümümde tersine dönüyor (en baştan başlayarak boşlukları sağdan sola alıp, alt kümenin toplamını soldan sağa çözerek), aksi halde çözücünün yapısı tamamen aynı . Tüm regex'i parçalayalım:

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

Tek bir karakterle eşleşip dizginin geri kalanını yakalarız ve imleci dizinin sonuna taşırız. Bu grubu 1daha sonra, çözücüyü maçın yerinde olup olmadığımızı kontrol etmek için kullanacağız .

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

Bu, yukarıdaki basit çözücünün ilk kısmı gibidir, ancak boşlukları sağdan sola kaldırmamız dışında. Boşluk sayısının geriye doğru izlenmesi, 5şimdi grubu kullanmamız dışında, eskisi gibi aynı şekilde çalışır .

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

Bu, daha önce olduğu gibi aynıdır, soldan sağa gidiyoruz |ve genişleyen dalda ne zaman bir eşleşirsek eşleşip eşleşmediğini kontrol ediyoruz.

(?=\1())?

Bu isteğe bağlı bir bakış açısıdır. Bu grup eşleştirmeye çalışır 1(biz karakter eşleştirilerek hemen sonra eğer, burada, mümkün olan tek olan) tekrar ve biz yaparsak, biz gruba boş bir dize yakalamak 4biz birinde geçerli karakteri buldunuz belirtir, genişletilmiş bitlerin. Eğer \1uymuyor, 4bir şey yakalamak ve olmayacaktır ?başarısız lookahead hiç çözücüsü etkilemez olmasını sağlar.

Sonunda, tüm çözme tamamlandıktan sonra, sadece \4bu bakış başlığının kullanılıp kullanılmadığını kontrol ederiz . Eğer öyleyse, şu anki karakteri ile değiştirmek istiyoruz /\.

Bir zorluk kalıyor: doğru miktarda alanı kaldırmak. Bunu şimdiye kadar bulduğum en kısa yol, birlikte bir boşluk ekleyip /\daha sonra, bu işaretleme alanlarının her biri için diller arasında bir boşluktan ayrı bir adımda kurtulmaktır:

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

Bu, bir dizgeyi parametre olarak alan ve bir dize döndüren bir işlevdir.

Çevrimiçi testler: http://ideone.com/uhdfXt

İşte okunabilir sürüm:

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

Golf edilen versiyonda, ana KISSfonksiyon yukarıdaki fonksiyonun karşılığıdır ve fonksiyon sıralanmıştır COMBINATIONS.


Belirtimlerin <|=||:)~~(:||||>geçerli bir girdi olduğu giriş başarısız olur .
Değerli Mürekkep

6

Python, 205 bayt

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","/\\")

Tek bir lambdaya sahip olmak düzgün görünüyor ve hepsi, ama bunun gitmenin en iyi yolu olmadığından neredeyse eminim. Ama bunu gönderiyorum çünkü şu ana kadar sahip olduğum tek şey yarı iyi görünüyor.

Bu, geçersiz yapılandırmaları filtreleyen |ile tüm olası değişimleri için basit bir kaba kuvvettir /\. Sanırım sadece düzgün biraz biz aslında herhangi birinin yerini kalmamasıdır |ile /\doğrudan - biz ilk değiştirmek |ile Xve bir damla .daha sonra değiştirmek, tüm geçerli dizeleri üzerinde minimum uzunluğu dize almak, her değiştirme ortasından Xler ile /\.

Özyinelemeli olanlar da dahil olmak üzere birkaç başka yaklaşım denedim, ancak oldukça dağınık geldi. Ayrıca, re.splitşu anda talihsiz olan boş dizelerle ayrılmadığını öğrendim , çünkü fikirlerimden biri \bkelime sınırlarını bölmekle ilgiliydi .


5

Mathematica, 381 bayt

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

Dizeyi argüman olarak alan saf işlev. Yılanlar arasında .değil bekler .

Bu kadar kötü olacağını düşünmemiştim ... İşte birlikte parçalayıp her şeyi karıştırmadan önce sahip olduklarım.

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

İşte açıklama içeren örnek bir örnek:

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.

a=StringReplace;b=StringSplit;c=StringLength;d=Total;İçinde başka yerlerde ihtiyaç 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~"~"&
duyulanlarla başlayıp daha sonraları

3

Prolog (ECLiPSe), 438 bayt

Diğer cevaplarım yanlış problemi çözmekti (gürültü için üzgünüm). İşte Prolog'da aslında tüm kurallara saygı duyan başka bir girişim.

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

Testler

(format: giriş, çıkış, yeni satır)

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

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

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

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

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

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

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

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

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

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

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

açıklamalar

  • Ana s/2yordam, girdiyi ilk argüman olarak alan ve sonucu ikinci argümanla (her iki dizede) birleştirendir. Giriş bir karakter kodları listesine dönüştürülür E.

  • Sonra, s(E,Z,X,Y,L)listeyi aşağıdaki unsurlara tahrip eder:

    • Z yılanlar arasındaki boşluk sayısı
    • Xve Y, sol ve sağ cisimlerin soyut gösterimi

      Bir vücudun biçimi, pozitif bir uzunluk olan bir liste n:Nveya s:Nifadelerdir N; nanlamına gelir normalve sanlamına gelir stretched.

    • L listenin toplam uzunluğu

Ne hakkında ilginçs/5 gidiyor olmasıdır her iki yönde , yani biz yapabilirsiniz inşa diğer argümanlar instanciated eğer bir yılan:

    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.
  • QYeni yılanları ayıran alanı en aza indirirken, her bir parçanın ya normal ya da gerilmiş olduğu değiştirilmiş sol ve sağ gövdeler inşa ediyoruz . Hesaplanan dizenin toplam uzunluğu, arama sonlandırılacak şekilde sınırlanır.

1

Python 2.7.3 427 421 400 371 Bayt

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

Golf dışı kod burada -

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

Golflü çözümü test etmek -

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

Elbette bu daha iyi yapılabilir (nasıl olduğunu çözemiyorum :)).
Golf sırasında bariz bir şeyi kaçırdıysam bana bildirin (Bu benim ilk kod yazarım, aptalca bir şey yapıyor olabilirim: P)


@ Sp3000 Bu iyi bir tane. Değiştirilen exitiçin sys.exit()(unuttum exitvar). Ve haklısın, __import__kaldırılabilir, 20 karakter gibi elenir :)
Kamehameha

btw kural: takma > 6ad için, iki kez kullanırsanız > 3karakterlerin takma değerinde olması gerekir ; Diğer f=' 'adın değerinin olduğundan emin değilim (iki kez
sayırım

@ Sp3000 evet haklısın. Daha önceki bir sürümde bu değişken üç kez kullanmıştı. Bana başka bir kaç bayt
kurtardı

1

05AB1E , 93 bayt

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

Yol çok uzun ..>.

Çevrimiçi deneyin veya tüm test durumlarını doğrulayın veya tüm test durumları için olası tüm sonuçları doğrulayın .

Açıklama:

#õ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)
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.