# Context

As a conlanger, I am interested in creating a uniform, naturalistic language. One of the tricks is to create vocabulary according to certain structures of words. An example from English: In English, we have the word “tap” structured consonant-vowel-consonant. Usually, this means that there are many other words of this structure: “cat”, “dog”, “rock”, “fog”, “good”, etc.

As input, you have:

• an array C containing strings: consonants (C is the first letter in the word consonants). Identical consonants cannot be repeated on this list. For example, this list cannot contain ['b', 'b'].
• an array V containing strings: vowels (V is the first letter of the word vowels). Identical vowels cannot be repeated on this list.
• string S, which contains something like this "CVCCV" (any combination of "C" and "V")

Your task is to replace “C” in the string with a randomly taken string from array C and replace “V” in the string with a randomly taken string from array V and return (or display) this string.

"randomly" is defined as all possibilities having an equal chance of being selected. This is a kind of simplification: in real languages as well as in conlangs, ​​there are very frequent (for example 'r' in English) and not very frequent sounds but this is just a code-golf.

# Rules

This is code-golf so the lowest byte count wins.

# Examples

Input:
C = ['p', 'b', 't', 'd', 'k', 'g', 'm', 'n', 'w']
V = ['a', 'o', 'u', 'i', 'e', 'ä']
S = 'CVCCV'

Output:
pakto

Input:
C = ['p', 'b', 't', 'd', 'k', 'g', 'v', 's', 'r']
V = ['a', 'o', 'u', 'i', 'e', 'ä', 'ᵫ']
S = 'CVVCCVCCV'

Output:
koebrᵫvtä


# 05AB1E, 4 bytes

Takes input as S, [V,C]

Çè€Ω


Try it online!

# Jelly,  5  4 bytes

-1 thanks to Neil!

OịX€


A dyadic Link accepting a list of characters, S, on the left and a list of two lists of characters, [C, V], on the right which yields a list of characters.

Try it online!

If we could take S as a list of 1s and 0s we'd have the three byte solution ịX€.

### How?

OịX€ - Link: S, [C,V]
O    - ordinals (of S)          i.e. 'C':67 'V':86
ị   - index into [C,V] (vectorises)      C      V   [Jelly indexing is 1-indexed and modular]
€ - for each:
X  -   random choice

• I like both solutions! The 5 and the 3 byte ones +1
– RGS
Feb 22, 2020 at 16:54
• What does Jelly do if an index is out of range? (Charcoal automatically reduces it modulo the range, so I don't need to extract the bit manually.)
– Neil
Feb 22, 2020 at 17:42
• @Neil you just saved a byte - thanks! I even noted in my code break-down that "Jelly indexing is 1-indexed and modular". Feb 22, 2020 at 17:47

# Python 3, 9268 61 bytes

Takes input as S, C, V:

lambda s,*w:[random.choice(w[a>"u"])for a in s]
import random


You can try it online! How it works:

The *w is used so that the lists of consonants and vowels are packed in a list w.

When we do w[a > "u"] we are essentially checking if a (a character of s) is "v" or not. If it is, then a > "u" returns True, which indexes as 1 into w. If a is "c", then a > "u" returns False, which indexes as 0.

We use those indices to retrieve the correct list of letters from w and then choose randomly from that list, picking the list of choices.

Thanks @Arnauld for saving one byte and to @Jonathan Allan for citing this meta, saving me 7 bytes.

• This is what I would've done in my C solution had it not been for that the lists of consonants and vowels are not of equal length. Feb 22, 2020 at 17:57
• I believe that you should be able to take s as a list of characters and return the same (see this meta) and as such can replace the "".join(...) with [...]. Feb 22, 2020 at 19:48
• @JonathanAllan thanks for this reference! Shaved 7 bytes :)
– RGS
Feb 22, 2020 at 20:51

# APL+WIN, 35 34 bytes

One byte saved thanks to Adam

Prompts for consonants and vowels as continuous strings and the desired output as a comma separated string

c←⍞⋄v←⍞⋄C←',c[?⍴c]'⋄V←',v[?⍴v]'⋄⍎⎕


Try it online! Courtesy of Dyalog Classic

• If you liked this golf question, please vote to reopen it. Feb 23, 2020 at 14:01
• If you don't like this golf challenge, please retain its closed state.
– user92069
Feb 23, 2020 at 14:23
• This is the first time I have been lobbied from both sides of a question closure. Personally I had no problem understanding the question and as I got two up votes I assume at least two people agreed with my interpretation and my answer Feb 23, 2020 at 15:04
• By using ⍞ instead of ⎕ you can specify that input shouldn't have quotes, and then use ⎕ instead of ⍎⎕ to save a byte: Try it online!
Feb 25, 2020 at 13:48
• @Adám Thanks for the suggestion but whilst it works in Dyalog Classic I cannot get it to work in APL+WIN. If I run the code as you suggest it simply outputs the concatenated code string which needs the second ⍎ to execute. Feb 25, 2020 at 16:28

# Ruby, 45 40 bytes

->s,*l{s.bytes.map{|x|l[x%2].sample}*''}


Try it online!

• I didn't think that ruby could outgolf python. Great! Feb 22, 2020 at 16:59
• Ruby code is usually shorter than the equivalent python code.
– G B
Feb 23, 2020 at 7:14

# Charcoal, 7 bytes

⭆η‽§θ℅ι


Try it online! Link is to verbose version of code. Takes the input in the form [V, C], S where each value can be either a string or an array of characters as desired. Explanation:

 η      S
⭆       Map over elements/characters
θ   [V, C]
§    Cyclically indexed by
℅  Ordinal of
ι Current element/character
‽     Random element/character
Implicitly print


# C# (Visual C# Interactive Compiler), 66 bytes

(C,V,s)=>s.Select(x=>(x<68?C:V).OrderBy(l=>Guid.NewGuid()).Last())


Try it online!

# Japt, 6 bytes

ËcgV ö


Takes input as S, [V,C]

Try it

• @a'_' Ok.6 more to go... Feb 23, 2020 at 14:28
• @a'_' By the way, did you like this code-golf question? Feb 23, 2020 at 14:29
• @VictorVosMottorthanksMonica I loved it. But it was blatant that I can't re-open it, because I don't have enough reputation to do so.
– user92069
Feb 23, 2020 at 14:30
• @VictorVosMottorthanksMonica, liking a challenge is not a valid reason to VTR it. Address the issues that led to it being closed and, once done so to the community's satisfaction, it will be reopened. Feb 23, 2020 at 19:21
• @a'_', similarly, not liking a challenge is not grounds for closing it or leaving it closed. There have been many challenges here over the years I haven't personally liked, as there have been for everyone - if you don't like a challenge, just skip it and move on to the next one. Feb 23, 2020 at 19:26

# Wfj, 4 bytes

Hmm, let's do a pure-ASCII port of that.

C[gr


## Explanation

C    % Convert the string to its codepoints
[   % Index into the other list
r % For every indexed item:
g  % "g"et a random item in this list

Flag:f % Flatten the output list
Flag:j % Join the flattened output list
$$$$

• @KevinCruijssen I absolutely can't understand the challenge, so feel free to post your answer so that I can get a better understanding of this. (I guess I'd keep it deleted because I don't know how to fix it.)
– user92069
Feb 27, 2020 at 11:35

# PHP, 68 bytes

function($C,$V,$s){for(;$r=$s[$i++];)echo$$r[rand(0,count($$r)-1)];}


Try it online!

# C (gcc), 92 bytes

f(s,c,v,m,n)char*s,**c,**v;{for(srand(&s);*s;)printf("%s",*s++/86?v[rand()%n]:c[rand()%m]);}


Takes as input a string (s), an array of consonant strings (c), an array of vowel strings v, the length of c (m), and the length of v (n).

Could use a temporary variable for the result of rand but it wouldn't save me anything.

Try it online!

# JavaScript (ES6),  65  64 bytes

(C,V,s)=>s.replace(/./g,x=>eval(x).sort(_=>Math.random()-.5)[0])
`

Try it online!

Or 55 bytes if we can use an array of characters as I/O.

• The eval trick is really nice! Sadly enough I don't think I can use it in my answer to save some bytes :(
– RGS
Feb 22, 2020 at 16:49
• 55 seems fine unless OP has explicitly said not since I==O and if it quacks like a duck, it is a duck (i.e. strings are lists of characters) Feb 22, 2020 at 19:46
• @a'_' I think I'm privileged enough to hammer this question, which I think would be inappropriate either way.
– Neil
Feb 24, 2020 at 10:19