Assemble automatiquement de manière anti-prévisible un air allitératif

15

Merci à @ComradeSparklePony pour le titre.

Ce défi devrait être très simple. On vous donne trois listes.

Le premier est une liste de prénoms, en majuscule.

Le second est une liste d'adjectifs, en minuscules.

Le troisième est une liste de noms, en minuscules.

Veuillez sélectionner au hasard un nom, un adjectif facultatif, un nom et une sortie <Name>'s <adjective> <noun>. Cependant, chaque mot doit commencer par la même lettre. Vous pouvez supposer que tous les mots commencent par une lettre. Vous pouvez également supposer (mais notez dans votre réponse si vous le faites):

  • que tous les mots sont composés uniquement de caractères alphabétiques
  • qu'il y a au moins un nom pour chaque nom
  • qu'il y a au moins un nom pour chaque nom

Vous ne pouvez cependant pas supposer qu'un adjectif existe pour une paire particulière de nom et de nom, car l'adjectif est facultatif et la sortie sera toujours valide.

Vous n'avez pas à sélectionner la lettre partagée de manière uniforme, bien que toutes les lettres disponibles doivent avoir une chance non nulle de se produire. Vous devez cependant vous assurer que toutes les sorties pour une lettre donnée ont autant de chances que possible de se produire dans les limites du générateur de nombres aléatoires de votre langue. Dans le cas de l'adjectif, cela équivaut à avoir une entrée supplémentaire signifiant "pas d'adjectif pour cette lettre" qui a la même chance que tous les autres adjectifs pour cette lettre.

Exemples de listes d'entrées:

Joan Neil Nicola Oswald Sherman Stephanie
new novel old original second silent
jeep noun novel output second sheep snake

Exemples de sorties pour ces entrées (chaque ligne est un exemple distinct):

Stephanie's second second
Sherman's silent snake
Oswald's original output
Nicola's novel novel
Neil's noun
Joan's jeep

Notez pas d'espace supplémentaire entre les mots dans les deux derniers exemples.

C'est le , donc le code le plus court qui ne casse aucune échappatoire standard gagne!

Dans le cas peu probable où cela aiderait, vous pouvez tout saisir en majuscules, mais vous devez toujours sortir en cas de phrase.

Neil
la source
Sommes-nous en droit de supposer que le programme devrait retourner: 1 nom 1 adjectif (si on correspond au nom) 1 nom? Ou demandez-vous de produire une sortie pour chaque nom?
DavidC
1
Peut-être devriez-vous ajouter «Joan» et «jeep» dans votre exemple pour illustrer le fait qu'il pourrait ne pas y avoir d'adjectif pour une lettre donnée?
Arnauld
Compte tenu de votre exemple d'entrée est la chance de ne pas avoir d'adjectif 1 sur 3 (puisque toutes les "listes" d'adjectifs sont longues de 2)? ... et si 'Joan' et 'Jeep' étaient également là sans jobjectif, la chance deviendrait-elle 4 sur 9? Cela pourrait valoir la peine de placer des probabilités par rapport aux sorties, ou d'énumérer toutes les sorties - si je comprends bien, non seulement "toutes les sorties pour une lettre donnée ...", mais aussi toutes les sorties distinctes devraient avoir la même probabilité (étant donné des valeurs distinctes dans chaque liste).
Jonathan Allan
@DavidC Désolé, je me rends compte que l'ajout d'exemples supplémentaires a rendu cela peu clair; vous ne produisez qu'une seule ligne de sortie pour chaque appel.
Neil
1
@JonathanAllan L'ajout de "Joan" et de "jeep" n'affecterait pas les chances relatives de sortie du "nom de Neil" par rapport aux autres options contenant "Neil" et "nom".
Neil

Réponses:

5

Gelée ,  27 25  24 octets

-1 grâce à Erik l'Outgolfer (utilisez un zéro au lieu d'un caractère espace)

Ż€2¦Œpḟ€0ZḢŒuEƲƇXż“'s“”K

Un programme complet acceptant un argument sous la forme d'une liste au format Python de listes de chaînes qui imprime la sortie sur STDOUTt.

Essayez-le en ligne!

Comment?

Ż€2¦Œpḟ€0ZḢŒuEƲƇXż“'s“”K - Main Link: list of lists of lists of characters
 € ¦                     - sparse application...
  2                      - ...to indices: [2]
Ż                        - ...action: prepend a zero (place holder for no adjective)
    Œp                   - Cartesian product (all choices, including invalid ones)
       €                 - for each:
      ḟ 0                -   filter out any zeros
               Ƈ         - filter keep those for which:
              Ʋ          -   last four links as a monad:
         Z               -     transpose
          Ḣ              -     head
           Œu            -     upper-case
             E           -     all equal?
                X        - random (uniform) choice  e.g. [['B','o','b'],['b','l','u','e'],['b','a','g']]
                 ż       - zip with:
                  “'s“”  -   list [["'", 's'], []]       [[['B','o','b'],["'", 's']],[['b','l','u','e'],[]],['b','a','g']]
                       K - join with spaces              [['B','o','b'],["'", 's'],' ',['b','l','u','e'],[],' ','b','a','g']
                         - implicit (smashing) print     Bob's blue bag
Jonathan Allan
la source
24 octets .
Erik the Outgolfer
Ah ouais, sympa :)
Jonathan Allan
5

05AB1E ,  24 23  21 octets

Suppose qu'il y a un nom pour chaque nom, comme le permet le défi.

„'s«I¯ªâI‘ʒl€нË}Ωðý

Essayez-le en ligne!

Explication

„'s«                    # append "'s" to all names in the name-list
    I¯ª                 # append an empty list to the adjective-list
       â                # cartesian product between the lists
        Iâ              # cartesian product with the noun-list
          €˜            # deep flatten each sublist
            ʒ    }      # filter, keep only lists that when
             l          # converted to lowercase
              €н        # with only heads kept
                Ë       # have all elements equal
                  Ω     # pick a valid list uniformly at random
                   ðý   # and join by spaces
Emigna
la source
Oh, les ¯ªet €˜sont intelligents! J'ai eu une réponse de 26 octets, mais j'ai eu du mal à corriger le double espace quand il n'y a pas d'adjectif ..
Kevin Cruijssen
@KevinCruijssen: Oui, c'est aussi la partie avec laquelle j'ai eu le plus de problèmes. Il m'a fallu un certain temps pour réaliser que je pouvais utiliser ¯au lieu de remplir avec des chaînes vides que j'ai dû nettoyer manuellement plus tard.
Emigna
4

R , 155 148 bytes

-7 octets grâce à Giuseppe (en utilisant *pour sample)

function(x,y,z){`*`=sample
while(T)T=length(unique(c(tolower(substr(c(a<-x*1,b<-c(y,"")*1,c<-z*1),1,1)),"")))-2
paste0(a,"'s ",b,if(nchar(b))" ",c)}

Essayez-le en ligne!

Utilise l'échantillonnage de rejet: dessinez au hasard un nom, un adjectif (éventuellement la chaîne vide) et un nom jusqu'à ce que les premières lettres correspondent. Cette condition est vérifiée en comptant si le nombre d'éléments uniques dans le vecteur formé des premières lettres, plus la chaîne vide, est de longueur 2 - cela permet d'avoir un adjectif vide.

Imprimez ensuite le résultat, avec un espace supplémentaire si l'adjectif n'est pas vide.

Les différentes possibilités commençant par la même lettre ont des probabilités d'occurrence égales, puisque sample proviennent de la distribution uniforme. La façon la plus simple de voir cela est de conditionner que le nom et le nom commencent par la même lettre (ce qui est bien: s'ils ne le font pas, nous rejetterions). Conditionnons maintenant l'événement que nous acceptons: cela signifie que nous dessinons soit l'adjectif vide, soit un adjectif commençant par la même lettre. Chacune de ces possibilités a toujours une probabilité égale.

dix5

Robin Ryder
la source
Est-ce que cela a une chance égale d'un adjectif vide à l'autre possibilité pour une première lettre donnée?
Nick Kennedy
@NickKennedy Oui, car samples'inspire de la distribution uniforme. La façon la plus simple de voir cela est de conditionner que le nom et le nom commencent par la même lettre (ce qui est bien: s'ils ne le font pas, nous rejetterions). Conditionnons maintenant l'événement que nous acceptons: cela signifie que nous dessinons soit l'adjectif vide, soit un adjectif commençant par la même lettre. Chacune de ces possibilités a toujours une probabilité égale.
Robin Ryder
merci, bien expliqué.
Nick Kennedy
@NickKennedy Merci, je vais ajouter cette explication au message avec un lien pour vérifier empiriquement que les probabilités sont égales.
Robin Ryder
1
148 octets
Giuseppe
3

JavaScript (ES6),  139 124 122  120 octets

Économisez 2 octets grâce à @Neil

Prend l'entrée comme (names,adjectives)(nouns).

(N,a)=>F=n=>/^(.)\S+( \1\S+)+$/i.test(s=(g=a=>a[Math.random()*a.length|0])(N)+"'s "+[(o=g([,...a]))&&o+' ']+g(n))?s:F(n)

Essayez-le en ligne!

Ou consultez la répartition sur 5 millions de tirages

Comment?

g

g = a => a[Math.random() * a.length | 0]

gs

s = g(N) + "'s " +
    [(o = g([, ...a])) && o + ' '] +
    g(n)

Nous vérifions ensuite si toutes les lettres initiales sont identiques avec l'expression régulière suivante:

/^(.)\S+( \1\S+)+$/i

s

Arnauld
la source
+[(o=g([,...a]))&&o+' ']+économise 2 octets, je pense?
Neil
@Neil Ah, oui. Joli.
Arnauld
3

Python 3 , 161 154 154 151 147 145 octets

( Merci ArBo, EmbodimentOfIgnorance, Neil qui ont contribué 2, 3 et 4 octets à mon premier golf! )

from random import*
c=choice
def f(N,a,n):
 s=c(N);w=s[0].lower();o=N
 while o[0]!=w:o=c(n)
 print(s+"'s",c([x+" "for x in a if x[0]==w]+[""])+o)

Essayez-le en ligne! (avec 500 000 exécutions)

  • Prend trois listes en entrée.

  • Suppose au moins un nom pour chaque nom.


Même score, plus de golf-y:

Python 3 , 145 octets

from random import*
c=choice
def f(N,a,n):
 s=c(N);y=lambda p,e=[]:c([x+" "for x in p if x[0]==s[0].lower()]+e);print(s+"'s",y(a,[""])+y(n)[:-1])

Essayez-le en ligne! (avec 500 000 exécutions)

Il n'est que de 140 si les espaces blancs arrière sont autorisés (en supprimant la face carrée [:-1])

Nicola Sap
la source
1
Belle première réponse! Vous pouvez enregistrer un octet dans la première boucle while: while t>""<t[0]!=w. Vous pouvez également remplacer la dernière ligne par print(s+"'s",t+(t and" ")+o), en supprimant u=la troisième ligne.
ArBo
J'ai fini par changer ma solution parce que la précédente ne répondait pas aux exigences
Nicola Sap
1
152 octets (pied de page supprimé pour tenir l'URL dans le commentaire)
Incarnation de l'ignorance
1
Vous n'utilisez la variable tqu'une seule fois, vous pouvez donc économiser 4 octets en insérant le code. Je pense que vous pouvez basculer opour utiliser un modèle de code similaire t, puis enregistrer 4 autres octets en insérant cela également.
Neil
Merci, vous nous aidez vraiment! @Neil, je n'ai pas pu refactoriser o: j'atteins ceci: from random import* c=choice def f(N,a,n): s=c(N);y=lambda p,e=[]:c([x for x in p if x[0]==s[0].lower()]+e);print(s+"'s",y(a,[""])+y(n))( 137 ) mais l'ajout de l'espace conditionnel, via un argument optionnel à y, me coûte 11 octets
Nicola Sap
0

Gelée , 28 octets

1ịZḢXɓŒuḢ=ɗƇ€Ż€2¦X€ḟ0ż“'s“”K

Essayez-le en ligne!

J'ai écrit cela avant de voir la réponse courte de @ JonathanAllan, mais j'ai pensé qu'il valait la peine d'être publié car il utilise une approche différente. Enregistré 3 octets par la suggestion de @ EriktheOutgolfer sur cette réponse.

Un programme complet prenant une liste de listes de chaînes et imprimant implicitement une allitération sélectionnée au hasard. Suppose au moins un nom par nom.

Nick Kennedy
la source
0

C # (Visual C # Interactive Compiler) , 176 octets

(a,b,c)=>(a=a[z.Next(a.Count)])+"'s "+b.Where(x=>(x[0]&95)==a[0]).Append("").OrderBy(x=>z.Next()).Last()+" "+c.OrderBy(x=>z.Next()).Last(x=>(x[0]&95)==a[0]);var z=new Random();

Essayez-le en ligne!

Incarnation de l'ignorance
la source
Vous pouvez supposer que les noms commencent par une lettre majuscule, vous pouvez donc simplement mettre les autres lettres en majuscule pour la comparaison, ce qui devrait vous faire économiser 10 octets?
Neil
@Neil Yep, exactement 10 octets :)
Incarnation de l'ignorance
0

rouge , 179 octets

func[a b c][random a random c
foreach k c[if k/1 = h: a/1/1 + 32[g: rejoin[sp k]]]collect/into[foreach
d b[if d/1 = h[keep rejoin[sp d]]]]e: copy[""]random e rejoin[a/1"'s"e/1 g]]

Essayez-le en ligne!

Explication:

Red[]
f: func[a b c][                     ; a function with 3 arguments
    random a                        ; shuffle the list of names in place
    random c                        ; shuffle the list of nouns in place
    foreach k c [                   ; for each item in the shuffled list of nouns
        if k/1 = h: a/1/1 + 32 [    ; check if it begins with the same lowercase letter
                                    ; as the first name in the shuffled list of names
            g: rejoin [" " k]       ; if yes, then insert a " " in front of it save it as g
        ]                           ; thus I always get the last match
    ]
    collect/into [                  ; collect in a new list e
        foreach d b [               ; all items form the adjectives list
            if d/1 = h [            ; that start with the same lowercase letter as the 1st noun
                keep rejoin [" " d] ; insert a " " in form of the adjective
            ]
        ]
    ] e: copy[""]                   ; the list initially has a single item - the empty string
   random e                         ; shuffle the extracted adjectives list
   rejoin [a/1 "'s" e/1 g]          ; return the formatted string
]
Galen Ivanov
la source
0

Scala , 234 226 234 206 octets

-28 en raison du fait que je pensais qu'il devait accepter StdIn, c'est une fonction maintenant

def f(a:List[String],b:List[String],c:List[String])=scala.util.Random.shuffle(for(d<-a;e<-("" +: b);g<-c;if(d.head.toLower==g.head&&(e.isEmpty||e.head==g.head))) yield s"$d's $e $g".replace("  ", " ")).head

Essayez-le en ligne!

Non golfé:

def f(names: List[String], adjectives: List[String], nouns: List[String]) = {
  val allPossible = for {
    name <- names
    adjective <- ("" +: adjectives) // Add the choice of no adjective
    noun <- nouns
    if (name.head.toLower == noun.head && (adjective.isEmpty || adjective.head == noun.head)) // Filter out so only matching entries remain
  } yield
    s"$name's $adjective $noun"
      .replace("  ", " ") // Get rid of artifact created by the empty adjective selection

  scala.util.Random.shuffle(allPossible.toList).head // Get a random element
}
Soren
la source
0

Rubis , 94 octets

->a,b,c{"#{n=a.sample}'s #{s=[p,*b.grep(r=/^#{n[0]}/i)].sample;s+" "if s}#{c.grep(r).sample}"}

Essayez-le en ligne!

Encre de valeur
la source
0

Icône , 167 163 octets

procedure f(a,b,c)
!a:=:?a&\x;!c:=:?c&\x;d:=[""]
e:=!b&e[1]==(t:=char(32+ord(a[1,1])))&put(d," "||e)&\x
!d:=:?d&\x;return(!a||"'s"||!d||" "||(k:=!c&t==k[1]&k))
end

Essayez-le en ligne!

Utilise le même algorithme que ma Redréponse.

Galen Ivanov
la source