Автоматично передбачувано збирають алітеративну арію


15

Дякуємо @ComradeSparklePony за назву.

Цей виклик повинен бути дуже простим. Вам надано три списки.

Перший - це список імен, у назви справи.

Другий - це перелік прикметників, малих букв.

Третя - це список іменників, малих речень.

Виберіть випадковим чином ім’я, необов'язковий прикметник та іменник та виведіть <Name>'s <adjective> <noun>. Однак кожне слово повинно починатися з тієї самої літери. Можна припустити, що всі слова починаються з літери. Ви також можете припустити (але зауважте у своїй відповіді, якщо це зробити):

  • що всі слова складаються виключно з алфавітних символів
  • що для кожного імені є принаймні один іменник
  • що для кожного іменника є хоча б одне ім’я

Однак ви не можете припустити, що прикметник існує для певної пари імен та іменників, оскільки прикметник необов’язковий, тому вихід все ще буде дійсним.

Не потрібно вибирати спільний лист рівномірно, хоча всі наявні листи повинні мати ненульовий шанс виникнення. Однак ви повинні гарантувати, що всі вихідні дані для даної літери мають максимально рівний шанс виникнути в межах можливого генератора випадкових чисел вашої мови. У випадку з прикметником це еквівалентно додатковому запису, що означає "немає прикметника для цієї літери", який має такий самий шанс, як і всі інші прикметники до цієї літери.

Приклади списків введення:

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

Приклади виходів для цих входів (кожен рядок є окремим прикладом):

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

В останніх двох прикладах не зазначайте пробілу між словами.

Це , тому перемагає найкоротший код, який не порушує стандартних лазівки!

У тому випадку, коли це допоможе, ви можете ввести все у верхньому регістрі, але все-таки потрібно вивести у регістрі речення.


Чи правильно ми вважаємо, що програма повинна повертати: 1 ім’я 1 прикметник (якщо один відповідає імені) 1 іменник? Або ви просите створити вихід для кожного імені?
DavidC

1
Можливо, вам слід додати у своєму прикладі «Джоан» та «джип», щоб проілюструвати той факт, що для даної літери може бути зовсім не прикметник?
Арнольд

З огляду на ваш приклад, чи є ймовірність відсутності прикметника 1 на 3 (оскільки всі прикметникові "списки" є 2 довгими)? ... і якби "Джоан" та "Джип" також були там без jприкметника, шанс став 4 з 9? Можливо, варто розмістити ймовірності проти результатів або перерахувати всі результати - наскільки я це розумію, не тільки "всі результати для даної літери ...", але й усі окремі результати повинні мати однакову ймовірність (з урахуванням відмінних значень у кожному списку).
Джонатан Аллан

@DavidC Вибачте, я розумію, що додавання додаткових прикладів зробило це незрозумілим; ви створюєте лише один рядок виводу для кожного виклику.
Ніл

1
@JonathanAllan Додавання "Джоан" та "джип" не вплине на відносні шанси виведення "Іменника Ніла" порівняно з іншими параметрами, що містять "Ніл" та "Іменник".
Ніл

Відповіді:


5

Желе ,  27 25  24 байт

-1 завдяки Еріку Попелу (використовуйте нуль замість символу пробілу)

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

Повна програма, що приймає аргумент у вигляді списку відформатованих Python списків рядків, який друкує вихід на STDOUTt.

Спробуйте в Інтернеті!

Як?

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


Ага так, приємно :)
Джонатан Аллан

5

05AB1E ,  24 23  21 байт

Припускає, що існує іменник для кожного імені, як це дозволено викликом.

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

Спробуйте в Інтернеті!

Пояснення

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

О, ¯ªі €˜розумні! У мене була відповідь 26 байтів, але виникли проблеми з виправленням подвійного пробілу, коли немає прикметника ..
Кевін Круїйсен

@KevinCruijssen: Так, це саме частина, з якою у мене виникло і найбільше проблем. Пішов на деякий час, щоб зрозуміти, що я можу використовувати ¯замість заповнення порожніх рядків, які мені довелося пізніше вручну прибирати.
Емінья

4

R , 155 148 байт

-7 байт завдяки Джузеппе (використовуючи *для 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)}

Спробуйте в Інтернеті!

Використовує вибірки відхилення: намалюйте навмання ім’я, прикметник (можливо, порожній рядок) та іменник до збігу перших літер. Ця умова перевіряється підрахунком, якщо кількість унікальних елементів у векторі, утвореному з перших літер, плюс порожній рядок, має довжину 2 - це дозволяє отримати порожній прикметник.

Потім надрукуйте результат з додатковим пробілом, якщо прикметник не порожній.

Різні можливості, що починаються з тієї самої літери, мають однакові ймовірності виникнення, оскільки sampleвипливає з рівномірного розподілу. Найпростіший спосіб це побачити - умовити той випадок, коли ім’я та іменник починаються з однієї і тієї ж літери (що добре: якщо їх немає, ми б відхилили). Тепер умова події, яку ми приймаємо: це означає, що ми малюємо або порожній прикметник, або прикметник, що починається з тієї самої літери. Кожна з цих можливостей все ще має рівну ймовірність.

105


Чи має це однаковий шанс порожнього прикметника один до одного для будь-якої заданої першої літери?
Нік Кеннеді

@NickKennedy Так, оскільки sampleчерпає з рівномірного розподілу. Найпростіший спосіб це побачити - умовити той випадок, коли ім’я та іменник починаються з однієї і тієї ж літери (що добре: якщо їх немає, ми б відхилили). Тепер умова події, яку ми приймаємо: це означає, що ми малюємо або порожній прикметник, або прикметник, що починається з тієї самої літери. Кожна з цих можливостей все ще має рівну ймовірність.
Робін Райдер

дякую, добре пояснив.
Нік Кеннеді

@NickKennedy Дякую, я додам це пояснення до публікації разом із посиланням, щоб емпірично підтвердити, що ймовірності рівні.
Робін Райдер


3

JavaScript (ES6),  139 124 122  120 байт

Збережіть 2 байти завдяки @Neil

Вводиться як " (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)

Спробуйте в Інтернеті!

Або перевірити розподіл на 5 мільйонів жеребкувань

Як?

g

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

gs

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

Потім ми перевіряємо, чи всі початкові букви однакові із таким регулярним виразом:

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

с


+[(o=g([,...a]))&&o+' ']+економить 2 байти, я думаю?
Ніл

@Neil Ага, так. Хороший.
Арнольд

3

Пітон 3 , 161 154 151 147 145 байт

( Дякую ArBo, EmbodimentOfIgnorance, Ніл, які внесли 2, 3 і 4 байти в мій перший гольф! )

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)

Спробуйте в Інтернеті! (з 500 тис. страт)

  • В якості вхідних даних приймає три списки.

  • Передбачає щонайменше один іменник для кожного імені.


Той самий рахунок, більше гольф-у:

Python 3 , 145 байт

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

Спробуйте в Інтернеті! (з 500 тис. страт)

Це просто 140, якщо дозволено пробіли білого простору (видаляючи квадратну грань [:-1])


1
Приємна перша відповідь! Ви можете зберегти байти в першому циклі в той час як: while t>""<t[0]!=w. Ви також можете замінити останній рядок на print(s+"'s",t+(t and" ")+o), опустивши u=в третій рядок.
ArBo

Я змінив своє рішення, тому що попередній не відповідав вимогам
Нікола Сап

1
152 байти (колонтитул видалено, щоб відповідати URL-адресу коментаря)
Втілення Невігластва

1
Ви використовуєте змінну лише tодин раз, щоб ви могли зберегти 4 байти, вставивши код. Я думаю, що ви можете переключитися oна використання аналогічного шаблону коду t, а потім зберегти ще 4 байти, включивши його.
Ніл

Дякую, ви, хлопці, дуже допомагаєте! @Neil, я не в змозі змінити показник o: Я досягаю цього: 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 ), але додавання умовного пробілу через необов'язковий аргумент yкоштує мені 11 байт
Nicola Sap

0

Желе , 28 байт

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

Спробуйте в Інтернеті!

Написав це, перш ніж я побачив коротшу відповідь @ JonathanAllan, але подумав, що варто опублікувати, оскільки використовує інший підхід. Збережено 3 байти за пропозицією @ EriktheOutgolfer щодо цієї відповіді.

Повна програма, що містить список списків рядків і неявно друкує випадково вибрану алітерацію. Припускає принаймні один іменник на ім’я.


0

C # (Visual C # Interactive Compiler) , 176 байт

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

Спробуйте в Інтернеті!


Ви можете припустити, що імена починаються з великої літери, тож ви можете просто порівняти інші літери для порівняння, що має заощадити 10 байт?
Ніл

@Neil Yep, рівно 10 байт :)
Втілення

0

Червоний , 179 байт

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

Спробуйте в Інтернеті!

Пояснення:

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 байт

-28 через те, що я думав, що він повинен прийняти StdIn, це функція зараз

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

Спробуйте в Інтернеті!

Безголівки:

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
}


Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.