# Put the Hat in the Cat

Inspired by the upcoming winter bash event

### Objetive

Add a hat ^,´ or ` to a single vowel in each word of the input.

### Rules

• The hat and the vowel must be chosen at random. Each hat has to appear with the same probability (33%) and the vowels must have the same probability within the valid vowels in the word (if the word have 2 valid vowels each must be 50% likely to be chosen) - or the closest that your language has.
• Only AEIOUaeiouare considered vowels (sorry y)
• Vowels with hats in the input DO NOT interfere with the rules (you can consider it as a consonant)
• If the input has no vowel it won't be modified
• Capitalization must be preserved.

### Examples

winter > wintér
bash > bâsh
rhythm > rhythm
rng ftw > rng ftw
cat in the hat > cât ìn thê hát
dès > dès
tschüss > tschüss
principî > prìncipî
PROGRAMMING PUZZLES & code golf > PROGRÂMMING PÚZZLES & codé gòlf

### Winning

This is so the shortest code wins

• "at random (or the closest that your language has)" so if my language has no random commands I can just do something deterministic??? – Fatalize Dec 16 '16 at 22:52
• @LuisMendo better? – Rod Dec 16 '16 at 22:55
• @Fatalize not even get the current time random? – Rod Dec 16 '16 at 22:57
• @Rod I don't have any language in mind. I'm just saying that you have to impose that it is random (and what kind of random) otherwise it makes no sense at all. – Fatalize Dec 16 '16 at 23:03
• The specs say we have to add ^ ´ or backtick, but the example tschuss shows an umlaut. Are umlauts required or not? – Level River St Dec 16 '16 at 23:18

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

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

# Mathematica, 226 bytes

Join@@((p=Position[w=#,Alternatives@@(v=Characters@"aeiouAEIOU")];If[p!={},i=#&@@RandomChoice@p;w[[i]]=FromCharacterCode[ToCharacterCode["àèìòùÀÈÌÒÙ"][[#&@@Position[v,w[[i]]]]]+RandomInteger@2]];w)&/@Split[#,{##}~FreeQ~" "&])&

Unnamed function taking a list of characters as input and returning a list of characters. Easier-to-read version, slightly ungolfed as well:

1  v = Characters["aeiouAEIOU"];
2  a = ToCharacterCode["àèìòùÀÈÌÒÙ"];
3  Join @@ (
4    (p = Position[w = #, Alternatives @@ v];
5      If[p != {},
6        i = First[RandomChoice[p]];
7        w[[i]] =
8          FromCharacterCode[
9            a[[ First[ Position[ v, w[[i]] ] ] ]] + RandomInteger[2]
10          ]
11        ]; w
12    ) &
13  ) /@ Split[#1, FreeQ[{##1}, " "] &] &

Line 13 splits the input into words (sublists of characters) at all the spaces; each word is operated on by the function defined by lines 4-12, and the results joined back together again in a single list by line 3.

Line 4 sets p to the list of indices indicating which characters of the word w are vowels. If there are any vowels (line 5), we make a random choice of one such index i (line 6) and then reset that single character of the word to a new character (lines 7-10). Finally we output the (possibly modified) word w.

To select the new character, we find where the vowel to be replaced sits in the string v and choose the corresponding character code from a. But to randomly select the three hats, we take that code and add a random integer between 0 and 2 (line 9) before converting back to a character. (Fortunately the behatted vowels all come in consecutive trios of UTF-8 character codes.)

# Python 3, 170 bytes

from random import *
c=choice
print(' '.join([w,w[:i]+c('̀́̂')+w[i:]][i>0]for w in input().split()for i in[c([j+1 for j,x in enumerate(w)if x in 'aeiouAEIOU']or[0])]))

Ungolfed:

from random import choice
print(' '.join([
w,  # Don't modify the word if no vowels were found

w[:i] + choice('̀́̂') + w[i:]
][i > 0]
for w in input().split()
for i in [choice([j + 1 for j, x in enumerate(w) if x in 'aeiouAEIOU']
or [0])  # choice requires a non-empty sequence
]))
• You do not need the space between import and *. – Mr. Xcoder Aug 29 '17 at 21:46
• j+1 for can be j+1for. – Jonathan Frech Feb 8 '18 at 15:09