g | x | w | all
Bytes Lang Time Link
127Swift 6250723T235402ZmacOSist
117Python 3171124T231403ZDLosc
201Python 3.5160501T233326ZR. Kap
095Haskell160501T173410Znimi
134JavaScript ES6160501T094259ZNeil
136JavaScript ES6160501T081710Zuser8165
018Pyth160501T045300ZMaltysen
080Ruby160501T033440ZValue In

Swift 6, 135 127 bytes

{(c:[_:String],s:[_])in(0..<100).map{_ in""+(.random(in:0..<5)..<5).flatMap{_ in""+s.shuffled()[0]}.map{c[$0]!.shuffled()[0]}}}

Try it on SwiftFiddle! The closure's type is (categories: [Character: String], syllableTypes: [String]) -> [String].

Python 3, 117 bytes

(Also works in Python 2.)

lambda C,T:[J(J(R(C[t])for t in R(T))for j in[0]*randint(1,5))for i in[0]*100]
from random import*
R=choice
J="".join

The lambda function takes the categories C as a dictionary and the syllable types T as a list of strings. It returns a list of 100 words. Try it online!

Ungolfed

import random

def wordlist(categories, types):
    return [
        "".join(
            "".join(
                random.choice(categories[t])
                for t in random.choice(types))
            for j in range(random.randint(1, 5)))
        for i in range(100)]

Python 3.5, 227 223 210 206 201 bytes:

def k(u,*p):
 import itertools as i,random as r;y=[]
 for z in p:y+=[''.join(i)for i in i.product(*[u[i]for o in z for i in o])]
 for q in'1'*100:print(''.join([r.choice(y)for i in'1'*r.randint(1,5)]))

Takes the categories in as a Python dictionary (e.g {'C':'hello','K':'hoop'}) and the syllable types in as normal strings, with each separated by a comma (e.g. 'CK','CKC'). Output is in the form of 100 lines, with 1 word per line. Will add detailed explanation later.

Try it online! (repl.it)

Haskell, 95 bytes

import Test.QuickCheck
e=elements
c#s=mapM putStr=<<(generate$resize 5$listOf1$e s>>=mapM(e.c))

The categories are passed as a function from Char to String and the syllables types as a list of strings, e.g.

cat 'C' = "st"
cat 'V' = "aeiou"
syl = ["CV","CVC"]

Usage example: cat # syl -> tesat. Or with function/list literals: (\c->case c of 'C' -> "st"; 'V' -> "aeiou") # ["CV","CVC"]. Note: the function prints the generated word to stdout. If you try this within ghci, the return value is also printed, but that's a feature of the REPL and not of my code.

Dealing with random values in a purely functional language like Haskell is usually awkward. Luckily Test.QuickCheck provides some random generators and combinators for them that hide all the nastiness in a monad.

How it works:

input:
  s: list of syllable types
  c: categories as a function from Char to String

        e s             --  pick a random syllable type from s
           >>=mapM(e.c) --  for each letter: apply c and pick a random letter
                            from the returned string. We now have a random
                            generator for a single syllable
       listOf1          --  make a list of syllables of random length with
                            a minimum of 1
     resize 5           --  limit the maximum size to 5 (the list is not simply
                              cut if it is too long, all lengths are equally likely
   generate             --  run the generator. We now have a list of 1 to 5 syllables
mapM putStr=<<          --  print the syllables.

I'm happy that it works at all, maybe there's room for improvement.

Some more examples:

*Main> mapM_ (\_ -> do (cat#syl) ; putStrLn "" ) [1..10]
sisatassetto
se
ti
taso
sittos
tuttuste
tottu
satutustittes
sutetsetusut
tattatosote

JavaScript (ES6), 134 bytes

(c,s,r=s=>s[Math.random()*s.length|0],t="01234")=>[...Array(100)].map(_=>t.slice(r(t)).replace(/./g,_=>r(s)).replace(/./g,s=>r(c[s])))

Explanation:

(c,s,                               // Parameters
 r=s=>s[Math.random()*s.length|0],  // Select random character
 t="01234"                          // Number of syllables to skip
)=>[...Array(100)].map(_=>          // Generate 100 words
 t.slice(r(t))                      // Skip random number of syllables
  .replace(/./g,_=>r(s))            // Select syllables randomly
  .replace(/./g,s=>r(c[s])))        // Select letters randomly

JavaScript (ES6), 136 bytes

document.write("<pre>"+(

c=>s=>eval("for(r=Math.random,i=100,o=``;i--;o+=` `)for(j=r()*5;j-->0;)for(t=s[r(k=0)*s.length|0];l=t[k++];)o+=c[l][r()*c[l].length|0]")

)({ C: "st", V: "aeiou" })([ "CV", "CVC" ]))

Takes an object for the categories and an array for the syllable types.

Pyth - 18 bytes

Takes input as a dict and then one structure per line.

V100ssmmO@QkO.zhO5

Try it online here.

Ruby, 80 bytes

gotta go fast

Input is a dictionary hash (for example, {'C' => ['b', 'c'], 'V' => ['a', 'e']}) and a list of syllable structures (for example, ['CV', 'VC'] or %w{CV VC}.

->c,s{100.times{puts (0..rand(5)).map{s.sample}.join.gsub(/./){|e|c[e].sample}}}

For sample input:

c = {
    'C' => %w{r s t l n},
    'V' => %w{a e i o u}
}
s = %w{CV CVC}

This produces a sample output:

salsun
lonlutunonnus
solitlaton
rusitar
lotol
ris
relussetsa
tanotte
nasun
sur
lusin
tuslu
nerunol
sorrelussenu
ni
nanro
nulila
ritlalatiso
nururlontensa
lilas
tatsisuto
lel
rerlisletnut
ler
netlo
sorora
surot
tilsasotisi
rilnolrati
lasrare
totni
surreratlaral
li
tullatilro
rusenoreto
lulnunen
nortille
tut
sanitare
soniserloras
tiritrattitsis
ratretrate
tesne
lastinsolta
sinirsitur
lulesuleno
li
sirurata
nutesnisitur
rulunna
natneretasi
lonre
les
laruletan
nitis
tarletu
tonrora
la
senru
seltotoniles
teransotutel
re
lulsirnilletus
nunanurlon
nunlortotsonna
nolun
tolso
nas
leltirninara
neltinlesla
lulutsisot
lesulusutnis
nolu
nun
tituntillini
ralteres
sasnirosse
tutorlari
nonlelletottan
lirsetutit
so
le
setse
susritterlilu
lorrirotri
linuritlilrat
rernilnelnutel
sulolletrolo
nisatellilru
tulene
tetnan
lisotoslersor
nerlani
ne
tunoletso
nonlontaroltun
rirrostarset
sotlonsiro
net
sutona