<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Martin Wolf&#039;s weblog</title>
	<atom:link href="http://mwolf.net/feed/" rel="self" type="application/rss+xml" />
	<link>http://mwolf.net</link>
	<description>Software development and assorted geekery</description>
	<lastBuildDate>Sun, 07 Feb 2010 15:19:34 +0000</lastBuildDate>
	<generator>http://wordpress.org/?v=2.8.4</generator>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
			<item>
		<title>LASEK</title>
		<link>http://mwolf.net/archive/lasek/</link>
		<comments>http://mwolf.net/archive/lasek/#comments</comments>
		<pubDate>Sun, 07 Feb 2010 14:48:26 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[me]]></category>
		<category><![CDATA[lasek]]></category>
		<category><![CDATA[lasik]]></category>

		<guid isPermaLink="false">http://mwolf.net/archive/lasek/</guid>
		<description><![CDATA[This is a blog post about something which took place six months ago, so it could be considered somewhat belated. On the other hand, that gives me the opportunity to give the full story in one go, rather than just posting &#8220;well, I had the operation two hours ago and they didn&#8217;t actually blow up [...]]]></description>
			<content:encoded><![CDATA[<p>This is a blog post about something which took place six months ago, so it could be considered somewhat belated. On the other hand, that gives me the opportunity to give the full story in one go, rather than just posting &#8220;well, I had the operation two hours ago and they didn&#8217;t actually blow up my eyeball, so I guess it could have been worse, but I&#8217;m not really supposed to be staring at a computer screen just now and anyway I am doped up on painkillers so I&#8217;m leaving now, okthxbye.&#8221;<br />
<span id="more-93"></span></p>
<p>I have been wearing glasses since I was ten years old or so. My vision has been fairly constant over the years: around -4 in the left eye, -0.75 in the right. Because of the right eye being only mildly myopic, I was able to function without glasses when necessary (just don&#8217;t ask me to catch a ball) but I would get a headache after a while. Never tried contacts. I had been playing with the idea of getting laser eye surgery for some years already, but it took me a long time to work up the courage to go ahead and do it. It&#8217;s a pretty routine thing nowadays, but it is still very easy to find horror stories of people ending up with vision problems worse than they started out with, although complete blindness is fortunately very rare. I&#8217;m rather attached to my ability to see, and it was not an easy decision to risk that in exchange for the rather minor inconvenience of wearing glasses.</p>
<p>So, why did I eventually decide to go under the laser? Largely for convenience. In a lot of outdoor activities, needing glasses can be a hassle. You&#8217;re constantly swapping between regular glasses and sunglasses. They are fragile, they fog up, fall off and get scratched. Your options for finding <a href="http://www.serengeti-eyewear.com/">good-quality sunglasses</a> are greatly reduced when you need them to be prescription glasses. Snow goggles for glacier use, in particular, are almost impossible to get in combination with prescription lenses. The best I have been able to find are the Elevation and Evil Eye series from Adidas, which have room for a little clip-in set of prescription lenses. However, that clip-in tended to fog up easily and also it was not quite wide enough for my face, resulting in headaches after a while.</p>
<p>I would be lying if I did not admit that vanity also played a part. Until just a few years ago, I was your stereotypical non-athletic flabby  nerd; the beard and glasses served nicely to complete that picture. Over the last couple of years, however, I have been <a href="http://mwolf.net/archive/dam-tot-dam-2009/">running</a> and working out a bit, and while I will never have a movie star physique I am actually fairly pleased with what I see in the mirror nowadays. Hence, the aesthetic aspect of displaying my face to the world unobscured by the ophthalmic equivalent of a pair of crutches, started to play a role in a way which had never been relevant to me before.</p>
<p>I did have one big advantage over most other people considering a laser operation: because the vision in my right eye was pretty good already, I only needed the surgery in one eye. This not only meant that even in the worst-case scenario I would still have a spare eye to see through, but it was a lot cheaper as well. Without a single exception that I could find, all laser clinics seem to charge on a per-eye basis. This has always seemed a bit strange to me, because most of the procedure takes up just as much time for one eye as for two; the actual operation is only a small portion, time-wise, of the whole process. But apparently a large part of the clinic&#8217;s cost goes to the provider of the hardware, and they charge per eye lasered.</p>
<p>Prices vary a lot; typical costs in the Netherlands are between €1,000 and €2000 per eye. You can go a little below €1,000 if you go outside the country or if you really hunt for the best possible bargain, but I didn&#8217;t mind paying a little extra for peace-of-mind, so I did not even consider the foreign options. Please note, I&#8217;m not saying that foreign clinics are less competent or reliable; I have not reason to suspect that. It&#8217;s just that the whole idea of having a guy scrape away my cornea and start cutting into my iris with a laser beam, was stressful enough without the added inconveniences of travelling to another country. Eventually I selected <a href="http://www.eyescan.nl/">EyeScan</a> in Utrecht, mostly because they scored very high in a test done by the <a href="http://www.consumentenbond.nl">Dutch Consumer&#8217;s Organization</a>, and also because they offered a pretty complete set of techniques: <a href="http://en.wikipedia.org/wiki/LASEK">LASEK</a>, <a href="http://en.wikipedia.org/wiki/LASIK">LASIK</a> and <a href="http://en.wikipedia.org/wiki/IntraLASIK">IntraLASIK</a>, which gave me some extra confidence that they would honestly advise me on which option was best for me.</p>
<p>Before contacting a clinic, I did my homework pretty thoroughly. The main options for laser surgery are the three I listed in the previous paragraph. All three are identical in so far as they use a laser to reshape and thereby correct the imperfections in the lens of the eye; the difference between them lies in how part of the cornea is removed to give the laser access to the inner parts of the eye. LASIK is the most popular form used today. Basically, a cheesegrater-like microkeratome knife is used to create a little doggy-door flap in the cornea; this is then folded aside so that the laser can do its thing. IntraLASIK works the same way, except that the creation of the flap is done using a femtolaser (which is different from the laser used for the lens-correction operation itself) instead of a microkeratome blade. IntraLASIK is typically a few hundred Euros more expensive than regular LASIK. Opinions vary about its added value; clinics which have the hardware needed to offer it tend to claim that it greatly improves the quality of the result and the risk of the dreaded &#8216;halo effects&#8217; afterwards, while clinics which have not yet invested in a femtolaser will assure you that there is no proven difference and it&#8217;s the skill of the surgeon that matters.</p>
<p>The main reason for the popularity of LASIK is, I think, the &#8220;instant satisfaction&#8221; aspect of it. If all goes well, you can be enjoying your new and improved vision within a few hours of the operation, and it only gets better from there. When everything goes well there is also supposed to be very little discomfort, other than dry eyes. However, the big disadvantage of LASIK, which scared me away from it, is that the &#8220;doggy door&#8221; flap remains a weak spot on the eyeball for years afterwards. Getting hit in the eye by a blunt object is never a good idea, but when that eye has been the recipient of a LASIK operation in the past, the consequences can be really nasty. Also, from what I learned most of the unwanted side-effects of a LASIK operation did not come from the actual laser surgery, but from the flap not falling nicely back into place or otherwise causing trouble. The main problem seems to be that, unlike most parts of the human body, the cornea does not really have the ability to heal damage sustained as an adult. The flap eventually gets fixed into place because the <a href="http://en.wikipedia.org/wiki/Corneal_epithelium">epithelium</a> grows back over it, but the cuts that were made into the cornea itself may never fully heal, and neither will the nerves that ran through it.</p>
<p>Therefore, I decided to go with LASEK instead. LASEK, also called PRK, is the older approach to giving the laser access to the lens. Instead of cutting into the cornea, the surgeon scrapes away the epithelium. The epithelium is the uppermost layer of the cornea and it does have the ability to regenerate cleanly after being damaged. The main disadvantage of LASEK over LASIK, and probably the reason why the latter is more popular nowadays, is that the initial recovery period is a lot longer and more painful. With LASEK, the patient is recommended to take a week off in order to recover; with LASIK if all goes well you can be back in the office after a day or two. However, the risk of side effects is lower and after the initial recovery period the eye should heal so completely that after some months, even an ophthalmologist may have trouble seeing evidence that an operation ever took place. An illustrative incident is that when I had made the appointment for the operation with EyeScan, I was sent home with the legal forms for both types of operation; the list of potential complications for LASIK was three times as long as the one for LASEK!</p>
<p>There is also <a href="http://en.wikipedia.org/wiki/EPI-LASIK">Epi-LASIK</a>, which is the obvious combination of the two ideas: as with LASIK, the surgeon uses a &#8216;cheesegrater&#8217; microkeratome or a femto-laser to cut a flap out of the cornea, but as with LASEK he only cuts as deep as the epithelium and does not cut into the deeper layers of the cornea that do not have the ability to regenerate. However, EyeScan did not offer that option (yet) when I had the operation.</p>
<p>One other choice to be made was between regular and <a href="http://en.wikipedia.org/wiki/Lasik#Wavefront-guided_LASIK">wavefront-guided</a> laser correction. EyeScan calls this &#8220;Superior / CustomVue&#8221;, other laser clinics have their own marketing terms, and all of them try to suggest that they have some extra-special technique for giving you a better result than you&#8217;d get from their competitors. What it comes down to is that instead of just re-shaping your lens from e.g. -4 to approximately 0, the laser is programmed to apply specific corrections to carefully measured local aberrations in the lens, thereby achieving the optimal result for your eye instead of applying a one-size-fits-all approach. Most clinics offer something like this next to their standard offer nowadays, at a higher price of course, and they all suggest that it will give you a more perfect vision, although at the same time they also keep their standard disclaimer that the results can vary and you are not even guaranteed not to need glasses anymore. To be honest, it seems a bit fishy to me: the way I envision it is that there is a little switch on the laser machine, with settings labeled &#8220;decent quality&#8221; and &#8220;extra good quality&#8221;, and the surgeon charges several hundred € for putting the switch to the &#8220;extra quality&#8221; setting, even though it&#8217;s the same machine! It&#8217;s a textbook case of <a href="http://www.joelonsoftware.com/articles/CamelsandRubberDuckies.html">market segmentation</a>, of course: charging more money to people who can afford it, for basically the same service, by putting some extra features only in the more expensive version of the product, even though they cost you nothing extra to produce. How much did I really get for that extra money? I will never know for sure, but I would rather live with the vague feeling that maybe I got ripped off just a little bit, than spend the rest of my life wondering if my vision would have been better if I had checked the &#8220;wavefront-guided&#8221; box. So I paid up, and would pay up again if I had to, even though there is that niggling feeling that I am being played. Hopefully, in the future wavefront-guided will just be the standard, and the inferior option won&#8217;t even be offered anymore.</p>
<p>I had the operation on July 9, 2009. My parents drove me to the clinic and there was a brief, last check-up to make sure that my eyes still matched the measurements that were taken a few weeks earlier. Then there was a brief conversation with the eye surgeon, I was dressed in sterile clothing, and walked into the operation room. As is the case with most private clinics as I understand it, EyeScan is not connected to a hospital, so the operation room is simply a converted room in an otherwise ordinary office building. I was told to lie down, and a variety of different kinds of eye-drops were applied. One of them was a topical anaesthetic; other than that no anaesthesia was used so I was fully conscious during the operation. Then, the surgeon used a scalpel to move aside the epithelium, which looks <em>really</em> weird when you&#8217;re looking up at it from underneath!</p>
<p>After that preparation, the actual laser surgery was pretty much an anti-climax: all I had to do was stare at a blinking yellow light for a minute or so. There was no feeling, no way to confirm that anything was happening. Afterwards, a temporary lens was placed onto my eye to protect the lens while the epithelium was growing back, to be removed three days later. Then, I got up and was given a cocktail of painkillers with instructions on how to use them, plus a set of protective goggles to wear at night to keep myself from subconsciously rubbing my eyes. The surgeon and his two assistants were very professional and businesslike during the whole process, except that during the surgery they were having a conversation about some minor problem which worried me a bit, but which I was told afterwards was not about my case. Apparently, the surgeon is not employed full-time by the clinic but works at a hospital or something and is hired by EyeScan for a couple of days per week.</p>
<p>Immediately after the operation, my vision was already noticeably improved! Unfortunately that didn&#8217;t last, as things got blurry during the week after the operation. In hindsight, this was not surprising: at that point there was basically no epithelium at all obstructing my vision, so I had a very clear view but was at a hightened risk of UV damage from the sun. For the first two months or so after the operation, I was instructed to wear dark sunglasses whenever I went outside, even on cloudy days. I was also somewhat extra light-sensitive during the first weeks, but it wasn&#8217;t very bad &#8212; apparently some people can be very affected by this, to the point where they have to live in a completely darkened room for the first several days. Anyway, that period of clear vision immediately after the operation did not last; as the epithelium was growing back it formed some &#8217;scar tissue&#8217; which took a while to clear up again, so for a week or so my vision got worse than it was before, after which it slowly got better again.</p>
<p>Next to the painkillers, I was also given a large collection of eye-drops: a large amount of &#8216;comfort drops&#8217; to keep the eye moistened, which I had to use for the first two months and then gradually wean myself off, and some antibiotics to prevent inflammation during the healing process. Unfortunately, I turned out to be allergic to the preservative used in those eye-drops, and that allergy caused extra inflammation of my eyes and the skin around it. This is apparently a fairly common problem, but it was not noticed on my first check-up visit four days after the operation. So during the first week, whenever I used those drops I was actually making the situation worse! Fortunately, once the problem was diagnosed and I was given a preservative-free alternative, things started to improve quickly. I had taken a week of vacation following the operation; after that week I was able to go back to work, although the vision in my left eye was still far from perfect. I am glad that I still had my untreated right eye to look through, otherwise I would have been unable to work for another week or so.</p>
<p>Somewhere between two and three weeks after the operation, the vision in my left eye was roughly comparable to that in my right: hardly perfect, but good enough to get around without needing glasses. From there on, it slowly but gradually kept improving. I had several check-up meetings with EyeScan during the first half year, at increasing intervals, and was surprised to notice that even between the three-month and six-month check-up there was still a noticeable improvement. I think part of it was not so much the healing of my eye, but had more to do with my brain having to learn to deal with the changed situation. For example, initially it often happened that when I tried to make out some fine detail in the distance, I could improve the clarity by closing my right eye &#8212; apparently my brain was not yet used to the fact that suddenly, after more than 30 years, my left eye was now the better one for distance use! But I don&#8217;t seem to have that problem anymore.</p>
<p>So, how did I end up? Very well! On my last check-up, I scored a very pleasing 150% acuity in my left eye, with 100% apparently being a somewhat arbitrary reference point meaning &#8220;normal sight&#8221;. And indeed, I get around perfectly well without glasses, for close-up reading and computer work as well as making out small details in the distance. The fact that my right eye is still less than perfect, does not seem to hinder me in any way that I have noticed.</p>
<p>The only remaining side effect is that my eye is still sometimes more dry than it should be, especially when waking up in the morning. This can be painful when there is a piece of dirt in my eye but I am not producing enough tear fluid to get rid of it. I knew in advance that this was the most common side effect of laser surgery; it can take a long time to go away and can even be permanent to some degree. Fortunately, at its current level it is a fairly minor annoyance rather than a problem. Apart from that, I am very happy that I took the plunge, and if I had to make the same decision again I would definitely go with LASEK again.</p>
<div class="zemanta-pixie"><img class="zemanta-pixie-img" src="http://img.zemanta.com/pixy.gif?x-id=dbd159d1-499c-818e-812d-935389368711" alt="" /></div>
]]></content:encoded>
			<wfw:commentRss>http://mwolf.net/archive/lasek/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>The Betrayal of the Spirit</title>
		<link>http://mwolf.net/archive/betrayal-of-spirit/</link>
		<comments>http://mwolf.net/archive/betrayal-of-spirit/#comments</comments>
		<pubDate>Sat, 30 Jan 2010 09:20:33 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[misc]]></category>
		<category><![CDATA[science]]></category>
		<category><![CDATA[mars]]></category>
		<category><![CDATA[nasa]]></category>
		<category><![CDATA[spirit rover]]></category>
		<category><![CDATA[webcomic]]></category>
		<category><![CDATA[xkcd]]></category>

		<guid isPermaLink="false">http://mwolf.net/?p=90</guid>
		<description><![CDATA[I don&#8217;t normally like to do &#8220;link blogging&#8221; &#8212; I&#8217;d rather post nothing at all for several months (which frequently happens) than just copy someone else&#8217;s work. But I&#8217;ll make an exception for this XKCD strip. I think it actually brought a tear to my eye.



]]></description>
			<content:encoded><![CDATA[<p>I don&#8217;t normally like to do &#8220;link blogging&#8221; &#8212; I&#8217;d rather post nothing at all for several months (which frequently happens) than just copy someone else&#8217;s work. But I&#8217;ll make an exception for <a href="http://xkcd.com/695/">this XKCD strip</a>. I think it actually brought a tear to my eye.</p>
<p><span id="more-90"></span></p>
<p><img style="max-width: 800px;" src="http://imgs.xkcd.com/comics/spirit.png" alt="" /></p>
<div class="zemanta-pixie"><img class="zemanta-pixie-img" src="http://img.zemanta.com/pixy.gif?x-id=26c00018-e157-8f46-9542-67f1d0edca2c" alt="" /></div>
]]></content:encoded>
			<wfw:commentRss>http://mwolf.net/archive/betrayal-of-spirit/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Scripting Excel: can it really be this horrible?</title>
		<link>http://mwolf.net/archive/vba-sucks/</link>
		<comments>http://mwolf.net/archive/vba-sucks/#comments</comments>
		<pubDate>Sun, 27 Dec 2009 18:58:13 +0000</pubDate>
		<dc:creator>martin</dc:creator>
				<category><![CDATA[hacks]]></category>
		<category><![CDATA[excel]]></category>
		<category><![CDATA[microsoft]]></category>
		<category><![CDATA[vba]]></category>

		<guid isPermaLink="false">http://mwolf.net/archive/vba-sucks/</guid>
		<description><![CDATA[OK, I have managed to avoid this for a long time, but I guess it was inevitable: here comes Martin&#8217;s cheap, nonconstructively sarcastic I-hate-Microsoft post.
So I was visiting my parents this week-end, and my Dad asked me to help him with a little macro job on an Excel spreadsheet. It sounded simple enough. However, I [...]]]></description>
			<content:encoded><![CDATA[<p>OK, I have managed to avoid this for a long time, but I guess it was inevitable: here comes Martin&#8217;s cheap, nonconstructively sarcastic I-hate-Microsoft post.</p>
<p>So I was visiting my parents this week-end, and my Dad asked me to help him with a little macro job on an Excel spreadsheet. It sounded simple enough. However, I had forgotten just how astonishingly horrible <a href="http://msdn.microsoft.com/en-us/isv/bb190538.aspx">Visual Basic For Applications</a>, the sorry excuse for a programming language built into Excel (and the other Office applications), can be.</p>
<p>As far as I remember, the last time I did anything with VBA was probably somewhere in the late nineties. Even by the standards of back then, VBA is a really shitty programming language. By the standards of 2009, it&#8217;s spectacularly bad. The only explanation I can think of is that somewhere high up in Microsoft Strategic Command, somebody decided to spend a lot of effort on making it as useless and infuriating as possible, while still keeping it just barely functional enough to be able to do the things you want to do with it, if you&#8217;re willing to go through a lot of pain. God only knows <em>why</em> they made that decision, but surely a language as bad as this cannot be created by accident.<br />
<!-- more --><span id="more-83"></span>What surprised me most is that it was still exactly as bad as I remembered. We&#8217;re talking about Office 2007 here, the all-new singing and dancing one with the cool magic fluffy ribbons and shit. Surely they could have made some minor improvements to the scripting language while they were hard at work at hiding the &#8216;File&#8217; menu behind a big round decorative window-corner ornament? In fact, I would have expected them to have simply integrated the .NET framework into Office by now, so that you could write your Excel macros into <a href="http://en.wikipedia.org/wiki/F_Sharp_%28programming_language%29" target="_self">F#</a> if you felt like it?</p>
<p>Apparently, that is not the case. The language is still filled with lots of little inconvenience such as the fact that, where every other programming language on Earth lets you return a value from a function by doing something like</p>
<blockquote>
<div><strong>def</strong> thisFunctionReturnsThree()<br />
&nbsp;&nbsp;&nbsp;&nbsp;<strong>return</strong> 3<br />
<strong>end</strong></div>
</blockquote>
<p>VBA, for reasons which I&#8217;m sure seemed like a good idea to somebody at some point, expect you to do it like this:</p>
<blockquote><p><strong>Function</strong> ThisFunctionReturnsThree()<br />
&nbsp;&nbsp;&nbsp;&nbsp;ThisFunctionReturnsThree = 3<br />
&nbsp;&nbsp;&nbsp;&nbsp;<strong>Exit</strong> <strong>Function</strong><br />
<strong>End</strong> <strong>Function</strong></p></blockquote>
<p>But minor inconveniences like that are just a scratch on a gaping shotgun wound. Where VBA <em>really</em> starts driving the red-hot splinters of aggravation under your fingernails, is when you try to use the Collection object. The VBA Collection is some kind of schizophrenic bastard datatype with a horrible identity crisis, which can never quite decide whether it wants to be a fancy-schmancy associative array (a.k.a. <em>hash</em> or <em>map</em>, for those of my readers who are used to non-braindead programming environments) or just an ordinary variable-sized array. Anyway, back in 1997 or whatever, the Collection type supported a grand total of four methods:</p>
<blockquote><p>Add<br />
Remove<br />
Count<br />
Item</p></blockquote>
<p>And here in 2009, it still supports the same four methods! Note that there is no way to enumerate all the keys in the collection (when using it as a hash), nor is there a way to ask the collection object if it contains a given value (when using it as a resizeable array). Doing <em>myCollection.Item(&#8221;foo&#8221;) </em>will throw an error if <em>foo</em> is not present in the collection. So there is no way, at least without grossly abusing the exception-catching mechanism as a flow control technique, which is evil, to access a value of which you are not certain whether it exists.</p>
<p>Nor does VBA seem to natively offer any more powerful container types. The standard trick, apparently, is to bring in the <a href="http://msdn.microsoft.com/en-us/library/x4k5wbx4%28VS.85%29.aspx">Scripting.Dictionary</a> from the Windows Scripting Library, which is not a standard part of either VBA or MS Office, but which can kinda-sorta generally be expected to probably be present on most Windows systems which have been installed and occasionally updated during the past five years. (The ones which have not been regularly updated are, of course, so bogged down with malware by now that there won&#8217;t be any CPU power left to run Excel anyway, so no need to worry about them.) Scripting.Dictionary is hardly the equal of, say, <a href="http://ruby-doc.org/ruby-1.9/classes/Hash.html">the <em>Hash</em> class from Ruby&#8217;s standard library</a>, but at least it has a <em>contains</em> method and it allows you to enumerate its keys and values. Welcome to the 1990&#8217;s, Microsoft!</p>
<p>By the way, have I already mentioned that VBA, again unlike every other programming language invented after the death of Blaise Pascal, does not do lazy evaluation on Boolean expressions? So if you want to write something along the lines of, say</p>
<blockquote><p><strong>If</strong> myDict.Contains(&#8221;foo&#8221;) <strong>And</strong> myDict(&#8221;foo&#8221;) = &#8220;bar&#8221; <strong>Then</strong><br />
&nbsp;&nbsp;&nbsp;&nbsp;&#8217; Do something cool<br />
<strong>Else</strong><br />
&nbsp;&nbsp;&nbsp;&nbsp;&#8217; Do something not-quite-as-cool<br />
<strong>End</strong> <strong>If</strong></p></blockquote>
<p>then your code will break because, after having cleverly determined that <em>myDictionary</em> does not contain an item named &#8220;foo&#8221;, VBA will then shrewdly try to access it anyway, and promply die.</p>
<p>Oh, and neither Collection nor Dictionary has a built-in ability to sort its contents. If you search for e.g. &#8220;vba sort container&#8221; you will find a lot of people who have helpfully written their own functions to perform this rather basic task.</p>
<p>We did eventually get my Dad&#8217;s spreadsheet to do what we wanted it to. I&#8217;d estimate that I spent about 10% of that time on actually writing the functionality we were after, and the other 90% of the time swearing at the absurd, arbitrary limitations of VBA and trying to come up with stupid workarounds for things which should be absolutely trivial, and which <em>would</em> be absolutely trivial in any other language, and which anybody who wants to write a non-trivial piece of code is going to need so why isn&#8217;t it present by default in this supposedly mature product? Gah.</p>
<p>Now, it is very possible, even quite likely, that many of the things I ran up against were simply a result of my unfamiliarity with the programming environment. I am more than happy to admit that I am not an Excel guru or a VBA guru. Probably then, there are much better solutions to each of the problems mentioned above. Please feel free to teach me about them and laugh at my ignorance!</p>
<p>However, I do know how to use Google, and what I found were not solutions but just a lot of other people having the same problems and complaining about how incredibly limited the language is. So, Microsoft, could we perhaps ask you to take perhaps one-half of a developer off the task of making Office 2010&#8217;s ribbons even sparklier, and bringing the facilities of VBA up to the level of an average scripting language from ten years ago? Thanks in advance.</p>
<div class="zemanta-pixie"><img class="zemanta-pixie-img" src="http://img.zemanta.com/pixy.gif?x-id=b085ed89-44da-8b79-a671-214213b15383" alt="" /></div>
]]></content:encoded>
			<wfw:commentRss>http://mwolf.net/archive/vba-sucks/feed/</wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
		<item>
		<title>Paying with bits</title>
		<link>http://mwolf.net/archive/paying-with-bits/</link>
		<comments>http://mwolf.net/archive/paying-with-bits/#comments</comments>
		<pubDate>Mon, 14 Dec 2009 21:52:40 +0000</pubDate>
		<dc:creator>martin</dc:creator>
				<category><![CDATA[algorithms]]></category>
		<category><![CDATA[security]]></category>

		<guid isPermaLink="false">http://mwolf.net/archive/paying-with-bits/</guid>
		<description><![CDATA[In the course of a friendly discussion with Dirk-Jan, I&#8217;ve been reading up on the miracles of digital cash.
And by digital cash, I do not mean lame stuff like Paypal, which is basically just an ordinary bank account to which you can send transfer orders. No, what I&#8217;m interested in is the real heavy stuff, [...]]]></description>
			<content:encoded><![CDATA[<p>In the course of a friendly discussion with <a href="http://www.djcbsoftware.nl/ChangeLog/" target="_blank">Dirk-Jan</a>, I&#8217;ve been reading up on the miracles of digital cash.</p>
<p>And by digital cash, I do not mean lame stuff like <a href="http://paypal.com/" target="_blank">Paypal</a>, which is basically just an ordinary bank account to which you can send transfer orders. No, what I&#8217;m interested in is the real heavy stuff, whereby you have a digital wallet full of cryptographic &#8220;coins&#8221; which can be transfered from one party to another, without a single central entity keeping track of the contents of your wallet. Ideally, you want to be able to transfer such coins even off-line, without the central entity needing to be involved with every individual transfer.</p>
<p>There are a couple of basic problems with the idea of using bits as money, which any &#8220;crypto cash&#8221; system will need to find solutions for.<br />
<!-- more --><span id="more-78"></span></p>
<p>Probably the biggest one is non-technical: the fact that governments really hate it when you propose something like an untraceable, anonymous and decentralized currency which is not under their control. Ask Douglas Jackson, founder of E-Gold, who in <a href="http://www.wired.com/threatlevel/2009/06/e-gold/" target="_blank">this Wired article</a> is painted as a naive but basically well-intentioned and idealistic guy who tried to create a currency for the twenty-first century but who ran afoul of a whole lot of government objections. But let&#8217;s ignore the political angle for now, and look into the technical obstacles.</p>
<p>The first technical problem is obvious: if my coins are just strings of bits, what is preventing me from spending a single coin multiple times, or minting my own coins?</p>
<p>And then there is an issue which is somewhere mid-way between technical and legal/practical: where does the money get its value from? Here in the real world, it used to be that money was backed by gold or silver: in theory, you could take your bank note to the bank and they would exchange it for a little sliver of precious metal. Nowadays, pretty much all money is fiat currency: it has value because the government says it has value, which works as long as we all believe that it does. The latter is a bit less intellectually satisfying than the former, but it does raise the interesting question of whether you could create a working fiat currency from scratch, without being backed by any government or central trusted organization.</p>
<p>When it comes to sophisticated cryptographic techniques for digital money, the work of <a href="http://en.wikipedia.org/wiki/David_Chaum" target="_blank">David Chaum</a> is the acknowledged gold standard (sorry). His digital money is a brilliant combination of pretty much all of the most advanced techniques in cryptography: blind signatures, commitment schemes, zero-knowledge proofs and lots more. Particularly brilliant is his solution to the &#8220;double spending problem&#8221; mentioned above. In his approach, people cryptographically sign digital money orders with their name when they receive them from the bank, but they sign them in such a way that the information can only be retrieved when a money order is spent twice. The spending (which can be done off-line) will succeed, but when the bank receives the same &#8220;coin&#8221; back through two different channels, it will not only know that cheating has occurred, but it can retrieve the name of the cheater! However, as long as you spend each coin only once, your anonymity is safe from the bank as well as from the people you exchange money with, even if they all work together!</p>
<p>Chaum&#8217;s work requires some seriously advanced crypto, though. In the book <a href="http://www.daviddfriedman.com/Future_Imperfect.html" target="_blank">Future Imperfect</a> from my favourite author David Friedman, there is an <a href="http://www.daviddfriedman.com/Future_Imperfect/Chapter6.html" target="_blank">alternative scheme</a> which is a lot less sophisticated, but just as elegant in its impressive simplicity. Here is the entire system:</p>
<ol>
<li>The bank gives out coins, which are simply large randomly-generated numbers.</li>
<li>When you receive a coin, you immediately send an (anonymous, encrypted) message to the bank, requesting that the coin&#8217;s number be changed to a different random value generated by you. You include a transaction code which is another random number.</li>
<li>If the bank can indeed find the original number in its database, it exchanges it for your new number, and publishes the transaction code in a public place so that you can verify that the coin you were given did indeed exist, and has been assigned the new number which only you know.</li>
<li>When you walk into the bank and present them with the new number, they will exchange it for, say, an amount of gold matching the value of the coin.</li>
</ol>
<p>That&#8217;s all!</p>
<p>It&#8217;s not quite as secure as Chaum&#8217;s system in all directions. The system can be used off-line, but only if the payee trusts the payer to give him a real coin. The bank cannot breach your anonymity, but it can cheat by refusing to honour a valid coin. Even in the case of an on-line transaction, if the payee claims that the payer did not give him a valid coin, there is no way for an outsider to determine which of the two is telling the truth. But within these limitations, the basic functionality works and it&#8217;s a rather impressive achievement for a system which is so trivially simple that you could explain it to your ten-year-old nephew.</p>
<p>If you&#8217;re looking for a nice little intellectual challenge, think about Friedman&#8217;s proposal a little further. Identify the various practical problems with it, and see if you can come up with a solution for each of them, using basic crypto techniques such as symmetric and asymmetric encryption, digital signatures and secure hash codes.</p>
<p>Now, in the above approaches, the assumption is that there is still a central bank, trusted by all parties, which gives out the money and which gives that money its value by pledging to exchange it for some real-world valuable material such as gold, or perhaps simply by linking it to an ordinary bank account containing ordinary government-backed euros or dollars.</p>
<p><a href="http://www.bitcoin.org/sites/default/files/bitcoin.pdf" target="_blank">Bitcoin</a> goes even further: it proposes (there exists a technical implementation, but they&#8217;re not really pretending that it&#8217;s ready for real-world use) a form of digital money which is completely decentralized: there is no central entity, anybody can create money and then spend it. As the FAQ explains it:</p>
<blockquote><p>What is Bitcoinâ€™s value backed by?</p>
<p>Bitcoin is valued for the things it can be exchanged to, just like all the traditional paper currencies are.</p>
<p>When the first user publicly announces that he will make a pizza for anyone who gives him enough Bitcoins, then he can use Bitcoins as payment to some extent &#8211; as much as people want pizza and trust his announcement. A pizza-eating hairdresser who trusts him as a friend might then announce that she starts accepting Bitcoins as payment for fancy haircuts, and the value of the Bitcoin would be higher &#8211; now it would be backed by pizzas &#8221;and&#8221; haircuts. When Bitcoins have become accepted widely enough, he could retire from his pizza business and still be able to use his Bitcoin-savings.</p></blockquote>
<p>That seems to make sense &#8212; money is basically a system of transferable IOUs whereby the participants agree to cover each other&#8217;s debts. However, if anybody can create Bitcoins and spend them anonymously, how can they ever be made to make good on their debts? And even without anonymity, what prevents me from creating more Bitcoins than I will ever be able to honour and then living like a king until the day of my death? Somewhere, it seems, there has to be a mechanism to create some artificial scarcity in order for the scheme to work.</p>
<p>Bitcoins proposes to solve this problem by making each coin represent a <a href="http://en.wikipedia.org/wiki/Proof_of_work" target="_blank">proof of work</a>: creating a Bitcoin requires a large amount of CPU power; anybody who receives a coin from you can verify that you have performed a very complex and time-consuming calculation. Coins are linked together and there is a peer-to-peer system to verify that coins are not being double-spent. As with Friedman&#8217;s approach, you can accept coins off-line if you want but then you will need to trust the payer to not deliberately cheat on you.</p>
<p>This way, the amount of Bitcoins in the economy is limited and grows predictably, which are two very important requirements for a usable currency. Using CPU power to back the money&#8217;s value is of course completely arbitrary, but in principle that is not an impediment for a working currency. As with a conventional fiat currency, once the pool of people willing to accept the money is large enough, it is resistant to occasional cheaters; anybody who refuses to play along is hurting themselves more than they are hurting the people who partake in the system. Obviously, getting to that point is the difficult part.</p>
<p>By the way, if you think that the above schemes are not secure enough to work in practice, what would you think of the following system?</p>
<ul>
<li>Your bank account is represented by a single sixteen-digit number, which remains the same for several years.</li>
<li>Anybody who knows this number can use it to withdraw money from your bank account.</li>
<li>Making a payment consists of giving the number to the person you want to pay. So if you want to purchase something at a gas station, for example, you show a card with the number to the gas station attendant, after which he knows your number and you will have to trust him not to abuse it.</li>
</ul>
<p>That must be the most horrible system anybody could possibly come up with, right? If you proposed this in an introductory computer security class for high-schoolers, your classmates would laugh you out of the room. Nobody with an ounce of common sense would every use such a horribly botched system for <em>anything</em>, let alone for making payments over the Internet, right?</p>
<p>And yet what I am describing here is, of course, the humble credit card.</p>
<p>I do not expect any of the cryptographic systems described above to become popular any time soon. But the most likely reason for their failure will be a combination of chicken-and-egg effect (nobody wants to use a currency which nobody else uses) and the first, non-technical problem mentioned at the start of this article. Nonetheless, it is awfully cool to consider what is possible in principle, and a good mental exercise to consider the various practical objections and try to come up with solutions to them.<br />
<a class="performancingtags" rel="tag" href="http://technorati.com/tag/david%20friedman"><br />
</a></p>
<div class="zemanta-pixie"><img class="zemanta-pixie-img" src="http://img.zemanta.com/pixy.gif?x-id=0bfda2a3-9717-8e43-97d5-80b05be56cac" alt="" /></div>
]]></content:encoded>
			<wfw:commentRss>http://mwolf.net/archive/paying-with-bits/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>I&#8217;m a runner!</title>
		<link>http://mwolf.net/archive/dam-tot-dam-2009/</link>
		<comments>http://mwolf.net/archive/dam-tot-dam-2009/#comments</comments>
		<pubDate>Sun, 20 Sep 2009 19:04:06 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[me]]></category>
		<category><![CDATA[running]]></category>
		<category><![CDATA[dam-tot-dam loop]]></category>

		<guid isPermaLink="false">http://mwolf.net/?p=75</guid>
		<description><![CDATA[Today was the day of the 25th Dam-tot-Dam-loop, a 16.1km running event from Amsterdam to Zaandam. Yours truly was one of the 35,000 people who signed up for the event, and one of the 17,614 people who made it to the finish line!
Even though, in the eyes of real hard-core marathon runners, 16km is no [...]]]></description>
			<content:encoded><![CDATA[<p>Today was the day of the 25th <a href="http://www.damloop.nl">Dam-tot-Dam-loop</a>, a 16.1km running event from Amsterdam to Zaandam. Yours truly was one of the 35,000 people who signed up for the event, and one of the 17,614 people who made it to the finish line!<span id="more-75"></span></p>
<p>Even though, in the eyes of <a href="http://www.djcbsoftware.nl/ChangeLog/">real hard-core marathon runners</a>, 16km is no big deal, I&#8217;m quite proud and excited about this, as it was my first participation in an organized running event ever. Or my first 16.1km run at all, for that matter. I started running somewhere in the beginning of 2008, so this was kind of like an exam for myself.</p>
<p>Speaking of organized events, the organization was excellent as far as I could see, despite the unprecedented number of participants in this 25th year of the Dam-tot-Dam. Dealing with thirty-five thousand runners plus an enormous number of onlookers is no small challenge, but at least as far as I am concerned everything was prepared perfectly: bags were transported to the finish area (unlike most runs the Dam-tot-Dam is not a loop: you don&#8217;t finish anywhere near the starting point), there were water and first-aid stands everywhere along the route, etc. Unfortunately, despite the best efforts of the medical personnel, one person died of a fatal heart attack a few kilometers before the finish line.</p>
<p>Thanks to the wonders of modern surveillance technology (specifically, an RFID chip tied to every runner&#8217;s shoelace) my progress has been tracked in <a href="http://evenementen.uitslagen.nl/2009/damloop/details.php?t=&amp;s=24213">excruciating detail</a>. Most interesting is of course my total time for the whole run: 1:34:20, which comes out to an average speed of 10.2 km/h. Not quite up there with the panthenon of running gods, but a perfectly respectable time for a first-timer, if I do say so myself.</p>
<p>I&#8217;m glad it went as well as it did, since I&#8217;ve been battling a pretty heavy cold for the past week and it was by no means over yet today. But during the actual run, I didn&#8217;t seem to be too bothered by that &#8212; probably the adrenaline doing its work. Immediately afterwards, however, the hammer fell; my lungs felt as if a host of insects had taken up inside them, and I was limping so badly that the steps of Zaandam Station seemed to be as big a challenge as the run itself. Well, OK, not <em>that</em> bad. But it didn&#8217;t matter, because I was wearing around my neck the medal proclaiming that I&#8217;m officially a runner now! I just hope that my <a href="http://www.copacabanarunners.net/i-immune-system.html">immune system</a> is not going to punish me too badly over the coming weeks, for dumping so much abuse on it in its already weakened state..</p>
<p>I&#8217;m going to take it easy for the next week or so, but there&#8217;s definitely going to be a follow-up on this if I have anything to say about it! Perhaps next year&#8217;s Dam-tot-Dam, and see if I can get my time down towards 1:25 or so? Or maybe a half marathon? Three years ago, nobody among my aquaintances, least of all myself, would have predicted that I would ever take part in a long-distance running event. But with 16km in the bag, suddenly 22km does not seem quite as utterly impossible anymore as it once did..</p>
]]></content:encoded>
			<wfw:commentRss>http://mwolf.net/archive/dam-tot-dam-2009/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>FritzBox!</title>
		<link>http://mwolf.net/archive/fritzbox-rocks/</link>
		<comments>http://mwolf.net/archive/fritzbox-rocks/#comments</comments>
		<pubDate>Tue, 23 Jun 2009 20:30:41 +0000</pubDate>
		<dc:creator>martin</dc:creator>
				<category><![CDATA[cool-tool]]></category>
		<category><![CDATA[linux]]></category>
		<category><![CDATA[automatic update]]></category>
		<category><![CDATA[fritzbox]]></category>
		<category><![CDATA[privacy]]></category>
		<category><![CDATA[speedtouch]]></category>
		<category><![CDATA[voip]]></category>
		<category><![CDATA[xs4all]]></category>

		<guid isPermaLink="false">http://mwolf.net/?p=71</guid>
		<description><![CDATA[The AVM FritzBox is really cool and it certainly beats the hell out of my Thompson Speedtouch. But what about that suspicous "permit [remote] automatic updates" option which I am not allowed to disable?]]></description>
			<content:encoded><![CDATA[<p>Wow!</p>
<p>I received my <a href="http://www.fritzbox.eu/en/index.php">FritzBox</a> 7170 today, as a present from XS4ALL for renewing my ADSL subscription for another year (cheap deal &#8212; I would have done that anyway). And it totally blows away my Thompson Speedtouch!</p>
<p><span id="more-71"></span></p>
<p>As regular readers of this blog may remember, the Speedtouch doesn&#8217;t properly support the &#8220;exposed host&#8221; feature, whereby all incoming traffic on any port is redirected to a single machine on the internal network, in combination with Voice Over IP. I eventually came up with a <a href="http://mwolf.net/archive/voip-on-speedtouch/">really crappy workaround</a> for that, but it never really worked nicely. Also, I never quite managed to explain to the Speedtouch that when a machine on the internal network tried to access 82.95.250.5, it should be sent to the internal address of my server, rather than get stuck in a loop trying to forward traffic to itself.</p>
<p>Well, the FritzBox didn&#8217;t have either of these problems. Port forwarding was just a few mouse-clicks away, and configuring VOIP in combination with that was trivially easy. Despite the fact that the router seems to have much more options than my Speedtouch (in &#8216;Expert mode&#8217;, at least), it is much easier to configure thanks to the well-organized menu structure.</p>
<p>So now I have it setup exactly the way I want it: all external traffic gets forwarder to my Linux server at 10.0.0.1, VOIP is handled by the FritzBox (I can even connect my ISDN modem to it!) and when a machine on the WLAN wants to access mwolf.net, it gets sent to 10.0.0.1 as it should. I couldn&#8217;t be happier.</p>
<p>Except.. There is one setting in the menu which worries me a bit. On the &#8220;Provider Services&#8221; tab of the &#8220;Network&#8221; menu, there is an option called &#8220;Permit automatic updates&#8221; which apparently allows my service provider to change the device&#8217;s settings without having to ask my permission. This setting is enabled and the checkbox is greyed-out so that I cannot disable it:</p>
<div class="wp-caption alignnone" style="width: 760px"><img title="Suspicious checkbox" src="http://mwolf.net/images/fritzbox.png" alt="Suspicious checkbox" width="750" height="212" /><p class="wp-caption-text">Suspicious checkbox</p></div>
<p>Needless to say, I don&#8217;t really like the idea of anybody being able to mess around with the gateway to my local network without my consent. Now, I do generally trust XS4ALL, which has a reputation to uphold when it comes to respecting its users&#8217; digital autonomy and privacy, so I assume that there&#8217;s an innocent reason for the fact that this checkbox cannot be easily unchecked by the user. I have already mailed AVM, the makers of the FritzBox, about this, and I plan to contact XS4ALL tomorrow. Let&#8217;s see what they say about it.</p>
<p><strong>UPDATE:</strong> false alarm, fortunately! Turns out it&#8217;s just a bit of a misleading user interface. The &#8220;permit automatic updates&#8221; option is dependent on the &#8220;allow automatic configuration&#8221; option above it. So when the latter is disabled, the former becomes greyed-out because it is no longer applicable. However, the software remembers what it was set to, resulting in a checkbox which incorrectly suggests that it is still enabled. If it makes you feel better, you can temporarily re-enable the &#8220;allow automatic configuration&#8221; option, then uncheck the &#8220;permit automatic updates&#8221; box and then disable automatic configuration again.</p>
]]></content:encoded>
			<wfw:commentRss>http://mwolf.net/archive/fritzbox-rocks/feed/</wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
		<item>
		<title>Golfing with prime factors</title>
		<link>http://mwolf.net/archive/golfing-with-prime-factors/</link>
		<comments>http://mwolf.net/archive/golfing-with-prime-factors/#comments</comments>
		<pubDate>Sun, 14 Jun 2009 13:57:53 +0000</pubDate>
		<dc:creator>martin</dc:creator>
				<category><![CDATA[hacks]]></category>
		<category><![CDATA[me]]></category>
		<category><![CDATA[code golf]]></category>
		<category><![CDATA[factoring]]></category>
		<category><![CDATA[hanoi]]></category>
		<category><![CDATA[perl]]></category>
		<category><![CDATA[perl golf]]></category>
		<category><![CDATA[prime factors]]></category>
		<category><![CDATA[prime numbers]]></category>
		<category><![CDATA[ruby]]></category>
		<category><![CDATA[towers of hanoi]]></category>

		<guid isPermaLink="false">http://mwolf.net/?p=55</guid>
		<description><![CDATA[Dirk-Jan reminded me of the Perl Golf and Code Golf contests, both of which have the aim of solving a simple programming task in as few characters of source code as possible. See his post for a stunning example.
One of the open challenges is to work out the prime factors of a given number. To [...]]]></description>
			<content:encoded><![CDATA[<p><a href="http://www.djcbsoftware.nl/ChangeLog/2009/05/perl-golf.html">Dirk-Jan</a> reminded me of the <a href="http://perlgolf.sourceforge.net/">Perl Golf</a> and <a href="http://codegolf.com/">Code Golf</a> contests, both of which have the aim of solving a simple programming task in as few characters of source code as possible. See his post for a stunning example.</p>
<p>One of the <a href="http://codegolf.com/competition/browse">open challenges</a> is to <a href="http://codegolf.com/prime-factors">work out the prime factors</a> of a given number. To make things a little more difficult, the output must be printed in a specific format:</p>
<blockquote><p><span style="font-family: Courier New;"> 7000: 2^3 5^3 7<br />
123456789: 3^2 3607 3803</span></p></blockquote>
<p><span id="more-55"></span>Here is one of my attempts at a Ruby implementation, which is 97 bytes after removing the final trailing newline:</p>
<blockquote><p><span style="font-family: Courier New;"> print&#8221;#{n=gets.to_i}: &#8221;<br />
(2..n).each{|x|i=0;n,i=n/x,i+1while n%x&lt;1<br />
print x,i&lt;2?&#8217; &#8216;:&#8221;^#{i} &#8220;if i&gt;0}</span></p></blockquote>
<p>Then we switched to Perl, and together Dirk-Jan and I managed to come up with a version which is just 82 bytes after removing all the newlines (just pipe it through &#8220;<span style="font-family: Courier New;">perl -pe chomp</span>&#8220;).</p>
<blockquote><p><span style="font-family: Courier New;"> print$n=pop,&#8217;:';for(2..$n){<br />
$i=0;$n/=$_,$i++until$n%$_;<br />
print&#8221; $_&#8221;.&#8221;^$i&#8221;x($i&gt;1)if$i}</span></p></blockquote>
<p>(Be aware that the Ruby version takes its input from <span style="font-family: Courier New;">stdin</span>, while the Perl program looks at its first command-line argument.)</p>
<p>That&#8217;s pretty compact, right? Algorithmically, the code is actually fairly straightforward; probably the most evil trick we use is to employ the &#8216;<span style="font-family: Courier New;">x</span>&#8216; operator, which does string concatenation a given number of times, in combination with the fact that any Boolean expression can be treated as a numeric value of either 0 or 1, as in C (but not in Ruby).</p>
<p>Unfortunately, both of the versions given above are horrendously slow. They have a running time of <a href="http://en.wikipedia.org/wiki/Big_O_notation">O(<em>n</em>)</a>, while any self-respecting factorization algorithm should be at most proportional with the largest prime factor of <em>n</em>. It took my Pentium-4 system almost 45 minutes to calculate the factors of 2,000,000,000, which a reasonably intelligent high school student could probably have done in half a minute or so. Here is a version which can do it in a fraction of a second, but at the cost of being a whole 10 bytes larger:</p>
<blockquote><p><span style="font-family: Courier New;"> print$n=pop,&#8217;:';<br />
for($x=2;$n&gt;1;$x++){<br />
$i=0;$n/=$x,$i++until$n%$x;<br />
print&#8221; $x&#8221;.&#8221;^$i&#8221;x($i&gt;1)if$i}</span></p></blockquote>
<p>So, how are we doing in the contest? Well, we&#8217;re not even competing. The <a href="http://codegolf.com/leaderboard/competition/prime-factors/">leader</a> is currently at an astonishing 76 bytes! I have no idea how they do that. The winning programs are all in Perl, which tends to do very well in this type of contest despite the fact that all variable names are at least two characters. The best Ruby program is 82 bytes, with Python coming in at 100 and PHP at 122.</p>
<p>Another <a href="http://codegolf.com/tower-of-hanoi">task</a> in Code Golf is to write a program which can solve the famous <a href="http://en.wikipedia.org/wiki/Towers_of_hanoi">Towers of Hanoi</a> puzzle, given a random starting position with up to nine disks. The input consists of three lines of text, each giving the sequence of disks for one of the three pegs. For example:</p>
<blockquote><p><span style="font-family: Courier New;"> 975<br />
864<br />
321</span></p></blockquote>
<p>The goal is to print the series of moves needed to get all disks together on peg C, the third one, following the usual rule that at no time may a larger disk be on top of (to the right of) a smaller one. Here is a very simple example run with only three disks:</p>
<blockquote><p><span style="font-family: Courier New;"> $ cat simple.txt<br />
31</span></p>
<p>2</p>
<p><span style="font-family: Courier New;"> $ ruby hanoi.rb simple.txt<br />
2 to B<br />
1 to B<br />
3 to C<br />
1 to A<br />
2 to C<br />
1 to C</span></p></blockquote>
<p><span style="font-family: sans-serif;">We haven&#8217;t spent as much time yet on this one as on the prime factorization problem. Here is my best effort so far:</span></p>
<blockquote><p><span style="font-family: Courier New;"> T,D=[],[:A,:B,:C]<br />
D.each{|t|gets.chomp.each_byte{|x|T[x-48]=t}}<br />
def m s,t<br />
if s&gt;0<br />
m s-1,(D-[t,T[s]])[0]<br />
puts&#8221;#{s} to #{t}&#8221;<br />
m s-1,T[s]=t<br />
end<br />
end<br />
m T.size-1,:C</span></p></blockquote>
<p><span style="font-family: sans-serif;">This is an embarassing 157 bytes. In the actual <a href="http://codegolf.com/leaderboard/competition/tower-of-hanoi/">contest participants</a>, Ruby is leading the pack this time, with 104 bytes, while the best Perl entry so far is a whole six bytes larger. Go Ruby!</span></p>
<p><span style="font-family: sans-serif;">The Code Golf contest is open to participants using <a href="http://en.wikipedia.org/wiki/Ruby_%28programming_language%29">Ruby</a>, <a href="http://en.wikipedia.org/wiki/Perl">Perl</a>, <a href="http://en.wikipedia.org/wiki/Python_%28programming_language%29">Python</a> and <a href="http://en.wikipedia.org/wiki/PHP">PHP</a>. Nonetheless, <a href="http://blog.leenarts.net/">Jeroen</a>, <a href="http://blog.hendricksen.eu">Jeroen</a> and <a href="http://blogs.infosupport.com/blogs/raimondb/">Raimond</a>, I look forward to you trying to beat the above programs in Java or C#..Â  <img src='http://mwolf.net/wordpress/wp-includes/images/smilies/icon_razz.gif' alt=':-P' class='wp-smiley' /> </span></p>
]]></content:encoded>
			<wfw:commentRss>http://mwolf.net/archive/golfing-with-prime-factors/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>Obfuscate your numbers!</title>
		<link>http://mwolf.net/archive/number-obfuscator/</link>
		<comments>http://mwolf.net/archive/number-obfuscator/#comments</comments>
		<pubDate>Sun, 07 Jun 2009 21:40:18 +0000</pubDate>
		<dc:creator>martin</dc:creator>
				<category><![CDATA[cool-tool]]></category>
		<category><![CDATA[hacks]]></category>
		<category><![CDATA[linux]]></category>
		<category><![CDATA[obfuscator]]></category>
		<category><![CDATA[ruby]]></category>

		<guid isPermaLink="false">http://mwolf.net/?p=52</guid>
		<description><![CDATA[Time for some silliness.
In a little over a month, I will be

years old.
What&#8217;s that, you didn&#8217;t get it? Here, I&#8217;ll repeat it for you in terms you may understand more easily:

At work, it has become a bit of a tradition that when people announce their birthday, they do so in an at least somewhat obfuscated [...]]]></description>
			<content:encoded><![CDATA[<p>Time for some silliness.</p>
<p>In a little over a month, I will be</p>
<p><img style="max-width: 800px;" src="http://mwolf.net/images/obfuscated-1.png" alt="" /></p>
<p>years old.</p>
<p>What&#8217;s that, you didn&#8217;t get it? Here, I&#8217;ll repeat it for you in terms you may understand more easily:</p>
<p><img style="max-width: 800px;" src="http://mwolf.net/images/obfuscated-2.png" alt="" /></p>
<p>At work, it has become a bit of a tradition that when people announce their birthday, they do so in an at least somewhat obfuscated format. Hexadecimal, binary and more obscure number formats are always popular, of course, as are silly descriptions of the form &#8220;my age is the ninth distinct <a href="http://en.wikipedia.org/wiki/Biprime">biprime</a>&#8220;. But last year I decided to take it to the next level, and write a little generator in Ruby for expressions such as the ones you see above. As you can probably guess, the expressions are generated using TeX.</p>
<p>You can <a href="http://mwolf.net/code/obfuscator/obfuscate.html">play with it for yourself, if you want to</a>, and also download the latest version of the code. But please be gentle with my server, as you can probably guess it&#8217;s a rather heavy application and I&#8217;m running this site on a little home PC..</p>
]]></content:encoded>
			<wfw:commentRss>http://mwolf.net/archive/number-obfuscator/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>
