Palavras cruzando

21

Entrada:

Duas strings (NOTA: a ordem de entrada é importante).

Saída:

Ambas as palavras / frases começam em linhas com uma linha vazia entre elas. Eles 'andam' horizontalmente 'próximos um do outro'. Mas quando eles têm o mesmo caráter na mesma posição, eles se cruzam e depois continuam andando 'próximos um do outro'.

Confuso você diz? Vamos dar um exemplo:

Entrada: Words crossing over& Ducks quacking:

Word  quack n 
    s      i g
Duck  cross n  over

Como você pode ver, estes são os caminhos:
Desculpe a pintura ruim do MS ..

Regras do desafio:

  • Sempre voltamos a andar em linha reta depois de atravessarmos antes de atravessarmos novamente (veja o caso de teste acima {1} - onde ingé igual, mas depois de atravessarmos i, primeiro precisamos voltar andando em linha reta (ignorando assim n), antes que possamos atravessar novamente g).
  • As entradas podem ter diferentes comprimentos; nesse caso, a mais longa continua andando em linha reta (consulte os casos de teste 1, 2, 4 e 6).
  • Ambas as entradas podem ser as mesmas (consulte o caso de teste 3).
  • As entradas não conterão nenhuma guia nem novas linhas.
  • Os espaços são ignorados como caracteres iguais (como um caso de aresta) ; nesse caso, o próximo caractere (sem espaço) depois disso - se houver - está passando por cima (consulte os casos de teste 3, 5 e 6).
  • As entradas não podem ter caracteres adjacentes (fora do espaço) na mesma posição; nesse caso, ambos caminham em linha reta horizontalmente (consulte os casos de teste 2).
  • Mesmo que o primeiro caractere seja igual, sempre começamos duas linhas separadas (consulte os casos de teste 3 e 6).
  • Espaços à direita e uma única linha nova à direita são opcionais.
  • Você pode assumir que as entradas conterão apenas caracteres ASCII imprimíveis (novas linhas e tabulações excluídas).
  • As entradas são caso-sensível, de modo Ae anão são iguais, e não vai atravessar (ver caso de teste 7).
  • Ambos os comprimentos das entradas sempre serão pelo menos 2.
  • Entrada e saída podem estar em qualquer formato razoável. Pode ser uma única String com novas linhas; um String-array / lista; impresso para STDOUT; Matriz 2D de caracteres; etc.

Regras gerais:

  • Isso é , então a resposta mais curta em bytes vence.
    Não permita que idiomas com código de golfe o desencorajem a postar respostas com idiomas que não sejam codegolf. Tente encontrar uma resposta o mais curta possível para 'qualquer' linguagem de programação.
  • As regras padrão se aplicam à sua resposta, para que você possa usar STDIN / STDOUT, funções / método com os parâmetros adequados e programas completos do tipo retorno. Sua chamada.
  • As brechas padrão são proibidas.
  • Se possível, adicione um link com um teste para o seu código.
  • Além disso, adicione uma explicação, se necessário.

Casos de teste:

1. Input: "Words crossing over" & "Ducks quacking"

1. Output:
Word  quack n 
    s      i g
Duck  cross n  over

2. Input: "bananas" & "ananas"

2. Output:
bananas

ananas

3. Input: "I see my twin!" & "I see my twin!"

3. Output:
I  e   y  w n 
  s e m  t i !
I  e   y  w n 

4. Input: "Is the weather nice?" & "Not really, no.."

4. Output:
Is th ally, no..
     e
Not r  weather nice?

5. Input: "Codegolf & Programming Puzzles" & "The golfer might solve puzzles"

5. Output:
Code o f & Programming P z l s
    g l                 u z e
The  o fer might solve p z l s

6. Input: "Can you turn the lights off?" & "Can you try to solve this?"

6. Output:
C n  o   urn the  ve  s off?
 a  y u t        l   t 
C n  o   ry to so igh his?

7. Input: "one Ampere" & "two apples"

7. Output:
one Am les
      p
two ap ere

8. Input: "Words crossing" & "Words Quacking"

8. Output:
W r s cross n 
 o d       i g
W r s Quack n 
Kevin Cruijssen
fonte

Respostas:

4

Japt , 56 47 33 bytes

y ®m+S éBv ©ZꬩZx ?°B:B=c2)¯3÷y

Teste online! Recebe a entrada como uma matriz de duas seqüências.

Eu sou um idiota total ... y ®é um milhão de vezes mais fácil de usar em duas cordas de comprimento diferente do que U¬íV¬@...

Explicação

y ®   m+S éBv © Zê¬ © Zx ?° B:B= c2)¯  3à ·  y
y mZ{Zm+S éBv &&Zêq &&Zx ?++B:B=Bc2)s0,3} qR y

              Implicit: U = array of two strings
y             Transpose U, padding the shorter string with spaces in the process.
mZ{        }  Map each pair of chars Z by this function: (we'll call the chars X and Y)
  Zm+S          Append a space to each char, giving X + " " + Y + " ".
  Bv            If B is divisible by 2
  &&Zêq           and Z is a palindrome (X and Y are the same)
  &&Zx ?          and Z.trim() is not empty (X and Y are not spaces):
    ++B           Increment B. B is now odd; the top and bottom strings are swapping.
  :             Otherwise:
    B=Bc2         Ceiling B to a multiple of 2. (0 -> 0, 1 -> 2, 2 -> 2, etc.)
  é       )     Rotate the string generated earlier this many chars to the right.
  s0,3          Take only the first 3 chars of the result.
qR            Join the resulting array of strings with newlines.
y             Transpose rows with columns.
              Implicit: output result of last expression

B é uma variável que monitora em que estado estamos:

  • B % 4 == 0 significa a primeira palavra no topo, mas pronta para alternar;
  • B % 4 == 1 significa que acabamos de mudar;
  • B % 4 == 2 significa segunda palavra no topo, mas pronta para alternar;
  • B % 4 == 3 significa que acabamos de voltar.

Bpassa a ser predefinido para 11; desde então 11 % 4 == 3, a primeira coluna sempre tem a primeira palavra no topo. Aumentamos Bsempre que as palavras trocam de posição ou quando é ímpar (com B=c2).

ETHproductions
fonte
6

APL (Dyalog) , 64 bytes

{C←⎕UCS1e' '1 0 1⍀⍵⊖⍨≠\eC(2/⊃l)⎕R(lC⌽⍳2)C(0@0=⌿⍵)∧' '1⌷⍵}

Experimente online!

Adão
fonte
Se as strings começam com 3 letras idênticas, isso cruza as terceiras letras, não as segundas . Não tenho certeza se este é o resultado correto, perguntei ao OP.
Mr. Xcoder
@ Mr.Xcoder Obrigado. Deve ser corrigido agora.
Adám 11/08/19
Ok, boa solução então. Se tiver tempo, talvez você possa adicionar uma explicação: P
Sr. Xcoder 11/17
@ Mr.Xcoder Sim, eu sempre faço. (Ping-me se você ver qualquer resposta inexplicável meu!)
Adám
1
@ Adám Sim, com certeza ... ou talvez ? Pode ter algo a ver com isso também ... Ah, e uma resposta inexplicável ! Ou talvez dois ...? E algo que eu não entendo direito .
Erik the Outgolfer
4

Carvão , 69 bytes

AE⮌θιθAE⮌ηιηW∧θη«A⊟θεA⊟ηδA∧¬∨φ⁼ε ⁼εδφ¿φ«εAθδAηθAδη»«↑↓ε↓↗δ»»¿θ↑↓↑⮌⁺θη

Experimente online! Link é a versão detalhada do código. Explicação:

AE⮌θιθAE⮌ηιη        Turn the input strings into arrays and reverse them
W∧θη«               While both valus still have characters left
     A⊟θεA⊟ηδ       Extract the next pair of characters
     A∧¬∨φ⁼ε ⁼εδφ   Determine whether this is a crossing point
     ¿φ«εAθδAηθAδη  If so then print the character and switch the value
      »«↑↓ε↓↗δ»»     Otherwise print the two characters apart
¿θ↑↓                Move to print any remaining characters accordingly
↑⮌⁺θη               Print any remaining characters
Neil
fonte
3

Python 2 , 217 210 bytes

-1 byte graças a officialaimm

a,b=map(list,input())
n=max(len(a),len(b))
c=[' ']*n
a=(a+c)[:n]
b=(b+c)[:n]
for i in range(1,n):
 if a[i]==b[i]!=' '==c[i-1]:c[i]=a[i];a[i]=b[i]=' ';a[i:],b[i:]=b[i:],a[i:]
print'\n'.join(map(''.join,[a,c,b]))

Experimente online!

Cajado
fonte
1
1 byte por predefiniçãos=' '
officialaimm
1
@officialaimm Fiz algumas alterações, agora ele tem a mesma contagem de bytes = / #
Rod Rod
2

Haskell, 142 138 bytes

g(a:b)f(c:d)|f>0,a==c,a>' '=[' ',a,' ']:g d 0b|1<2=[a,' ',c]:g b 1d
g[]_[]=[]
g b f d=g(max" "b)f$max" "d
a&b=[[j!!i|j<-g a 0b]|i<-[0..2]]

Experimente online!

Como funciona:

g                    -- function g constructs a list of lists of three characters
                     --   the 1st char belongs to the upper line,
                     --   the 2nd char to the middle line and
                     --   the 3rd char to the lower line
      f              -- flag f indicates if crossing is allowed or not
 (a:b) (c:d)         -- strings to cross
  |f>0               -- if crossing is allowed
      ,a==c          -- and both strings start with the same char
           ,a>' '    --   that is not a space
   =[' ',a,' ']      -- return space for upper/lower line and char a for the middle line
      :g d 0b        -- and go on with crossing disabled and strings swapped
 |1<2=               -- else
   [a,' ',c]         -- keep chars in their lines and
      :g b 1d        --  go on with crossing enabled

g[]_[]=[]            -- base case: stop when both strings are empty

g b f d=             -- if exactly one string runs out of characters
 g(max" "b)f$max" "d --   replace it with a single space and retry

a&b=                 -- main function
          i<-[0..2]  -- for each line i from [0,1,2]    
       j<-g a 0b     -- walk through the result of a call to g with crossing disabled
    j!!i             -- and pick the char for the current line  
nimi
fonte
+1 boa resposta. Parece ter um pequeno bug, no entanto, porque agora começa a cruzar quando os dois primeiros caracteres são iguais, como nos testes 3, 6 e 8 ( TIO ). Além disso, acho que você esqueceu uma palavra em sua frase de explicação "retorne espaço para a linha superior / inferior e um ¿¿¿para a linha do meio ".
Kevin Cruijssen
1
@KevinCruijssen: Obrigado por encontrar o bug. Felizmente, é fácil de corrigir: basta começar g 0. Com relação à palavra que faltava: "a" como em "variável chamada a", mas isso é realmente confuso, então eu a reformulei.
N /
Ah isso a. :) Eu pessoalmente uso anas minhas explicações ao indicar para as variáveis, embora geralmente seja claro o suficiente sem. Obrigado pelo esclarecimento, e eu estava realmente esperando uma correção muito fácil para isso.
Kevin Cruijssen 11/08/19
Não tenho certeza de como fazer 'a' (com 'a substituição de um back-tick) em um comentário, o que eu queria dizer .. (Então, eu uso back-ticks em torno de variáveis, dentro dos meus blocos de código.)
Kevin Cruijssen
2

JavaScript (ES6), 112 bytes

(a,b,c='',g=([a,...A],[b,...B],w)=>a?w&a==b&a>' '?' '+g(B,A,c+=a):a+g(A,B,1,c+=' '):'')=>g(a,b)+`
`+c+`
`+g(b,a)

Ungolfed:

f=
(a,b,                                    //the inputs
 c='',                                   //c will hold the middle sentence
 g=([a,...A],[b,...B],w)=>               //define a function to walk through the strings
                                         //w will be false if we're at the beginning,
                                         //... or if we've just done a swap
     a?                                  //are there any letters left?
       w&a==b&a>' '?' '+g(B,A,c+=a):     //if we haven't just swapped and the letters match,
                                         //... add the current letter to c 
                                         //... and recurse swapping the strings
                    a+g(A,B,1,c+=' '):   //else add a space to c and continue processing
                    ''
)=>
g(a,b)+'\n'+                             //call g with a, b
c+'\n'+                                  //output c
g(b,a)                                   //call g with b, a

Casos de teste:

Rick Hitchcock
fonte
1

APL (Dyalog) , 50 bytes

{3↑(0,+\2∨/2|{⍵⌈a×1+11↓⍵}⍣≡a←>⌿2=⌿3↑⍵)⊖⍵⍀⍨¯1*⍳4}

Experimente online!

⍵⍀⍨¯1*⍳4 dá a matriz:

Words.crossing.over
...................
Ducks.quacking.....
...................

(os pontos representam espaços). Suas colunas serão rotacionadas em diferentes quantidades, de modo que as três primeiras linhas acabem parecendo o resultado desejado - daí o 3↑próximo começo. O restante do algoritmo calcula os valores de rotação.

Dentro dos parâmetros: 3↑⍵cria uma matriz como

Words.crossing.over
Ducks.quacking.....
...................

e 2=⌿compara suas linhas em pares, ou seja, primeira string vs segunda string e segunda string vs a linha all-spaces.

0 0 0 0 1 0 0 0 0 0 0 1 1 1 1 0 0 0 0
0 0 0 0 0 1 0 0 0 0 0 0 0 0 1 1 1 1 1

Estamos interessados ​​em saber onde o primeiro é verdadeiro (1) e o último falso (0); portanto, reduzimos >⌿para obter um vetor booleano chamado a.

0 0 0 0 1 0 0 0 0 0 0 1 1 1 0 0 0 0 0

Agora, em cada trecho de 1 s, precisamos zerar as ocorrências pares, porque duas torções não podem ocorrer próximas uma da outra. Primeiro, obtemos uma numeração como:

0 0 0 0 1 0 0 0 0 0 0 1 2 3 0 0 0 0 0

falando vagamente, substituindo a[i]por a[i]*max(a[i-1]+1, a[i])até que o resultado se estabilize:, {⍵⌈a×1+1,¯1↓⍵}⍣≡e tomamos esse mod 2:2|

0 0 0 0 1 0 0 0 0 0 0 1 0 1 0 0 0 0 0

Agora sabemos onde as torções ocorrerão. Copiamos cada um 1para a esquerda - 2∨/ (em pares "ou"):

0 0 0 0 1 1 0 0 0 0 0 1 1 1 1 0 0 0 0

e calcular as somas parciais - +\

0 0 0 0 1 2 2 2 2 2 2 3 4 5 6 6 6 6 6

Isso nos dá a quantidade de rotação de colunas que precisávamos no começo. O módulo 4 está implícito.

ngn
fonte
Agradável! Até 14 bytes mais curtos que Adám . Você pode adicionar uma explicação (eu tenho certeza que você está fazendo isso enquanto falamos, mas no caso de você não está ..;)
Kevin Cruijssen
Explicações única tirar o prazer de descobrir como ele funciona em seu próprio ... :)
NGN
1

Perl 5 , 211 bytes

@a=map[/./g],<>;$b=1;($f,@{$r[$i]})=$a[0][$i]eq$a[1][$i]&&$f&&$a[0][$i]ne$"?(0,$",$a[0][$i],$",$t=$b++):(1,$a[$t%2][$i],$",$a[$b%2][$i]),$i++while$a[0][$i]||$a[1][$i];for$i(0..2){print$r[$_][$i]for 0..$#r;say''}

Experimente online!

# Perl 5 , 234 bytes

corrigido o bug que Kevin apontou

@a=map[/./g],<>;$l=@{$a[0]}>@{$a[1]}?@{$a[0]}:@{$a[1]};$b=1;@{$r[$_]}=$a[0][$_]eq$a[1][$_]&&$_&&$r[$_-1][1]eq$"&&$a[0][$_]ne$"?($",$a[0][$_],$",$t=$b++):($a[$t%2][$_],$",$a[$b%2][$_])for 0..$l;for$i(0..2){print$r[$_][$i]for 0..$l;say}

Experimente online!

Xcali
fonte
Olá, quando tento testar o caso de teste "Can you turn the lights off?" & "Can you try to solve this?", parece que estou recebendo um erro: Modification of non-creatable array value attempted, subscript -1 at .code.tio line 1, <> line 2.isso é um bug ou estou fazendo algo incorreto? Aqui está o TIO.
Kevin Cruijssen
1
Erro. Quando os dois primeiros caracteres eram iguais, um subscrito da matriz era -1, válido apenas se houver dados na matriz. Corrigido com mais 4 bytes.
Xcali
0

05AB1E , 31 bytes

ζεËNĀ¾Èyðå_Pi¼ë¾É½}yð«S¾._¨}øJ»

Resposta da porta do Japt do @ETHproductions , mas com duas pequenas diferenças:
1) Aceito a entrada como uma lista 2D de caracteres em vez de uma lista de strings.
2) O counter_variableem 05AB1E é 0 por padrão, em vez de 11 (ou 3) como o Bem Japt; portanto, é adicionado como verificação adicional dentro do mapa (e eu giro para a direita em vez de para a esquerda).

Experimente online ou verifique todos os casos de teste .

Explicação:

ζ                  # Zip/transpose (swapping rows/columns) the (implicit) input-list
                   # with space filler by default to create pairs
 ε          }      # Map each pair `y` to:
  Ë                #  Check if both values in the pair are equal
  NĀ               #  Check if the map-index is not 0
  ¾È               #  Check if the counter_variable is even
  yðå_             #  Check if the pair contains no spaces " "
  Pi               #  If all checks are truthy:
    ¼              #   Increase the counter_variable by 1:
   ë               #  Else:
    ¾É             #   Check if the counter_variable is odd
      ½            #   And if it is: increase the counter_variable by 1
   }               #  Close the if-else
    yð«            #  Add a space after both characters in the pair
       S           #  Convert it to a list of characters (implicitly flattens)
        ¾._        #  Rotate this list the counter_variable amount of times towards the right
           ¨       #  And then remove the last character
             ø     # Zip/transpose; swapping rows/columns
              J    # Join each inner character-list to a single string
               »   # Join everything by newlines (and output implicitly)
Kevin Cruijssen
fonte