27 June 2008

Name-generating algorithm

I've been dabbling with algorithms to generate new, fictional names for new, fictional cultures for ages. Sometimes I just goof around, sometimes I do real research and sometimes I devise implementations. I've got some code that I've been playing with today and I decided to write about what I'm doing. As you will see, the results are not yet entirely satisfying.

Check out the short wiki article on syllable theory for some basics. There's lots more to read on the web if you want to.

The first step was to build up a potential language. I selected an incomplete, base set of phonemes with which I would work:

Co: b, f, j, k, l, p, r, st, y
Cr: b, d, ph, g, h, dge, ck, ll, m, n, p, r, s, t, v, gh, z
v: a, e, ee, o, oo, u, au, ea, eu, oa, ou, ua, ue

I chose these five years ago when I was first developing a spreadsheet that would generate all the possible syllables of certain configurations. I know that limiting the raw numbers was one concern, but I frankly don't recollect why I kept which ones. It doesn't really matter and I could swap them out as desired.

(I think that Co indicates consonants used in syllabic onset and Cr indicates consonants used in the rime. Note some, but not total, overlap.)

I was writing this up today as an element in a little game that I've been messing with so that pawns would have names and personalities. Because of this context I wanted each game to have a cohesive linguistic feel. I went with those default phonemes above and then for each game-run, limited the available elements by removing roughly 50% of them at random. (Each phoneme had a 50% chance to stay or go so really weird things could occasionally happen.)

In one example (which I'll stick to through this article), the retained phonemes look like this:
Co: j, k, p, st, y
Cr: b, ph, g, h, dge, ck, ll, m, p, r, t, v
v: oo, u, ea, oa, ou

The next step is to build syllables that the language uses. I started out accumulating EVERY syllable possible of three different schemes. But that's too much because it lead to a bunch of over-similar syllables and the language ends up feeling funny. I already had a function that trimmed an array in half as described above, so I just ran them through that.

So the three kinds of syllables that I built are: VC Rime, CVC and CV. using the above-described phonemes and trimming algorithm, I created the following syllables that would be available for use in names (or other words, for more ambitious projects):

R/Rime: oob, oodge, oock, ooll, ub, uph, uh, uck, ull, up, eall, eap, ear, oab, oaph, oag, oadge, oack, oat, oav, oum, our, ouv

CoR/CVC: joodge, jooll, jup, jeall, joaph, joag, joadge, joack, joat, koob, koodge, koock, kooll, kub, kuh, kull, kup, keall, koab, koaph, koag, koack, koat, koum, kouv, poob, poodge, pub, puck, pup, pear, poab, poag, poadge, poack, poat, poav, poum, stoob, stub, stuh, stuck, stull, stup, steap, stear, stoaph, stoag, stoadge, stoack, stoat, stour, yoob, yoodge, yoock, yooll, yub, yuph, yuh, yull, yup, yeall, yeap, yoack, yoat, yoav, youm, your

CoV/CV: jea, joa, jou, ku, koa, poo, pu, poa, pou, stoo, stea, yea, yoa

Then in order to put these together to form words, I identified (some taken from literature and some made up by me) eight configurations that were reasonably likely to produce plausible word-forms. They are:

CoR 'CVC
CoV_CoR 'CV_CVC
CoV_CoV 'CV_CV
CoR_CoR 'CVC_CVC
CoR_CoV 'CVC_CV
R_CoV 'R_CV
R_CoR 'R_CVC
CoR_R 'CVC_R

In my application, I just randomly select one as the pattern to which male names will adhere and one to which female names will. using the above syllables, my app generated the following sixty names:


female names using(CoR_CoV):
koabkoa
koagstea
koatpou
stoatyoa
stuhpu
stupjoa
stulljou
koodgeyoa
poadgestoo
poabpoa
stearku
stubyoa
stoaphpu
poobkoa
kealljoa
koollpu
joatpu
poavstea
stoagjou
stullpu
joollstea
stuckkoa
yullstea
stoatpoo
koodgepoo
stearpoo
poodgejoa
stourjea
yoodgekoa
joadgestea


male names using(CoR_R):
keallup
stoageap
koackooll
joodgeoock
stulluck
kealluh
joatouv
poatoav
stearuh
joadgeoum
yoodgeouv
koockoav
puboack
joadgeoob
yoobear
jupull
joatoat
kulloaph
joackoock
youroadge
yooboag
yoodgeoav
koockup
koackup
stooboum
koumeap
kupub
joolluh
kulloav
joadgeoab


Sadly, these are really, hideous names. They do seem to share a set of sounds and rules, but a horrible one. So, clearly, I have some work to do to avoid Joadgeoum and Koodgepoo, but I'm getting there.

If anyone wants the VB.NET class that I'm using to generate this stuff, here it is:


Imports System.Text

Public Class Language
Dim rand As New Random

Public Co() As String = {"b", "f", "j", "k", "l", "p", "r", "st", "y"}
Public Cr() As String = {"b", "d", "ph", "g", "h", "dge", "ck", "ll", "m", "n", "p", "r", "s", "t", "v", "gh", "z"}
Public v() As String = {"a", "e", "ee", "o", "oo", "u", "au", "ea", "eu", "oa", "ou", "ua", "ue"}

Public R As New List(Of String) 'VC (VCr) Rimes
Public CoR As New List(Of String) 'CVC (CoVCr) Syllables
Public CoV As New List(Of String) 'CV (CoV) Syllables

Public malePattern As wordPattern = rand.Next(0, 8)
Public femalePattern As wordPattern = rand.Next(0, 8)

Public Sub New()
Co = randomHalf(Co)
Cr = randomHalf(Cr)
v = randomHalf(v)
popR()
popCoR()
popCoV()
End Sub

Public Function getName(ByVal sex As gender) As String
Dim pattern As wordPattern
If sex Then pattern = malePattern Else pattern = femalePattern
Dim sb As New StringBuilder
For Each seg As String In pattern.ToString.Split("_")
Select Case seg
Case "Co" : sb.Append(Co(rand.Next(0, Co.Length)))
Case "Cr" : sb.Append(Cr(rand.Next(0, Cr.Length)))
Case "v" : sb.Append(v(rand.Next(0, v.Length)))
Case "R" : sb.Append(R(rand.Next(0, R.Count)))
Case "CoR" : sb.Append(CoR(rand.Next(0, CoR.Count)))
Case "CoV" : sb.Append(CoV(rand.Next(0, CoV.Count)))
End Select
Next
Return sb.ToString
End Function

Private Sub popR()
For Each seg1 As String In v
For Each seg2 As String In Cr
R.Add(seg1 + seg2)
Next
Next
R = randomHalf(R)
End Sub

Private Sub popCoR()
For Each seg1 As String In Co
For Each seg2 As String In R
CoR.Add(seg1 + seg2)
Next
Next
CoR = randomHalf(CoR)
End Sub

Private Sub popCoV()
For Each seg1 As String In Co
For Each seg2 As String In v
CoV.Add(seg1 + seg2)
Next
Next
CoV = randomHalf(CoV)
End Sub

Private Function randomHalf(ByVal a() As String) As String()
Dim output As New StringBuilder
For i As Int16 = 0 To a.Length - 1
If rand.Next(0, 2) Then
If output.Length > 0 Then output.Append(",")
output.Append(a(i))
End If
Next
Return output.ToString.Split(",")
End Function

Private Function randomHalf(ByVal a As List(Of String)) As List(Of String)
Dim output As New List(Of String)
For i As Int16 = 0 To a.Count - 1
If rand.Next(0, 2) Then
output.Add(a(i))
End If
Next
Return output
End Function

End Class

Public Enum wordPattern
CoR 'CVC
CoV_CoR 'CV_CVC
CoV_CoV 'CV_CV
CoR_CoR 'CVC_CVC
CoR_CoV 'CVC_CV
R_CoV 'R_CV
R_CoR 'R_CVC
CoR_R 'CVC_R
End Enum

26 June 2008

Conservative Justices -- I choose you!

Today!

The Supreme Court of the United States, just today, decided a case in a way that, while I think it's butt-obvious, is very, very pleasing to me. Below are some highlights from their decision (some of which I've been arguing for twenty years).

The Second Amendment protects an individual right to possess a firearm unconnected with service in a militia, and to use that arm for traditionally lawful purposes, such as self-defense within the home.
Hooray!

The “militia” comprised all males physicallycapable of acting in concert for the common defense.
Ayup!

SCALIA, J., delivered the opinion of the Court, in which ROBERTS,
C. J., and KENNEDY, THOMAS, and ALITO, JJ., joined. STEVENS, J., filed a dissenting opinion, in which SOUTER, GINSBURG, and BREYER, JJ., joined. BREYER, J., filed a dissenting opinion, in which STEVENS, SOUTER, and GINSBURG, JJ., joined.
Ouch! I'm usually with the other guys. I still don't like that Alito, but Thomas seems like a good pick -- I wonder how GW pulled that off.

The Amendment’s prefatory clause announces a purpose, butdoes not limit or expand the scope of the second part, the operativeclause.
This is specifically what I've been advocating. My friend Aaaron Hunsley helped me clarify my nascent thoughts on this in the early 90s.

So this is me doing a happy dance!

24 June 2008

Our new CSA is starting slowly

When we were in Jersey, we were members of a Community Supported Agriculture farm-coop that we really liked. The fact that it was a block from the Bristol-Myers Squibb campus where I worked was great too. But when we moved to Minnesota three and a half years ago, I couldn't find one that was a reasonable distance -- Rochester is too far for fresh produce!

But a couple months ago I found myself at the Department of Agriculture web pages and noticed a link to MN CSAs and in that directory, I found a link to The Farm at Prairie Oaks Institute which is on the outskirts of Belle Plaine -- the next town down 169 from Jordan! So I inquired and found that this was their first year doing CSA and Cathy and I decided to join them. Two weeks ago we got a preliminary box with some light offerings and today I picked up our second box of goodies.



There's a nice bunch of onions and cilantro and dill and good-sized baggies of mint and marjoram and a small salad worth of mixed greens (mustard, sorel, arugula and romaine) and wee, cute samples of broccoli and kale. The produce is still slow in coming, but I figure it'll soon be bursting forth from the ground. We also got a dozen eggs.

I need to figure out what to do with the dill and marjoram -- I can always dice and freeze, but I'd rather cook. Hmmm...

Combatting obesity

So, I'm fat. Pretty fat, but not crazy fat, I think. And I shouldn't be. I know (intellectually) how not to be. I should go vegan -- eating two salads and five fruits per day and also swim for an hour. And obesity is a chronic epidemic -- spreading as the American diet spreads. I guess at some point I'll care enough about my failing health to get serious. Hopefully it won't be too late. But anyway, enough of my background regarding obesity -- I really want to talk about public policy.

Slashdot just cited new Japanese policy that will require employers to inspect waist size of employees and be fined if they are too big. My first thought was that this was a horrible invasion of privacy and personal liberty and yadda, yadda. You know what, though? Screw that! Sometimes the greater good has a cost to be paid and sometimes, a bit of personal liberty is a worthwhile expense. So, I think this would be a really stupid thing for the US to do, not because it's unjust but because it is pointless.

It would cause hostility and discrimination and enhance low self-esteem issues and further marginalize fat folks. Which isn't necessarily all bad if it would motivate people to effect positive change. But it wouldn't. See, most Americans have no clue. There are thirty popular diets at any given time -- all of them telling you (at least a little) different stuff. Not only that, but 95% of the food in the American supermarket is junk. Not just Chef Boy-R-Dee and the candy isle. Rice-a-Roni, Hamburger Helper, canned soup, all breakfast cereal, 99% of the bread, cow's milk and all meat. Everything. And, I hope it goes without saying, it is almost *literally* impossible to eat right eating out. (OK, go to Subway and get a salad -- none of the bread if nutritive and don't get any of the dressings (maybe a fat-free dressing is also devoid of carcinogenic chemicals, but I wouldn't count on it) and that's reasonably nutritive, but not particularly exciting -- it'll do in a pinch, for sure.) If you buy normal flour from the grocer and bake your own bread, it's still garbage. What if you get whole wheat flour? It's rancid and has lost much of the grain's native value. You have to grind your own and bake right then or freeze it (for not too long!).

I don't know what life is like in Japan. Are they living like this now too? It would be dumb to institute workplace fat-checks and maintain the way of life that we have built around e.g. corn syrup. It's a stupid band-aid which entirely fails to address the problem.

If the government wants to address obesity, there are things to remediate. Craft a sensible farm bill. Incentivize small family farms, (the good, permaculturish) organic methods and local farmers markets. For God's sake, how about requiring that schools stop poisoning our children! Tax fast food and give tax breaks to genuinely healthy restaurants. I'm sure there's lots of stuff.