15
\$\begingroup\$

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

\$\endgroup\$
  • \$\begingroup\$ "at random (or the closest that your language has)" so if my language has no random commands I can just do something deterministic??? \$\endgroup\$ – Fatalize Dec 16 '16 at 22:52
  • \$\begingroup\$ @LuisMendo better? \$\endgroup\$ – Rod Dec 16 '16 at 22:55
  • \$\begingroup\$ @Fatalize not even get the current time random? \$\endgroup\$ – Rod Dec 16 '16 at 22:57
  • \$\begingroup\$ @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. \$\endgroup\$ – Fatalize Dec 16 '16 at 23:03
  • \$\begingroup\$ The specs say we have to add ^ ´ or backtick, but the example tschuss shows an umlaut. Are umlauts required or not? \$\endgroup\$ – Level River St Dec 16 '16 at 23:18
1
\$\begingroup\$

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
}
\$\endgroup\$
2
\$\begingroup\$

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]));
\$\endgroup\$
1
\$\begingroup\$

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

\$\endgroup\$
1
\$\begingroup\$

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
                             ]))
\$\endgroup\$
  • 1
    \$\begingroup\$ You do not need the space between import and *. \$\endgroup\$ – Mr. Xcoder Aug 29 '17 at 21:46
  • \$\begingroup\$ j+1 for can be j+1for. \$\endgroup\$ – Jonathan Frech Feb 8 '18 at 15:09

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.