Put the Hat in the Cat

C#, 273 267 bytes

using System.Linq;A=s=>{var r=new System.Random();var a=s.Split(' ');return string.Join(" ",a.Select(w=>w.Select((c,i)=>"AEIOUaeiou".Any(d=>c==d)?i:-1).Where(x=>x>=0).ToList()).Select((l,i)=>l.Any()?a[i].Insert(l[r.Next(l.Count)]+1,""+(char)r.Next(768,771)):a[i]));};

repl.it demo

I really feels like I'm cheating, since I still add hats to already accented vowels created by combining characters. If that is not acceptable, let me know so I can add boilerplate codes declare this answer non-competing.

This thing adds a random character among U+0300 or U+0301 or U+0302, after a random vowel of each input word (if any).

Ungolfed (lambda body only)

var r=new System.Random();
// Split sentence to array of words
var a=s.Split(' ');
// Join the (hat-ed) words back to sentence
return string.Join(
    " ",
    // Select an IEnum of list of integers indicating the positions of vowels
    a.Select(w=>
        w.Select((c,i)=>
            // If it's vowel, return position (>=0), else return -1
            "AEIOUaeiou".Any(d=>c==d)?i:-1
        // Filter vowels only
        ).Where(x=>x>=0)
        .ToList()
    // Convert each list of integers to hat-ed words
    ).Select((l,i)=>
        l.Any()
            // Insert "something" into the word...
            ?a[i].Insert(
                // ...at the position after a random vowel in that word...
                l[r.Next(l.Count)]+1,
                // "something" is a random integer in [0x0300, 0x0303), then casted to UTF16 i.e. [U+0300, U+0302]
                ""+(char)r.Next(768,771))
            // List is empty => just return original word
            :a[i]));

Perl 6, 101 bytes

~*.words.map: {(my$p=m:ex:i/<[aeiou]>/».to.pick)~~Mu:D??~S/.**{$p}<(/{("\x300".."\x302").pick}/!!$_}

Try it

Expanded:

~      # stringify (join with spaces)
*\     # Whatever lambda (input parameter)
.words # split into words

.map:  # for each word

{ # bare block lambda with implicit parameter 「$_」
  (

    my $p =

    m
    :exhaustive               # all possible matches
    :ignorecase
    /<[aeiou]>/\              # match a vowel

    ».to.pick                 # pick one of the positions

  ) ~~ Mu:D                   # is it defined ( shorter than 「.defined」 )

  ??                          # if 「$p」 is defined

    ~                         # stringify

    S/
      . ** {$p}               # match 「$p」 positions

      <(                      # ignore them
    /{
      ("\x300".."\x302").pick # pick one of the "hats" to add
    }/


  !!                          # if 「$p」 is not defined    
    $_                        # return the word unchanged
}

Tags:

Code Golf