The author of this blog is no longer publishing new posts. Please visit his homepage for links to active projects.
February 13, 2009

The 140 character webapp challenge!

Article about ▸

written by Marek Foss

WebApp challenge tweet by Arun Shroff

How many interesting webapps can you code in one Twitter message? I have one — a micro-twitter. I want to see many!

Back at Twitter I read this message on 222 character Wikis, by Arun Shroff. I thought — why not — and replied with a challenge: Make a 140 chars webapp in 2 weeks! Whatever language, library or module included, as long as it’s standard. I made an example micro-twitter, described later in the post. If you think you can do better — I dare you. You’ve got 2 weeks again. Post your webapp here in the comments! (complete code, link or anything such that we can see it at its best)

(url)UPDATE! 32 WebApps under 140 Characters — Finale of The Challenge wrapped up!

(url)24 WebApps under 140 Characters — 7 days of The Challenge wrapped up!
(url)Test my example micro-twitter online
(zip)Download the micro-twitter source code

Now, to my micro-twitter app. It’s written in Perl, using just the CGI module. The one-line code has 140 characters, although in the source code file you can find a further minimized version with just 123 characters, but less features.

What the micro-twitter basically does, is let you update your status and show it. Don’t expect any social candy, there’s no room for that, but it works, and you can test it here — the PIN is 1234, and this version is a bit more secure, for obvious reasons. To post a message, type the PIN number, a space, and then your message.

Micro Twitter screenshot

I’ve worked about 2 hours refining the code. That’s around 51 seconds per character, funny how such a short piece takes so much time. And here it is:

use CGI':all';print header.'<form>'.submit.textfield 0,'',99;open F,'<0';print $f=(param 0)=~/1234 (.*)/?hr.$1.<F>:<F>;open F,'>0';print F$f

The extent to which I bended the common practices of Perl are quite bizarre to me, but on the other hand this code is completely valid in my IDE of choice — Komodo Edit. First of all, I include all the fancy stuff from CGI, but in fact I am using just the :standard, :form and :html extensions. I’m printing the heading, otherwise the browser will spit an Internal Server Error. Next, I’m starting the form, no html, head or body rubbish. I’m printing the submit button and a textfield using the mentioned :form extension.

After that, I handle the possible message. I’m using a regular expression to analyze it, looking for the PIN. If found, I append the message at the beginning of the file, adding a hrizontal line to make it look readable. At the same time, I push all the file contents to a $f variable. I use it then to overwrite the database file, so the messages don’t get lost. And that’s it.

Now, again — I dare you, make something better, shorter, fancier! The rules are simple: whatever language you choose, whatever module or library you include, as long as it’s standard, it’s good. But share your webapp in the comments, even if they bend the rules — it will be interesting. The challenge is on. So are you skilled enough for this? Bring it on! And follow me.


If you liked the article, please spread the word and share it!


Comments


fathermocker writes:

You’re really talented mate! Keep it up!


Christian writes:

Thats simply beautiful. I love it.
I thought briefly about rewriting your app in PHP but unfortunately, I think its impossible as I’d need to construct the form and that alone would be more than 140chars. :(


Pure Roon writes:

PHP takes too many characters, need some standard form building libraries!


Isaac Van Name writes:

Rewrote in PHP, but it’s still too long… 156 characters, I think.  Maybe someone could improve?  :-)

<form><input name=“a”><input type=“submit” value=“send”/></form><?php if($_GET[‘a’]){$q=fopen(‘micro.php’,‘a’);fwrite($q,$_GET[‘a’].’<hr>’);fclose($q);}?>

That code’s assuming that the filename is ‘micro.php’ and all of the default form attributes (inputs defaulting to text, form action defaulting to self, form method defaulting to GET) and a shaky conditional that I’d never use in code!  :-P

Can’t imagine there’d be much that could be done in 140 chars in PHP but, if it can be done, it would be so hot.


Christian writes:

Nice Isaac.
renaming to m.php will save you another 4 chars.


Christian writes:

Also, using short tags and getting apache to parse .p files as .php will do the rest probably. :)


Bari writes:

Modification of Issac’s code :
<form><input type=“submit”><input name=“a”></form><?php $a=$_GET[“a”];if($a){$q=fopen(‘m.php’,‘a’);fwrite($q,”<hr>$a”);fclose($q);}?>

only 134 characters, it doesn’t work that properly! Here the code assuming the name of this PHP file is m.php(trying to save characters by using small name).


Bari writes:

<form><input type=“submit”><input name=“a”></form><?php $a=$_GET[a];if($a){$q=fopen(‘m.php’,‘a’);fwrite($q,”<hr>$a”);fclose($q);echo $a;}?>

Now works fine! Within 140 characters.


Isaac Van Name writes:

Yeah, thought about making the filename shorter… but, I’m a sucker for appellation.  ;-)

I agree that those two would shorten it to almost the limit, but that would almost be cheating?  :-P The major way I was trying to shorten it was putting the fopen() in the handle portion of the fwrite(), but then I wouldn’t be able to fclose() it.  =/

file_put_contents() would probably be about as long (since we’d have to set the FILE_APPEND flag), but fputs() does save a char over fwrite()!  :-D


Andy Bailey writes:

ok so I saw this on tweetdeck when I had blurry eyes. Now they’re even blurier (real word?) lol
this javascript will attempt to guess your age and tell you how many tries it took..
this is my code
var c=0;var i=35;do{var x=confirm(‘are you ‘+i+’?\n(ok=Y)’);i=Math.floor(Math.random()*70);c++;}while(!x);alert(‘I only took ‘+c+’ tries!’);

you can run it on this page by pasting it into the address bar like this
[removed]var c=0;var i=35;do{var x=confirm(‘are you ‘+i+’?\n(ok=Y)’);i=Math.floor(Math.random()*70);c++;}while(!x);alert(‘I only took ‘+c+’ tries!’);

I don’t ever do javascript unless it’s jquery but I think javascript was the only other language I know that could do anything. I tried a little in php but it failed!

well, that set me up for a nice day of coding! I’m really in the mood now


James writes:

PHP, 134 characters, works perfectly plus will order the list backwards - newest at the top…

<form><input name=“s”><input type=“submit”><?$s=$_GET[s];$f=file(‘a’);$a=!empty($s)?”<hr>$s$f[0]”:’‘;fwrite(fopen(‘a’,‘w’),$a);echo$a;


Isaac Van Name writes:

Wow, nice revision!  Should’ve thought of storing the GET!  :-)  Also, good catch on the echo… forgot that the page wouldn’t render the addition since it writes after the PHP is getting processed.

One small question, though… If a submit element has no value, what will show up in the button?  My memory is not so good, but I think I remember it showing up as an empty button? 

Still, it’s 140 chars, no arguing that.  Nicely done.  :-)


Andy Bailey writes:

dammit. I didn’t realize I had to write a program to do the same thing! still, it was fun trying to make something work with 140 characters or less!


Marek Foss writes:

Awesome guys, you’re really at it. I like the PHP implementation, looks really slick!
And good idea Andy to shift to other areas besides twitter - let’s get this challenge running!

To everyone! - Thanks for the great feedback and testing out my app! I’m happy you like it. And spread the word! RT and Digg like mad! Thanks :D


Keenora writes:

Hmm, ok, 136 in php :)

<?=’<form><input name=a value=...><input type=submit></form>’;$h=fopen(a,‘a’);fwrite($h,$_GET[a].”\n<hr>”);fclose($h);echo@readfile(a)?>


Keenora writes:

Well, everybody crops the fclose…so I do:

<?=’<form><input name=a value=...><input type=submit></form>’;$h=fopen(a,‘a’);fwrite($h,$_GET[a].”\n<hr>”);echo@readfile(a)?>

125 Chars :)


Sergry Agarkov writes:

My code in PHP 241 chars :)
Here is code http://dumpz.org/5512/


Keenora writes:

Sorry for Triple-Post o.o

Ok, if we delete the Default-Text in the input field, we can crop it further, of course. Then I’ve used the idea of James, and sorted the entries backwards, to show the latest entries at top. Cropped to 139 Chars!
I used a ALT+250 to implode the data at the end, to save one char. Is there a short-tag to get the $_GET var?

<?=’<form><input name=a><input type=submit></form>’;$h=fopen(a,‘a’);fwrite($h,$_GET[a].”\n<hr>”);$a=file(a);krsort($a);echo implode( ,$a)?>


James writes:

This little script will tell you how many seconds, minutes and hours you’ve been alive… (approx of course)

d=prompt(‘DOB?’,‘DD-MM-YYYY’).split(/[^\d]/);d=new Date(d[2],d[1],d[0])/1000;alert(d+’ seconds\n’+d/60+’ minutes\n’+d/60/60+’ hours’)

Prefix it with “[removed]” and copy it all into the browser to test it out :)


James writes:

Sorry, the above is wrong, here’s the correct one:

d=prompt(‘DOB?’,‘DD-MM-YYYY’).split(/[^\d]/);d=(new Date()-new Date(d[2],d[1],d[0]))/1000;alert(d+’ seconds\n’+d/60+’ minutes\n’+d/60/60+’ hours’)


Andy Bailey writes:

ok I made a similar app to the first one in jquery here http://www.fiddyp.co.uk/internal/140charchallenge/

the jquery is
[removed](”<input value=..><p>[go]”);$(‘p’).click(function(){$(‘body’).append($(‘input’).val() + ‘<hr>’);}); 117 characters!

the html to include the source files takes it way over and the page doesn’t get saved if you leave it. but it does look similar and it sort of does what’s needed (if you’re the only person in the world!)

:-)


Keenora writes:

Ok, my final version, including backward-sorting and so on…. 129 Chars ....

Reminds me to the .kkrieger ;)

<?=’<form><input name=a><input type=submit></form>’;fputs(fopen(a,a),$_GET[a].”\n<hr>”);$a=file(a);krsort($a)?><?=implode( ,$a)?>

And without sorting only 112 Chars!

<?=’<form><input name=a><input type=submit></form>’;fputs(fopen(a,a),$_GET[a].”\n<hr>”)?><?=implode( ,file(a))?>


Marek Foss writes:

Nice going guys, keep them coming! I will wrap them up into contenders in a couple of days!

BTW please note that my most stripped down version, without PIN security but with sorting, is just 124 chars :)

use CGI’:all’;print header.’<form>’.submit.textarea 0;open F,’<0’;print $f=param 0?hr.param(0).<F>:<F>;open F,’>0’;print F$f

But the point is to make any awesome app with at most 140 chars, NOT the least amount of chars ! (however it is an achievement to code with less :D)


Ormo writes:

A rudimentary version of http://downforeveryoneorjustme.com/

<?=’<form><input name=s><input type=submit></form>’;$a=$_GET[s];echo(@file((stripos($a,”:”))?$a:“http://”.$a))?‘just you’:‘its down’;?>

weighing in at 136 chars…

http://loughanmore.f2s.com/down.php


Mirko Grönroos writes:

I managed to put together a really hacky ruby/shell version using Sinatra and Haml gems. The app has very basic functionality, no pin or anything but it does sport a separate “view”, escaped html output and runs standalone using a builtin web server so I think that sort of makes up for the lack of other features. :)

Exactly 140 bytes, access it at http://localhost:4567/ after starting the script ( ruby scriptname.rb )
%w[rubygems sinatra].each{|w|require w};get’/‘do;m=params[:m];open(“f”,“a”){|f|f<<m+”\n”}if m;haml’%form <input name=“m”/>
%pre&=`cat f`‘end

The same thing at pastebin in case the code gets mangled on submit: http://pastebin.com/m430d6705


Dennis Kempin writes:

I wonder why no one has posted a brainfuck version yet :D

Very nice idea!


Tony Buser writes:

I managed to do almost the same thing in ruby using Sinatra too.  I had to really cut some corners, but it comes out to 137 characters.  Like Mirko said, it’s even cooler because it runs standalone with it’s own built in webserver.  ;)

require’rubygems’;require’sinatra’;get(”/”){r=”<form><input name=‘t’></form>”;t=params[:t];`echo ‘<hr>#{t}’ >> t` if t;r<<`tail -r t`;r}

See: http://pastie.org/388329 in case it doesn’t paste here right.


toydime writes:

Insteresting!!!


adamo writes:

Although I am bending the rules a little: http://blog.postmaster.gr/2009/02/13/does-this-count-as-a-web-application/


synodinos writes:

140 characters javascript game “Am I thinking of an odd number or not”:

[removed]function x(){if(confirm(“odd?”)&&((Math.floor(Math.random()*10))%2))alert(”:)”);else alert(”:(”);if(confirm(“rpt?”))x()}x()[removed]

130 characters javascript game “Am I thinking of 1 or 0”:

[removed]function x(){if(confirm(“1?”)&&(Math.round(Math.random())))alert(”:)”);else alert(”:(”);if(confirm(”rpt?”))x()}x()[removed]

Just paste inside a completely blank page and open with a browser. More info on:



Bastian Albers writes:

Heres my php version with the actual twitter limitation of less than 140 characters in 136 characters of code (no fclose…):

<form><input name=a><input type=submit></form><?if(strlen($_GET[a])<140){$h=fopen(a,“a”);fwrite($h,$_GET[a].”<hr>”);}echo@readfile(a)?>

I only managed a 141 character version that forbids empty entries and only with the ugly hack of not closing the form:

<form><input name=a><input type=submit><?$l=strlen($_GET[a]);if($l<140&&$l>0){$h=fopen(a,“a”);fwrite($h,$_GET[a].”<hr>”);}echo@readfile(a)?>


I tried to make an album art finder app in PHP. I could only get the code down to 331 characters. However, I still think it’s cool enough to share.

<?=”<form>Artist:<input name=artist>Album:<input name=album><input type=submit></form>”;$q=$_SERVER[‘QUERY_STRING’];if($q){$x=new SimpleXMLElement(file_get_contents(“http://ws.audioscrobbler.com/2.0/?method=album.getinfo&api_key=b25b959554ed76058ac220b7b2e0a026&”.$q));$i=$x->album->image;echo’‘.$i[count($i)-1].’;}?>

The API key is the one provided in the LastFM API examples.

To try my app out, visit: http://phattangent.com/140.php



Chris writes:

I challenge you to do that in COBOL :-)


Marek Foss writes:

Great apps everyone! I’ll be wrapping them in a new post soon, and so we’ll know what’s going on! Thanks! And if you have more - bring them on!

@Chris: haha unless I had any idea how to code COBOL, I’d take that challenge :)

@Michael Cotterell: awesome app for such a small amount of code! The API key is the problem here, I think you’d gain some chars by putting it in a file and just $h=fopen(a,“a”) ? Also, don’t close the form with </form>, everybody is ditching that. I think you could go to 300 with that :)


Facyla writes:

Thanks for the challenge ; A 140 bits twitter-like with date and blog sorting http://facyla.net/proto/twitter/twitter-like.php5


I slimmed mine down to 300 characters.

<form>Artist<input name=artist>Album<input name=album><input type=submit><?$q=$_SERVER[QUERY_STRING];if($q){$k=file(a);$x=new SimpleXMLElement(file_get_contents(“http://ws.audioscrobbler.com/2.0/?method=album.getinfo&api;_key=”.$k[0].”&”.$q));$i=$x->album->image;?><img >

A demo is available at http://phattangent.com/140.php


Looks like my code didn’t copy over. You can see it here: http://pastebin.com/f5d585265


Hartog writes:

3 apps

1: display all the links from an RSS file on disk - 117 chars:

use CGI’:all’;open(I,”<r”);$/=undef;$a=<I>;print header.join(”“,map{a({href=>$_},$_).br} $a=~/\<link.*?\>([^\<]+)/gm)

2: put an RSS file onto disk (usefull with 1) - 128 chars:

use CGI’:all’;if($a=param(‘a’)){open(O,”>r”);print O $a;}print header.($a?“kthxbynoa”:’<form method=post>’.textarea(‘a’).submit)

3: a working version of http://downforeveryoneorjustme.com/ - actually does a ping - 135 chars:

use CGI’:all’;print header.’<form>down4u?:’.br.textarea(‘a’).br.submit;if($a=param(‘a’)){`ping -c1 $a.`;print h3($? ? “down”:“just4u”)}

In all 3 off them you can ‘use strict’ without breaking anything - althoug the 3rd would exceed 140 chars. How cool is that ;->


Got my code down to 274 characters… http://pastebin.com/d26a928e7 Maybe even 208 if my commented suggestion isn’t bending the rules too much.

A demo is available at http://phattangent.com/140.php


266 characters… http://pastebin.com/f3093dc3b


Jim writes:

Took a shot at creating it with Ruby/Camping.  Currently at 308 characters.  =(  Might have to take another crack at it later by removing the ActiveRecord model and reading/writing to a file similar to the Sinatra posts above.

I’m not a camping expert.  Anyone else able to shrink this??

require’camping’;Camping.goes:T;module T::Models;class T<Base;end;end;module T::Controllers;class I<R:/;def get;@s=T.all;render:i;end;def post;T.create:d=>input.d;redirect’/’;end;end;end;module T::Views;def i;form(:method=>:post){;input:type=>:submit;input:name=>‘d’,:type=>:text;};@s.each{|t|hr t.d};end;end


192 characters… http://pastebin.com/f2efc6065 and http://phattangent.com/140.php


fabien writes:

A PHP web framework in a tweet:

require __DIR__.’/c.php’;
if (!is_callable($c = @$_GET[‘c’] ?: function() { echo ‘Woah!’; }))
  throw new Exception(‘Error’);
$c();

See the explanation on how it works here: http://www.twitto.org/


Fabien writes:

Have a look at twitto, a web framework in a tweet: http://twitto.org/


Keenora writes:

Someone wants the actual Delicious Links? 136 Chars

<?$x=new SimpleXMLElement(file_get_contents(“http://feeds.delicious.com/v2/rss”));foreach($x->channel->item as$a)echo$a->title.’
‘;?>


Keenora writes:

@Bastian Albers:

Well, I tried your version, including a shorter submit (just hit Enter), which decrease my old version to 82 chars and Bastians to 114 chars:

My one: <?=’<form><input name=a>’;fputs(fopen(a,a),$_GET[a].’<hr>’)?><?=readfile(a)?>

Bastians: <form><input name=a><?$l=strlen($_GET[a]);if($l<140&&$l>0)fputs(fopen(a,a),$_GET[a].’<hr>’)?><?=readfile(a)?>


Keenora writes:

C’mon Coders…do a bit more…I am feeling alone here :P

Get the HTTP Code of a given URL (133 Chars).

<?$a=(@stream_get_meta_data(fopen($_GET[a],80)));preg_match(’# (\d+) #’,@implode($a[wrapper_data]),$b)?><?=($b)?‘Code: ‘.$b[1]:’:(’?>

...php?a=http://www.flickr.com/ => 200
...php?a=http://www.dsfhdsjkofhdskfdjs.com/ => :(


Keenora writes:

Sorry for triple post :P
I forgot to remove the brackets before, so, 131 chars ;)

Maybe you want to resize a JPEG to the half of its size in 186 Chars? :)

<?header(‘Content-type:’);list($w,$h)=getimagesize($_GET[a]);$b=imagecreatetruecolor($w/2,$h/2);imagecopyresized($b,imagecreatefromjpeg($_GET[a]),0,0,0,0,$w/2,$h/2,$w,$h);imagejpeg($b)?>


 1 2 >

Leave a comment: (comments may not appear immediately due to page caching)

Name: Email: (not disclosed)

WWW: Remember my details

Notify me of follow-up comments

Feed me:

to feed
  • Subscribe and get the new articles every now and then directly in your reader — I recommend using Google Reader

Facebook:

Connect:

 by Google
Google FriendConnect appears to be down at the moment. Sorry for inconvenience.
Related Posts with Thumbnails