Зробіть поцілунок з міцними зміями


57

Еластична змія виглядає приблизно так:

<||=|||:)~

Кожна окрема послідовність вертикальних брусків ( |) в еластичній змії, відомій як еластична частина , індивідуально розширюється вдвічі більше її ширини і намальована поперемінними нахилами ( /, \) один раз подовженими.

Конкретна змія вгорі має дві такі еластичні ділянки, надаючи їй чотири можливі пози:

<||=|||:)~

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

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

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

Загальна форма витягнутої змії в її найменш розтягнутій позі визначається цим регулярним виразом :

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

Які можна сказати словами як:

<, За яким слід будь-яку кількість послідовностей |«и вступив з =ознаками, а потім :)~.

Так <|:)~і <||:)~і <|=|:)~і <|=|=||=|||||=||:)~є еластичні змії, але <=:)~і <=|:)~і <||=:)~і <|==||:)~не є.

Еластичні змії можуть також стикатися ліворуч, а не праворуч, наприклад ~(:|||=||>. Форми однакові, просто дзеркальні.

Виклик

Напишіть програму, яка включає в один рядок рядок двох еластичних змій, звернених один до одного, з деякою кількістю пробілів між ними. Обидві змії будуть знаходитись у найменш розтягнутій позі (всі вертикальні бруски, без косої риски). Рядок розпочнеться з хвоста змії, що стоїть правою стороною, і закінчиться хвостом змії, що стоїть ліворуч (можна, при бажанні, припустити, що є також зворотний новий рядок).

Наприклад, ось можливий вхід з п'ятьма пробілами між зміями:

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

Я використовую періоди ( .) замість фактичних символів простору для наочності.

Нульовий пробіл між зміями також є дійсним введенням:

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

Ми кажемо, що змії цілуються, коли їхні язики так торкаються.

Вашій програмі необхідно розширити деяку комбінацію розтяжних частин обох змій, щоб змії мали між собою найменшу кількість пробілів (без перекриття), тобто такі, щоб змії були максимально близькими до поцілунків .

Обидві хвости змій закріплені, але їх голови та тіла можуть переміщатися - праворуч для правої змії, ліворуч - для змії, що стоїть ліворуч - відповідно до того, які розтягнуті частини були розширені.

Результатом вашої програми є однорядковий рядок (плюс необов'язковий трейлінг нового рядка), який показує змій якомога ближче до поцілунків, з чергуванням нахилів, накреслених замість вертикальних брусків для розтягнутих ділянок, які були розширені.


Наприклад, вихід для <|=||:)~.....~(:||||>(зверху) буде:

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

Це єдине рішення тут, оскільки при будь-якій іншій комбінації розтягнутих частин, змії або перекриваються, або віддаляються від поцілунків.


Якщо можливі кілька рішень, вихід може бути будь-яким з них.

Наприклад, якщо введення було

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

вихід може бути

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

або

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

Пам'ятайте, що змусити змій поцілуватися не завжди вдасться, але все одно потрібно наблизити їх якомога ближче.

Наприклад, якщо введення було

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

вихід може бути

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

або

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

Якщо змії вже цілуються, вихід буде таким же, як і вхід. напр

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

Загалом, вихід буде таким же, як і вхідний, якщо розширення будь-якої розтягнутої частини зробить змій перекриттям. напр

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

Примітки

  • Приймає введення з stdin або командного рядка, як зазвичай, або записує функцію, яка займає рядок. Роздрукуйте або поверніть вихід.
  • Ви можете використовувати періоди ( .) для введення та виводу замість пробілів ( ), якщо вам зручніше.
  • Важливо лише, щоб косої риси чергувались у послідовності вертикальних брусків, які вони замінили. Їх впорядкованість у змії взагалі чи те, що спочатку наступає нахил уперед чи назад, не має значення.
  • Еластичні ділянки не можуть подовжуватися частково - це рівно подвійне або зовсім не розширення.

Оцінка балів

Це код-гольф . Виграє найкоротше подання в байтах. Тирбейкер - це відповідь раніше.


17
Snex Education 101 - Як правильно поцілуватися
Optimizer

45
"Ми кажемо, що змії цілуються, коли їхні мови торкаються так". Що я читаю ...
Підтвердити

8
Тож змії роблять тільки французьку?
Оптимізатор

3
@PeterTaylor Добре, "дзеркальне відображення", а не "зворотний" (інакше >не стане <і те ж, і для, (і )), але він також каже: "Важливо лише, щоб косої риски чергувалися в послідовності вертикальних смуг, які вони замінили. Їх впорядкування в змія в цілому, чи те, що спочатку наступає нахил вперед або назад, не має значення ".
Мартін Ендер

Відповіді:


9

CJam, 87 71 70 68 байт

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

Спробуйте його в Інтернеті в інтерпретаторі CJam .

Як це працює

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

Сітківка , 209 107 99 97 92 байт

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

Для підрахунку кожного рядка йде окремий файл, але ви можете запустити код з одного файлу з -sпрапором.

Об'єднання кращих особливостей .NET-регулярного виразів та сітківки: балансування груп, довільна довжина відставання та повторне заміщення регулярних виразів.

По суті, довгий регулярний вираз кодує дійсне рішення, і зворотний трекер двигуна регексу знаходить одне з оптимальних для мене.

Пояснення

Спочатку розглянемо, як ми можемо знайти дійсне рішення (не обов’язково даючи правильний результат) за допомогою регулярного вираження. Ми можемо використовувати балансуючі групи .NET, щоб допомогти нам підрахувати складні частини. Розглянемо наступний простіший регулярний вираз:

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

Ми можемо відхилити це.

\S+( )+.+

Це відповідає всій рядку, натискаючи на одне захоплення на груповий 1стек для кожного проміжку на вході. Ми будемо використовувати цей стек для того, щоб розтягуючі частини точно заповнювали простір, захоплений цими групами.

Далі - огляд. Проблема полягає в тому, що оглядові панелі узгоджуються справа вліво в .NET (так ось як слід їх читати). Це дає нам можливість перейти рядок вдруге, з'ясувавши, чи є підмножина розтягнутої частини, яка підсумовує кількість відповідних пробілів. Переглядаючи вид ззаду справа наліво:

>

Це просто гарантує, що ми насправді починаємо з кінця струни (зміїного хвоста).

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

Для кожної розтягнутої частини це або просто відповідає всій частині, нічого не роблячи ( \|+), або відповідає всій частині під час вискакування захоплює стек 1( (?<-1>\|)*). Таке чергування гарантує, що ми можемо лише повністю розтягнути розтягувану частину або залишити її незмінною, а не отримати подібні речі |/\|. Потім переходимо до наступної еластичної частини с [^|]+.

(?(1)!)^

Нарешті, ми гарантуємо, що ми пройшли всю нитку (обидві змії), і що стек 1повністю порожній. Тобто ми знайшли підмножину еластичної частини, яка точно відповідає кількості пробілів, які ми захопили раніше.

Зворотний трекер буде проходити вперед і назад по рядку, намагаючись усі комбінації незмінних і розширених частин, поки не буде вирішена проблема суми підмножини. Якщо такої підмножини не існує, вигляд ззаду буде невдалим. Це призведе до того, що ретранслятор повернеться до \S+( )+.+частини та спробує захопити на простір менше ( )+(що .+замість цього буде просто прикритим ). Через жадібність +ми намагаємось заповнити якомога більше пробілів.

Ви можете перевірити обгрунтованість цього підходу за допомогою цієї трохи зміненої заміни:

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

Що дасть вам рядок =spaces=з точно такою кількістю пробілів, які можна заповнити заданими зміями.

Мені довелося додати ще кілька хитрощів, щоб фактично розширити правильний |s. В основному, я хочу замінити всі |, які були узгоджені за допомогою (?<-1>\|)+гілки. Ідея полягає у тому, щоб відповідати індивідуальному персонажу, помістити розв'язувач у пошуковий ланцюг і встановити прапор, якщо збіг знаходиться всередині цієї гілки. Якщо цей прапор не встановлено, ми визнаємо недійсним матч наприкінці, щоб уникнути заміни інших символів.

Для цього ми використовуємо купу вкладених циклів пошуку. Знову-таки, вигляд змінного довжини .NET узгоджується справа наліво, тому, якщо ми вкладемо штрихи та дивимось позаду, ми можемо дозволити двигуну регулярного випромінювання переходити рядок кілька разів. З міркувань гри в гольф, вирішувач перетворюється на моє фактичне рішення (починаючи з кінця, підбираючи пробіли справа наліво, а потім вирішуючи підмножину зліва направо), але в іншому випадку структура розв'язувача точно така ж . Розкриємо повний вираз:

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

Ми підбираємо один символ, потім захоплюємо решту рядка і переміщуємо курсор до кінця рядка. 1Пізніше ми скористаємося цією групою, щоб перевірити, чи знаходимося ми в матчі.

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

Це подібно до першої частини простого вирішувача вище, за винятком того, що ми підбираємо пробіли справа наліво. Відслідковування кількості пробілів працює точно так само, як і раніше, за винятком того, що зараз ми використовуємо групу 5.

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

Це те саме, що і раніше, за винятком того, що ми рухаємося зліва направо, і кожного разу, коли ми співставляємо а |в гілці, що розширюється, ми перевіряємо, чи відповідає вона правій

(?=\1())?

Це необов'язковий пошук. Він намагається знову співставити групу 1(що, тут, можливо лише в тому випадку, якщо ми відразу після відповідності символу), і якщо ми це зробимо, ми захопимо порожню рядок у групу 4, що вказує на те, що ми знайшли поточного символу в одному розширених бітів. Якщо \1не збігається, 4нічого не буде захоплено, і ?гарантує, що невдалий пошук не вплине на вирішувач.

Нарешті, після того, як все вирішено, ми просто перевіряємо, \4чи використовувався цей підказник. Якщо так, ми хочемо замінити поточний символ на /\.

Залишається одна складність: видалити потрібну кількість пробілів. Найкоротший спосіб зробити це я знайшов поки що - вставити пробіл разом із, /\а потім позбутися одного проміжку між язиками для кожного з цих маркерних пробілів в окремий крок:

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

6

Рубін 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}

Це функція, яка приймає рядок як параметр і повертає рядок.

Тести в Інтернеті: http://ideone.com/uhdfXt

Ось читабельна версія:

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

У версії для гольфу основна функція є еквівалентом KISSфункції, наведеної вище, і COMBINATIONSфункція була накреслена.


Помилка при введенні <|=||:)~~(:||||>, що вказано в специфікації, є коректним входом.
Значення чорнила

6

Пітон, 205 байт

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

Єдина лямбда виглядає акуратно і все, але я майже впевнений, що це не найкращий шлях. Але я це публікую, тому що це все, що я маю до цих пір, виглядає наполовину пристойно.

Це простий перебір по всіх можливих замін |з /\, фільтруючи недійсні конфігурації. Єдиний акуратний трохи я думаю, що ми на самому ділі не замінити який - або |з /\напряму - ми спочатку замінимо |з Xі опускаємо .з середини для кожної заміни, візьміть мінімальну довжину рядка на всі дійсні рядки, а потім замінити Xs з /\.

Я спробував кілька інших підходів, включаючи рекурсивні, але вони виявилися досить безладними. Я також дізнався, що re.splitнаразі не розділяється на порожні рядки, що було прикро, тому що одна з моїх ідей передбачала розбиття \bмеж слова.


5

Математика, 381 байт

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

Чиста функція, беручи рядок як аргумент. Очікує, .а не між зміями.

Я не думав, що це буде так погано ... Ось що я мав до того, як разом розбив і все зафіксував.

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

Ось приклад проходження з поясненням:

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.

Легко скорочується до 355, починаючи з, a=StringReplace;b=StringSplit;c=StringLength;d=Total;а потім замінюючи ті, що потрібно в іншому місці: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~"~"&
Алекс Майбург

3

Пролог (ECLiPSe), 438 байт

Інші мої відповіді були вирішенням неправильної проблеми (вибачте за шум). Ось ще одна спроба в Prolog, яка насправді дотримується всіх правил.

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

Тести

(формат: введення, вихід, новий рядок)

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

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

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

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

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

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

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

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

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

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

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

Пояснення

  • Основним предикатом є те s/2, що приймає вхід як перший аргумент і видаляє результат другим аргументом (обидва рядки). Вхід перетворюється в список кодів символів, E.

  • Потім s(E,Z,X,Y,L)деструктурує список на такі елементи:

    • Z кількість пробілів між зміями
    • Xі Y, абстрактне зображення лівих і правих органів

      Формат тіла - це список n:Nабо s:Nвирази, де Nє додатна довжина; nзасоби normalта sзасоби stretched.

    • L загальна довжина списку

Що цікаво,s/5 це те, що він йде обома шляхами , тобто ми можемо побудувати змію, якщо інші аргументи є примірниками:

    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.
  • Ми будуємо модифіковані ліві та праві тіла, де кожна частина є нормальною або розтягнутою, зменшуючи при цьому простір, Qякий розділяє нові змії. Загальна довжина обчислюваного рядка обмежена так, що пошук закінчується.

1

Python 2.7.3 427 421 400 371 байт

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

Код без гольфу тут -

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

Тестування розчину для гольфу -

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

Звичайно, це можна зробити краще (я не можу зрозуміти, як :)).
Дайте мені знати, якщо я пропустив щось очевидне під час гольфу (це мій перший кодовий гольф, я можу робити щось дурне: P)


@ Sp3000 Це хороший. Замінено exitна sys.exit()(забув, що exitіснував). І ви маєте рацію, __import__може бути знято, що ліквідується як 20 символів :)
Kamehameha

btw правило: для згладжування вам потрібні > 6символи, які будуть варті згладжування, якщо ви використовуєте його двічі, > 3символи, якщо ви використовуєте його три рази. Я не впевнений, що f=' 'псевдонім того вартий (я рахую двічі)
Sp3000

@ Sp3000 да, ви праві. У попередній версії я використовував цю змінну тричі. Врятували мені ще пару байтів :) :)
Камехамеха

1

05AB1E , 93 байти

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

Шлях занадто довгий ..>.>

Спробуйте в Інтернеті або перевірити всі тестові випадки або перевірити всі можливі результати для всіх тестових випадків .

Пояснення:

#õ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)
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.