<?xml version='1.0' encoding='UTF-8'?><?xml-stylesheet href="http://www.blogger.com/styles/atom.css" type="text/css"?><feed xmlns='http://www.w3.org/2005/Atom' xmlns:openSearch='http://a9.com/-/spec/opensearchrss/1.0/' xmlns:georss='http://www.georss.org/georss' xmlns:gd='http://schemas.google.com/g/2005' xmlns:thr='http://purl.org/syndication/thread/1.0'><id>tag:blogger.com,1999:blog-7429374688602565856</id><updated>2012-02-16T10:59:44.280+01:00</updated><category term='thesis'/><category term='accuracy'/><category term='javascript'/><category term='The Puzzle Toad'/><category term='darts'/><category term='ultra low power'/><category term='ballista'/><category term='low power'/><category term='competition'/><category term='comic'/><category term='puzzle'/><category term='algorithms'/><category term='RPC'/><category term='crazy'/><category term='cepc'/><category term='tricoder'/><category term='brainfuck'/><category term='confirmed solution'/><category term='home'/><category term='StarCraft'/><category term='acid'/><category term='htc hero'/><category term='insane'/><category term='analysis'/><category term='AI'/><category term='python'/><category term='comparison'/><category term='script'/><category term='html 5'/><category term='parallel'/><category term='layout'/><category term='edit distance'/><category term='performance'/><category term='getTime'/><category term='JSON-RPC'/><category term='science'/><category term='silence'/><category term='scanner'/><category term='research'/><category term='precission'/><category term='shortest path'/><category term='games'/><category term='microwave'/><category term='monte-carlo'/><category term='experiment'/><category term='game'/><category term='networking'/><category term='home network'/><category term='wikipedia'/><category term='android'/><category term='genetic programming'/><category term='design'/><category term='pmrpc'/><category term='fun'/><category term='machine learning'/><category term='awsome'/><category term='university'/><category term='cleaning'/><category term='modular'/><title type='text'>Marko's Hacks</title><subtitle type='html'>This blog serves as my scratchpad and notebook. I put stuff I don't want to forget here, if there is even a remote chance of it being useful to others.</subtitle><link rel='http://schemas.google.com/g/2005#feed' type='application/atom+xml' href='http://mivankovic.blogspot.com/feeds/posts/default'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7429374688602565856/posts/default?max-results=100'/><link rel='alternate' type='text/html' href='http://mivankovic.blogspot.com/'/><link rel='hub' href='http://pubsubhubbub.appspot.com/'/><author><name>Marko Ivanković</name><uri>https://profiles.google.com/105493585317824062514</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh4.googleusercontent.com/-YvEzqR3eb2M/AAAAAAAAAAI/AAAAAAAABiU/mQ3RxGl7tN8/s512-c/photo.jpg'/></author><generator version='7.00' uri='http://www.blogger.com'>Blogger</generator><openSearch:totalResults>13</openSearch:totalResults><openSearch:startIndex>1</openSearch:startIndex><openSearch:itemsPerPage>100</openSearch:itemsPerPage><entry><id>tag:blogger.com,1999:blog-7429374688602565856.post-9207778139596555804</id><published>2011-08-30T21:37:00.004+02:00</published><updated>2011-08-30T21:37:53.266+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='comparison'/><category scheme='http://www.blogger.com/atom/ns#' term='low power'/><category scheme='http://www.blogger.com/atom/ns#' term='layout'/><category scheme='http://www.blogger.com/atom/ns#' term='design'/><category scheme='http://www.blogger.com/atom/ns#' term='home network'/><category scheme='http://www.blogger.com/atom/ns#' term='modular'/><category scheme='http://www.blogger.com/atom/ns#' term='networking'/><title type='text'>Home network: Monolith vs beehive</title><content type='html'>&lt;div dir="ltr" style="text-align: left;" trbidi="on"&gt;&lt;br /&gt;The first choice I am faced with is: a lot of small specialized devices, one large device or something&amp;nbsp;in between.&lt;br /&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-size: x-large;"&gt;One large server&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;Having one large server is a viable solution, albeit a classic one. A single 8 disk server running in RAID0 has more than enough storage space. It can serve as a SSH server and VPN server. A large server is also cost effective and easily(ish)&amp;nbsp;upgradeable.&lt;br /&gt;&lt;br /&gt;However, there are a few problems with one colossal server: power usage, noise and coolness factor.&lt;br /&gt;&lt;br /&gt;A large machine requires lots of power. Now, granted, a lot of small machines add up to lots of power, however small machines are much simpler to switch off when not needed. Even though you can spin down drives in a server and clock down CPU it still costs you SOME power. And even if you do spin down drives and clock down CPU the PSU is still rated for 500W or so, so operating at 40W is not exactly efficient.&lt;br /&gt;&lt;br /&gt;Large classic server also has a bit more moving parts and a larger box. This affects the noise both ways. You can suspend drives with elastic to reduce noise, pad out the box, use larger fans that spin on lower RPM and put in other sound improvements. What you can't do, is hide it. It's a big box that has to be connected to your TV and sound system. Of course you can drag cables or try wifi, but those are either ugly, require construction work or cost a lot. And that is if you have somewhere to hide a box of that size, which I don't really have.&lt;br /&gt;&lt;br /&gt;Also, it's much more cool to build a large network of small machines. Much more SF :D&lt;br /&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-size: x-large;"&gt;How would one large server look like?&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;For comparison I decided to look into a large server assembly as well. First off, some performance requirements.&lt;br /&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-size: large;"&gt;Storage&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;I am looking at around 100GB of 3x replicated storage, 1TB of 2x replicated storage and around 2TB of non replicated storage. On top of that, some small amount of storage is used up by the OS, let's say 10GB SSD.&lt;br /&gt;To get replication I can use RAID or simply make backup of everything on different drives. RAID is good because it comes with performance improvements, is mostly hassle free and is considered the way to go.&lt;br /&gt;I however, do not think RAID is appropriate for home networks. In a typical home network, instantaneous replication is not really all that important. In fact, sometimes it's not wanted. If, for example, I would accidentally delete a folder RAID would be of no use to me at all. On the other hand, if I made automated backups to another disk every 6 hours, I would have at most 6 hours to rescue my data. Of course this means I don't have the performance benefits or RAID, and I have to take care not to ware out one drive more than other, but that can be coded away mostly. And performance is not such a big issue, once the initial copying is done.&lt;br /&gt;Keeping that in mind, my storage needs can be satisfied by 3 2TB drives. Currently one of the best on the market are WD Caviar Green disks. They are low power, low noise and cost effective.&lt;br /&gt;&lt;br /&gt;A WD Caviar Green 2TB drive is around 6.5W.&lt;br /&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-size: large;"&gt;CPU/Motherboard&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;The most CPU intensive action for this machine would be HD video encoding/decoding. Today, that is not such a big thing. Both Intel and AMD offer "standard" and low power platforms. After going through the roundups at&amp;nbsp;&lt;a href="http://www.silentpcreview.com/"&gt;http://www.silentpcreview.com/&lt;/a&gt;, a site with lots of great reviews for silent builds, I picked out:&lt;br /&gt;&lt;div style="text-align: left;"&gt;&lt;/div&gt;&lt;ul style="text-align: left;"&gt;&lt;li&gt;Undervolted&amp;nbsp;Intel Core i5 2400 as it has the best performance per watt and is midrange in performance per dollar.&lt;/li&gt;&lt;li&gt;Intel Core i3 2100T has the best absolute power usage, rated at 35W&lt;/li&gt;&lt;/ul&gt;Both of these would easily power all my needs. Of course, a motherboard is needed as well, Asus P8P67 would do. Or any of that lot. Intel motherboards are said to be the most energy efficient ones.&amp;nbsp;Intel DH57JG (not the correct socket for i3 2100 but....) is one of the better ones and puts CPU+MB at around 75W.&lt;br /&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-size: large;"&gt;GPU and other&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;Is not needed. The integrated GPU in Intel chips is good enough for video playback. A stand alone GPU could easily use 100W or more, and would be the most expensive part in the whole box.&lt;br /&gt;&lt;span class="Apple-style-span" style="font-size: large;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-size: large;"&gt;Total&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;So in total we have worst case power consumption at (75 + 3*6.5) = &lt;b&gt;94.5W&lt;/b&gt;. Truth be told, the drives will be idle most of the time, so will the CPU and MB so the number is somewhere in the &lt;b&gt;40-50W&lt;/b&gt; area. However, we do need a good PSU. Rated at 100W, at least. And since those are actually not so easy to find and can be costly, we probably end up with something along the lines of Enermax PRO II 425W, so 40W will actually be quite outside the optimal operation area.&lt;br /&gt;&lt;br /&gt;With the modular design I am aiming at &lt;b&gt;10W&lt;/b&gt;&amp;nbsp;while "idle", with a max of &lt;b&gt;54W&lt;/b&gt; on full usage. Also, perfect setup should be with 0 moving parts when the disks are spun down.&lt;br /&gt;&lt;br /&gt;Now, I actually already run one such installation with a single large box. I will measure in full detail the power consumption on it and compare it to the eventual beehive design I plan to put up in my&amp;nbsp;apartment. So at the end, there will be some real data here as well.&lt;br /&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7429374688602565856-9207778139596555804?l=mivankovic.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://mivankovic.blogspot.com/feeds/9207778139596555804/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://mivankovic.blogspot.com/2011/08/home-network-monolith-vs-beehive.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7429374688602565856/posts/default/9207778139596555804'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7429374688602565856/posts/default/9207778139596555804'/><link rel='alternate' type='text/html' href='http://mivankovic.blogspot.com/2011/08/home-network-monolith-vs-beehive.html' title='Home network: Monolith vs beehive'/><author><name>Marko Ivanković</name><uri>https://profiles.google.com/105493585317824062514</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh4.googleusercontent.com/-YvEzqR3eb2M/AAAAAAAAAAI/AAAAAAAABiU/mQ3RxGl7tN8/s512-c/photo.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7429374688602565856.post-8352466269609346818</id><published>2011-08-28T16:11:00.001+02:00</published><updated>2011-08-28T16:13:21.085+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='low power'/><category scheme='http://www.blogger.com/atom/ns#' term='analysis'/><category scheme='http://www.blogger.com/atom/ns#' term='ultra low power'/><category scheme='http://www.blogger.com/atom/ns#' term='silence'/><category scheme='http://www.blogger.com/atom/ns#' term='design'/><category scheme='http://www.blogger.com/atom/ns#' term='networking'/><category scheme='http://www.blogger.com/atom/ns#' term='home'/><title type='text'>Home Network: Initial requirements analysis</title><content type='html'>&lt;div dir="ltr" style="text-align: left;" trbidi="on"&gt;&lt;span class="Apple-style-span" style="font-size: x-large;"&gt;Introduction&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;I decided to pimp up my home network, and this time do it properly. It turns out, a lot of analysis goes into doing so, so I decided to keep it as a series of blogposts. This is mostly going to serve me as a central place for all my plans, but if someone finds my results usable, even better.&lt;br /&gt;&lt;br /&gt;So the first step is to list everything I would like my network to do.&lt;br /&gt;&lt;br /&gt;&lt;span class="Apple-style-span" style="font-size: x-large;"&gt;Use cases&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;The following is a list of use cases. You might notice that they are broken down into small,&amp;nbsp;manageable&amp;nbsp;chunks:&lt;br /&gt;&lt;ol style="text-align: left;"&gt;&lt;li&gt;Data storage - photo&lt;/li&gt;&lt;li&gt;Data storage - audio&lt;/li&gt;&lt;li&gt;Data storage - video&lt;/li&gt;&lt;li&gt;Data storage - documents&lt;/li&gt;&lt;li&gt;Music player&lt;/li&gt;&lt;li&gt;Video player&lt;/li&gt;&lt;li&gt;Permanent SSH server (DynDNS)&lt;/li&gt;&lt;li&gt;VPN server&lt;/li&gt;&lt;/ol&gt;&lt;div&gt;Some details for each case:&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="font-size: large;"&gt;Data storage - Photos, Audio, Video, Documents&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;You might wonder why data storage was broken down in 4 components. The reason is lifetime. Storing photos is for life, or longer. I want to store all my photos, have automated backup system within the network, health checks and also manually assisted remote backup either to the cloud (Picassa proved usable so far) or to some other network under my control. This requires a paranoid level setup. Luckily, photos are usually on the order of 1-10MB size. Worst case for me are RAW 14.1MB photos.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Storing audio files is for decades. Some people like to imagine large collections of music. Perfectly sorted, tagged and ready for usage. I am one of them. Naturally, it takes quite a lot of time and energy to create such collections. Therefore it's a long lasting project. Years. Maybe decade or two. So I want my audio storage to be backed up within the network as well. File sizes are similar to photos for compressed, and a bit larger for&amp;nbsp;lossless files.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Documents are also for decades. However, they are usually quite small. I can safely asume an average of 1MB per document.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Videos on the other hand, do not need such extensive backup and safety measures. They are however much much much larger.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="font-size: large;"&gt;Music &amp;amp;amp;amp; Video player&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;All that data would be pointless if unused. A small HTPC, media center or some other form of music &amp;amp;amp;amp; video player is needed. HD is probably required.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="font-size: large;"&gt;SSH server&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;SSH server is very important for two reasons:&lt;/div&gt;&lt;div&gt;&lt;ol style="text-align: left;"&gt;&lt;li&gt;It allows me to use the network even when outside&lt;/li&gt;&lt;li&gt;It allows me to grant access to the network to other people&lt;/li&gt;&lt;/ol&gt;&lt;div&gt;I have a reasonable cable internet connection so bandwidth should not be a problem. Latency might be, but only in peak hours, and even then only for latency sensitive tasks such as editing files.&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="font-size: large;"&gt;VPN server&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Since I plan to have this kickass setup, I might as well use it to secure myself when I am out of the safety of the network. A VPN server would do wonders here.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="font-size: x-large;"&gt;Other stuff&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Aside&amp;nbsp;from what I would like the network to enable me to do, there are some other things I would like it to be. On top of the list is &lt;b&gt;SILENT&lt;/b&gt;. I wan't the devices to be as silent as possible. What I am looking for is in the dark of the night, 3am, to be able to be in the same room with them and not notice anything. Luckily, this goes hand in hand with the next&amp;nbsp;requirement:&lt;b&gt; ultra low power&lt;/b&gt;. Some of the parts are going to be operational 24/7 and I do not want them to draw more power than is&amp;nbsp;absolutely necessary. Next in line is &lt;b&gt;cost&lt;/b&gt;. I understand that what I am going for is not the cheapest option out there, but I'm not ready to pay for overpriced&amp;nbsp;hardware either. In the end, &lt;b&gt;size&lt;/b&gt; matters. And &lt;b&gt;visual&lt;/b&gt; design.&lt;/div&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7429374688602565856-8352466269609346818?l=mivankovic.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://mivankovic.blogspot.com/feeds/8352466269609346818/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://mivankovic.blogspot.com/2011/08/home-network-initial-requirements.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7429374688602565856/posts/default/8352466269609346818'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7429374688602565856/posts/default/8352466269609346818'/><link rel='alternate' type='text/html' href='http://mivankovic.blogspot.com/2011/08/home-network-initial-requirements.html' title='Home Network: Initial requirements analysis'/><author><name>Marko Ivanković</name><uri>https://profiles.google.com/105493585317824062514</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh4.googleusercontent.com/-YvEzqR3eb2M/AAAAAAAAAAI/AAAAAAAABiU/mQ3RxGl7tN8/s512-c/photo.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7429374688602565856.post-6675569092342117385</id><published>2011-03-26T11:16:00.021+01:00</published><updated>2011-04-05T16:41:50.975+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='performance'/><category scheme='http://www.blogger.com/atom/ns#' term='javascript'/><category scheme='http://www.blogger.com/atom/ns#' term='accuracy'/><category scheme='http://www.blogger.com/atom/ns#' term='research'/><category scheme='http://www.blogger.com/atom/ns#' term='precission'/><category scheme='http://www.blogger.com/atom/ns#' term='thesis'/><category scheme='http://www.blogger.com/atom/ns#' term='getTime'/><title type='text'>Research results: Can JavaScipt getTime() be used for measuring performance of JavaScript code?</title><content type='html'>Recently, during research for my masters thesis I had to answer the question "Can we use JavaScirpt &lt;span style="font-style: italic;"&gt;getTime()&lt;/span&gt; function in our benchmarks and get portable benchmarks that are valid?".&lt;br /&gt;&lt;br /&gt;For the tl;dr crowd here is a short answer: Yes on Linux (and OS X &lt;span style="font-weight: bold;"&gt;probably&lt;/span&gt;) - not really on Windows.&lt;br /&gt;&lt;br /&gt;After some research on the Internet, I found &lt;a href="http://ejohn.org/blog/accuracy-of-javascript-time/"&gt;this blog post&lt;/a&gt; from 2008. by John Resig that explores this issue. He concludes that &lt;span style="font-style: italic;"&gt;getTime()&lt;/span&gt; is basically useless on Windows XP irregardless of browser choice, while being safe to use it on OS X. I wanted to update his results to 2011 and explore the issue a bit more.&lt;br /&gt;&lt;br /&gt;My goal was to measure the precision and not the accuracy  (the difference is nicely explained in &lt;a href="http://en.wikipedia.org/wiki/Accuracy_and_precision"&gt;this Wikipedia article&lt;/a&gt;) of the &lt;span style="font-style: italic;"&gt;getTime()&lt;/span&gt; function. We could do &lt;span style="font-weight: bold;"&gt;some&lt;/span&gt; analysis of accuracy, but opt not to because it's not so easy to setup a good experiment for accuracy. Precision on the other hand is nicely quantified in terms of the standard deviation of the experiment.&lt;span style="font-weight: bold;"&gt; Smaller standard deviation is better.&lt;/span&gt; The best possible outcome would be for the results to follow a very narrow Gaussian distribution.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-size:180%;"&gt;&lt;span style="font-weight: bold;"&gt;The setup&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;The code for most benchmarks in JavaScript can be summarized in these three lines:&lt;br /&gt;&lt;pre&gt;var start = (new Date).getTime()&lt;br /&gt;doStuff()&lt;br /&gt;var diff = (new Date).getTime() - start&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;so this is the scenario I decided to test. The obvious question of course is what to use as a sample load. It's important for the test load to have deterministic duration that can be easily controlled, and is too complicated for the browser to simply optimize away. A nice way to do this is to have a O(n^2) math function that does some of the slowest operations, such as the modulus operation. I used the following code:&lt;br /&gt;&lt;pre&gt;    function sample(size) {&lt;br /&gt;  var result = 0;&lt;br /&gt;  for (var i = 0; i &amp;lt; size; i++) {&lt;br /&gt;    innerSample(i, result);&lt;br /&gt;  }&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;function innerSample(i, result) {&lt;br /&gt;  result = i * i + i + (0x09F91102 % i) / 2;&lt;br /&gt;  for (var j = 0; j &amp;lt; i; j++)&lt;br /&gt;    result = (result * result) % (0x09F91102);&lt;br /&gt;  return result;&lt;br /&gt;} &lt;/pre&gt;&lt;br /&gt;The reason it's split in two is because I had a pre calibration step first. Since we are not interested in comparing relative browser speeds we do not need to use the same number of iterations of the sample function on all browsers. What would be much better is to have the same &lt;span style="font-weight: bold;"&gt;duration&lt;/span&gt; on all browsers. This is why, before testing, I run a pre calibration step that determines the number of iterations I should use so that the average duration of one sample is a bit under 75ms. Since we are not measuring accuracy a rough estimate will do just fine, as long as the duration is long enough so as to allow for anomalous shorter run times.&lt;br /&gt;&lt;br /&gt;This completes the setup.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-size:180%;"&gt;&lt;span style="font-weight: bold;"&gt;The experiment&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;The experiment is performed by looping 500 times over the sample code with the pre calibrated number of steps. After that the standard deviation is calculated. This is repeated a few times if possible to see if the results are stable.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-size:180%;"&gt;&lt;span style="font-weight: bold;"&gt;The results&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;I tested Firefox 3.6 and 4.0 and Chrome 9 and 10 on Linux (Arch Linux  2.6.37 kernel), Windows XP fully patched and Windows 7 fully patched. I  did run the Linux test on four machines: an Intel i3 desktop, two different Core2Duo laptops and Atom netbook and the results did not differ significantly. This shows that  the hardware itself does not influence the tests. As for the Windows  tests, I don't even own a Windows box so I used volunteer help for  those tests (if you were one of these unfortunate "volunteers" I am so so sorry, I promise not to spam you all again). They were run on a wide variety of machines. There were &lt;span style="font-weight: bold;"&gt;significant &lt;/span&gt;variations on Windows machines, these are analysed below.&lt;br /&gt;&lt;br /&gt;Mac OS X is omitted because I do not have access to a Mac OS X machine  at the moment. In future the results will be appended. I also plan to  include Opera and Safari. What will &lt;span style="font-weight: bold;"&gt;never &lt;/span&gt;be included is Internet Explorer, for two reasons: the script runtime limit in Firefox and Chrome is based on actual &lt;span style="font-weight: bold;"&gt;time&lt;/span&gt;  whereas IE limits the number of operations you can execute between  events (MSDN site sets the limit as ~5.000.000 operations) and, more  importantly, you can switch OFF the runtime limit in Firefox and Chrome.&lt;br /&gt;&lt;br /&gt;The results were pretty much consistent with the previous results from 2008. Here is a summary table of standard deviations:&lt;br /&gt;&lt;br /&gt;&lt;table style="border: 1px solid black;border-collapse: collapse"&gt;  &lt;tbody&gt;&lt;tr&gt;    &lt;th style="border: 1px solid black;"&gt;&lt;br /&gt;&lt;/th&gt;    &lt;th style="border: 1px solid black; text-align: center"&gt;Linux&lt;/th&gt;    &lt;th style="border: 1px solid black; text-align: center"&gt;Windows XP&lt;/th&gt;    &lt;th style="border: 1px solid black; text-align: center"&gt;Windows 7&lt;/th&gt;  &lt;/tr&gt;  &lt;tr&gt;    &lt;td style=" text-align: center"&gt;Firefox 3.6&lt;/td&gt;    &lt;td style="border: 1px solid black; text-align: center"&gt;0.5ms&lt;br /&gt;&lt;/td&gt;    &lt;td style=" text-align: center"&gt;6.8ms&lt;/td&gt;    &lt;td style="border: 1px solid black; text-align: center"&gt;[1.2ms, 7.3ms]&lt;/td&gt;  &lt;/tr&gt;  &lt;tr&gt;    &lt;td style="border: 1px solid black; text-align: center"&gt;Firefox 4.0&lt;/td&gt;    &lt;td style="border: 1px solid black; text-align: center"&gt;0.4ms&lt;/td&gt;    &lt;td style="border: 1px solid black; text-align: center"&gt;37.4ms&lt;/td&gt;    &lt;td style="border: 1px solid black; text-align: center"&gt;[3.6ms, 7.9ms]&lt;/td&gt;  &lt;/tr&gt;  &lt;tr&gt;    &lt;td style="border: 1px solid black; text-align: center"&gt;Chrome 9&lt;/td&gt;    &lt;td style="border: 1px solid black; text-align: center"&gt;1.2ms&lt;/td&gt;    &lt;td style="border: 1px solid black; text-align: center"&gt;12.7ms&lt;/td&gt;    &lt;td style="border: 1px solid black; text-align: center"&gt;[4.7ms, 17.3ms]&lt;/td&gt;  &lt;/tr&gt;  &lt;tr&gt;    &lt;td style="border: 1px solid black; text-align: center"&gt;Chrome 10&lt;/td&gt;    &lt;td style="border: 1px solid black; text-align: center"&gt;1.7ms&lt;/td&gt;    &lt;td style="border: 1px solid black; text-align: center"&gt;33.8ms&lt;/td&gt;    &lt;td style="border: 1px solid black; text-align: center"&gt;[4.9ms, 19.7ms]&lt;/td&gt;  &lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;br /&gt;As you can see from the results, Firefox on Linux is the most precise with only 0.4 ms of deviation on 75ms test load. Chrome works OK on Linux too. It's worse than Firefox but still excellent. The results on Linux were stable across many different machines and are quite good. I did not test it against older kernels, but I don't think this is a major problem since all major Linux distributions do have up-to-date kernels.&lt;br /&gt;&lt;br /&gt;This is a normalized graph of all 4 browsers on Linux. The X-axis values are omitted on purpose since each series is normalized so that the smallest value is 10. Since we are not interested in accuracy this gives a nicer and equally valid image:&lt;br /&gt;&lt;br /&gt;&lt;a href="http://chart.apis.google.com/chart?cht=bvs&amp;amp;chs=632x474&amp;amp;chxt=x%2Cy&amp;amp;chxl=0%3A%7C%7C%7C%7C%7C%7C%7C%7C%7C%7C%7C%7C%7C%7C%7C%7C%7C%7C%7C%7C%7C%7C%7C%7C%7C%7C%7C%7C%7C%7C%7C%7C%7C%7C%7C%7C%7C%7C%7C%7C%7C%7C&amp;amp;chdlp=r&amp;amp;chdl=Firefox%203.6%7CFirefox%204%7CChrome%209%7CChrome%2010&amp;amp;chco=3399CC%2C80C65A%2CFF0000%2CFFCC33&amp;amp;chxr=1%2C0%2C326&amp;amp;chbh=a&amp;amp;chd=e%3AAAAAAAAAAAAAAAAAAAAAAM2kDuAAAAAAAAAAAAAMAAAAAAAAAAAAAAAAAAAMAAAAAAAAAAAAAAAAAAAAAAAA%2CAAAAAAAAAAAAAAAAAAAAen..CWAlAZAAAAAAAMAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA%2CAAAAAAAAAAAAAAAAAAAAw3J0AMAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA%2CAAAAAAAAAAAAAAAAAAAA9odoDiA-AMBkAAAMAAAAAAAAAMAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAM" onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}"&gt;&lt;img style="float:left; margin:0 10px 10px 0;cursor:pointer; cursor:hand;width: 632px; height: 474px;" src="http://chart.apis.google.com/chart?cht=bvs&amp;amp;chs=632x474&amp;amp;chxt=x%2Cy&amp;amp;chxl=0%3A%7C%7C%7C%7C%7C%7C%7C%7C%7C%7C%7C%7C%7C%7C%7C%7C%7C%7C%7C%7C%7C%7C%7C%7C%7C%7C%7C%7C%7C%7C%7C%7C%7C%7C%7C%7C%7C%7C%7C%7C%7C%7C&amp;amp;chdlp=r&amp;amp;chdl=Firefox%203.6%7CFirefox%204%7CChrome%209%7CChrome%2010&amp;amp;chco=3399CC%2C80C65A%2CFF0000%2CFFCC33&amp;amp;chxr=1%2C0%2C326&amp;amp;chbh=a&amp;amp;chd=e%3AAAAAAAAAAAAAAAAAAAAAAM2kDuAAAAAAAAAAAAAMAAAAAAAAAAAAAAAAAAAMAAAAAAAAAAAAAAAAAAAAAAAA%2CAAAAAAAAAAAAAAAAAAAAen..CWAlAZAAAAAAAMAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA%2CAAAAAAAAAAAAAAAAAAAAw3J0AMAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA%2CAAAAAAAAAAAAAAAAAAAA9odoDiA-AMBkAAAMAAAAAAAAAMAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAM" alt="" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;As you can see the results are neatly packed with more than 95% of results packed in a 2ms range.&lt;span style="font-weight:bold;"&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;The results on Windows were much more inconclusive. You will notice that the results for Windows 7 are given as intervals. This is because the results varied &lt;span style="font-weight: bold;"&gt;wildly &lt;/span&gt;between different machines. The results were quite stable on any given machine, so it's not an artifact of the experiment itself. If you look at the best results, they are larger than on Linux, but still usable: 4.9 ms is not that bad. It's an order of magnitude bigger than 0.5, but still usable. In my personal opinion (since extensive tests should be done for a stronger result) good results on Windows were rare. Only 2 out of 10 Windows 7 machines produced good results. A typical distribution for a Windows machine is displayed below:&lt;br /&gt;&lt;br /&gt;&lt;a href="http://chart.apis.google.com/chart?cht=bvs&amp;amp;chs=632x474&amp;amp;chxt=x%2Cy&amp;amp;chxl=0%3A%7C70%7C71%7C72%7C73%7C74%7C75%7C76%7C77%7C78%7C79%7C80%7C81%7C82%7C83%7C84%7C85%7C86%7C87%7C88%7C89%7C90%7C91%7C92%7C93%7C94%7C95%7C96%7C97%7C98%7C99%7C100%7C101%7C102%7C103%7C104%7C105%7C106%7C107%7C108%7C109%7C110%7C111%7C112%7C113%7C114%7C115%7C116%7C117%7C118%7C119%7C120%7C121%7C122%7C123%7C124%7C125%7C126%7C127%7C128%7C129%7C130%7C131%7C132%7C133%7C134%7C135%7C136%7C137%7C138%7C139%7C140%7C141%7C142%7C143%7C144%7C145%7C146%7C147%7C148%7C149%7C150%7C151%7C152%7C153%7C154%7C155%7C156%7C157%7C158%7C159%7C160%7C161%7C162%7C163%7C164%7C165%7C166%7C167%7C168%7C169%7C170&amp;amp;chdlp=r&amp;amp;chdl=Frequency&amp;amp;chco=3399CC&amp;amp;chxr=1%2C0%2C51&amp;amp;chbh=a&amp;amp;chd=e%3ACgBQDwBQBQBQAAAAAAAAAAAABQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAKCIyPDZF0s8O-uyL..zcr6tKoJc2X1IyMiDwAABQAABQAABQBQAABQAAAAAAAABQ" onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}"&gt;&lt;img style="float:left; margin:0 10px 10px 0;cursor:pointer; cursor:hand;width: 632px; height: 474px;" src="http://chart.apis.google.com/chart?cht=bvs&amp;amp;chs=632x474&amp;amp;chxt=x%2Cy&amp;amp;chxl=0%3A%7C70%7C71%7C72%7C73%7C74%7C75%7C76%7C77%7C78%7C79%7C80%7C81%7C82%7C83%7C84%7C85%7C86%7C87%7C88%7C89%7C90%7C91%7C92%7C93%7C94%7C95%7C96%7C97%7C98%7C99%7C100%7C101%7C102%7C103%7C104%7C105%7C106%7C107%7C108%7C109%7C110%7C111%7C112%7C113%7C114%7C115%7C116%7C117%7C118%7C119%7C120%7C121%7C122%7C123%7C124%7C125%7C126%7C127%7C128%7C129%7C130%7C131%7C132%7C133%7C134%7C135%7C136%7C137%7C138%7C139%7C140%7C141%7C142%7C143%7C144%7C145%7C146%7C147%7C148%7C149%7C150%7C151%7C152%7C153%7C154%7C155%7C156%7C157%7C158%7C159%7C160%7C161%7C162%7C163%7C164%7C165%7C166%7C167%7C168%7C169%7C170&amp;amp;chdlp=r&amp;amp;chdl=Frequency&amp;amp;chco=3399CC&amp;amp;chxr=1%2C0%2C51&amp;amp;chbh=a&amp;amp;chd=e%3ACgBQDwBQBQBQAAAAAAAAAAAABQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAKCIyPDZF0s8O-uyL..zcr6tKoJc2X1IyMiDwAABQAABQAABQBQAABQAAAAAAAABQ" alt="" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;This chart was produced on Chrome 10 tested on Windows 7. Interesting observation is that the first few measurements were on the 75ms mark, but the execution slowed down afterwards moving the median value up to 125ms. This slow down was not accounted for or explained. It's left as an open question.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-size:180%;"&gt;&lt;span style="font-weight: bold;"&gt;The conclusion&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span&gt;Using &lt;span style="font-style: italic;"&gt;getTime()&lt;/span&gt; on &lt;span style="font-weight: bold;"&gt;Linux&lt;/span&gt; in the manner described here is VALID on both browsers.&lt;/span&gt; Using &lt;span style="font-style: italic;"&gt;getTime()&lt;/span&gt; on &lt;span style="font-weight: bold;"&gt;Windows&lt;/span&gt; will give some results, but you can never be sure that another user will be able to repeat them on his machine.&lt;br /&gt;&lt;span style="font-size:180%;"&gt;&lt;span style="font-weight: bold;"&gt;&lt;br /&gt;The future&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;These results are a good start but there is much room for expansion. If time permits I plan to answer some of these questions in the future:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;How does the standard deviation behave on longer loads, say 1000ms?&lt;/li&gt;&lt;li&gt;What are the possible factors affecting precision on Windows?&lt;/li&gt;&lt;li&gt;How do other browser place?&lt;/li&gt;&lt;li&gt;Do Windows results follow a pattern? Can some results be discarded and attributed to "start up" problems?&lt;/li&gt;&lt;li&gt;Test on more machines&lt;/li&gt;&lt;/ul&gt;&lt;div&gt;&lt;span class="Apple-style-span"&gt;&lt;b&gt;The update&lt;/b&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span"&gt;&lt;b&gt;&lt;br /&gt;&lt;/b&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span"&gt;The code used can be found on GitHub &lt;/span&gt;&lt;a href="https://github.com/ivankovic/cccm-benchmark"&gt;https://github.com/ivankovic/cccm-benchmark&lt;/a&gt;. There is also a GitHub Page that can be used at once &lt;a href="http://ivankovic.github.com/cccm-benchmark/"&gt;http://ivankovic.github.com/cccm-benchmark/&lt;/a&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span"&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;One possible reason for Windows is that the precision of the GetSystemTime system call is in the 10ms - 16ms range. This however does not explain why sometimes the results of Windows were good. Or how to deal with benchmarks on Windows.&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7429374688602565856-6675569092342117385?l=mivankovic.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://mivankovic.blogspot.com/feeds/6675569092342117385/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://mivankovic.blogspot.com/2011/03/research-results-can-javascipt-gettime.html#comment-form' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7429374688602565856/posts/default/6675569092342117385'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7429374688602565856/posts/default/6675569092342117385'/><link rel='alternate' type='text/html' href='http://mivankovic.blogspot.com/2011/03/research-results-can-javascipt-gettime.html' title='Research results: Can JavaScipt getTime() be used for measuring performance of JavaScript code?'/><author><name>Marko Ivanković</name><uri>https://profiles.google.com/105493585317824062514</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh4.googleusercontent.com/-YvEzqR3eb2M/AAAAAAAAAAI/AAAAAAAABiU/mQ3RxGl7tN8/s512-c/photo.jpg'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7429374688602565856.post-1413093963744789598</id><published>2011-02-09T15:47:00.003+01:00</published><updated>2011-02-09T16:08:25.671+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='insane'/><category scheme='http://www.blogger.com/atom/ns#' term='acid'/><category scheme='http://www.blogger.com/atom/ns#' term='cleaning'/><category scheme='http://www.blogger.com/atom/ns#' term='science'/><category scheme='http://www.blogger.com/atom/ns#' term='microwave'/><category scheme='http://www.blogger.com/atom/ns#' term='experiment'/><title type='text'>Science in pursuit of lazyness: Cleaning a silver ring in 60 seconds</title><content type='html'>I'm gonna go ahead and start with this: Following this advice will make you put metal inside a microwave. &lt;span style="font-weight: bold;"&gt;You probably should not be following this unless you can understand the full implications of that.&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;What is the best way to clean a silver ring with cubic zirconia ornaments? I have no idea.&lt;br /&gt;&lt;br /&gt;There is however a lazy way to do it under 60 seconds. For this you will need:&lt;br /&gt;&lt;ol&gt;&lt;li&gt;The ring&lt;/li&gt;&lt;li&gt;Citric acid (the household variety, it's dirt cheap)&lt;/li&gt;&lt;li&gt;Small glass&lt;/li&gt;&lt;li&gt;Water&lt;br /&gt;&lt;/li&gt;&lt;li&gt;Microwave oven&lt;/li&gt;&lt;/ol&gt;Put enough water in the glass so that you can fully submerse the ring. You might want to leave at least some space between the water level and glass edge, because boiling could happen and cleaning the microwave would be very un-lazy.&lt;br /&gt;&lt;br /&gt;Pour citric acid in the water. Make a fine solution. I have no idea how much I used, but I'm going to guess it as around 5-10%. Drop the ring in the acid. Put all of that in the microwave. Let her rip with 700W on 30 seconds, or until everything starts boiling and you think it would be a good idea to pull it out.&lt;br /&gt;&lt;br /&gt;Carefully take the glass out, extract the ring, cool it, wipe it dry. Enjoy the no effort sparkliness.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Things to note:&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;Too much water is better than too little watter.&lt;br /&gt;&lt;br /&gt;Citric acid is, well, acidic. Also, HOT citric acid will burn you. Use some gloves man!&lt;br /&gt;&lt;br /&gt;The ring is made of metal, and metal in microwave is not a good idea. However, there should be no danger. In fact, we are counting on the fact that the metal will act as an antenna, causing it to absorb microwaves which in turn will heat up the metal much faster than the water around it causing:&lt;br /&gt;&lt;ol&gt;&lt;li&gt;The acidic reaction around the ring to speed up&lt;/li&gt;&lt;li&gt;Formation of water vapour bubbles on the ring surface that will physically remove dirt particles of the ring.&lt;br /&gt;&lt;/li&gt;&lt;/ol&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7429374688602565856-1413093963744789598?l=mivankovic.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://mivankovic.blogspot.com/feeds/1413093963744789598/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://mivankovic.blogspot.com/2011/02/science-in-pursuit-of-lazyness-cleaning.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7429374688602565856/posts/default/1413093963744789598'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7429374688602565856/posts/default/1413093963744789598'/><link rel='alternate' type='text/html' href='http://mivankovic.blogspot.com/2011/02/science-in-pursuit-of-lazyness-cleaning.html' title='Science in pursuit of lazyness: Cleaning a silver ring in 60 seconds'/><author><name>Marko Ivanković</name><uri>https://profiles.google.com/105493585317824062514</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh4.googleusercontent.com/-YvEzqR3eb2M/AAAAAAAAAAI/AAAAAAAABiU/mQ3RxGl7tN8/s512-c/photo.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7429374688602565856.post-5700747083469927592</id><published>2010-03-22T10:57:00.003+01:00</published><updated>2010-03-22T11:03:28.974+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='insane'/><category scheme='http://www.blogger.com/atom/ns#' term='darts'/><category scheme='http://www.blogger.com/atom/ns#' term='ballista'/><title type='text'>Darts during storms</title><content type='html'>My brother and I tried to play darts outdoors a few days ago during heavy winds. Needles to say, it didn't exactly go as planned. It did however bring forth a crazy idea for a brand new sport.&lt;br /&gt;&lt;br /&gt;The ballista darts!&lt;br /&gt;&lt;br /&gt;Think about it, each team must construct a ballista from scratch. Then they fire comically sized darts into a 10-meter-radius dartboard. All other rules would be like standard darts, except everything would be HUGE.&lt;br /&gt;&lt;br /&gt;It would be awesome. Until somebody loses an eye, that is. Than it would be just hilarious.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7429374688602565856-5700747083469927592?l=mivankovic.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://mivankovic.blogspot.com/feeds/5700747083469927592/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://mivankovic.blogspot.com/2010/03/darts-during-storms.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7429374688602565856/posts/default/5700747083469927592'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7429374688602565856/posts/default/5700747083469927592'/><link rel='alternate' type='text/html' href='http://mivankovic.blogspot.com/2010/03/darts-during-storms.html' title='Darts during storms'/><author><name>Marko Ivanković</name><uri>https://profiles.google.com/105493585317824062514</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh4.googleusercontent.com/-YvEzqR3eb2M/AAAAAAAAAAI/AAAAAAAABiU/mQ3RxGl7tN8/s512-c/photo.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7429374688602565856.post-4337634361615941072</id><published>2010-02-09T15:32:00.004+01:00</published><updated>2010-02-09T16:30:13.795+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='algorithms'/><category scheme='http://www.blogger.com/atom/ns#' term='edit distance'/><category scheme='http://www.blogger.com/atom/ns#' term='parallel'/><title type='text'>Simple fast edit distance</title><content type='html'>Edit distance (or &lt;a href="http://en.wikipedia.org/wiki/Levenshtein_distance"&gt;Levenshtein distance&lt;/a&gt;)&lt;span style="text-decoration: underline;"&gt;&lt;/span&gt;&lt;a href="http://en.wikipedia.org/wiki/Levenshtein_distance"&gt;&lt;/a&gt; is a measure of similarity between two strings. Given two strings &lt;span style="font-weight: bold;"&gt;A&lt;/span&gt; and &lt;span style="font-weight: bold;"&gt;B&lt;/span&gt;,&lt;span style="font-weight: bold;"&gt; &lt;/span&gt;if you are allowed to delete any character in &lt;span style="font-weight: bold;"&gt;B&lt;/span&gt;, insert a new character in &lt;span style="font-weight: bold;"&gt;B &lt;/span&gt;(at any position) or substitute any character in &lt;span style="font-weight: bold;"&gt;B &lt;/span&gt;what is the minimal number of operations required to turn &lt;span style="font-weight: bold;"&gt;B&lt;/span&gt; into &lt;span style="font-weight: bold;"&gt;A&lt;/span&gt;?&lt;br /&gt;&lt;br /&gt;The solution is simple dynamic programming. Suppose we want to know how much operations it takes to make the first &lt;span style="font-style: italic;"&gt;i &lt;/span&gt;characters of &lt;span style="font-weight: bold;"&gt;A&lt;/span&gt; equal the first &lt;span style="font-style: italic;"&gt;j &lt;/span&gt;characters of &lt;span style="font-weight: bold;"&gt;B&lt;/span&gt;. If &lt;span style="font-weight: bold;"&gt;A&lt;/span&gt;[i] equals &lt;span style="font-weight: bold;"&gt;B&lt;/span&gt;[j] than it's the same number of operations it takes to make the first &lt;span style="font-style: italic;"&gt;i - 1 &lt;/span&gt;characters of &lt;span style="font-weight: bold;"&gt;A&lt;/span&gt; equal the first j - 1 characters of &lt;span style="font-weight: bold;"&gt;B&lt;/span&gt;. If not, than its one more operation than making:&lt;br /&gt;&lt;ol&gt;&lt;li&gt;&lt;span style="display: block;" id="formatbar_Buttons"&gt;&lt;span class="on" style="display: block;" id="formatbar_CreateLink" title="Link" onmouseover="ButtonHoverOn(this);" onmouseout="ButtonHoverOff(this);" onmouseup="" onmousedown="CheckFormatting(event);FormatbarButton('richeditorframe', this, 8);ButtonMouseDown(this);"&gt;The first &lt;span style="font-style: italic;"&gt;i - 1&lt;/span&gt; characters of &lt;span style="font-weight: bold;"&gt;A&lt;/span&gt; equal the first &lt;span style="font-style: italic;"&gt;j&lt;/span&gt; characters of &lt;span style="font-weight: bold;"&gt;B&lt;/span&gt; (this correspond to deleting a character from &lt;span style="font-weight: bold;"&gt;B&lt;/span&gt;)&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span style="display: block;" id="formatbar_Buttons"&gt;&lt;span class="on" style="display: block;" id="formatbar_CreateLink" title="Link" onmouseover="ButtonHoverOn(this);" onmouseout="ButtonHoverOff(this);" onmouseup="" onmousedown="CheckFormatting(event);FormatbarButton('richeditorframe', this, 8);ButtonMouseDown(this);"&gt;The first &lt;span style="font-style: italic;"&gt;i &lt;/span&gt; characters of &lt;span style="font-weight: bold;"&gt;A&lt;/span&gt; equal the first &lt;span style="font-style: italic;"&gt;j - 1&lt;/span&gt; characters of &lt;span style="font-weight: bold;"&gt;B&lt;/span&gt; (this correspond to inserting a character in &lt;span style="font-weight: bold;"&gt;B&lt;/span&gt;)&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span style="display: block;" id="formatbar_Buttons"&gt;&lt;span class="on" style="display: block;" id="formatbar_CreateLink" title="Link" onmouseover="ButtonHoverOn(this);" onmouseout="ButtonHoverOff(this);" onmouseup="" onmousedown="CheckFormatting(event);FormatbarButton('richeditorframe', this, 8);ButtonMouseDown(this);"&gt;The first &lt;span style="font-style: italic;"&gt;i - 1&lt;/span&gt; characters of &lt;span style="font-weight: bold;"&gt;A&lt;/span&gt; equal the first &lt;span style="font-style: italic;"&gt;j&lt;/span&gt; - 1 characters of &lt;span style="font-weight: bold;"&gt;B&lt;/span&gt; (this correspond to substituting a character in &lt;span style="font-weight: bold;"&gt;B&lt;/span&gt;)&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;&lt;/ol&gt;&lt;span style="display: block;" id="formatbar_Buttons"&gt;&lt;span class="on" style="display: block;" id="formatbar_CreateLink" title="Link" onmouseover="ButtonHoverOn(this);" onmouseout="ButtonHoverOff(this);" onmouseup="" onmousedown="CheckFormatting(event);FormatbarButton('richeditorframe', this, 8);ButtonMouseDown(this);"&gt;Whichever number is the smallest, plus one, gives the answer. Using this we can solve the problem bottom up or top down. The &lt;span style="font-weight: bold;"&gt;worst case &lt;/span&gt;complexity of this algorithm is O(&lt;span style="font-weight: bold;"&gt;n&lt;/span&gt; * &lt;span style="font-weight: bold;"&gt;m&lt;/span&gt;) where &lt;span style="font-weight: bold;"&gt;n &lt;/span&gt;and &lt;span style="font-weight: bold;"&gt;m &lt;/span&gt;are lengths of strings &lt;span style="font-weight: bold;"&gt;A&lt;/span&gt; and &lt;span style="font-weight: bold;"&gt;B&lt;/span&gt; respectively.&lt;br /&gt;&lt;br /&gt;Now, in certain areas this problem is expanded to: given a string &lt;span style="font-weight: bold;"&gt;A&lt;/span&gt; and a &lt;span style="font-weight: bold;"&gt;dictionary D&lt;/span&gt;. Find the closest string (with minimal edit distance) to &lt;span style="font-weight: bold;"&gt;A&lt;/span&gt; in &lt;span style="font-weight: bold;"&gt;D&lt;/span&gt;. The simple solution is to run the algorithm described above and just take the minimal distance. This however, can be greatly improved upon.&lt;br /&gt;&lt;br /&gt;Our first observation is this, if the length of string &lt;span style="font-weight: bold;"&gt;A&lt;/span&gt; is &lt;span style="font-weight: bold;"&gt;n&lt;/span&gt; and the length of some string &lt;span style="font-weight: bold;"&gt;B&lt;/span&gt; in &lt;span style="font-weight: bold;"&gt;D&lt;/span&gt; is &lt;span style="font-weight: bold;"&gt;m&lt;/span&gt;. The distance between &lt;span style="font-weight: bold;"&gt;A&lt;/span&gt; and &lt;span style="font-weight: bold;"&gt;B&lt;/span&gt; is at least the absolute value of &lt;span style="font-weight: bold;"&gt;n&lt;/span&gt; - &lt;span style="font-weight: bold;"&gt;m&lt;/span&gt;. Now suppose that we have processed some words in &lt;span style="font-weight: bold;"&gt;D&lt;/span&gt; and the current solution is &lt;span style="font-weight: bold;"&gt;x&lt;/span&gt;. We now know there is no point in even considering any word whose length is more than &lt;span style="font-weight: bold;"&gt;x&lt;/span&gt; away from &lt;span style="font-weight: bold;"&gt;A&lt;/span&gt;.&lt;br /&gt;&lt;br /&gt;But suppose we have a string &lt;span style="font-weight: bold;"&gt;B&lt;/span&gt; whose length is less than &lt;span style="font-weight: bold;"&gt;x&lt;/span&gt; away from &lt;span style="font-weight: bold;"&gt;A&lt;/span&gt;. Can we use the current minimum solution to our advantage here? It turns out we can. If you use top-down approach for the algorithm described above, you can maintain the current minimum number of operations. If this number increases above &lt;span style="font-weight: bold;"&gt;x&lt;/span&gt;, you can terminate that entire branch without fear. This reduces the complexity from O(&lt;span style="font-weight: bold;"&gt;n&lt;/span&gt; * &lt;span style="font-weight: bold;"&gt;m&lt;/span&gt;) to O(&lt;span style="font-weight: bold;"&gt;n&lt;/span&gt; * &lt;span style="font-weight: bold;"&gt;x&lt;/span&gt;). If we can rapidly decrease &lt;span style="font-weight: bold;"&gt;x&lt;/span&gt; to small numbers (say 1,2,3) this is quite a speedup.&lt;br /&gt;&lt;br /&gt;The best way to rapidly decrease &lt;span style="font-weight: bold;"&gt;x&lt;/span&gt; is to apply the first observation again. The only words who can have edit distance 0 in &lt;span style="font-weight: bold;"&gt;D&lt;/span&gt; are those that have exactly the same number of characters as &lt;span style="font-weight: bold;"&gt;A&lt;/span&gt;. So it makes sense to first start with them and try to get &lt;span style="font-weight: bold;"&gt;x&lt;/span&gt; as small as possible. If we do not find a match, it makes sense to try words who have 1 character more/less first. Then 2. Then 3. Then 4. So by preprocessing &lt;span style="font-weight: bold;"&gt;D&lt;/span&gt;, grouping by word length, we can greatly increase the speed.&lt;br /&gt;&lt;br /&gt;Another thing you might notice is that it makes sense to prefer the diagonal top-down move (using  &lt;span style="font-style: italic;"&gt;i - 1, j - 1 &lt;/span&gt;to calculate &lt;span style="font-style: italic;"&gt;i, j&lt;/span&gt;) first since diagonals are more likely to yield smaller solutions.&lt;br /&gt;&lt;br /&gt;If you would like to try out some of the things described here you can try &lt;a href="http://www.facebook.com/careers/puzzles.php?puzzle_id=17"&gt;this facebook puzzle&lt;/a&gt;. I was able to speed up my solution by a factor of 15 using the observations above.&lt;br /&gt;&lt;br /&gt;No code this time, solve the puzzle yourself :D&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7429374688602565856-4337634361615941072?l=mivankovic.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://mivankovic.blogspot.com/feeds/4337634361615941072/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://mivankovic.blogspot.com/2010/02/simple-fast-edit-distance.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7429374688602565856/posts/default/4337634361615941072'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7429374688602565856/posts/default/4337634361615941072'/><link rel='alternate' type='text/html' href='http://mivankovic.blogspot.com/2010/02/simple-fast-edit-distance.html' title='Simple fast edit distance'/><author><name>Marko Ivanković</name><uri>https://profiles.google.com/105493585317824062514</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh4.googleusercontent.com/-YvEzqR3eb2M/AAAAAAAAAAI/AAAAAAAABiU/mQ3RxGl7tN8/s512-c/photo.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7429374688602565856.post-4804485152226075280</id><published>2010-01-09T12:28:00.002+01:00</published><updated>2010-01-09T12:39:38.113+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='confirmed solution'/><category scheme='http://www.blogger.com/atom/ns#' term='puzzle'/><category scheme='http://www.blogger.com/atom/ns#' term='monte-carlo'/><category scheme='http://www.blogger.com/atom/ns#' term='The Puzzle Toad'/><title type='text'>Puzzled</title><content type='html'>Tom Bohman, Oleg Pikhurko, Alan Frieze and Danny Sleator from Carnegie Mellon run a cool puzzle site &lt;a href="http://www.cs.cmu.edu/puzzle/"&gt;The Puzzle Toad&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;They present a series of quite interesting and challenging puzzles. A friend of mine raised some questions about &lt;a href="http://www.cs.cmu.edu/puzzle/solution29.pdf"&gt;the solution&lt;/a&gt; to one of &lt;a href="http://www.cs.cmu.edu/puzzle/puzzle29.html"&gt;their puzzles called "Seating"&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;Without further ado &lt;a href="http://code.google.com/p/mivankovic-blog/source/browse/trunk/puzzle-seating/puzzle-seating.cpp"&gt;here&lt;/a&gt; is a monte-carlo simulation confirming their result.&lt;br /&gt;&lt;br /&gt;On a side note the current puzzle "Let there be light" is fascinating and difficult and that same friend of mine and I are trying to storm it as you read this.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7429374688602565856-4804485152226075280?l=mivankovic.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://mivankovic.blogspot.com/feeds/4804485152226075280/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://mivankovic.blogspot.com/2010/01/puzzled.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7429374688602565856/posts/default/4804485152226075280'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7429374688602565856/posts/default/4804485152226075280'/><link rel='alternate' type='text/html' href='http://mivankovic.blogspot.com/2010/01/puzzled.html' title='Puzzled'/><author><name>Marko Ivanković</name><uri>https://profiles.google.com/105493585317824062514</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh4.googleusercontent.com/-YvEzqR3eb2M/AAAAAAAAAAI/AAAAAAAABiU/mQ3RxGl7tN8/s512-c/photo.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7429374688602565856.post-2819865677913093592</id><published>2009-12-08T10:28:00.002+01:00</published><updated>2009-12-08T10:55:56.302+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='htc hero'/><category scheme='http://www.blogger.com/atom/ns#' term='scanner'/><category scheme='http://www.blogger.com/atom/ns#' term='android'/><category scheme='http://www.blogger.com/atom/ns#' term='tricoder'/><title type='text'>HTC Hero</title><content type='html'>So, recently I got a &lt;a href="http://en.wikipedia.org/wiki/HTC_Hero"&gt;HTC Hero&lt;/a&gt; and it really is good. Of course I am not the average Hero user, having no Facebook or Flickr (and Hero Loooooooooooves syncing with Facebook and Flickr) so I may be having a bit different experience than the rest. I got a black version of it, and my first thought when I saw it was: "Wow, this thing totally looks like some Sci-Fi scanning thingy". My first instinct was "Install scanning stuff". And oh did the market provide:&lt;br /&gt;&lt;ol&gt;&lt;li&gt;WiFi analyzer by Kevin Yuan - this is the hackers dream. It displays serious amount of data on wireless networks surrounding you. Channel list, signal strength, encryption type, BSSID. What it lacks however is the ability to save IV-s from WEP networks and handshakes for WAP networks. That would turn it into a real hacking tool. I know that active attack is the best for WEP but don't think that will come so fast to android.&lt;/li&gt;&lt;li&gt;Metal detector (not the musical kind) by Kurt Radwanski - does exactly what it says on the tin - it detects metal objects under your android. This is hyper useful if you ever need to drill a hole next to a power line. I tested it around my apartment and it successfully detected around 80% of wires running through my walls. It failed on one wall, but I think it is the main wall with armed concrete so it kept constantly detecting wall armature.&lt;/li&gt;&lt;li&gt;Compass by Snaptic, Inc. - a nice looking compass. Tested it, it works really well. Not much to say here. If I ever get lost, maybe I'll post more about it :)&lt;/li&gt;&lt;li&gt;GPS Test by Mike Lockwood - this one I installed a bit late in the game, it does one thing, but it does it good. It shows the GPS status and locations of detected satellites. Really useful if you want to check your GPS quality before launching Google Maps. It also helped me determine one important thing: GPS doesn't work while you are in train. Not sure why. I guess the train acts as a Farradey cage.&lt;/li&gt;&lt;li&gt;Spectral View Analyzer by RadonSoft - It computes the spectral analysis of audio input it gets from the mic and shows it on screen. I only have the free version, sampling in 0-8 kHz range but it works really well. The full version (4 euro) gives you the option to select ranges and color schemes. It's really fun to scan your speakers and determine the range they opperate in. Also, it changes the way you look at some things. You can notice patterns in sound that you would never notice before.&lt;/li&gt;&lt;/ol&gt;Now, there is one app that would do all this: the tricoder ( http://code.google.com/p/moonblink/wiki/Tricorder ). But I couldn't find it in the market. I am not completely sure why is that. The web site states that it can be found at the market, but my search runs blank every time I try.&lt;br /&gt;&lt;br /&gt;So, that's that. I already downloaded Android SDK and will write stuff for it. Probably start with something WiFi oriented. I wonder how difficult it would be to write a passive sniffer for WEP IV-s and WAP handshakes.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7429374688602565856-2819865677913093592?l=mivankovic.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://mivankovic.blogspot.com/feeds/2819865677913093592/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://mivankovic.blogspot.com/2009/12/htc-hero.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7429374688602565856/posts/default/2819865677913093592'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7429374688602565856/posts/default/2819865677913093592'/><link rel='alternate' type='text/html' href='http://mivankovic.blogspot.com/2009/12/htc-hero.html' title='HTC Hero'/><author><name>Marko Ivanković</name><uri>https://profiles.google.com/105493585317824062514</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh4.googleusercontent.com/-YvEzqR3eb2M/AAAAAAAAAAI/AAAAAAAABiU/mQ3RxGl7tN8/s512-c/photo.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7429374688602565856.post-3191305423829308044</id><published>2009-11-14T18:42:00.002+01:00</published><updated>2009-11-14T19:00:56.636+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='crazy'/><category scheme='http://www.blogger.com/atom/ns#' term='fun'/><category scheme='http://www.blogger.com/atom/ns#' term='genetic programming'/><category scheme='http://www.blogger.com/atom/ns#' term='brainfuck'/><title type='text'>Brainfuck genetic programming</title><content type='html'>For fun and a bit of overkill I decided to code a genetic programming project. For starters I needed a problem so I decided to evolve Brainfuck programs. For starters I wanted to evolve a basic "Hello World!\n" program.&lt;br /&gt;&lt;br /&gt;And boy was it different than I expected. First of all, NOT ALL brainfuck codes are valid. The brackets need to be balanced or the whole thing explodes. Second, not all valid brainfuck codes terminate. Now I did expect both of these things, but accounting for them was funny. At first I generated random strings of BF code, and accounted for it's validity in the fitness function. That did not turn out so good. Turns out it is much more efficient to always produce valid code, even if it does complicate mutations somewhat.&lt;br /&gt;&lt;br /&gt;Other observations I made are:&lt;br /&gt;&lt;br /&gt;&lt;ul&gt;&lt;li&gt;A lot can be done in less than 10.000 execution steps of BF code. Setting 10.000 as the endless loop limit is ok.&lt;/li&gt;&lt;li&gt;Getting to the exact output is far more difficult than getting somewhere in the ballpark.&lt;/li&gt;&lt;li&gt;Crossovers are not as useful as advertised in this problem&lt;/li&gt;&lt;/ul&gt;&lt;br /&gt;Of course my code is quite bad and could be improved much more beyond this point, but it is usable as is so you can download it &lt;a href="http://code.google.com/p/mivankovic-blog/source/browse/trunk/bfgenetic/bfgenetic.cpp"&gt;here&lt;/a&gt;. If you tinker with it and improve the performance drastically please let me know.&lt;br /&gt;&lt;br /&gt;Oh yeah, fragments of the code suggest input support, and I do plan to evolve programs that consume user input. But that will be another post.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7429374688602565856-3191305423829308044?l=mivankovic.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://mivankovic.blogspot.com/feeds/3191305423829308044/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://mivankovic.blogspot.com/2009/11/brainfuck-genetic-programming.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7429374688602565856/posts/default/3191305423829308044'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7429374688602565856/posts/default/3191305423829308044'/><link rel='alternate' type='text/html' href='http://mivankovic.blogspot.com/2009/11/brainfuck-genetic-programming.html' title='Brainfuck genetic programming'/><author><name>Marko Ivanković</name><uri>https://profiles.google.com/105493585317824062514</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh4.googleusercontent.com/-YvEzqR3eb2M/AAAAAAAAAAI/AAAAAAAABiU/mQ3RxGl7tN8/s512-c/photo.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7429374688602565856.post-813596935042938121</id><published>2009-11-13T11:37:00.002+01:00</published><updated>2009-11-13T11:43:02.016+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='AI'/><category scheme='http://www.blogger.com/atom/ns#' term='awsome'/><category scheme='http://www.blogger.com/atom/ns#' term='games'/><category scheme='http://www.blogger.com/atom/ns#' term='StarCraft'/><category scheme='http://www.blogger.com/atom/ns#' term='machine learning'/><title type='text'>StarCraft AI Tournament</title><content type='html'>I recently got this link from a friend:&lt;br /&gt;&lt;br /&gt;&lt;a href="http://eis.ucsc.edu/StarCraftAICompetition"&gt;http://eis.ucsc.edu/StarCraftAICompetition&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;It's so incredibly awesome. I always wandered how it would be to write a StarCraft AI but was always set back by the idea that I have to spend god-only-knows how long hacking StarCraft itself so that it lets me interface. But with the API these guys provided, this could prove to be quite fun.&lt;br /&gt;&lt;br /&gt;It could actually be a continuation of my project for the machine learning class, the micromanagement part at least since it requires fast tactical adaptation.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7429374688602565856-813596935042938121?l=mivankovic.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://mivankovic.blogspot.com/feeds/813596935042938121/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://mivankovic.blogspot.com/2009/11/starcraft-ai-tournament.html#comment-form' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7429374688602565856/posts/default/813596935042938121'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7429374688602565856/posts/default/813596935042938121'/><link rel='alternate' type='text/html' href='http://mivankovic.blogspot.com/2009/11/starcraft-ai-tournament.html' title='StarCraft AI Tournament'/><author><name>Marko Ivanković</name><uri>https://profiles.google.com/105493585317824062514</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh4.googleusercontent.com/-YvEzqR3eb2M/AAAAAAAAAAI/AAAAAAAABiU/mQ3RxGl7tN8/s512-c/photo.jpg'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7429374688602565856.post-4073699862081003868</id><published>2009-10-17T17:33:00.004+02:00</published><updated>2009-10-17T17:40:31.259+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='competition'/><category scheme='http://www.blogger.com/atom/ns#' term='algorithms'/><category scheme='http://www.blogger.com/atom/ns#' term='university'/><category scheme='http://www.blogger.com/atom/ns#' term='cepc'/><title type='text'>CEPC</title><content type='html'>Today my team and I competed at the university tryouts for this years &lt;a href="http://cepc09.ii.uni.wroc.pl/"&gt;CEPC&lt;/a&gt;. We totally rocked and are going as the second team for our university. All tasks, test data and results can be found &lt;a href="http://hsin.hr/studenti2009/"&gt;here&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;It's in Croatian, so in the off chance that somebody that doesn't understand it and reads my blog a brief translation is presented here: Zadaci = tasks, Test podaci = test data, Rezultati = results.&lt;br /&gt;&lt;br /&gt;Wrocław, here we come!&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7429374688602565856-4073699862081003868?l=mivankovic.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://mivankovic.blogspot.com/feeds/4073699862081003868/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://mivankovic.blogspot.com/2009/10/cepc.html#comment-form' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7429374688602565856/posts/default/4073699862081003868'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7429374688602565856/posts/default/4073699862081003868'/><link rel='alternate' type='text/html' href='http://mivankovic.blogspot.com/2009/10/cepc.html' title='CEPC'/><author><name>Marko Ivanković</name><uri>https://profiles.google.com/105493585317824062514</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh4.googleusercontent.com/-YvEzqR3eb2M/AAAAAAAAAAI/AAAAAAAABiU/mQ3RxGl7tN8/s512-c/photo.jpg'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7429374688602565856.post-3903699892574103391</id><published>2009-10-05T15:33:00.004+02:00</published><updated>2009-10-17T17:40:03.901+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='javascript'/><category scheme='http://www.blogger.com/atom/ns#' term='RPC'/><category scheme='http://www.blogger.com/atom/ns#' term='html 5'/><category scheme='http://www.blogger.com/atom/ns#' term='pmrpc'/><category scheme='http://www.blogger.com/atom/ns#' term='JSON-RPC'/><title type='text'>Pmrpc</title><content type='html'>I've been working on this project sometime now and finally it is good enough to be presented to the world.&lt;br /&gt;&lt;br /&gt;&lt;strong&gt;&lt;a href="http://code.google.com/p/pmrpc/"&gt;Pmrpc&lt;/a&gt; &lt;/strong&gt;is a HTML5 inter-window cross-domain JSON-RPC based remote procedure call JavaScript library. The library provides a simple API for exposing and calling procedures from windows or iFrames on different domains, without being subject to the same-origin policy. Pmrpc also provides several&lt;span style="font-weight: bold;"&gt; &lt;/span&gt;advanced features&lt;strong&gt;&lt;/strong&gt;: callbacks similar to AJAX calls, ACL-based access control, asynchronous procedure support and fault-tolerance via retries.&lt;br /&gt;&lt;br /&gt;It's based on open standards and distributed under Apache v2.0 license which is awesome :D&lt;br /&gt;&lt;br /&gt;I'm very excited about it because it's such a bountiful project. We have a lot of ideas where to go next and we would appreciate community input to help us in choosing our direction. Comment here, on google code, why you can even email me if you like :D&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7429374688602565856-3903699892574103391?l=mivankovic.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://mivankovic.blogspot.com/feeds/3903699892574103391/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://mivankovic.blogspot.com/2009/10/pmrpc.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7429374688602565856/posts/default/3903699892574103391'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7429374688602565856/posts/default/3903699892574103391'/><link rel='alternate' type='text/html' href='http://mivankovic.blogspot.com/2009/10/pmrpc.html' title='Pmrpc'/><author><name>Marko Ivanković</name><uri>https://profiles.google.com/105493585317824062514</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh4.googleusercontent.com/-YvEzqR3eb2M/AAAAAAAAAAI/AAAAAAAABiU/mQ3RxGl7tN8/s512-c/photo.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7429374688602565856.post-2226802829903787938</id><published>2009-09-17T20:46:00.009+02:00</published><updated>2009-09-17T23:03:28.825+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='wikipedia'/><category scheme='http://www.blogger.com/atom/ns#' term='python'/><category scheme='http://www.blogger.com/atom/ns#' term='comic'/><category scheme='http://www.blogger.com/atom/ns#' term='shortest path'/><category scheme='http://www.blogger.com/atom/ns#' term='script'/><category scheme='http://www.blogger.com/atom/ns#' term='game'/><title type='text'>Wikipedia game -  in 5 clicks</title><content type='html'>A friend of mine told me about a game he stumbled upon recently. It's called "five clicks to Hitler". The objective of the game is to go to the &lt;a href="http://en.wikipedia.org/wiki/Special:Random"&gt;Wikipedia Random article page&lt;/a&gt; and try to get to Adolf Hitler article in 5 clicks or less.&lt;br /&gt;&lt;br /&gt;I was a bit bored one day and said, "well, why would I play the game myself? Real programmers write scripts to do all the dirty work for them.". So I did. And I release it to the world so nobody has to actually play the game.&lt;br /&gt;&lt;br /&gt;The starting page is passed as a command line argument. You don't need to enter the full URL. Just the part after "/wiki/". For example if you want to start from &lt;a href="http://en.wikipedia.org/wiki/Bodok_seal"&gt;this&lt;/a&gt; Wikipedia article describing the fascinating Bodok seal: http://en.wikipedia.org/wiki/Bodok_seal , you would start the script like so&lt;br /&gt;&lt;br /&gt;./wikiscp.py Bodok_seal&lt;br /&gt;&lt;br /&gt;The default target of the script is the Wikipedia article on Mahatma Ghandi, but if you want to change that a -t command line option is provided. So if you would like to know the shortest click-path between the Bodok seal article and Alpine skiing article you start the script like this&lt;br /&gt;&lt;br /&gt;./wikiscp.py -t Alpine_skiing Bodok_seal&lt;br /&gt;&lt;br /&gt;Have fun.&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;#!/usr/bin/env python&lt;br /&gt;# A small script that seeks the shortest path between two wikipedia articles&lt;br /&gt;#&lt;br /&gt;# Copyright 2009 Marko Ivankovic&lt;br /&gt;#&lt;br /&gt;#    This program is free software: you can redistribute it and/or modify&lt;br /&gt;#    it under the terms of the GNU General Public License as published by&lt;br /&gt;#    the Free Software Foundation, either version 3 of the License, or&lt;br /&gt;#    (at your option) any later version.&lt;br /&gt;#&lt;br /&gt;#    This program is distributed in the hope that it will be useful,&lt;br /&gt;#    but WITHOUT ANY WARRANTY; without even the implied warranty of&lt;br /&gt;#    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the&lt;br /&gt;#    GNU General Public License for more details.&lt;br /&gt;#&lt;br /&gt;#    You should have received a copy of the GNU General Public License&lt;br /&gt;#    along with this program.  If not, see http://www.gnu.org/licenses/.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;from urllib import FancyURLopener&lt;br /&gt;import re&lt;br /&gt;import getopt, sys&lt;br /&gt;&lt;br /&gt;class CoolURLOpener(FancyURLopener, object):&lt;br /&gt;   version = 'Mozilla/5.0 (Windows; U; Windows NT 5.1; it; rv:1.8.1.11) Gecko/20071127 Firefox/2.0.0.11'&lt;br /&gt;&lt;br /&gt;opts, args = getopt.getopt(sys.argv[1:], "t:", ["target"])&lt;br /&gt;&lt;br /&gt;target = "Mohandas_Karamchand_Gandhi"&lt;br /&gt;limit = 5&lt;br /&gt;for o, a in opts:&lt;br /&gt;   if o in ("-t", "--target"):&lt;br /&gt;      target = a&lt;br /&gt;&lt;br /&gt;coolOpener = CoolURLOpener()&lt;br /&gt;prefix = "http://en.wikipedia.org/wiki/"&lt;br /&gt;for start in args:&lt;br /&gt;   visited = {}&lt;br /&gt;   existing = {}&lt;br /&gt;   queue = []&lt;br /&gt;   existing[start] = (0, "N/A")&lt;br /&gt;   current = start&lt;br /&gt;   num = 0&lt;br /&gt;   links = 0&lt;br /&gt;   targetFound = False&lt;br /&gt;   maxDist = 0&lt;br /&gt;   while not targetFound:&lt;br /&gt;     visited[current] = existing[current]&lt;br /&gt;     step = existing[current][0]&lt;br /&gt;     del existing[current]&lt;br /&gt;     if step == limit:&lt;br /&gt;         current = queue[0]&lt;br /&gt;         del queue[0]&lt;br /&gt;         continue&lt;br /&gt;     handle = coolOpener.open(prefix + current)&lt;br /&gt;     data = handle.read()&lt;br /&gt;     data = re.findall(r"&amp;lt;a href=\"/wiki/(.*?)\" .*?&amp;gt;.*?&amp;lt;/a&amp;gt;", data, re.S)&lt;br /&gt;     num = num + 1&lt;br /&gt;     for candidate in data:&lt;br /&gt;         if not ":" in candidate and candidate != "Main_Page":&lt;br /&gt;          links = links + 1&lt;br /&gt;          if not candidate in visited and not candidate in existing:&lt;br /&gt;              if candidate == target:&lt;br /&gt;               targetFound = True&lt;br /&gt;              existing[candidate] = (step + 1, current)&lt;br /&gt;              if step + 1 &gt; maxDist:&lt;br /&gt;               maxDist = step + 1&lt;br /&gt;              queue.append(candidate)&lt;br /&gt;     current = queue[0]&lt;br /&gt;     del queue[0]&lt;br /&gt;   &lt;br /&gt;   if target in existing:&lt;br /&gt;    print "Target found in %d steps" % existing[target][0]&lt;br /&gt;    print "Path is (upsidedown):"&lt;br /&gt;    print "\t %s" % target&lt;br /&gt;    target = existing[target][1]&lt;br /&gt;    while target != start:&lt;br /&gt;     print "\tarrived from: %s" % target&lt;br /&gt;     target = visited[target][1]&lt;br /&gt;    print "\tarrived from: %s" % target&lt;br /&gt;   else:&lt;br /&gt;    print "There is no link between %s and %s" % (start, target)&lt;br /&gt;&lt;/pre&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7429374688602565856-2226802829903787938?l=mivankovic.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://mivankovic.blogspot.com/feeds/2226802829903787938/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://mivankovic.blogspot.com/2009/09/wikipedia-game-in-5-clicks.html#comment-form' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7429374688602565856/posts/default/2226802829903787938'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7429374688602565856/posts/default/2226802829903787938'/><link rel='alternate' type='text/html' href='http://mivankovic.blogspot.com/2009/09/wikipedia-game-in-5-clicks.html' title='Wikipedia game - &lt;page&gt; in 5 clicks'/><author><name>Marko Ivanković</name><uri>https://profiles.google.com/105493585317824062514</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh4.googleusercontent.com/-YvEzqR3eb2M/AAAAAAAAAAI/AAAAAAAABiU/mQ3RxGl7tN8/s512-c/photo.jpg'/></author><thr:total>1</thr:total></entry></feed>
