Tuesday, June 24, 2014

Creative Programming for Digital Media & Mobile Apps on Coursera

I just wanted to let you know that another interesting course is starting today on Coursera - Creative Programming for Digital Media and Mobile Apps. I've just gone through the first week of video lessons and they are quite cool. They feature Processing - a development environment for visual arts and various creative projects. It's basically Java with a convenient library of functions that let you write graphic applications much faster. What is great about it is that it lets you export your projects as JavaScript or Android code, so you can easily run them on mobile devices (including iPods and iPads). I used Processing in the past and I quite liked its simplicity and power, although debugging was somewhat difficult.

Using the occasion, I'd like to present to you a site that inspired me a couple years ago to play with computational graphics and various visual effects: Complexification. Although it seems discontinued, you can still find there lots of awesome yet simple pieces of computational art... and the source code is mostly available as well (everything is written in no other than Processing again).

My firts Android live wallpaper has been inspired by the Binary Ring effect from Complexification. Later on, I created another one - Blender, which was based on a submission to the Processing's Exhibition section. It was all before I discovered that live wallpapers were extremely difficult to monetize (especially after notification ads have been banned by Google) and that people didn't download them almost at all, despite being advertised on sites like LiveWallpapers.org...

If you browse through the exhibition archives some more, you'll find plenty of mind-blowing ideas like Mycelium or Shadow Monsters. I've been trying to code up something as awesome ever since I discovered them, but never with much success. Nonetheless, I had a chance to experiment with fractals (Mandelbrot Set rules) and decomposing images into single-colored rectangles, which resulted in a pretty neat effect as well. Hell, at some point I even decided to give my whole family huge prints of computational art interpretations of their photographs for Christmas. How geeky is that!

But I got excited again, so let's come back to the main subject for a while longer. Sign up for the Coursera course, if you haven't done it already, because it's cool, educating and doesn't cost you a dime. If you come up with a Processing app that you'd like sharing with the rest of the people here, feel free to post it in the comments section. I'd be happy to give it a try. Perhaps I'll manage to create something worth mentioning as well...

Thursday, June 19, 2014

Transforming SVG images into Android Drawables


Today I'd like to share with you a technique I used to create my map apps. I've never heard of anyone using it before, even though I find it quite simple. It lets you use SVG images inside your Android apps without any external libraries or extra code. What is more, the images obtained this way load instantly and can be magnified indefinitely without any loss of quality. Sounds interesting? Keep on reading to find out how it actually works.

It all began with my frustration with bitmaps, which caused OutOfMemoryErrors when used in too high resolution or zoomed in too much. I decided to switch to vector images, which unfortunately are not supported out of the box by Android. You have to use SVG parsing libraries that sometimes do not support certain features (text, gradients, symbols), contain bugs, and take a couple of seconds to create a medium-sized image.

After some time an idea came to me - what if I transformed an SVG loading library so that it printed Java code instead of executing it and returning a Drawable instance? It sounded very easy and turned out to require much more work than I initially expected, but the final result was great. All I needed to do was take the printed Java code and paste it inside a new class.

If it still sounds a little abstract to you, I created a sample app that uses an image generated this way. It basically just shows a vector-based creature and lets you magnify it up to 16 times (see the screenshots on the right). You can download it for free from Google Play and test it yourself. I'm making its full source code available as well, so feel free to take a look at it.

If you're wondering what kind of apps you could create using vector images, go and see my Milan Metro. It's a great example of simplicity and performance (just compare it with other similar apps!).

Apart from that, vector graphics is great for UI elements, because it scales without losing quality on all devices and screen densities. There is no need to create separate versions of resources for mdpi, hdpi, xhdpi, xxhdpi, etc.

Another good example I can think of are splash screens. What if you could make sure that they look pretty, regardless of the screen resolution and size, taking much less space at the same time? Wouldn't that be awesome?!

If you'd like to have your SVG pictures transformed into Drawables, check out my Fiverr gig - I can do it for you. You can also contact me via email (bartas [dot] wesolowski [at] gmail [dot] com) if you have a bigger task for me or if you want more instructions on how to implement a similar thing yourself.

Sunday, June 8, 2014

How I didn't get a job at Google

About 2 months ago I got an email asking me if I'd be interested in working for Google. Without much thinking I replied "hell yes", or something of this meaning. They were supposed to call me in a couple of days to discuss the whole procedure. In fact, being quite absent minded at times, I totally forgot about it, and you can imagine my surprise when during my dinner I got an international call from a guy explaining to me how the hiring process works, and then asking me questions about asymptotic complexity. Fortunately, my answers, although somewhat chaotic, seemed to satisfy my interlocutor. We scheduled another interview, also on the phone, but this time involving solving problems and writing code online. I was given four weeks to refresh my knowledge of algorithms.

At that point I decided to get some outside help. I contacted a friend who works for Google in the USA. She suggested that I should go through the MIT Algorithms course and familiarize myself with The Algorithms Design Manual. I started with the video course, since it seemed to me easier to chew up (how wrong I was at that time!). I watched almost 40h of material, took tons of notes and did extensive research online on some of the techniques I didn't quite understand. I didn't have time to event touch the book, but I was putting trust in the MIT professors and their extraordinary teaching skills.

Four weeks passed in a blink of an eye, and so came the day of the interview. I wasn't sure what problem difficulty to expect but I was about to find out. To my bewilderment, the task was actually quite simple. I had to write a Java method building a team ranking chart based on the match results given in a specific format. I breathed with relief, but I still made some small mistakes (fortunately I was able to detect them fairly fast). I didn't even think that they were judging not just my coding skills but also the way I approached the problem and tested my solution. All in all, I got through again and got accepted for an on-site interview. Things were getting really serious.

I had another four weeks to prepare for the next step. I finally coped with the algorithms book, which was great and I recommend it to all of you. I solved 69 problems on Timus (a Russian online judge, which I like). I took part in one online coaching session organized by Google (although I was very late for it because the person who organized it gave me a wrong hour). I studied the official guides telling you how to prepare for a Google interview. I found another helpful book- Cracking the Coding Interview, which was a great source of possible questions and tips for coping with them. In the end, I felt as prepared as I possibly could be.

The interview itself took place in Cracow (Poland) and was composed of five sessions (each with different person) and a lunch (not being evaluated by them). They paid for my plane tickets from Milan and booked me a 4-star hotel (only one night though, the second night I stayed with a friend in a 4-person room :)). Obviously, I didn't sleep very well because I was nervous as hell. I couldn't wait to finally get the burden off my chest, no matter the result. I arrived at the Market Square, where the company's seat is, feeling rather shitty, and trying to make myself think about more pleasant things.

The five sessions went actually quite well. I never had a major glitch. I managed to get out of difficult situations (e.g. when I didn't know the exact method signatures or class names) by going around them in a fairly elegant way. This time I was very aware that they were judging my approach and testing capabilities as well, so even when they were asking me about something simple, I tried to be as thorough as I possibly could. At lunch, I had a pleasant chit-chat with a guy who was telling me about his work (even going into details, which I was quite surprised to hear). Eventually, I let him eat because he didn't have a chance to touch his food when I was already half through mine.

When I left the building I felt such a release that I can't really describe it with words. The world was suddenly beautiful again, the sun was shining, and the ice cream tasted great. I half-convinced myself that I would get the job, because I was happy about my performance. I honestly couldn't think of anything I could have done better, bearing in mind all my preparation. Now, I just had to wait for my recruiter to call me (she went on vacations for two weeks, so I knew it would be in some time).

Three days ago, when I was on a train, I got the actual call. She told me that unfortunately she didn't have any good news for me. I was not accepted. She assured me that they usually give extensive feedback, but in my case she simply had nothing to say. She suggested trying again next year. Then she hung up.

I probably don't have to tell you that I felt terribly sad, not only because I didn't get the job all programmers dream about, but also because I commited so much of my time to preparing myself. Telling my friends about it, while they were expecting from you to be a genius, was not an easy task as well. I think I'm getting over it now, although I still feel a little nostalgic. We'll see what the future will bring for me instead.

When I come to think of it now, I'm not even sure if Google would be the best place for me. Of course, they have great working conditions and let you be part of a solution that millions of people use every day. However, they are still a big corporation with all its disadvantages - there are people above you who decide what's to be done and in what way, and you're just a cog in a big machine.

For all of you who'd like to give Google a try as well, you can apply here:
http://www.google.com/about/careers/
Just bear in mind that you'll have to commit quite a lot of your time for preparations, and that perhaps it's not exactly the thing that you would like to be doing (maybe you like mobile apps like me). Anyway, I hope you enjoyed my story, and should you ever go through the whole process, I wish you more luck than I had.

Thursday, May 22, 2014

Plans for the future

Hi guys! Thanks for visiting my blog again. Today, I'd like to reveal some of my plans for the next couple of months. I know I haven't been very active recently, but hopefully it's going to change next week. I've been studying for a very important job interview, which is going to be on Monday. Please, keep your fingers crossed. No matter the result though, I'll definitely be going back to Android work and here's a list of stuff that I'm going to focus on.

Crashlytics

I really want to try this crash reporting system. I'm using Crittercism right now, but I only have a limited free version, which doesn't let me do more sophisticated stuff like sending information about caught exceptions. The reports don't look too pretty as well. I was hoping that Crashlytics might be the way to go, especially that it's used by such companies like PayPal, Walmart, Dominos or Groupon. Oh, and I forgot the best thing - it's totally free (even the enterprise features).

Mastermind Group

Recently, I came to the conclusion that I need a group of people who would help me make my apps better and share their experiences with me. I don't mean just giving me good ratings on Google Play. I mean giving me information on what I could do better, which app kinds are working and which are not, what ad networks bring the most revenue, etc. Of course I would help them as well, sharing as much of my knowledge as I can. I'm in the process of contacting some of the people I know, who are on the similar stage as I am. I think 5-8 members would be optimal. If you'd like to join and meet with us once a week or two (on Skype or Google Hangout), you can write me an email at bartas [dot] wesolowski [at] gmail [dot] com.

Map apps

I really like the tool that I created, which transforms SVG images into Android Drawables. I'm thinking about creating new apps similar to Milan Metro - just with different maps. People in other cities would probably be happy as well to see a high quality version of their metro map for Android. There are also trams, buses, university campuses, parks, and other places just waiting to be transformed into vector images and published as an app. I already have the necessary code base. Why not replace the map itself, the icon and the screenshots and put it on Google Play?

Blogger Stats

Some time ago I experimented with Google APIs and tried to write an app which would fetch my blog statistics without the need of logging in (it would use the Google account stored on the device). After the initial struggle I managed to get it working. The only bad thing is that the Blogger API doesn't let you see very detailed statistics - it just shows weekly, monthly, and all time views. It might change in the future though. Anyway, I just need to remove my hardcoded blog name, add Google account selection, and make the app pretty to be ready to release it. I use it from time to time, why not let other people do the same.

Video ads and alternative ad networks

Since I already have quite a lot of users of my apps (around 15,000), I should probably start thinking about monetizing them better. The CPM of around $0.5 which I'm seeing now is not the highest I could dream of. Other people have been advising me to start using ad networks other than AdMob. I also receive email offers from less known networks from time to time. I definitely want to try video ads and experiment with ad types and their placement. I hope it can increase my income and perhaps allow me to go full time at some point (although I'm quite far away from it right now).

Google Analytics for Android

I hate the fact that I don't know anything about my apps' usage. How many people play my games daily? How many of them make it through the whole game? Are the difficulty levels ok? What are the most common settings? I've been looking for a solution and I think I finally found one - Google Analytics. It's supposed to let you get all the answers you want. Having the data available, it should be much easier to make adjustments to your apps/games, place the ads, detect bugs and create new features. I'll definitely give it a shot.

Blobby Volley multiplayer

Being able to play with other human beings is what's missing in my game. Although my AI is quite strong and I'm quite proud of it, it can't compare with the possibility of kicking your friend's ass. I'm not sure how I'm going to do it yet. I don't have much experience in implementing multiplayer games, but I have to find a way to do it. For now, I'm considering AndEngine Multiplayer Extension and Google Play Services. I can't wait to see it in action!

Updating old apps

It's been a while since I created my first apps and they got quite old in the meantime. Not only at the time of writing them did I have the knowledge I have now, but some of the more sophisticated libraries simply didn't exist. There was no way of easily downloading, caching and showing online images. There were no pretty gallery views. No one even heard about Android 4.0. That's why I think my Raczkowski na dziś and Galeria Andrzeja Mleczki need a general rewrite. I'm not giving this task the highest priority, but I'd like to make those apps more user friendly and less buggy. They are part of my portfolio and I feel bad every time someone gives them a bad rating.


That's more or less what I have planned for the summer, unless something unexpected happens. If you want to see the results of my work, visit me again and check out the progress. I can't wait to see what the future will bring. Wish me luck.

Thursday, May 8, 2014

5 things that are working for me right now

Hi there! Today I'd like to share with you the results of my recent actions and experiments. Even if I don't create new apps, I try to at least update the ones already existing, with some new features, bug fixes and enhancements. Here's the list of five items that I consider the most successful/promising/helpful. I'm sure you can find there something that will work for you as well.

1. Online crash reporting solutions

Since I started using sites like BugSense or Crittercism, I think they are a must for every app. The Google Play's crash and ANR's section lets you see only a fraction on errors. It doesn't show any nice reports either. External systems like the ones mentioned earlier are much more powerful. They let you mark at which version each bug was fixed, they can give you additional exception information, they let you send reports about caught exceptions, they send you email reports, and their look-and-feel is much nicer.

In the past I used ACRA as well. It gives you more flexibility when it comes to data storage - you can even code your own adapter doing whatever you like with the exception that was caught. For me it was too complicated and I preferred other solutions, but I just took a look at their website and it seems that a lot has change in the past couple of months. Perhaps you will want to give them a try as well.

What I want to test in the near future is Crashlytics. Since Twitter acquired it, it has become completely free and I've heard a lot of good words about it. It looks quite pretty and professional as well. BugSense and Crittercism offer free plans, which usually are quite sufficient for indie developers, but to use their pro versions you have to pay, which is not an option for me right now.

Anyway, start using online crash reporting, if you aren't already doing it. It takes one line of code to add them and they let you avoid a lot of bad ratings and reviews.

And when it comes to user feedback, let's take a look at the next point.

2. Discreet App Rate

As the name suggests, it a neat library displaying a small banner asking the user to rate the app. The banner only shows up after the app has been opened a specific number of times or when the app has been installed for a while. It's easy to dismiss and it doesn't take the whole screen, which can annoy users and actually make them give you one star. If you're interested in the motivation behind it, you can read the article Nicolas Ponepuy (the author of the library) wrote.

I found out about Discreet App Rate through the Android Weekly newsletter. It's a great source of information about new Android libraries, tools and learning resources. You might want to sign up for it as well. Btw, my interviews got featured on it a couple of times at the beginning of its existence, which I'm extremely proud of.

But back to the main subject. Since I installed Discreet App Rate in my Milan Metro app (more than 3 weeks ago), the number of ratings has practically doubled and the average rating has increased from 3.8 to 4.24. It caused a 20% rise in downloads as well, although I changed the icon, screenshots and some app details as well, so the positive trend might have been caused by those as well.

3. Ad networks other than AdMob

I really like AdMob for its reliability, transparency, on-time payouts and in-depth statistics. Nevertheless, I don't think you should be using only their ads, because they don't give you the highest CPMs and possible ad types are definitely not up to date with the industry standards. My AdMob average CPM is only $0.58, which is not very high, although I do get up to $3.69 on a banner (!) in my Toothbrush app (I still can't explain this anomaly).

Anyway, I have been using Airpush and AdBuddiz for some time extensively and they give me average CPMs of $1.44 and $1.01 respectively. I use both of them with my Blobby Volley game, so the results should be representative. I have Airpush in one of my other apps - Supermarkets in Milan and it has a CPM of $2.58 (unfortunately with much fewer impressions).

In conclusion, if you experiment with alternative ad networks, they can basically triple your income. I'm probably not doing it well enough anyway, as Matey Nenoff mentioned in the comments on my last income report. There are video ads and other specialized ad networks that migh give me better rates. I will definitely commit some time in the future to experimenting some more.

Just as a remark, using too many ad networks might not be good either. They usually pay you after you've reached a certain level of income (like $100), so if you don't make too much, you may never see the money or you'll have to wait for it longer. Also, they don't always give you access to full statistics (I calculated the AdBuddiz CPM on a calculator), so it's not easy for you to analyze the traffic. Finally, they have limited payment options, so if you're used to being paid via PayPal or wire transfer, you might get disappointed and be forced to create an account on a third party money transfer site.

4. Transforming SVG images to Android Drawables

This point will be more technical, but it really changed a lot for me. Remember February 2013 and my post about using SVG images in Android apps? Probably not :) Just as a quick reminder then. Vector images are very nice to use, because they don't lose quality while magnified. They also usually take up much less space and memory than bitmaps. Sometimes they are the only way to go, when an image is very big and can't be loaded into memory. That was the case with my Milan Metro app.

Unfortunately Android does not support SVG images natively, so you have to use an external library to transform them into instances of the Drawable class. The existing libraries are not of very high quality though - some of them only support a subset of the SVG standard, others don't let you use text, different ones just transform the image into a bitmap, which may not be what you want. All of them have to parse the SVG file first, which takes quite some time (up to a couple of seconds). These disadvantages make it quite hard to use SVG images.

What I did was as follows. I used the svg-android-2 library (an updated version of the svg-android library I was using previously) not to parse SVG files and make Drawables out of them, but to print the code that would be executed in the process. This way I had the whole image in Java code, looking more or less like this:

public class MapPicture extends Picture {
    private final Canvas canvas;
    private final Paint fillPaint = new Paint();
    private final Paint strokePaint = new Paint();
    public MapPicture() {
        canvas = beginRecording(530, 415);
        fillPaint.setLinearText(true);
        fillPaint.setStyle(Paint.Style.FILL);
        fillPaint.setAntiAlias(true);
        fillPaint.setColor(Color.TRANSPARENT);
        strokePaint.setLinearText(true);
        strokePaint.setAntiAlias(true);
        strokePaint.setStyle(Paint.Style.STROKE);
        canvas.save();
        canvas.concat(/* some matrix transformation */);
        fillPaint.setColor(-14917974);
        fillPaint.setAlpha(255);
        fillPaint.setTextSize(4.0f);
        strokePaint.setColor(Color.TRANSPARENT);
        canvas.drawText("PORTA ROMANA FS", 0.0f, 0.0f, fillPaint);
        canvas.restore();
        /* other shapes and text */
        endRecording();
    }
}

I didn't have to add the SVG parsing library any more, the image loading time was practically unnoticeable and the map looked just as before. It wasn't as easy as I first thought to print the Java code instead of executing it, but it was totally worth trying. I started even thinking about creating a tool for other developers to do the same thing, and start using vector images without the necessity of adding external libraries and wasting time on svg file parsing. If you are interested in such a tool, please let me know in the comments section.

5. Simple apps

Many people think that by making a mobile app they can get extremely rich. Sometimes they spend a lot of time and money to create one, just to find out that it's a total flop. I believe such an approach to be wrong, at least for indie developers like me.

Making something small and simple is usually what works for me. I don't get bored and frustrated during the development process, I don't need to commit half a year of my free time to finishing the app, I can see if it has a potential of being popular much faster and then perhaps add more features.

I still can't believe that my Toilet Sounds game, which was basically a practice excercise for me, when I was trying to learn how to play sounds on a physical device, has been downloaded 40,000 times. I guess sometimes you just can't guess what people will like.

Another thing is, I'm quite ok with having 10 simpler apps, each making me a smaller amount of money. Complexity brings a lot of trouble - tons of crashes and pissed off users, long development time, investment in design and graphic resources, etc. Remember that if you create a map app or a simple point-and-click game, you can always make another one based on the existing code, e.g. make a map of something else, reskin the game to be played in another environment. This way every bug can be corrected in the common code base and not cause trouble in every derived version.

To put it in short once again, my extremely simple apps have probably the same amount of downloads as the more complex ones, although they took 1/10 of their development time. They made me realize what may or may not be successful (live wallpapers suck), they usually crash much less, they build up my portfolio. I'm definitely going to be making more of them in the future.



I hope you liked my list. I might make another one in the future, because I quite enjoyed the process of creating it. In the meantime, feel free to let me know what's working for you.

Sunday, April 20, 2014

Android Income Report: March 2014

It's been a while since I published my last income report, so I decided to prepare one for you as an Easter present. In fact, the times when I would open my ad statistics every day and analyze them meticulously are long gone. To be honest, I wasn't really sure how much I was making a month these days (at least not exactly) before writing this post. It's been helpful for me as well to realize where most of my revenue comes from and what I should do to maximize it. Let's see the results together.

Ad networks and ad types I use

In my apps I have AdMob banners and interstitials as well as Airpush smart wall ads and AdBuddiz interstitials. Why I chose these? AdMob was just the most obvious choice - they are very reliable when it comes to payments and they have very detailed statistics. Unfortunately, they don't offer so many ad types (banners and interstitials only) and their CPM is not the best as well. I decided to try Airpush and AdBuddiz, because their ads are quite pretty and they promised high rates for each click. They actually are decent, although definitely not as good as advertised. You'll have a chance to see the numbers below. I haven't been paid for them so far, because I only just realized that you need to fill some forms with payment details first, but I believe that I won't have any problems with it.

Statistics

Here are some numbers that might interest you. With some simple math you can figure out how much you could earn with a similar app or what kind of ads make the most revenue. I decided to skip the paid apps, because they generate less than $10 a month for me.

AdMob
revenue: $52.04
requests: 109,142
CPM: $0.51 (max: $2.75, min: $0.07)
fill rate: 93.9%


Airpush
revenue: $37.66
requests: 18,652
CPM: $2.02
fill rate: ?

AdBuddiz
Note: the values below are approximate, because AdBuddiz doesn't offer detailed statistics (only those visible in the screenshot below).
revenue: ~$7.5
requests: 14,503
CPM: $1.21
fill rate: ?

Total
revenue: $96.9
requests: 142,297
CPM: $0.68

Conclusions

My income increased in the past couple of months from less than $20 to almost $100. In fact, I'm seeing a slight (around 20%) growth in April as well. This is definitely a good thing, but the fundamental question stays the same - was the app development really worth my time and effort. So far the answer is "no", at least if we take into account only the money. What else did I gain? Experience in Android programming; some apps I can show my family, friends and... prospective employers; I got to know other interesting people from the business; I received a free license for TexturePacker, PhysicsEditor and tPacker; finally I feel very proud that people download my apps and find them useful and fun - it's a great feeling and it gives me a sense of purpose.

Will I continue making apps? Of course I will! I still quite enjoy it and I feel that every time I make one, it's much better than my previous creations. As to the money factor, I could probably improve it by trying different ad networks and replacing (at least to some extent) AdMob - which isn't always the best option when it comes to generating revenue. I should also update my old apps, because they use old ad API's and display banners/interstitials in very inefficient ways (CPM=$0.07 is definitely very bad). As a matter of fact, I'm planning to release a big update to my metro app in a couple of days. It will feature some cool improvements and I'm really excited to see what will happen afterwards. I can't wait to give you more details about it, but unfortunately it's out of the scope of this post, so you'll have to wait a little bit more.

Before I finish, I'd like to wish you Happy Easter! Spend some time offline with your friends and family, and have a break from whatever you do on the everyday basis. I'll see you in a while- relaxed and ready for new challenges.

Monday, April 7, 2014

Google Code Jam - Learn to be a better programmer

In three days Google Code Jam starts! It's an annual programming contest held by Google, started in 2008. It serves them as a means of finding new talents to hire. For most, however, it's a great occasion to test their algorithmical skills and have some fun with other geeks. I've already signed up. Have you?

If you're still undecided or you just think that the knowledge of algorithms is not important, you should definitely give the subject a closer look. After all, a company such as Google rarely takes ill-conceived decisions, and they find new workers based on their ability to understand, analyze and design algorithms. In my opinion, being familiar with at least the basics in this subject distinguishes professional programmers from self-taught hacker wannabies (and I don't mean that it's bad to learn how to code at home). Other than that, it opens your mind on the world of deep understanding why some libraries have been designed in a particular way and which data structure you should use in your app. Finally, it is fun (at least for me and for a bunch of other people) and gives extreme satisfaction whenever you find a solution to a unique problem.

Anyway, I'm not here to try to convince you that learning algorithms is useful. I want to give you some resources that you can use to practice and learn. I'm pretty sure you'll find them quite interesting.

First of all, you should take a look at the Google Code Jam's practice section. There you can find all the problems from previous contests and you can try to submit your own solutions. You can also read the analysis of each problem, which is a great way to learn, when you're not able to solve something yourself.

The biggest site I know is Timus. It's run by Russians and it contains more than a thousand problems. They can be grouped by type, difficulty, or just by their adding date. Oh, and they're still adding new ones. You submit your code and it runs on the server against multiple test inputs. If it's fast enough, doesn't use too much memory, and, what is probably the most important, produces correct answers, you get an "Accepted" result. Easy enough? Perhaps with the easiest problems. Then they become much more challenging...

Other interesting site that has consumed loads of my time and has given me sleepless nights is Projec Euler. It's different from Timus, because it offers problems that are more mathematical in nature. They don't expect you to upload your code - an answer is good enough. This way, you can use whatever programming language you want or such software as Excel, Mathematica or Matlab. Sometimes a pencil and a piece of paper is enough. After you've solved a problem, you can see other people's solutions, which might be quite surprising and inspiring... and you see how they code and structure their programs, which is very educative as well.

Lastly, I would like to tell you about a site I was using during my university years - Usaco. Their training section was great, because it gave you hints if you had a hard time solving a problem and it showed to you the exact test case your program was failing to cope with. This way it was much harder to get stuck. They had a nice system, in which you had to solve all the problems from a section to be able to get to the next one. Each section gave you slightly more difficult problems as well as a theoretical introduction of a new algorithmical technique. I have to say that I haven't used this site for a long time, and I can't even remember my password, but I'll try to recover it in one way or another, because I used to like it a lot.

I hope you agree with me on the importance of algorithms now and that you'll choose a training site for yourself (if you aren't using one already). Who knows, maybe Google is going to contact you as well. I've had recruiters contacting me based on my good ranking on such sites, so it's not just an urban legend. I even put some information about them in my CV. It's always nice to find out that your interviewer uses the same site that you do... and even nicer to see that he's lower in the ranking than you ;)

If you use any other interesting sites, please let me know. See you on the Google Code Jam eliminations this weekend and feel free to brag in the comments section if you do particularly well.