Pleasanortmanteaus

32

Un mot -valise est une combinaison de deux mots qui fait partie de chaque mot et en fait un seul nouveau mot. Par exemple, lion + tigre => liger .

Écrivons un programme pour générer des portemanteaux à partir d'une paire de mots d'entrée. Les ordinateurs ne sont pas les meilleurs en anglais, nous devrons donc établir des règles pour garantir que les ports de sortie sont agréables à l'œil et à l'oreille.

(Des exemples sont présentés ici avec un séparateur entre le préfixe et le suffixe pour plus de clarté:. li|gerCependant, les sorties réelles du programme ne devraient pas avoir de séparateur:. liger)

  • Chaque valise consistera en un préfixe non vide du premier mot concaténé à un suffixe non vide du deuxième mot: oui à li|ger, non à |iger.
  • Si le préfixe se termine par une voyelle, le suffixe doit commencer par une consonne, et vice versa: oui à lio|gerou l|er, non à lio|igerou l|ger. Vous pouvez décider de compter ycomme une voyelle ou une consonne. Votre solution doit cependant choisir une option et la respecter.
  • Le mot résultant ne doit contenir ni l'un ni l'autre des mots d'origine: oui à lio|ger, non à lion|igerou li|tiger.
    • Cette règle s'applique même si la partie en question est formée de parties des deux mots: avec une entrée de two+ words, la sortie tw|ordsest toujours illégale car elle contient la sous-chaîne words. (La seule sortie valide pour cette paire serait t|ords.)

Votre programme ou fonction doit prendre deux mots et afficher / renvoyer une liste de tous les portmanteaus agréables qui peuvent être formés à partir de ces mots dans cet ordre.

Détails

  • Les méthodes d'entrée et de sortie standard s'appliquent. Les failles standard sont interdites.
  • Les mots ne seront composés que de lettres minuscules (ou, si vous préférez, uniquement de lettres majuscules).
  • Vous pouvez prendre les deux mots d'entrée comme une liste, un tuple, deux entrées distinctes, une seule chaîne avec un délimiteur non-lettre, etc.
  • Le format de sortie est tout aussi flexible; si vous retournez ou sortez une chaîne, elle doit être délimitée de telle sorte qu'il soit clair où se termine un mot de valise et où commence le suivant.
  • Il ne devrait pas y avoir de délimiteurs à l'intérieur d'un mot-valise.
  • Ce n'est pas grave si votre liste de sortie inclut des résultats en double; il est également possible de supprimer les doublons.

Cas de test

> 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

Solution de référence

Voici une solution de référence dans Pip (traite ycomme une consonne).


C'est le : la réponse la plus courte dans chaque langue gagne!

DLosc
la source
le délimiteur doit-il être constant ou puis-je mettre un tas d'espaces entre les mots?
Asone Tuhid
@AsoneTuhid Bien sûr, des quantités variables d'espaces blancs seraient un délimiteur acceptable. La seule exigence est qu '"il est clair où un mot de valise se termine et le suivant commence."
DLosc

Réponses:

5

05AB1E , 28 octets

y est une voyelle (même nombre d'octets que la consonne).

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

Essayez-le en ligne! ou comme une suite de tests légèrement modifiée

Emigna
la source
2
Bonne réponse! C'est drôle comme il y a pas mal d'options pour le dernier filtre, mais malheureusement tout de même le nombre d'octets .. ʒs¢Z_; ʒsåO_; ʒsм__; etc.
Kevin Cruijssen
4

Rétine , 72 octets

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

Essayez-le en ligne!

Martin Ender
la source
Bah, j'étais allé aussi loin Lw$`(?<=[aeiou])(.+),(.+)(?<!^\2\1,\2)(?!\1)(?=[^aeiou])|(?<=[^aeiou])(.+),(.+)(?<!^\4\3,\4)(?!\3)(?=[aeiou])mais je ne pouvais pas me concentrer sur le golf à cause d'un mal de tête.
Neil
Ma première tentative a été assez similaire, même si j'ai évité de répéter la partie centrale en vérifiant la chose voyelle / consonne à la fin avec quelque chose comme (?=.(?<=[aeiou]\1[^aeiou]|[^aeiou]\1[aeiou])), puis j'ai probablement dû au moins six itérations pour la ramener là où elle est maintenant.
Martin Ender
(Les ^s dans mon commentaire précédent sont erronés) En effet, je n'aurais jamais pensé à cette ()|.()astuce, je me serais probablement arrêté à Lw$`(?<=([aeiou])|.)((.+),(.+))(?<!\4\2)(?!\3)(?=(?(1)[^aeiou]|[aeiou])).
Neil
3

Pyth , 38 octets

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

L'entrée est une liste des deux mots et y n'est pas traité comme une consonne.

Essayez-le en ligne ici ou vérifiez tous les cas de test en même temps ici .

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)
Sok
la source
3

Java 8, 228 225 215 octets

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

Prend deux chaînes dans la syntaxe de curry et renvoie une chaîne. Traite ycomme une consonne. Essayez-le en ligne ici .

Merci à DLosc pour avoir joué au golf 2 octets.

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
}
OOBalance
la source
3

Japt , 32 octets

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

Interprète Japt

10 octets enregistrés grâce à la compréhension plus claire de Shaggy de la syntaxe de Japt.

8 octets enregistrés grâce à une nouvelle fonctionnalité de langue

Enregistré 2 octets grâce à quelques suggestions de ETHproductions

La dernière version de Japt a introduit la fonction Produit cartésien, qui a économisé pas mal d'octets et m'a permis de restaurer l'ordre des entrées (donc "lion" "tigre" sorties "liger" et autres). "y" est toujours traité comme une consonne.

Explication:

   ï     )       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
Kamil Drakari
la source
Bienvenue à Japt (encore!). Je peux certainement voir un certain potentiel pour plus de golf ici; Je vais l'examiner correctement lorsque je reviendrai à un ordinateur.
Shaggy
1
Quelques économies rapides pour vous grâce à mon téléphone.
Shaggy
3

Python 3 , 156 150 octets

J'ai considéré ycomme une consonne.

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 octets grâce à Jonathan Frech

Essayez-le en ligne!

PieCot
la source
150 octets possibles .
Jonathan Frech
@JonathanFrech merci de l'avoir repéré
PieCot
Vous pouvez utiliser des arguments par défaut lambda x=0pour le faire descendre pour enregistrer ... 0 caractères, de façon ennuyeuse. 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:])}(Toujours 150)
Le Matt
2

JavaScript (ES6), 124 octets

Prend les 2 mots dans la syntaxe de curry (a)(b)et imprime les résultats avec alert(). Suppose que y est une consonne.

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

Essayez-le en ligne!

Arnauld
la source
1

Gelée , 27 octets

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

Essayez-le en ligne!

Yy est une consonne. Les deux cas sont pris en charge. Renvoie les doublons.

La sortie a été améliorée sur TIO. Retirez +/€du pied de page pour voir la sortie réelle.

Erik le golfeur
la source
1

C ++ 11, 217 202 octets

[](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;}

Fait un usage intensif de std::string#find. Traite ycomme une consonne. Essayez-le en ligne ici .

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
}
OOBalance
la source
1

Python 2 , 179 176 166 162 octets

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

Essayez-le en ligne!

3 octets de Jonathan Frech . Et 10 octets de thx à The Matt .

Dans mon monde, ce yn'est pas une voyelle. (C'est un hurlement!)

Chas Brown
la source
Il y a des espaces perdus dans t) ifet t) or [].
Jonathan Frech
@Jonathon Frech: Merci! Vous êtes un peu paresseux là-bas ...
Chas Brown
Je vois ... Je suppose que vous êtes aussi devenu un peu paresseux en tapant mon nom: P
Jonathan Frech
* JonathAn: D'oh! Eh bien, au moins, j'étais cohérent! :)
Chas Brown
1
@The Matt: Merci! En fait, j'ai pressé 2 octets supplémentaires via (s in w)<1>(t in w).
Chas Brown
0

Rubis , 113112109104 octets

y est une consonne

Cela génère les mêmes doublons que les exemples de la question, je dois utiliser la même boucle

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

Essayez-le en ligne!

Asone Tuhid
la source
0

Emacs Lisp , 306 + 13 = 319 octets

+13 pour (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))))))))

Essayez-le en ligne!

Définit une fonction lambda anonyme. Génère une séquence de portmanteaux séparés par des sauts de ligne, chacun étant entouré de guillemets. Les conseils de golf sont les bienvenus. La lettrey est considérée comme une consonne.

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))
            )
          )
        )
      )
    )
  )
)
R. Kap
la source