Conjugação na vida real

14

No Dyalog APL Extended de @ Adám , o operador (sub) significa conjugação: aplique uma função, depois uma segunda função e o inverso da primeira. É divertido pensar em ações da vida real em termos de conjugação:

Um problema é transformado por g em outro domínio, onde é mais facilmente resolvido por f e, em seguida, transformado novamente no domínio original. Um exemplo da vida real é "sob anestesia":

apply anesthetics
    perform surgery
wake up from anesthetics

Desafio

O inverso de uma linha gé "un" anexado ge vice-versa. Defina qualquer linha entre se sua inversa, nessa ordem, como "abaixo" s. Para cada linha fna entrada, em ordem:

  • Se fe seu inverso ocorrerem, não faça nada
  • Se fnão estiver "sob" nenhuma outra ação, imprimaf
  • Se festiver "abaixo" de uma linha g, imprima f + " under " + gonde +está a concatenação.

Entrada

Uma sequência multilinha não vazia, ou lista de sequências, etc., consistindo em espaços e letras minúsculas (você pode usar maiúsculas). Exatamente uma linha começará com "un"; e será o inverso de alguma outra linha. Nenhuma linha estará vazia.

Resultado

Saída no mesmo formato em que você inseriu ou conforme permitido pela E / S padrão.

Casos de teste:

Input:
apply anesthetics
perform surgery
unapply anesthetics

Output:
perform surgery under apply anesthetics


Input:
unite asia
establish the silk road
ite asia

Output:
establish the silk road under unite asia


Input:
desire a book
walk to store
take the book
pay for the book
unwalk to store
read the book

Output:
desire a book
take the book under walk to store
pay for the book under walk to store
read the book


Input:
drink excessively
undrink excessively

Output:
[empty string]
lirtosiast
fonte
1
Eu também não tenho nenhuma saída quando eu beber excessivamente
Stan Strum
1
não deveria ser "pegue o livro e pague pelo livro a pé para guardar"? caso contrário, não é claro que a transformação é equivalente ao original ...
Jonah
1
@ Jonah A idéia está em um mundo ideal w = "caminhar para armazenar" e w ^ -1 = "caminhar para armazenar" são inversos, então matematicamente wfw ^ -1wg ^ -1 = wfgw ^ -1.
lirtosiast
Ah, é justo, @lirtosiast.
Jonah

Respostas:

3

Braquilog , 90 bytes

;Ṡ{hhH↰₂gB&hb~c[A,B,C]&tT;C↔↰U∧" under ",H,T;A↔↰,U|tT&hh,TgJ&hb;T↰Q∧J,Q|h}
~↰₃|↰₃
∧"un";?c

Fiz isso com a impressão de que isso poderia ser recursivo e várias partes inferiores poderiam ser empilhadas. Provavelmente não otimizado. Além disso, como esse é o bracylog, o encanamento leva alguns bytes.

Experimente online!

Kroppeb
fonte
2

Retina , 82 bytes

m{A`^(un)?(.+)¶(?(1)|un)\2$
^((un)?(.+)¶)(.+)¶((.+¶)*(?(2)|un)\3)$
$4 under $1$1$5

Experimente online! O link inclui casos de teste. Explicação:

m{

Executar todo o programa em modo de várias linhas (de modo que ^e $coincide com o início eo fim de linhas individuais) e repita até que não haja mudanças.

A`^(un)?(.+)¶(?(1)|un)\2$

Procure por linhas que possam começar une sejam seguidas por uma linha que comece unsomente se a linha anterior não continuar enquanto o restante da linha for a mesma e exclua as duas linhas. (Essa é uma alteração de comportamento da Retina 0.8.2, que divide as linhas antes de tentar corresponder e, portanto, nunca pode excluir linhas se a correspondência precisar abranger mais de uma linha ao mesmo tempo.)

^((un)?(.+)¶)(.+)¶((.+¶)*(?(2)|un)\3)$

Procure por linhas que possam começar un, seguidas por pelo menos uma linha, seguida por uma linha que comece unsomente se a linha original não aparecer enquanto o restante da linha for o mesmo.

$4 under $1$1$5

Mova a linha original para baixo uma linha e também a adicione underà linha que acabou de atravessar. (Linhas adicionais serão tratadas pela repetição.)

Neil
fonte
2

Python 2 , 106 bytes

s=input()
x=''
l=[]
for i in s:
 if'un'==i[:2]or'un'+i in s:x=(' under '+i)*(not x)
 else:l+=[i+x]
print l

Experimente online!

Se a entrada puder ser uma lista de STDIN e a saída for separada por nova linha, teremos esta solução de 94 bytes:

s=input()
x=''
for i in s:
 if'un'==i[:2]or'un'+i in s:x=(' under '+i)*(not x)
 else:print i+x
Erik, o Outgolfer
fonte
1

JavaScript (Nó Babel) , 91 bytes

Recebe a entrada como uma matriz de seqüências de caracteres em minúsculas. Retorna outra matriz de strings.

a=>a.flatMap(s=>s==r|'un'+s==r?(u=u?'':' under '+s,[]):s+u,u='',r=a.find(s=>/^un/.test(s)))

Experimente online!

Comentado

a =>                     // a[] = input array
  a.flatMap(s =>         // for each string s in a[]:
    s == r |             //   if s matches the reference string
    'un' + s == r ? (    //   or its opposite:
      u =                //     update u:
        u ?              //       if u is not an empty string:
          ''             //         turn it to an empty string
        :                //       else:
          ' under ' + s, //         set it to s with the ' under ' prefix
      []                 //     yield an empty array so that this entry is removed
    ) :                  //   else:
      s + u,             //     yield s followed by u
    u = '',              //   initialize u to an empty string
    r = a.find(s =>      //   initialize r ...
      /^un/.test(s)      //     ... to the string beginning with 'un'
    )                    //
  )                      // end of flatMap()
Arnauld
fonte
Falhou?
L4m2
@ l4m2 Falha mesmo. Agora consertado.
Arnauld
1

Limpo , 147 bytes

import StdEnv,Data.List
a=inits;b=tails
$l=hd[w++[e++[' under ':u]\\e<-z]++y\\i<-a l&t<-b l,w<-a i&u<-i,z<-a t&[x:y]<-b t|u==['un':x]||x==['un':u]]

Experimente online!

Furioso
fonte