Secara otomatis diprediksi anti aria alliteratif

15

Terima kasih kepada @ComradeSparklePony untuk judulnya.

Tantangan ini harus sangat sederhana. Anda diberi tiga daftar.

Yang pertama adalah daftar nama depan, dalam kasus judul.

Yang kedua adalah daftar kata sifat, dalam huruf kecil.

Yang ketiga adalah daftar kata benda, dalam huruf kecil.

Harap pilih nama, kata sifat opsional, dan kata benda, dan keluaran secara acak <Name>'s <adjective> <noun>. Namun, setiap kata harus dimulai dengan huruf yang sama. Anda dapat mengasumsikan bahwa semua kata dimulai dengan huruf. Anda juga dapat mengasumsikan (tetapi perhatikan jawaban Anda jika Anda melakukannya):

  • bahwa semua kata hanya terdiri dari karakter alfabet
  • bahwa setidaknya ada satu kata benda untuk setiap nama
  • bahwa setidaknya ada satu nama untuk setiap kata benda

Namun Anda tidak dapat mengasumsikan bahwa kata sifat ada untuk pasangan nama dan kata benda tertentu, karena kata sifat bersifat opsional sehingga hasilnya akan tetap valid.

Anda tidak harus memilih surat bersama secara seragam, meskipun semua surat yang tersedia harus memiliki peluang yang tidak nol untuk terjadi. Namun Anda harus memastikan bahwa semua keluaran untuk surat yang diberikan memiliki peluang yang sedekat mungkin terjadi dalam batas-batas pembangkit angka acak bahasa Anda. Dalam hal kata sifat, ini setara dengan memiliki entri tambahan yang berarti "tidak ada kata sifat untuk surat ini" yang memiliki peluang yang sama dengan semua kata sifat lainnya untuk surat itu.

Contoh daftar masukan:

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

Contoh output untuk input ini (setiap baris adalah contoh terpisah):

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

Perhatikan tidak ada ruang ekstra antara kata-kata dalam dua contoh terakhir.

Ini adalah , jadi kode terpendek yang tidak mematahkan celah standar menang!

Jika hal itu tidak membantu, Anda dapat memasukkan semuanya dalam huruf besar, tetapi Anda masih perlu menampilkan dalam huruf besar.

Neil
sumber
Apakah kita benar dengan menganggap bahwa program tersebut harus kembali: 1 nama 1 kata sifat (jika ada yang cocok dengan namanya) 1 kata benda? Atau apakah Anda meminta untuk menghasilkan output untuk setiap nama?
DavidC
1
Mungkin Anda harus menambahkan 'Joan' dan 'jeep' dalam contoh Anda untuk menggambarkan fakta bahwa mungkin tidak ada kata sifat sama sekali untuk surat yang diberikan?
Arnauld
Mengingat input contoh Anda adalah kemungkinan tidak ada kata sifat 1 dalam 3 (karena semua "daftar" kata sifat 2 panjang)? ... dan jika 'Joan' dan 'Jeep' juga ada di sana tanpa j-duga akankah peluang menjadi 4 in 9? Mungkin layak menempatkan probabilitas terhadap output, atau menghitung semua output - seperti yang saya pahami tidak hanya "semua output untuk huruf yang diberikan ..." tetapi juga semua output yang berbeda harus memiliki kemungkinan yang sama (diberi nilai berbeda dalam setiap daftar).
Jonathan Allan
@ DavidvidC Maaf, saya sadar menambahkan contoh tambahan telah membuat itu tidak jelas; Anda hanya menghasilkan satu jalur output untuk setiap doa.
Neil
1
@JonathanAllan Menambahkan "Joan" dan "jeep" tidak akan mempengaruhi peluang relatif dari "kata benda Neil" menjadi keluaran dibandingkan dengan opsi lain yang mengandung "Neil" dan "kata benda".
Neil

Jawaban:

5

Jelly ,  27 25  24 byte

-1 berkat Erik the Outgolfer (gunakan nol alih-alih karakter spasi)

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

Program lengkap yang menerima argumen dalam bentuk daftar string yang diformat Python yang mencetak output ke STDOUTt.

Cobalah online!

Bagaimana?

Ż€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
sumber
24 byte .
Erik the Outgolfer
Ah ya, bagus :)
Jonathan Allan
5

05AB1E ,  24 23  21 byte

Asumsikan ada kata benda untuk setiap nama, sebagaimana diizinkan oleh tantangan.

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

Cobalah online!

Penjelasan

„'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
sumber
Oh, ¯ªdan dia €˜pintar! Saya punya jawaban 26 byte, tetapi mengalami kesulitan memperbaiki ruang ganda ketika tidak ada kata sifat ..
Kevin Cruijssen
@KevinCruijssen: Ya itu adalah bagian yang paling banyak saya hadapi. Butuh beberapa saat untuk menyadari bahwa saya bisa menggunakan ¯alih-alih mengisi dengan string kosong saya harus membersihkan secara manual nanti.
Emigna
4

R , 155 148 byte

-7 byte terima kasih kepada Giuseppe (gunakan *untuk 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)}

Cobalah online!

Menggunakan sampel penolakan: menggambar secara acak nama, kata sifat (mungkin string kosong) dan kata benda sampai huruf pertama cocok. Kondisi ini diperiksa dengan menghitung jika jumlah elemen unik dalam vektor yang terbentuk dari huruf pertama, ditambah string kosong, panjangnya 2 - ini memungkinkan kata sifat kosong.

Kemudian cetak hasilnya, dengan ruang tambahan jika kata sifat tidak kosong.

Kemungkinan yang berbeda dimulai dengan huruf yang sama memiliki probabilitas kejadian yang sama, karena sample menarik dari distribusi yang seragam. Cara termudah untuk melihat ini adalah dengan syarat jika nama dan kata benda dimulai dengan huruf yang sama (yang tidak masalah: jika tidak, kami akan menolak). Sekarang syarat pada acara yang kami terima: ini berarti kami menggambar kata sifat kosong, atau kata sifat dimulai dengan huruf yang sama. Setiap kemungkinan ini masih memiliki probabilitas yang sama.

105

Robin Ryder
sumber
Apakah ini memiliki peluang yang sama untuk kata sifat kosong satu sama lain kemungkinan untuk huruf pertama yang diberikan?
Nick Kennedy
@NickKennedy Ya, karena samplemenarik dari distribusi seragam. Cara termudah untuk melihat ini adalah dengan syarat jika nama dan kata benda dimulai dengan huruf yang sama (yang tidak masalah: jika tidak, kami akan menolak). Sekarang syarat pada acara yang kami terima: ini berarti kami menggambar kata sifat kosong, atau kata sifat dimulai dengan huruf yang sama. Setiap kemungkinan ini masih memiliki probabilitas yang sama.
Robin Ryder
terima kasih, dijelaskan dengan baik.
Nick Kennedy
@NickKennedy Terima kasih, saya akan menambahkan penjelasan itu ke posting bersama dengan tautan untuk memverifikasi secara empiris bahwa probabilitasnya sama.
Robin Ryder
1
148 byte
Giuseppe
3

JavaScript (ES6),  139 124 122  120 byte

Simpan 2 byte berkat @Neil

Mengambil input sebagai (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)

Cobalah online!

Atau periksa distribusi 5 juta undian

Bagaimana?

g

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

gs dengan format yang valid, tetapi tanpa mengambil huruf awal ke rekening. Untuk kata sifat, kami menambahkan entri kosong dan pastikan untuk tidak memasukkan spasi tambahan jika itu dipilih.

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

Kami kemudian memeriksa apakah semua huruf awal identik dengan ekspresi reguler berikut:

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

s

Arnauld
sumber
+[(o=g([,...a]))&&o+' ']+menghemat 2 byte, saya pikir?
Neil
@Neil Ah, ya. Bagus
Arnauld
3

Python 3 , 161 154 151 147 145 byte

( Terima kasih ArBo, EmbodimentOfIgnorance, Neil yang telah berkontribusi 2, 3 dan 4 byte untuk golf pertama saya! )

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)

Cobalah online! (dengan eksekusi 500 ribu)

  • Mengambil tiga daftar sebagai input.

  • Diasumsikan setidaknya satu kata benda untuk setiap nama.


Skor yang sama, lebih banyak 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])

Cobalah online!(dengan eksekusi 500 ribu)

Itu hanya 140 jika spasi spasi tambahan diperbolehkan (dengan menghapus wajah persegi [:-1])

Nicola Sap
sumber
1
Jawaban pertama yang bagus! Anda dapat menyimpan byte dalam loop sementara pertama: while t>""<t[0]!=w. Anda juga dapat mengganti baris terakhir dengan print(s+"'s",t+(t and" ")+o), menjatuhkan u=baris ketiga.
ArBo
Saya akhirnya mengubah solusi saya karena sebelumnya tidak sesuai dengan persyaratan
Nicola Sap
1
152 byte (Footer dihapus agar sesuai URL dalam komentar)
Perwujudan Ketidaktahuan
1
Anda hanya menggunakan variabel tsatu kali sehingga Anda dapat menyimpan 4 byte dengan memasukkan kode. Saya pikir Anda dapat beralih ountuk menggunakan pola kode yang serupa t, dan kemudian menyimpan 4 byte lainnya dengan menguraikannya juga.
Neil
Terima kasih, kalian benar-benar membantu! @ Neil, saya belum bisa refactor o: Saya mencapai ini: 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 ) tetapi menambahkan spasi putih bersyarat, melalui argumen opsional untuk y, biaya saya 11 byte
Nicola Sap
0

Jelly , 28 byte

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

Cobalah online!

Tulis ini sebelum saya melihat jawaban yang lebih pendek dari @ JonathanAllan, tetapi menganggapnya layak untuk dikirim karena menggunakan pendekatan yang berbeda. Disimpan 3 byte oleh saran @ EriktheOutgolfer pada jawaban itu.

Program lengkap mengambil daftar daftar string dan secara implisit mencetak aliterasi yang dipilih secara acak. Diasumsikan setidaknya satu kata benda per nama.

Nick Kennedy
sumber
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();

Cobalah online!

Perwujudan Ketidaktahuan
sumber
Anda dapat mengasumsikan nama dimulai dengan huruf besar, jadi Anda bisa menggunakan huruf besar untuk perbandingan, yang mana akan menghemat 10 byte?
Neil
@Neil Yap, tepatnya 10 byte :)
Perwujudan Ketidaktahuan
0

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

Cobalah online!

Penjelasan:

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

Scala , 234 226 234 206 byte

-28 karena saya pikir itu harus menerima StdIn, itu berfungsi sekarang

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

Cobalah online!

Tidak Disatukan:

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

Ruby , 94 byte

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

Cobalah online!

Nilai Tinta
sumber
0

Ikon , 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

Cobalah online!

Menggunakan algoritma yang sama dengan Redjawaban saya .

Galen Ivanov
sumber