Взаимно заполните пробелы


11

Если введены две строки с последовательностями символов подчеркивания, представляющими соответствующие слова, выведите предложения с заполненными пробелами.

Лучший способ описать эту проблему - это на примере. Вот пример ввода:

programming _____________ and code golf
programming puzzles ______ code ____

И вот соответствующий вывод:

programming ___puzzles___ and code golf
programming puzzles _and__ code golf

Для целей этой задачи «слово» определяется как последовательность из одной или нескольких строчных букв, а «пробел» определяется как одно или несколько подчеркиваний (ввод всегда будет содержать только строчные буквы, пробелы и подчеркивания) , Слова и пробелы во входных строках разделены пробелами, а сумма количества слов и пробелов в предложениях всегда будет равна.

Задача состоит в том, чтобы заполнить все пробелы правильными словами , которые являются словами, которые занимают тот же индекс в другой строке при разбиении на пробелы.

  • Слово должно быть в центре пробела, как показано со словом «головоломки» в приведенном выше примере - с обеих сторон остается одинаковое количество подчеркиваний.

  • Если слово не может быть точно отцентрировано, дополнительное подчеркивание может идти как слева, так и справа (например, слово «и» в приведенном выше примере).

  • Для соответствия слову всегда будет достаточно подчеркивания, но может быть ровно столько, сколько длина слова (например, слово «гольф» в приведенном выше примере).

  • Никогда не будет пробела в одной и той же позиции в обеих строках.

Ввод / вывод может быть любым из следующих (ввод / вывод не обязательно должен быть одним и тем же способом):

  • одиночная строка, разделенная любым символом, который не является буквенным, пробелом или подчеркиванием (например, строка новой строки или запятая)

  • массив / список / и т. д. из двух струн

  • два аргумента функции / командной строки (только для ввода)

Поскольку это , победит самый короткий код в байтах.

Приведенный выше пример можно использовать в качестве тестового примера. Вот более крупный тестовый пример (вторая строка в выводе может немного отличаться из-за разного поведения центрирования):

lorem _____ dolor _____ amet _______________ adipiscing elit mauris dapibus tincidunt _____________________________ accumsan fringilla proin vulputate viverra lorem fermentum dictum
lorem ipsum ______ sit _______ consectetur _______________ elit mauris dapibus tincidunt metus accumsan fringilla proin vulputate viverra lorem ____________________________ dictum

lorem ipsum dolor _sit_ amet __consectetur__ adipiscing elit mauris dapibus tincidunt ____________metus____________ accumsan fringilla proin vulputate viverra lorem fermentum dictum
lorem ipsum dolor_ sit _amet__ consectetur __adipiscing___ elit mauris dapibus tincidunt metus accumsan fringilla proin vulputate viverra lorem _________fermentum__________ dictum

Хороший двухлетний вызов.
Rɪᴋᴇʀ

Ответы:


5

Пиф, 30

jL;Cmm|*}J\_k.[lkhx#JdJkdCcR;Q

Принимает ввод и вывод в виде списка из двух строк. Использует довольно простой подход «раздвоение - застежка - двойная карта - центр - застежка - молния».

Попробуй здесь

Expanded:

jL;Cmm|*}J\_k.[lkhx#JdJkdCcR;Q   ##
                          cR;Q   ##  split
                         C       ##  zip
    mm                           ##  double map
      |*}J\_k.[lkhx#JdJkd        ##  centre
   C                             ##  zip
jL;                              ##  join

Я объясню больше, как только я действительно буду удовлетворен тем, что я больше не могу играть в гольф, хотя это должно быть довольно ясно, учитывая повсеместность подхода «раздвоение-застежка-двойная карта-центр-застежка-молния» и все такое.


8
Аааа, классический подход split-zip-double map-center-zip-join. Я с любовью помню, как он использовался в качестве вводного примера в моей лекции «Алгоритмы 101».
Мартин Эндер

3
@ MartinBüttner Да, у меня плохие воспоминания об этом, потому что я спал в этом классе, и мне пришлось решать задачи на экзамене, используя вместо этого подход duplicate-append-lookback-match-add-center.
FryAmTheEggman

4
Я пойду приложу немного холодной воды к ожогу.
Мартин Эндер

7

Сетчатка , 102 100 93 88 байт

Количество байтов предполагает кодировку ISO 8859-1.

$
!¶$`
m`(?<=^(\w+ )*)(?=_.*¶(?<-1>\w+ )*(\w+))
$2
(([a-z])+)(?<-2>_)*(_*)\3|!\D+
$3$1$3

Строки будут разделены переводом строки. Если осталось нечетное количество подчеркиваний, постороннее будет после слова.

Попробуйте онлайн!

объяснение

Я предполагаю, что это "подход дубликата-добавления-просмотра-совпадения-добавления-центра", или что-то близкое ...

$
!¶$`

Мы начнем с дублирования ввода (разделенных !символом a и переводом строки). Цель этого состоит в том, что мы можем затем обрабатывать обе строки, выбирая слова из следующей строки (вместо того, чтобы обрабатывать вторую строку отдельно).

m`(?<=^(\w+ )*)(?=_.*¶(?<-1>\w+ )*(\w+))
$2

Это добавляет правильное слово для каждого пробела. Начнем с подсчета текущей позиции слова с помощью lookbehind (?<=^(\w+ )*)(позиция сохраняется как глубина группы 1). Тогда опережение а) гарантирует , что мы в начале промежутка согласования _, а затем переходит к следующей строке с .*¶, соответствует правильному количеству слов с , (?<-1>\w+ )*чтобы попасть в нужное положение, а затем сопоставляет слово нашло там с (\w+)в группа 2.

(([a-z])+)(?<-2>_)*(_*)\3|!\D+
$3$1$3

Этот этап делает три вещи:

  • Он удаляет подчеркивания, соответствующие каждой длине слова. Это делается путем подсчета длины слова в группу 2с ([a-z])+последующим сопоставлением такого количества подчеркиваний (которые никогда не записываются обратно).
  • Он сдвигает слово к центру пробела, захватывая половину оставшихся подчеркиваний (_*)\3и записывая $3$1$3обратно.
  • Он удаляет дублированный ввод путем сопоставления !\D+и замены его ничем.

4

Python 2, 109

def f(a,b):exec"print' '.join([x,y][x<'`'].center(len(x),'_')for x,y in zip(a.split(),b.split()));a,b=b,a;"*2

Функция принимает две строки в качестве аргументов и печатает выходные данные, как в примерах. Он использует скучный подход, str.center(width, fillchar)выполняя большую часть работы.

Попробуйте онлайн .


1
Я не думаю, что вам нужно z, если я что-то упустил, вы можете просто сделать обмен после печати и в строке z.
FryAmTheEggman

@FryAmTheEggman да, ты прав. Спасибо :)
GRC

2

Рубин, 111 109 символов

->l{l.map(&:split).transpose.map{|c|c[m=c[0]<c[1]?0:1]=c[1-m].center c[m].size,?_
c}.transpose.map{|s|s*' '}}

Ввод: массив из 2 строк; вывод: массив из 2 строк.

Образец прогона:

2.1.5 :001 > puts ->l{l.map(&:split).transpose.map{|c|c[m=c[0]<c[1]?0:1]=c[1-m].center c[m].size,?_;c}.transpose.map{|s|s*' '}}[[
2.1.5 :002 >       'programming _____________ and code golf',
2.1.5 :003 >       'programming puzzles ______ code ____',
2.1.5 :004 >       ]]
programming ___puzzles___ and code golf
programming puzzles _and__ code golf

1

JavaScript, 194 185 байт

f=(m,n)=>(m=m.split` `,n=n.split` `,G=(x,i,a)=>x[0]!='_'?x:(b=(a?n:m)[i],s=x.length-b.length,(k='_'.repeat(s/2))+b+k+(s%2?'_':'')),H=(e,y)=>e.map((x,i)=>G(x,i,y)).join` `,[H(m,1),H(n)])

Принимает две строки в качестве параметров и выводит две строки в виде массива / списка


1

Mathematica 223

Должен быть более короткий способ сделать это.

k=StringLength;m=StringSplit;
g=Partition[Riffle[m@#,m@#2],2]/.{{a_,a_}:> a<>" ",{a_,b_/; StringTake[b,1]=="_"}:> a<>" ",
{a_,b_}:>Table["_",Ceiling[z=(k@a-k@b)/2]]<>b<>""<>Table["_",Floor@z]<>" "}&;
s_~h~t_:={""<>g[s,t],""<>g[t,s]}

Пробный прогон

h["programming _____________ and code golf", "programming puzzles ______ code ____"]

введите описание изображения здесь


0

Гема, 208 203 персонажа

\B=@set{i;0}
<I>=@push{${v;f};$0}@incr{i}
\n=@set{v;s}@set{i;0}
 =
\E=@repeat{$i;@cmps{$f;$s;@set{f;@fill-center{$f;$s}};;@set{s;@fill-center{$s;$f}}}@set{F;$f ${F;}}@set{S;$s ${S;}}@pop{f}@pop{s}}$F\n$S

Просто потому, что Gema имеет идеальную функцию для этой задачи .@fill-center{background;value}

Ввод: 2 строки, разделенные новой строкой (без последней строки); вывод: 2 строки, разделенные новой строкой (с завершающими пробелами - не похоже, что это запрещено).

Образец прогона:

bash-4.3$ echo -ne 'programming _____________ and code golf\nprogramming puzzles ______ code ____' |
> gema '\B=@set{i;0};<I>=@push{${v;f};$0}@incr{i};\n=@set{v;s}@set{i;0}; =;\E=@repeat{$i;@cmps{$f;$s;@set{f;@fill-center{$f;$s}};;@set{s;@fill-center{$s;$f}}}@set{F;$f ${F;}}@set{S;$s ${S;}}@pop{f}@pop{s}}$F\n$S'
programming ___puzzles___ and code golf 
programming puzzles _and__ code golf 

0

C 197 байтов

#define c(w,y)l=strspn(w,"_"),r=strcspn(y," "),memcpy(w+(l-r)/2,y,r),w+=l,y+=r;
main(l,v,w,y,r)char**v,*w,*y;{for(w=v[1],y=v[2];*w;w++,y++)if(*w^*y)if(*w^95)c(y,w)else c(w,y)puts(v[1]);puts(v[2]);}

Выход

$ ./a.out "lorem _____ dolor _____ amet _______________ adipiscing elit mauris dapibus tincidunt _____________________________ accumsan fringilla proin vulputate viverra lorem fermentum dictum" "lorem ipsum ______ sit _______ consectetur _______________ elit mauris dapibus tincidunt metus accumsan fringilla proin vulputate viverra lorem ____________________________ dictum"
lorem ipsum dolor _sit_ amet __consectetur__ adipiscing elit mauris dapibus tincidunt ____________metus____________ accumsan fringilla proin vulputate viverra lorem fermentum dictum
lorem ipsum dolor_ sit _amet__ consectetur __adipiscing___ elit mauris dapibus tincidunt metus accumsan fringilla proin vulputate viverra lorem _________fermentum__________ dictum

0

ES6, 122 байта

a=>a.map(s=>s.split` `).map((s,n,a)=>s.map((w,i)=>w<'a'?(l=w.length,t=w+a[n^1][i]+w,t.substr(t.length-l>>1,l)):w).join` `)

Принимает массив из двух строк в качестве одного параметра и возвращает другой массив из двух строк.

Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.