Automatically anti-predictably assemble an alliterative aria Thanks to @ComradeSparklePony for the title.

This challenge should be very simple. You are given three lists.

The first is a list of first names, in title case.

The second is a list of adjectives, in lower case.

The third is a list of nouns, in lower case.

Please randomly select a name, optional adjective, and noun, and output &lt;Name&gt;'s &lt;adjective&gt; &lt;noun&gt;. However, each word must begin with the same letter. You can assume that all words begin with a letter. You can also assume (but note in your answer if you do):


that all words are composed solely of alphabetic characters
that there is at least one noun for each name
that there is at least one name for each noun


You cannot however assume that an adjective exists for a particular pair of name and noun, as the adjective is optional so the output will still be valid.

You do not have to select the shared letter uniformly, although all available letters must have a non-zero chance of occurring. You must however ensure that all outputs for a given letter have as near equal chance of occurring as possible within the limits of your language's random number generator. In the case of the adjective, this is equivalent to having an extra entry meaning "no adjective for this letter" which has the same chance as all of the other adjectives for that letter.

Example input lists:

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


Example outputs for these inputs (each line is a separate example):

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


Note no extra space between words in the last two examples.

This is code-golf, so the shortest code that breaks no standard loopholes wins!

In the unlikely event that it helps, you can input everything in upper case, but you still need to output in sentence case.
Jelly, &nbsp;27 25&nbsp; 24 bytes

-1 thanks to Erik the Outgolfer (use a zero instead of a space character)

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


A full program accepting an argument in the form of a Python formatted list of lists of strings which prints the output to STDOUTt.

Try it online!

How?

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