2009-08-25

Simplified Chemistry

I'm designing a cell simulation program. One aspect that I wanted to simulate in a simplified way was the actual chemistry of biology; respiration, photosynthesis, energy storage, enzymes, and catalysts.

For obvious reasons, actually simulating chemistry is currently impossible. But what about a mathematical approximation?

Let's fill our universe with elements... like 2, 3, 5, 7, 11, 13, etc. Elements are prime numbers, and our universe will be populated exclusively with prime numbers below 100. Molecules will be any non-element number > 1. So 42 is a compound of elements 2, 3, and 7. The obvious difference between this and chemistry is that multiplucation is commutative:

  50 = 2*5*5 = 5*2*5

But as an approximation it has obvious similarities. We can always decompose any compound into its elements by factoring it. And a compound has 'features' (visible digits) unrelated to its elements.

Next we need a rule for whether energy is gained or lost when molecules are joined or split. The rule can't strongly favor joining or splitting, or the universe will dissolve either into elements that have no interest in joining, or into massive compounds with no free elements.

My idea is the average value of the digits indicates the 'energy' of a particular number. This means that the element '3' does not join easily into compounds 9, 27, or 81... but has no problem becoming compound 243 (3^5). Similarly, the unstable compounds 9 and 27 (not naturally occurring in this universe) will easily 'burn' and join into compound 243 or split into element 3, releasing energy.

Even oxygen and hydrogen, mixed, do not burn without an initial input of energy. I'm not sure what heuristic for the triggering energy is appropriate. The triggering energy should be independent of the energy lost or gained, and like using the 'average of the digits' that indicates bond energy, it should be related to features of the number. This will allow the full range of chemical reactions: self-sustaining endothermic (cold-packs), self-sustaining exothermic (fire), and the less visible (but more common) endo- and exo- reactions that do not sustain themselves at normal temperatures.

The final requirement to simulate biological processes is the idea of catalysts and enzymes. Compounds that facilitate the joining or splitting of compounds by decreasing the triggering energy. My thought is that an enzyme matches a compound when the final digits match. How many final digits is specified by the first digit. For example, the compound 5214664 could act as an enzyme for the compound 14664. Uncertain is how to decide when the catalyst will be endothermic or exothermic (splitting the compound to release the most energy, or splitting it in the way that takes the least energy), and when a catalyst will instead encourage joining two compounts into a larger one (again, endo or exothermically). It is ok if the features that identify a catalyst are uncommon or improbable... catalysts are pretty rare in real chemistry too. Without billions of years of evolution discovering and manufacturing them, molecules that act like catalysts would be pretty uncommon.

The end result of this thought experiment would be to have a simplified chemistry model to design a cell inside. This simplified universe would not simulate form... the structure of molecules will not be simulated. Cell walls will be a mathematical construct rather than a chemical substance. The same is true for the DNA of the cells... simulating the chemical processes that copy genes is beyond the project scope.

But I can simulate everything else, in a reasonably efficient manner. Enzymes, receptors, metabolism, exo and endocytosis. The important thing from my point of view is that biological chemistry in this simulated universe can be emergent. Rather than being coded in a particular way, the metabolic processes of a simulated cell will actually metabolize... even if the metabolism is just another way of saying 'factoring'.

2008-11-05

Code Golf

I've been spending a lot of time fidding with Code Golf, a game where you take relatively easy computer problems, solve them, and then torture and maim the resulting code until it's as short as possible. Then you upload the resulting script and get scored based on how short your code is.

It's hard. Harder than it looks. For example, one of the contests is to take a list of numbers, such as '1 2 3 4 6 7 8 9 11 13 14', and output a series of ranges in the form of '1-4, 6-9, 11, 13-14.' I was able to do it with a Ruby script 89 bytes long:

$><<gets.split.inject{|s,i|$r=i.to_i-s.to_i>1?(print s,', '):(!$r&&$><<s<<'-';1);i}<<'.'

The best answer was done in 50 bytes of Perl, or 67 bytes of Ruby. My answer is already close to line noise... the code highlighter can't even make heads or tails of it. I have a hard time seeing how I would shave off an entire 22 additional bytes!

It's a fascinating process. Determining when you can skip assigning something... whether to keep the input as a string, and convert to numbers as needed, or convert them all to numbers and output strings as needed. Which is shorter? Are there completely different algorithms that would be shorter? These are fun questions if you're a programmer.

2008-10-01

Altering Map Links

While playing with Wufoo, I was impressed by how addresses automatically include a link to map it. Very convenient. It would be even more convenient if you could choose who it maps with, rather than being stuck with Yahoo.

Sadly, that option does not exist. So I decided to write my first Greasemonkey script, and make that option myself. This entailed re-learning javascript and the DOM, and the unique properties of Greasemonkey scripts. Here was my first attempt, adapted from an example in the free online book Dive Into Greasemonkey:

var allElements, thisElement;
anchors = document.evaluate(
  "//a[@title='Show a Map of this Location']",
  document,
  null,
  XPathResult.UNORDERED_NODE_SNAPSHOT_TYPE,
  null
);

for (var i = 0; i < anchors.snapshotLength; i++) {
  link = anchors.snapshotItem(i);
  link.href.match(/addr=([^&]+)\&csz=(.+)/);
  link.href = "http://maps.google.com/q?" + RegExp.$1 + ", " + RegExp.$2;
}
My first naive attempt failed because Wufoo generates links on the fly... this anchor in question does not exist yet when this script executes, just after the page finishes loading. So I needed to instead check the link right when I clicked on it. Not too difficult to adapt a different example:
document.addEventListener('click', function(event) {
  if (event.target.title == 'Show a Map of this Location') {
    event.target.href.match(/addr=([^&]+)\&csz=([^&]+)/);
    event.target.href = "http://maps.google.com/maps?q=" + RegExp.$1 + ", " + RegExp.$2;
  }
}, true);

A lot simpler! But still wrong. As an experienced javascript code monkey would know, the click event returns the most specific element it can. In the case of Wufoo's address, it returns the span containing the specific address element... <span class='region'>, or <span class='zip'>, etc. Depending on where the user clicks, they MIGHT get the anchor itself, or one of its child elements. So I need to search from the given element up until I find the anchor before altering.

The most appropriate method is to do a recursive search up. This unfortunately required me to create a global function on the window object... not very pretty, but it works:

window.myrddinFindParent = function(element,elementType) {
  if (element.tagName.toLowerCase() == elementType.toLowerCase()) {
    return element;
  } else {
    if (element.parentNode != null) {
      return window.myrddinFindParent(element.parentNode, elementType);
    } else {
      return null;
    }
  }
}

document.addEventListener('click', function(event) {
  anchor = window.myrddinFindParent(event.target, 'a');
  if (anchor != null && 'Show a Map of this Location' == anchor.title) {
    anchor.href.match(/addr=([^&]+)\&csz=([^&]+)/);
    anchor.href = "http://maps.google.com/maps?q=" + RegExp.$1 + ", " + RegExp.$2;
  }
}, true);

This, finally, works. Of course, I should mention I'm leaving out all the very noobish mistakes I made... calls to '.toLower' and '.toLowerCase' rather than the correct '.toLowerCase()'. Calls to '.parent' rather than '.parentNode'. These are the semi-working intermediates... you can fill in the dozens of versions with typos, missed semicolons, and improper names with a little imagination.

This function isn't the best either. I'd rather use an anonymous function for the recursive FindParent, but I don't know how to call an anonymous function recursively, or if it's even possible. So I pollute the global namespace slightly.

The final script, with a final tweak to prevent it from editing the same link twice, I uploaded as my first Greasemonkey script.

Go me.

2008-09-15

Welcome

You don't care about me, and I don't know you; hopefully I'll write something interesting, and you'll comment, and that will change.

I've recently been playing an older XBox game, Chromehounds. It's a good game, but it has a definite lack of polish around its interface. Specifically there are surprisingly long delays when going from menu to menu... the game is frustrating to navigate, and you need to use many menus when building your hounds (which would probably be called Mechs if FASA didn't have a trademark on that term).

Chromehounds supports in-game packs, their name for guilds or clans. Unfortunately, like nearly all games out there, they don't support any sort of persistent messaging system... no message boards, no forum. I'd like to see that kind of guild support integrated into games, because the quality of communication between members makes a huge difference in the cohesiveness of a gaming group.