Montare automaticamente un'anti-prevedibile aria anti-prevedibile


15

Grazie a @ComradeSparklePony per il titolo.

Questa sfida dovrebbe essere molto semplice. Ti vengono date tre liste.

Il primo è un elenco di nomi, nel caso del titolo.

Il secondo è un elenco di aggettivi, in minuscolo.

Il terzo è un elenco di nomi, in minuscolo.

Seleziona in modo casuale un nome, un aggettivo facoltativo, un nome e un output <Name>'s <adjective> <noun>. Tuttavia, ogni parola deve iniziare con la stessa lettera. Puoi presumere che tutte le parole inizino con una lettera. Puoi anche assumere (ma nota nella tua risposta se lo fai):

  • che tutte le parole sono composte esclusivamente da caratteri alfabetici
  • che esiste almeno un nome per ogni nome
  • che esiste almeno un nome per ciascun sostantivo

Non si può tuttavia supporre che esista un aggettivo per una particolare coppia di nome e nome, poiché l'aggettivo è facoltativo, quindi l'output sarà comunque valido.

Non è necessario selezionare la lettera condivisa in modo uniforme, sebbene tutte le lettere disponibili debbano presentarsi con probabilità diversa da zero. Tuttavia, è necessario assicurarsi che tutti gli output di una determinata lettera abbiano le probabilità quasi uguali di verificarsi nei limiti del generatore di numeri casuali della propria lingua. Nel caso dell'aggettivo, ciò equivale ad avere una voce in più che significa "nessun aggettivo per questa lettera" che ha le stesse possibilità di tutti gli altri aggettivi per quella lettera.

Esempi di elenchi di input:

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

Esempi di output per questi input (ogni riga è un esempio separato):

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

Nota nessuno spazio aggiuntivo tra le parole negli ultimi due esempi.

Questo è , quindi vince il codice più corto che non rompe nessuna scappatoia standard!

Nel caso improbabile che ti aiuti, puoi inserire tutto in lettere maiuscole, ma devi comunque produrre in maiuscolo.


È corretto supporre che il programma debba restituire: 1 nome 1 aggettivo (se uno corrisponde al nome) 1 sostantivo? O stai chiedendo di produrre un output per ogni nome?
DavidC,

1
Forse dovresti aggiungere "Joan" e "jeep" nel tuo esempio per illustrare il fatto che potrebbe non esserci alcun aggettivo per una determinata lettera?
Arnauld,

Dato il tuo esempio di input è la possibilità di nessun aggettivo 1 su 3 (poiché tutti gli "elenchi" aggettivi sono lunghi 2)? ... e se anche "Joan" e "Jeep" fossero presenti senza alcun jaggettivo, la possibilità diventerebbe 4 su 9? Potrebbe valere la pena collocare le probabilità rispetto agli output o enumerare tutti gli output, poiché lo capisco non solo "tutti gli output per una determinata lettera ...", ma anche tutti gli output distinti dovrebbero avere la stessa probabilità (dati valori distinti all'interno di ciascun elenco).
Jonathan Allan,

@DavidC Siamo spiacenti, mi rendo conto che l'aggiunta di esempi aggiuntivi lo ha reso poco chiaro; produci solo una riga di output per ogni invocazione.
Neil,

1
@JonathanAllan L'aggiunta di "Joan" e "jeep" non influirebbe sulle possibilità relative dell'output di "Neil's noun" rispetto ad altre opzioni contenenti "Neil" e "noun".
Neil,

Risposte:


5

Gelatina ,  27 25  24 byte

-1 grazie a Erik the Outgolfer (usa uno zero invece di uno spazio)

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

Un programma completo che accetta un argomento sotto forma di un elenco in formato Python di elenchi di stringhe che stampa l'output su STDOUTt.

Provalo online!

Come?

Ż€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


Ah sì, bello :)
Jonathan Allan,

5

05AB1E ,  24 23  21 byte

Suppone che ci sia un nome per ogni nome, come consentito dalla sfida.

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

Provalo online!

Spiegazione

„'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

Oh, i ¯ªe €˜sono intelligenti! Avevo una risposta di 26 byte, ma avevo problemi a sistemare il doppio spazio quando non c'era un aggettivo ..
Kevin Cruijssen,

@KevinCruijssen: Sì, quella è stata anche la parte con cui ho avuto più problemi. Mi ci è voluto un po 'per capire che avrei potuto usare ¯invece di riempire con stringhe vuote che dovevo ripulire manualmente in seguito.
Emigna

4

R , 155 148 byte

-7 byte grazie a Giuseppe (usando *persample )

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

Provalo online!

Usa il campionamento del rifiuto: disegna a caso un nome, un aggettivo (possibilmente la stringa vuota) e un sostantivo fino a quando le prime lettere corrispondono. Questa condizione viene verificata contando se il numero di elementi univoci nel vettore formato dalle prime lettere, più la stringa vuota, è di lunghezza 2 - questo consente un aggettivo vuoto.

Quindi stampare il risultato, con uno spazio aggiuntivo se l'aggettivo non è vuoto.

Le diverse possibilità che iniziano con la stessa lettera hanno uguali probabilità di occorrenza, da allora sample attinge dalla distribuzione uniforme. Il modo più semplice per vederlo è condizionare l'evento che il nome e il nome iniziano con la stessa lettera (il che va bene: se non lo facessero, rifiuteremmo). Ora condizione sull'evento che accettiamo: questo significa che disegniamo l'aggettivo vuoto o un aggettivo che inizia con la stessa lettera. Ognuna di queste possibilità ha ancora pari probabilità.

105


Questo ha le stesse possibilità di un aggettivo vuoto tra loro possibilità per una data prima lettera?
Nick Kennedy,

@NickKennedy Sì, poiché sampleattinge dalla distribuzione uniforme. Il modo più semplice per vederlo è condizionare l'evento che il nome e il nome iniziano con la stessa lettera (il che va bene: se non lo facessero, rifiuteremmo). Ora condizione sull'evento che accettiamo: questo significa che disegniamo l'aggettivo vuoto o un aggettivo che inizia con la stessa lettera. Ognuna di queste possibilità ha ancora pari probabilità.
Robin Ryder,

grazie, ben spiegato.
Nick Kennedy,

@NickKennedy Grazie, aggiungerò questa spiegazione al post insieme a un link per verificare empiricamente che le probabilità siano uguali.
Robin Ryder,


3

JavaScript (ES6),  139 124 122  120 byte

Risparmia 2 byte grazie a @Neil

Accetta input come (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)

Provalo online!

Oppure controlla la distribuzione su 5 milioni di pareggi

Come?

g

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

gS

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

Quindi controlliamo se tutte le lettere iniziali sono identiche alla seguente espressione regolare:

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

S


+[(o=g([,...a]))&&o+' ']+salva 2 byte, penso?
Neil,

@Neil Ah, sì. Ben fatto.
Arnauld,

3

Python 3 , 161 154 151 147 145 byte

( Grazie ArBo, EmbodimentOfIgnorance, Neil che hanno contribuito con 2, 3 e 4 byte al mio primo 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)

Provalo online! (con esecuzioni 500k)

  • Accetta tre elenchi come input.

  • Presuppone almeno un nome per ciascun nome.


Stesso punteggio, più golf-y:

Python 3 , 145 byte

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

Provalo online!(con esecuzioni 500k)

Sono solo 140 se gli spazi bianchi finali sono consentiti (rimuovendo la faccia quadrata [:-1])


1
Bella prima risposta! È possibile salvare un byte nel primo ciclo while: while t>""<t[0]!=w. Puoi anche sostituire l'ultima riga print(s+"'s",t+(t and" ")+o), facendo cadere la u=nella terza riga.
ArBo,

Ho finito per cambiare la mia soluzione perché la precedente non soddisfaceva i requisiti
Nicola Sap,

1
152 byte (piè di pagina rimosso per inserire l'URL nel commento)
Incarnazione dell'ignoranza

1
Stai usando la variabile solo tuna volta, così puoi salvare 4 byte incorporando il codice. Penso che puoi passare oa utilizzare un modello di codice simile a t, quindi salvare altri 4 byte inserendo anche quello.
Neil

Grazie, state davvero aiutando! @Neil, non sono in grado di eseguire il refactoring o: raggiungo questo: 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 ) ma l'aggiunta dello spazio bianco condizionale, tramite un arg opzionale a y, mi costa 11 byte
Nicola Sap

0

Gelatina , 28 byte

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

Provalo online!

Ho scritto questo prima che vedessi la risposta più breve di @ JonathanAllan, ma ho pensato che valesse la pena pubblicare perché utilizza un approccio diverso. Salvato 3 byte dal suggerimento di @ EriktheOutgolfer su quella risposta.

Un programma completo che prende un elenco di elenchi di stringhe e stampa implicitamente un'allitterazione selezionata casualmente. Presuppone almeno un sostantivo per nome.


0

C # (compilatore interattivo Visual C #) , 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();

Provalo online!


Puoi presumere che i nomi inizino con una lettera maiuscola, quindi puoi solo mettere in maiuscolo le altre lettere per il confronto, il che dovrebbe farti risparmiare 10 byte?
Neil,

@Neil Sì, esattamente 10 byte :)
Incarnazione dell'ignoranza,

0

Rosso , 179 byte

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

Provalo online!

Spiegazione:

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
]

0

Scala , 234 226 234 206 byte

-28 a causa del fatto che ho pensato che dovesse accettare StdIn, ora è una funzione

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

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


0

Icona , 167 163 byte

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

Provalo online!

Utilizza lo stesso algoritmo della mia Redrisposta.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.