Stellen Sie automatisch eine alliterative Arie zusammen, die nicht vorhersehbar ist

15

Vielen Dank an @ComradeSparklePony für den Titel.

Diese Herausforderung sollte sehr einfach sein. Sie erhalten drei Listen.

Das erste ist eine Liste der Vornamen, in Titelbuchstaben.

Die zweite ist eine Liste von Adjektiven in Kleinbuchstaben.

Das dritte ist eine Liste von Substantiven in Kleinbuchstaben.

Bitte wählen Sie nach dem Zufallsprinzip einen Namen, ein optionales Adjektiv und ein Substantiv aus und geben Sie es aus <Name>'s <adjective> <noun>. Jedes Wort muss jedoch mit demselben Buchstaben beginnen. Sie können davon ausgehen, dass alle Wörter mit einem Buchstaben beginnen. Sie können auch annehmen (aber notieren Sie in Ihrer Antwort, wenn Sie dies tun):

  • dass alle Wörter nur aus Buchstaben bestehen
  • dass es für jeden Namen mindestens ein Nomen gibt
  • dass es für jedes Nomen mindestens einen Namen gibt

Sie können jedoch nicht davon ausgehen, dass ein Adjektiv für ein bestimmtes Paar aus Name und Nomen vorhanden ist, da das Adjektiv optional ist und die Ausgabe weiterhin gültig ist.

Sie müssen den freigegebenen Buchstaben nicht einheitlich auswählen, obwohl alle verfügbaren Buchstaben eine Wahrscheinlichkeit ungleich Null haben müssen. Sie müssen jedoch sicherstellen, dass alle Ausgaben für einen bestimmten Buchstaben innerhalb der Grenzen des Zufallszahlengenerators Ihrer Sprache mit möglichst gleicher Wahrscheinlichkeit erfolgen. Im Fall des Adjektivs entspricht dies einem zusätzlichen Eintrag, der "kein Adjektiv für diesen Buchstaben" bedeutet und die gleiche Chance hat wie alle anderen Adjektive für diesen Buchstaben.

Beispiel-Eingabelisten:

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

Beispielausgaben für diese Eingaben (jede Zeile ist ein separates Beispiel):

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

Beachten Sie in den letzten beiden Beispielen kein zusätzliches Leerzeichen zwischen den Wörtern.

Das ist , also gewinnt der kürzeste Code, der keine Standardlücken durchbricht!

In dem unwahrscheinlichen Fall, dass es hilft, können Sie alles in Großbuchstaben eingeben, aber Sie müssen immer noch in Satzbuchstaben ausgeben.

Neil
quelle
Gehen wir zu Recht davon aus, dass das Programm Folgendes zurückgeben soll: 1 Name 1 Adjektiv (wenn eines mit dem Namen übereinstimmt) 1 Substantiv? Oder möchten Sie für jeden Namen eine Ausgabe erstellen?
DavidC
1
Vielleicht sollten Sie in Ihrem Beispiel 'Joan' und 'Jeep' hinzufügen, um die Tatsache zu veranschaulichen, dass es für einen bestimmten Buchstaben möglicherweise überhaupt kein Adjektiv gibt?
Arnauld
In Anbetracht Ihrer Beispieleingabe ist die Chance, dass 1 zu 3 kein Adjektiv enthält (da alle Adjektiv- "Listen" 2 lang sind)? ... und wenn 'Joan' und 'Jeep' auch ohne jAdjektiv da wären, würde die Chance 4 in 9 werden? Könnte es wert sein, Wahrscheinlichkeiten gegen Ausgaben zu setzen oder alle Ausgaben aufzulisten - da ich verstehe, dass nicht nur "alle Ausgaben für einen bestimmten Buchstaben ...", sondern auch alle unterschiedlichen Ausgaben die gleiche Wahrscheinlichkeit haben sollten (gegebene unterschiedliche Werte in jeder Liste).
Jonathan Allan
@DavidC Tut mir leid, dass das Hinzufügen zusätzlicher Beispiele zu Unklarheiten geführt hat. Sie erstellen für jeden Aufruf nur eine Ausgabezeile.
Neil,
1
@JonathanAllan Das Hinzufügen von "Joan" und "Jeep" würde die relative Wahrscheinlichkeit der Ausgabe von "Neils Nomen" im Vergleich zu anderen Optionen, die "Neil" und "Nomen" enthalten, nicht beeinträchtigen.
Neil,

Antworten:

5

Jelly ,  27 25  24 Bytes

-1 danke an Erik den Outgolfer (benutze eine Null anstelle eines Leerzeichens)

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

Ein vollständiges Programm, das ein Argument in Form einer Python-formatierten Liste von String-Listen akzeptiert und die Ausgabe an STDOUTt ausgibt.

Probieren Sie es online!

Wie?

Ż€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
quelle
24 Bytes .
Erik der Outgolfer
Ah ja, nett :)
Jonathan Allan
5

05AB1E ,  24 23  21 Bytes

Angenommen, es gibt ein Substantiv für jeden Namen, wie es die Herausforderung zulässt.

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

Probieren Sie es online!

Erläuterung

„'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
quelle
Oh, die ¯ªund €˜sind schlau! Ich hatte eine 26-Byte-Antwort, hatte aber Probleme, das doppelte Leerzeichen zu
korrigieren,
@ KevinCruijssen: Ja, das war der Teil, mit dem ich die meisten Probleme hatte. Es dauerte eine Weile, bis mir klar wurde, dass ich ¯anstelle des Füllens mit leeren Zeichenfolgen später manuell aufräumen musste.
Emigna
4

R , 155 bis 148 Bytes

-7 Bytes dank Giuseppe (mit *für 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)}

Probieren Sie es online!

Verwendet Ablehnungsstichproben: Zeichnen Sie einen Namen, ein Adjektiv (möglicherweise die leere Zeichenfolge) und ein Substantiv nach dem Zufallsprinzip, bis die ersten Buchstaben übereinstimmen. Diese Bedingung wird überprüft, indem gezählt wird, ob die Anzahl der eindeutigen Elemente in dem aus den ersten Buchstaben gebildeten Vektor plus der leeren Zeichenfolge die Länge 2 hat - dies ermöglicht ein leeres Adjektiv.

Drucken Sie dann das Ergebnis mit einem zusätzlichen Leerzeichen aus, wenn das Adjektiv nicht leer ist.

Die unterschiedlichen Möglichkeiten, die mit dem gleichen Buchstaben beginnen, haben gleiche Auftrittswahrscheinlichkeiten, da samplesich aus der Gleichverteilung ergibt. Dies lässt sich am einfachsten feststellen, wenn der Name und das Substantiv mit demselben Buchstaben beginnen (was in Ordnung ist: Wenn dies nicht der Fall ist, lehnen wir ab). Jetzt Bedingung für das Ereignis, das wir akzeptieren: Das heißt, wir zeichnen entweder das leere Adjektiv oder ein Adjektiv, das mit demselben Buchstaben beginnt. Jede dieser Möglichkeiten hat immer noch die gleiche Wahrscheinlichkeit.

105

Robin Ryder
quelle
Hat dies die gleiche Chance eines leeren Adjektivs für einen gegebenen Anfangsbuchstaben?
Nick Kennedy
@ NickKennedy Ja, seitdem sample schöpft die Gleichverteilung aus. Dies lässt sich am einfachsten feststellen, wenn der Name und das Substantiv mit demselben Buchstaben beginnen (was in Ordnung ist: Wenn dies nicht der Fall ist, lehnen wir ab). Jetzt Bedingung für das Ereignis, das wir akzeptieren: Das heißt, wir zeichnen entweder das leere Adjektiv oder ein Adjektiv, das mit demselben Buchstaben beginnt. Jede dieser Möglichkeiten hat immer noch die gleiche Wahrscheinlichkeit.
Robin Ryder
Danke, gut erklärt.
Nick Kennedy
@ NickKennedy Danke, ich füge diese Erklärung dem Post zusammen mit einem Link hinzu, um empirisch zu überprüfen, ob die Wahrscheinlichkeiten gleich sind.
Robin Ryder
148 Bytes
Giuseppe
3

JavaScript (ES6),  139 124 122  120 Byte

Sparen Sie 2 Bytes dank @Neil

Übernimmt die Eingabe als (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)

Probieren Sie es online!

Oder überprüfen Sie die Verteilung auf 5 Millionen Ziehungen

Wie?

Die Helferfunktion G

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

Gs

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

Wir prüfen dann, ob alle Anfangsbuchstaben mit dem folgenden regulären Ausdruck identisch sind:

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

s gültig ist.

Arnauld
quelle
+[(o=g([,...a]))&&o+' ']+spart 2 bytes, denke ich?
Neil,
@ Neil Ah, ja. Schön.
Arnauld,
3

Python 3 , 161 154 151 147 145 Bytes

( Danke, ArBo, Verkörperung der Unabhängigkeit, Neil, der 2, 3 und 4 Bytes zu meinem ersten Golf beigetragen hat! )

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)

Probieren Sie es online!(mit 500k Ausführungen)

  • Nimmt drei Listen als Eingaben.

  • Nimmt mindestens ein Nomen für jeden Namen an.


Gleiche Punktzahl, mehr Golf:

Python 3 , 145 Bytes

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

Probieren Sie es online!(mit 500k Ausführungen)

Es ist nur 140, wenn nachfolgende Leerzeichen zulässig sind (durch Entfernen der quadratischen Fläche [:-1])

Nicola Sap
quelle
1
Schöne erste Antwort! Sie können ein Byte in der ersten while - Schleife sparen: while t>""<t[0]!=w. Sie können die letzte Zeile auch durch print(s+"'s",t+(t and" ")+o)Löschen u=der dritten Zeile ersetzen .
ArBo
Nicola Sap,
1
152 Bytes (Fußzeile entfernt, um URL in Kommentar
einzufügen
1
Sie verwenden die Variable nur teinmal, sodass Sie durch Einfügen des Codes 4 Bytes sparen können. Ich denke, Sie können umschalten o, um ein ähnliches Codemuster zu verwenden t, und dann weitere 4 Bytes sparen, indem Sie das auch inlinieren.
Neil,
Danke, ihr helft wirklich! @Neil, ich kann nicht umgestalten o: Ich erreiche Folgendes : 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 ) Aber das Hinzufügen des bedingten Leerzeichens über ein optionales Argument zu ykostet mich 11 Bytes
Nicola Sap
0

Gelee , 28 Bytes

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

Probieren Sie es online!

Schrieb dies, bevor ich die kürzere Antwort von @ JonathanAllan sah, fand es aber lohnenswert, es zu posten, da es einen anderen Ansatz verwendet. Gespeichert 3 Bytes von @ EriktheOutgolfers Vorschlag zu dieser Antwort.

Ein vollständiges Programm, das eine Liste von Zeichenfolgen aufnimmt und implizit eine zufällig ausgewählte Alliteration druckt. Nimmt mindestens ein Nomen pro Name an.

Nick Kennedy
quelle
0

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

(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();

Probieren Sie es online!

Verkörperung der Ignoranz
quelle
Sie können davon ausgehen, dass Namen mit einem Großbuchstaben beginnen. Sie können also nur die anderen Buchstaben für den Vergleich in Großbuchstaben schreiben. Dies sollte Ihnen 10 Bytes ersparen.
Neil,
@ Neil Yep, genau 10 Bytes :)
Verkörperung der Ignoranz
0

Rot , 179 Bytes

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

Probieren Sie es online!

Erläuterung:

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
quelle
0

Scala , 234 226 234 206 Bytes

-28 Da ich dachte, dass es StdIn akzeptieren muss, ist es jetzt eine Funktion

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

Probieren Sie es online!

Ungolfed:

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
quelle
0

Ruby , 94 Bytes

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

Probieren Sie es online!

Wert Tinte
quelle
0

Icon , 167 163 Bytes

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

Probieren Sie es online!

Verwendet den gleichen Algorithmus wie meine RedAntwort.

Galen Ivanov
quelle