Skip to content

Instantly share code, notes, and snippets.

@fergusq
Created October 21, 2018 20:12
Show Gist options
  • Save fergusq/302635842791f778ad800cec227baff1 to your computer and use it in GitHub Desktop.
Save fergusq/302635842791f778ad800cec227baff1 to your computer and use it in GitHub Desktop.
A script for finding Finnish rap rhymes
{
case := require("case").case
vok := "aeiouyäöå"
kon := "bcdfghjklmnpqrstvwx"
}
select l {
return l[abs(randomInteger())%#l]
}
length {
i := 0
i ++ for _
push i
}
main file {
errprint "Calculating size... "
size := 0
readLines file | orderedUniq | size ++ for _
errprint "[done]\n"
start_time := currentTime()
i := 1
rhymes := new map
seq 1, 15 | rhymes[_] = new map
readLines file |
orderedUniq |
for l do
i++
if [ i % 1000 = 0 ] do
if [ i > 100000 ] do
eta := round((currentTime()-start_time) / (i-100000) * (size-i) / 1000)
errprint "\rLine: ", i, " / ", size, " (ETA: ", eta//60, ":"
errprint "0" if [ eta%60 < 10 ]
errprint eta%60, ")"
else
errprint "\rLine: ", i, " / ", size
done
done
if [ i = 100000 ] do
start_time = currentTime()
done
k := lowerCase(l)
k ~= "([aeiouyäö])\\1+", "$1", "[^aeiouyäö]+", "-", "-$|^-", ""
continue if [ #k < 7 ]
L := #splitMany(l, sep=`(?<=[$vok$kon])(?=[$kon][$vok])|(?<=[$vok&&[^a]])(?=[a])|(?<=[$vok&&[^o]])(?=[o])|\s+`)
seq 1, 15 | for K if [ L = K ] do
k := k[-7:]
rhymes[K][k] = [] unless [ rhymes[K][k]? ]
rhymes[K][k] += l
done
done
push "\n> "
for command do
case command | pull matches, noMatch
if matches "help|h|\\?( (help|h|\\?))" do
print "Commands: help list print quit random select\nType 'help command' to get help about a command."
done
if matches "list|l" do
print "N\tL\tKEY"
keys rhymes | { keys(rhymes[L]) | [[#rhymes[L][_1], L, _1]] } for L | sort | print _1&"\t"
done
print "list|l: print a list of rhymes" if matches "(help|h|\\?) (list|l)"
if matches "(print|p) [0-9]+ [aeiouyäö\\-]+" do
args := command / " "
L := parseInteger(args[1])
print line for line in rhymes[L][args[2]]
done
print "print|p <length> <rhyme>: print a list of sentences with a given length rhyme" if matches "(help|h|\\?) (print|p)"
if matches "(select|s) [0-9]+( [0-9]+( [aeiouyäö\\-]+)?)?" do
args := command / " "
n := parseInteger(args[1])
L := parseInteger(args[2]) if [ #args >= 3 ] else select([keys(rhymes)])
rhyme := push(args[3]) if [ #args >= 4 ] else select([keys(rhymes[L])])
seq 1, n | print(select(rhymes[L][rhyme])) for _
done
print "select|s <n> [<length> [<rhyme>]]]: print n sentences" if matches "(help|h|\\?) (select|s)"
if matches "(random|r) [0-9]+" do
args := command / " "
n := parseInteger(args[1])
seq 1, 100 | for _ do
L := select([keys(rhymes)])
rhyme := select([keys(rhymes[L])])
lines := [seq(1, n) | select(rhymes[L][rhyme]) for _]
if lines | [_1[-indexOf(" ", _1[::-1])-1:]] | orderedUniq | length | [_ = n] do
lines | print _
break
done
done
done
print "random|r <n>: print n rhyming sentences" if matches "(help|h|\\?) (random|r)"
if matches "quit|q" do
return
done
print "quit|q: exit this program" if matches "(help|h|\\?) (quit|q)"
{} if matches ""
if noMatch do
print "Type 'help' to get help."
done
push "> "
done
print "quit"
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment