Preencha mutuamente os espaços em branco

11

Dada a entrada de duas strings com seqüências de sublinhados representando as palavras correspondentes, imprima as frases com os "espaços em branco" preenchidos.

A melhor maneira de descrever esse desafio é pelo exemplo. Aqui está um exemplo de entrada:

programming _____________ and code golf
programming puzzles ______ code ____

E aqui está a saída correspondente:

programming ___puzzles___ and code golf
programming puzzles _and__ code golf

Para os fins deste desafio, uma "palavra" é definida como uma sequência de uma ou mais letras minúsculas e um "em branco" é definido como um ou mais sublinhados (a entrada sempre conterá apenas letras minúsculas, espaços e sublinhados) . Palavras e espaços em branco nas cadeias de entrada são separados por espaços únicos, e a soma do número de palavras e espaços em branco nas frases sempre será igual.

O objetivo do desafio é preencher todos os espaços em branco com as palavras corretas , que são as que ocupam o mesmo índice na outra sequência quando divididas por espaços.

  • A palavra deve estar centralizada em branco, conforme mostrado com a palavra "quebra-cabeças" no exemplo acima - um número igual de sublinhados permanece em ambos os lados.

  • Se a palavra não puder ser exatamente centralizada, o sublinhado extra poderá ficar à esquerda ou à direita (por exemplo, a palavra "e" no exemplo acima).

  • Sempre haverá sublinhados suficientes para a palavra caber, mas pode haver exatamente o tamanho da palavra (por exemplo, a palavra "golfe" no exemplo acima).

  • Nunca haverá um espaço em branco na mesma posição nas duas cadeias.

Entrada / saída pode ser uma das seguintes opções (entrada / saída não precisa necessariamente ser pelo mesmo método):

  • sequência única separada por qualquer caractere que não seja alfabético, espaço ou sublinhado (por exemplo, sequência separada por nova linha ou vírgula)

  • uma matriz / lista / etc. de duas cordas

  • dois argumentos de função / linha de comando (apenas entrada)

Como esse é o , o código mais curto em bytes será vencedor.

O exemplo acima pode ser usado como um caso de teste. Aqui está um caso de teste maior (a segunda sequência na saída pode variar um pouco devido ao comportamento de centralização diferente):

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
Maçaneta da porta
fonte
Bom desafio bidiurnal.
Rɪᴋᴇʀ

Respostas:

5

Pyth, 30

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

Recebe entradas e saídas como uma lista de duas strings. Usa uma abordagem bastante básica de divisão - zip - mapa duplo - centro - zip - junção.

Experimente aqui

Expandido:

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

Vou explicar mais uma vez que estou realmente satisfeito de não poder jogar mais isso, embora deva ficar bem claro, dada a onipresença da abordagem de divisão - zip - mapa duplo - centro - zip - junção e tudo.

FryAmTheEggman
fonte
8
Ahhh, a abordagem clássica dividir-zip-duplo mapa-centro-zip-join. Lembro-me com carinho de ter sido usado como exemplo introdutório em minha palestra sobre Algoritmos 101.
Martin Ender
3
@ MartinBüttner Sim, eu tenho algumas lembranças ruins porque dormi durante aquela aula, tive que resolver problemas no exame usando a abordagem duplicar-acrescentar-lookback-combinar-adicionar-centro.
FryAmTheEggman
4
Vou aplicar um pouco de água fria na queimadura.
Martin Ender
7

Retina , 102 100 93 88 bytes

A contagem de bytes assume a codificação ISO 8859-1.

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

As strings serão separadas por um avanço de linha. Se houver um número ímpar de sublinhados, o estranho será depois da palavra.

Experimente online!

Explicação

Eu acho que essa é a "abordagem duplicar-acrescentar-lookback-combinar-adicionar-centro", ou algo próximo ...

$
!¶$`

Começamos duplicando a entrada (separada por um !e um avanço de linha). O objetivo disso é que podemos processar as duas linhas buscando palavras da próxima linha (em vez de precisar tratar a segunda linha separadamente).

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

Isso antecede a palavra correta a cada intervalo. Começamos contando a posição atual da palavra com o lookback (?<=^(\w+ )*)(a posição é armazenada como a profundidade do grupo 1). Em seguida, a cabeça de impressão a) garante que estamos no início de uma lacuna combinando e _, em seguida, pula para a próxima linha com .*¶, combina o número correto de palavras com (?<-1>\w+ )*para chegar à posição correta e, em seguida, combina com a palavra encontrada lá (\w+)em grupo 2.

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

Esta etapa faz três coisas:

  • Remove os sublinhados correspondentes ao tamanho de cada palavra. Isto é feito através da contagem do comprimento de palavra em grupo 2com ([a-z])+e, em seguida, combinar que muitos sublinhados (que nunca são escritos de volta).
  • Ele muda a palavra para o centro da lacuna capturando metade dos sublinhados restantes (_*)\3e escrevendo de $3$1$3volta.
  • Ele remove a entrada duplicada combinando !\D+e substituindo-a por nada.
Martin Ender
fonte
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

A função pega duas strings como argumentos e imprime a saída como nos exemplos. Ele usa uma abordagem chata, str.center(width, fillchar)fazendo a maior parte do trabalho.

Experimente online .

grc
fonte
1
Eu não acho que você precise z, a menos que esteja faltando alguma coisa, você pode fazer a troca após a impressão e a impressão em linha z.
FryAmTheEggman
@FryAmTheEggman sim, você está certo. Obrigado :)
grc
2

Ruby, 111 109 caracteres

->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*' '}}

Entrada: matriz de 2 strings; output: array de 2 strings.

Exemplo de execução:

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
homem a trabalhar
fonte
1

JavaScript, 194 185 bytes

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

Pega duas strings como parâmetros e gera duas strings como array / list

removido
fonte
1

Mathematica 223

Deve haver uma maneira mais curta de fazer isso.

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

Execução de amostra

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

insira a descrição da imagem aqui

DavidC
fonte
0

Gema, 208 203 caracteres

\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

Só porque Gema tem a função perfeita para esta tarefa: .@fill-center{background;value}

Entrada: 2 linhas separadas por nova linha (sem nova linha final); saída: 2 linhas separadas por nova linha (com espaços à direita - não parece ser proibido).

Exemplo de execução:

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 
homem a trabalhar
fonte
0

C, 197 bytes

#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]);}

Resultado

$ ./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
Cole Cameron
fonte
0

ES6, 122 bytes

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

Toma uma matriz de duas cadeias como um único parâmetro e retorna outra matriz de duas cadeias.

Neil
fonte