Pleasanortmanteaus


32

Uma palavra portmanteau é uma combinação de duas palavras que participam de cada palavra e as transformam em uma única palavra nova. Por exemplo, leão + tigre => liger .

Vamos escrever um programa para gerar portmanteaus a partir de um par de palavras de entrada. Os computadores não são os melhores em inglês; portanto, precisamos estabelecer algumas regras para garantir que os portmanteaus de saída sejam agradáveis ​​aos olhos e aos ouvidos.

(Os exemplos aqui são mostrados com um separador entre o prefixo e o sufixo para maior clareza:. li|gerNo entanto, as saídas reais do programa não devem ter um separador:. liger)

  • Cada portmanteau consistirá em um prefixo não vazio da primeira palavra concatenado em um sufixo não vazio da segunda palavra: sim para li|ger, não para |iger.
  • Se o prefixo terminar com uma vogal, o sufixo deverá começar com uma consoante e vice-versa: sim para lio|gerou l|er, não para lio|igerou l|ger. Você pode decidir se conta ycomo vogal ou consoante. Sua solução deve escolher uma opção e permanecer com ela, no entanto.
  • A palavra resultante não deve conter nenhuma das palavras originais na íntegra: sim para lio|ger, não para lion|igerou li|tiger.
    • Essa regra é válida mesmo que a parte em questão seja formada por partes de ambas as palavras: com a entrada de two+ words, a saída tw|ordsainda é ilegal porque contém a substring words. (A única saída válida para esse par seria t|ords.)

Seu programa ou função deve ter duas palavras e gerar / retornar uma lista de todos os portmanteaus agradáveis que podem ser formados a partir dessas palavras nessa ordem.

Detalhes

  • Aplicam-se métodos de entrada e saída padrão . As brechas padrão são proibidas.
  • As palavras consistirão apenas em letras minúsculas (ou, se preferir, apenas em letras maiúsculas).
  • Você pode usar as duas palavras de entrada como uma lista, tupla, duas entradas separadas, uma única sequência de caracteres com um delimitador sem letra, etc.
  • O formato de saída é igualmente flexível; se você retornar ou gerar uma string, ela deverá ser delimitada de forma que fique claro onde uma palavra do portmanteau termina e a seguinte começa.
  • Não deve haver delimitadores dentro de uma palavra portmanteau.
  • Tudo bem se sua lista de saída incluir resultados duplicados; também é bom remover duplicatas.

Casos de teste

> lion, tiger
< liger, ler, liger, lir, lioger, lior

> tiger, lion
< tion, ton, tin, tigion, tigon, tigen

> spoon, fork
< sork, spork, spork, spok, spoork, spook

> smoke, fog
< sog, smog, smog, smokog

> gallop, triumph
< giumph, gumph, gariumph, gamph, gaph, gah, galiumph, galumph, galliumph, gallumph, galloriumph, gallomph, galloh

> breakfast, lunch
< bunch, brunch, brench, brech, breh, breanch, breach, breah, breakunch, breakfunch, breakfanch, breakfach, breakfah, breakfasunch

> two, words
< tords

> harry, ginny (if y is treated as a consonant)
< hinny, hanny, hany, hay, harinny, harrinny

> harry, ginny (if y is treated as a vowel)
> hinny, hy, hanny, hany, harinny, hary, harrinny

Solução de referência

Aqui está uma solução de referência no Pip (trata ycomo uma consoante).


Este é o : a resposta mais curta em cada idioma vence!



o delimitador deve ser constante ou posso colocar um monte de espaços entre as palavras?
Asone Tuhid 11/07/2018

@AsoneTuhid Claro, quantidades variáveis ​​de espaço em branco seriam um delimitador aceitável. O único requisito é que "fique claro onde uma palavra do portmanteau termina e a seguinte começa".
DLosc 12/07/19

Respostas:


5

05AB1E , 28 bytes

y é uma vogal (mesmo número de bytes que consoante).

нη¨sθ.s¨âʒ`нsθ‚žOsåË_}Jʒs¢Z_

Experimente online! ou como um conjunto de testes ligeiramente modificado


2
Boa resposta! Engraçado como existem várias opções para o último filtro, mas infelizmente todas as mesmas contagens de bytes .. ʒs¢Z_; ʒsåO_; ʒsм__; etc.
Kevin Cruijssen

4

Retina , 72 bytes

L$w`(?<=[aeiou]()|.())((.+),(.+))\B(?!\4)(?<!\5\3)(?([aeiou])\2|\1)
$`$'

Experimente online!


Bah, eu tinha chegado tão longe, Lw$`(?<=[aeiou])(.+),(.+)(?<!^\2\1,\2)(?!\1)(?=[^aeiou])|(?<=[^aeiou])(.+),(.+)(?<!^\4\3,\4)(?!\3)(?=[aeiou])mas não conseguia me concentrar em jogar golfe por causa de uma dor de cabeça.
214 Neil

Minha primeira tentativa foi bem parecida, embora eu tenha evitado repetir a parte central verificando a vogal / consoante no final com algo parecido (?=.(?<=[aeiou]\1[^aeiou]|[^aeiou]\1[aeiou]))e precisando, provavelmente, de pelo menos seis iterações para chegar até onde está agora.
Martin Ender

(Os ^s no meu comentário anterior são errôneos) Na verdade, eu nunca teria pensado nesse ()|.()truque, provavelmente teria parado Lw$`(?<=([aeiou])|.)((.+),(.+))(?<!\4\2)(?!\3)(?=(?(1)[^aeiou]|[aeiou])).
214 Neil

3

Pitão , 38 bytes

f!s}RTQm+hd_edfxFm}ed"aeiou"T*._hQ.__e

Entrada é uma lista das duas palavras, e y não é tratado como uma consoante.

Experimente on-line aqui ou verifique todos os casos de teste de uma vez aqui .

f!s}RTQm+hd_edfxFm}ed"aeiou"T*._hQ.__e   Implicit: Q=eval(input())
                                hQ       First input word
                              ._         All prefixes of the above
                                     e   Second input word (Q inferred)
                                  .__    Reverse, take all prefixes
                             *           Cartesian product of the above
              f                          Filter the above using:
                 m          T              Map d in the current element using:
                   ed                        The last letter of the word part
                  }  "aeiou"                 Is it contained in the vowel list?
               xF                          Take the XOR of the list
                                         (This ensures that the word parts meet at one consonant)
       m                                 Map d in the filtered set using:
        +hd_ed                             Add the first part to the reversed second part
f                                        Filter the above using:
  s}RTQ                                    Does the portmanteau contain either of the input words?
 !                                         Logical NOT (remove from list if the above is true)

3

Java 8, 228 225 215 bytes

v->w->{String r="",t,p=" aeiou";for(int i=w.length(),j;--i>0;)for(j=1;j<v.length();)r+=(t=v.substring(0,j)+w.substring(i)).matches(v+".*|.*"+w)|p.indexOf(t.charAt(j-1))*p.indexOf(t.charAt(j++))>0?"":t+" ";return r;}

Pega duas Strings na sintaxe de curry e retorna uma String. Trata ycomo uma consoante. Experimente online aqui .

Graças ao DLosc por jogar 2 bytes.

Ungolfed:

v -> w -> { // lambda taking two String parameters in currying syntax
    String r = "", // result
    t, // temporary variable used for storing
       // the portmanteau candidate currently being evaluated
    p = " aeiou"; // vowels for the purposes of this function;
                  // the leading space is so that they all have a positive index
    for(int i = w.length(), j; --i > 0; ) // loop over all proper suffixes
                                          // of the second word
        for(j = 1; j < v.length(); )      // loop over all proper prefixes
                                          // of the first word
            r += // construct the portmanteau candidate
                 (t = v.substring(0, j) + w.substring(i))
                 // if it contains one of the input words ...
                 .matches(v + ".*|.*" + w)
                 // ... or the boundary is consonant-consonant 
                 // or vowel-vowel (here we make use of the facts
                 // that all the vowels have a positive index, and
                 // indexOf() returns -1 in case of no match) ...
                 | p.indexOf(t.charAt(j-1)) * p.indexOf(t.charAt(j++)) > 0
                 ? "" // ... reject it ...
                 : t + " "; // ... else add it to the result
    return r; // return the result
}

3

Japonês , 32 bytes

å+ ïVw å+)f_xè"%v$" uÃmrÈ+YwÃkøN

Intérprete Japt

Economizou 10 bytes graças ao entendimento mais claro de Shaggy da sintaxe de Japt.

8 bytes salvos devido a um novo recurso de idioma

Economizou 2 bytes graças a algumas sugestões da ETHproductions

A versão mais recente do Japt introduziu a função Produto Cartesiano, que salvou alguns bytes e me permitiu restaurar a ordem das entradas (então "leão" "tigre" gera "liger" e outras). "y" ainda é tratado como uma consoante.

Explicação:

   ï     )       Cartesian product of...
å+                prefixes of first input
    Vw å+         and suffixes of second input.

f_         Ã     Remove the ones where...
  xè"%v$"         the number of vowels at the joining point
          u       is not 1.

m     Ã          Replace each pair with...
 rÈ+Yw            the prefix and suffix joined together
       køN       then remove the ones that contain either input

Bem-vindo ao Japt (de novo!). Definitivamente, vejo algum potencial para mais golfe aqui; Vou dar uma olhada adequada quando voltar ao computador.
Shaggy


3

Python 3 , 156 150 bytes

Eu considerei ycomo uma consoante.

lambda a,b:{a[:i]+b[j:]for i in range(1,len(a))for j in range(1,len(b))if((a[i-1]in'aeiou')^(b[j]in'aeiou'))*0**(a in a[:i]+b[j:]or b in a[:i]+b[j:])}

-6 bytes graças a Jonathan Frech

Experimente online!


Possíveis 150 bytes .
Jonathan Frech

@JonathanFrech agradecimentos para manchar-lo
PieCot

Você pode usar argumentos padrão lambda x=0para reduzi-lo e salvar ... 0 caracteres, irritantemente. lambda a,b,v='aeiou',r=range:{a[:i]+b[j:]for i in r(1,len(a))for j in r(1,len(b))if((a[i-1]in v)^(b[j]in v))*0**(a in a[:i]+b[j:]or b in a[:i]+b[j:])}(Ainda 150)
The Matt

2

JavaScript (ES6), 124 bytes

Pega as 2 palavras na sintaxe de curry (a)(b)e imprime os resultados com alert(). Supõe que y é uma consoante.

a=>b=>[...a].map(c=>[...b].map((C,j)=>!(w=s+b.slice(j)).match(a+'|'+b)&v.test(c)-v.test(C)&&alert(w),s+=c),s='',v=/[aeiou]/)

Experimente online!


1

Gelatina , 27 bytes

¹Ƥp¹ÐƤ}Ø.ị"e€Øc⁻/ƲƇẎ€wÐḟƒ@,

Experimente online!

Yy é uma consoante. Ambos os casos são suportados. Retorna duplicados.

A saída foi pré-modificada pelo TIO. Remova +/€do rodapé para ver a saída real.


1

C ++ 11, 217 202 bytes

[](auto v,auto w){auto r=v,t=v,p=v;r="",p="aeiou";for(int i=w.size(),j;--i;)for(j=v.size();j;)(t=v.substr(0,j)+w.substr(i)).find(v)+1|t.find(w)+1|p.find(t[j-1])<5==p.find(t[j--])<5?v:r+=t+" ";return r;}

Faz uso pesado de std::string#find. Trata ycomo uma consoante. Experimente online aqui .

Ungolfed:

// lambda; relies on auto to keep declarations short
[] (auto v, auto w) {
    // let's declare some strings. To keep it terse, we're using auto and the type of the arguments.
    auto r = v, // result string
    t = v,      // temporary string for storing the portmanteau candidate
    p = v;      // vowels string
    // now assign them their values
    r = "",    // result starts empty
    p = "aeiou"; // vowels don't include 'y'
    for(int i = w.size(), j; --i; ) // suffixes of the second word
        for(j = v.size(); j; ) // prefixes of the first word
            // create the portmanteau candidate
            (t = v.substr(0, j) + w.substr(i))
            // if it includes one of the input words ...
            .find(v) + 1 | t.find(w) + 1
            // ... or the boundary is consonant-consonant or vowel-vowel ...
            | p.find(t[j - 1]) < 5 == p.find(t[j--]) < 5
            ? v // ... discard it ...
            : r += t + " "; // ... else add it to the result.
    return r; // return the result
}

1

Python 2 , 179 176 166 162 bytes

lambda s,t:[w for w in g(s,t)if(s in w)<1>(t in w)]
g=lambda s,t:s[:-1]and[s[:-1]+t[j:]for j in range(1,len(t))if(s[-2]in'aeiou')^(t[j]in'aeiou')]+g(s[:-1],t)or[]

Experimente online!

3 bytes de Jonathan Frech . E 10 bytes thx para o Matt .

No meu mundo, ynão é uma vogal. (É uma uiva!)


Existem espaços dispersos em t) ife t) or [].
Jonathan Frech

@ Jonathon Frech: Obrigado! Tem um pouco preguiçoso lá ...
Chas Brown

Eu vejo ... Eu presumo que você também tem um pouco preguiçoso, enquanto escrevendo meu nome: P
Jonathan Frech

JonathAn: Oh! Bem, pelo menos eu fui consistente! :)
Chas Brown 07/07

11
@ The Matt: Obrigado! Na verdade, eu apertei mais 2 bytes via (s in w)<1>(t in w).
Chas Brown

0

Ruby , 113 112 109 104 bytes

y é uma consoante

Isso gera as mesmas duplicatas que os exemplos na pergunta, devo estar usando o mesmo loop

->a,b,i=j=1{r=a[0,i]+b[j..-1];g=:aeiou;!g[a[i-1]]^g[b[j]]|r[a]|r[b]||z=[*z,r];b[j+=1]||a[i+=j=1]?redo:z}

Experimente online!


0

Emacs Lisp , 306 + 13 = 319 bytes

+13 para (require'seq)

(require'seq)(lambda(a b)(dotimes(i(1-(length b)))(dotimes(j(1-(length a)))(progn(setq w(substring a 0(1+ j))x(substring b(1+ i))c(concat w x))(defun V(c)(seq-contains"aeiou"(elt c 0)'char-equal))(if(not(or(string-prefix-p a c)(string-suffix-p b c)))(if(V(substring w -1))(if(not(V x))(print c))(if(V x)(print c))))))))

Experimente Online!

Define uma função lambda anônima. Gera uma sequência de portmanteaus separados por nova linha com cada um entre aspas. Dicas de golfe são bem-vindas. A carta yé considerada uma consoante.

Ungolfed

(require 'seq)                                                                                                                                                           
(defun Portmanteus(word1 word2)
  "Find all valid portmanteus of the two given words"
  (dotimes (i (1- (length word2)))
    (dotimes (j (1- (length word1)))
      (progn
        (setq w (substring word1 0 (1+ j)) w2 (substring word2 (1+ i)) comb (concat w w2))
        (defun isVowel (c) (seq-contains "aeiou" (elt c 0) 'char-equal))
        (if (not (or (string-prefix-p word1 comb) (string-suffix-p word2 comb)))
          (if (isVowel (substring w -1))
            (if (not (isVowel w2))
              (princ (format "%s\n" comb))
            )
            (if (isVowel w2)
              (princ (format "%s\n" comb))
            )
          )
        )
      )
    )
  )
)
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.