Wednesday, July 25, 2012

Steam on Linux

Steam is coming to Linux!!!. If you don't believe me check out this link: http://blogs.valvesoftware.com/linux. Valve will start off by releasing Left 4 Dead 2, with more of their games to follow.

Thursday, July 12, 2012

Regarding the Whaleventures-pact of 10/11/12 July 2012

Wow, this is quite strange, it feels like a lifetime ago when I last read the comments on Jaco's original post regarding time travel and the "whaleventures-pact" as he put it.

Firstly, I have seen the future. Heck, I just came from it. (I just realised that talking about it is more difficult than I thought it would be, because for me everything is past tense, but for you guys everything will be future tense. So forgive me if I get the tenses wrong.)

Secondly, for fear of causing a butterfly effect I have decided not to tell you guys about all the stuff that has happened (is going to happen) through the years, except that time travel is (has become) a reality as you may have deducted by now. So, let it be known that the Whaleventures-pact is a strong bond that ties us together.

Anyways, gotta run, the time travel police is closing in. Yeah, I know right!? Such a cliché.

Tuesday, July 10, 2012

Monday, July 9, 2012

Thrift TThreadedPoolServer thread pool

Don't know how many of you are still using Thrift - it's still going strong here because it works so much better than RMI.

Just a small tip, I recently came across a TThreadedPoolServer. The idea is that a thread pool gets used to serve requests from the clients - so each client has its own thread. In my opinion, this is not ideal, but this is how it's working at the moment.

There is a danger though: make sure you set the maximum number of threads in the pool! Otherwise it just keeps on adding threads to the pool - returning them I don't know when. The app was sitting at 400+ threads just now.

It's easy to do:

You can of course set a minimum etc. as well. I'm not sure when the threads are "freed" and returned to the pool - I'll investigate this later today.

Thursday, July 5, 2012

On progress of thought and not just jumping in

We all know it's hard to think. One of my previous employers always famously said "Thinking is hard work. If it wasn't, everyone would be doing it.". So I just want to share something that happened to me this morning, to illustrate this point. And also how you shouldn't just always write down the first thing that comes to mind.

So, I had a list: [a,b,c,d,e]. I wanted to get the "pairs" in this list. So basically, I wanted a function f(l), that given [a,b,c,d,e] would give me [[a,b],[b,c],[c,d],[d,e],[e,a]]. I wanted to use this to draw lines, connecting a bunch of points. (Note: it is important that the last element in the list connects to the first, otherwise I'll have a gap in my line drawing)

So, the classical way to do this, would be to go ahead and code up something like:

This works. But it's not particularly elegant, and it has a special case for the last entry, which I don't like, and would like to avoid. Also, it's very specific - I can't easily change it to pair n and n+2, or n,n+1,n+2 for example (Not that I need it at the moment, but still, its a very *specific* implementation.

So then I thought, what about taking the list, and zipping f(x) = x, with f(x) = x + 1, over the length of the array. That would give me the indexes of the pairs. So, I would end up with a list like: [[0,1],[1,2],[2,3],...] etc. and then I could just use that list, and map over it to get the appropriate elements in the original list. I could even then zip additional lists as well, for eg. f(x) = x + 2, f(x) = x + 3 which will give me 4-element pairs. Nice.

Problem solved right? On further inspection - not really. There is still a MASSIVE edge case there at the end. In fact, with this solution, the edge case is probably even more difficult to manage then in the purely imperative form. So I decided, I'm not even gonna code up the solution like this, cos I haven't yet had enough caffeine to deal with this edge case mess.

So then I realised, that basically what I want to do, is "rotate" the original list, and zip the original one, with the rotated one. Yes, good old ROT-n. So I take my input list, rot-1 it, and then map the input list with this rotated list. This gives me _exactly_ what I want, and also solves the edge case problem for me very elegantly! I now also have the ability to pair an arbitrary number of elements from the list, by just rot-1'ing, then rot-2'ing, then rot-3'ing, and then zipping all these lists together. Very nice.

But now, I need a rot-n function. Javascript (or underscore) doesn't have one, so I'm gonna have to implement my own. Dammit, right? Remember those varsity excercises where we did rot-13 in like first year? Not really lus to implement this right now! And then, what will I gain, really? Then I could just my original implementation!

Then, I had a quick chat with Gary, and we came to the conclusion, that a rot-n list, is simply the concatenation of the tail of the list, from (n,length), with the head of the list from (0,n). This makes my job much, much easier. Turns out, rot-n in Javascript looks as follows:

So, armed with that, my original solution simply becomes:

Much nicer hey? And also, more general. And I sommer got a rot-n function out of the deal as well!

This was just my latest example of how it helped me to think things throught a bit before I start to write the solution. I'm very much a Just Do It guy, but it's good to sit back and think, you tend to get much more out of it then what you just intended to write.

Monday, July 2, 2012

You selfish pig!

Ok, so the story goes as follows:

You are on a plane on the aisle seat. At the window is guy in a business suit. Quiet and seemingly very annoyed. You don't like him. In the middle, a proverbial little old lady is sitting. In contrast to the guy in the window, she seems rather chirpy. In the middle of the flight she starts talking to the both of you: "Fellows... you know what? My husband was in the steel business and he died last year, leaving me with a fortune. I'm bored and I want some fun. I'll tell you what. I'll give $100,000.00 and if you can decide how to split it, you can have it. If not, you both get nothing."

For the first time in the flight the guy at the window seems interested. "My name is Dick. What's the catch?" he says. "Ok Dick", the lady continues. "You can decide how the money should be split and if the handsome fellow next to me agrees, you can have the money, okay?". "Sure!", Dick says. "I'll take $99,000.00 and the guy in the aisle can have the other $1,000.00"

So what do you do? Can you feel Richard Dawkins' selfish gene stirring in your loins? Logically, you should always accept, because you have nothing to lose. Right?Strangely, the majority of people starts declining at around 60% (i.e. 60% for the proposer and 40% for the decider).

I was wondering what a computer will do with this... I set up the experiment as follows: A hundred thousand agents playing the game in a tournament fashion. Pick two random agents, let them play, repeat (they play one game, one the decider, the other the proposer). Each agent evolves two values. One value (the "proposition") is the value it will propose and the "decision-threshold", which is the minimum it will accept. Therefore, for a [0.9, 0.6] pair, the agent will propose 90% of the money for itself and will only accept a minimum cut of 40%, when it has to decide. I allowed this to evolve (population size of 100,000). After several generations, quadrillions of games, the most successful agent was as follows:

 P:0.73 D:0.85

This means, proposing a 73%-27% split and declining any selfish agent that wants more then 85% was optimal. Hell, this was not at all expected! I repeated the experiment several times, each time with similar results. The decision-threshold was always slightly higher, but the proposition threshold seemed to be fairly stable at around 0.7-0.9. How come? Can computers really be selfish too?

EDIT: After further experimentation, I found that the TOTAL money distributed amongst individuals tend to increase (i.e. the group improves as a whole) - and rather quickly as well.

If I initialise all agents to the most narsistic value of (P,D)=(1,0), which means I want all the money and if you don't propose I get everything, I say no.  The total money made by each generation changes as follows (generation; total money):



After which it stabilises.  This is completely emergent as I never test the total money made by the population.