Programming Comparisons: BEncoding


Problem: give the smallest possible complete subroutine/function/method definition in a language of your choice which, when called with an object, reference to a data structure, etc. returns a bencoded string representing a basic serialization of that object. Objects which are not lists, hashes, strings, or integers may be skipped. Each entry is displayed below as language: byte count followed by a commented call to the function taking as an argument a structure like: { 'foo' => 42, 'bar' => [1, 2, 3] } and returning the string: d3:barli1ei2ei3ee3:fooi42ee.

perl: 164 (205 bz2)
# b({foo => 42, bar => [1, 2, 3]})
sub b{my($o)=@_;ref($o)=~/Y/?'l'.join('',map
b $_,@$o).'e':ref($o)=~/H/?'d'.join('',map{b($_).b($o->{$_})}sort
keys%$o).'e':$o=~/^\d+$/?"i@{[$&+0]}e":length($o).":$o"}
ruby: 167 (193 bz2)
# b({'foo' => 42, 'bar' => [1, 2, 3]})
def b(o)case o
when Array
"l#{o.map{|i|b i}*''}e"when Hash
"d#{o.keys.sort.map{|k|"#{k.size}:#{k+b(o[k])}"}*''}e"when Integer
"i#{o}e"else "#{o.to_s.size}:#{o}"end end
coffeescript: 208 (223 bz2)
# b { foo: 42, bar: [1, 2, 3] }
b=(n)->switch Object.prototype.toString.call(n)[13]
 when ']'
  "l#{(b(x)for x in n).join ''}e"
 when 'r'
  "i#{n}e"
 when 't'
  "d#{(b(k)+b n[k]for k in(k for k of n).sort()).join ''}e"
 else n.length+':'+n
python: 237 (240 bz2)
# b({ 'foo': 42, 'bar': [1, 2, 3] })
def b(o):s=lambda l:l.sort()or l;return{list:lambda:'l'+"".join(map(b,o))+'e',dict:lambda:'d'+"".join(map(lambda x:b(x)+b(o[x]),s(o.keys())))+'e',str:lambda:"%s:"%len(o)+o,int:lambda:"i%se"%o}.get(o.__class__,lambda:"%s:"%len(`o`)+`o`)()
gnu smalltalk: 244 (245 bz2)
"(Dictionary from: { 'foo' -> 42. 'bar' -> #(1 2 3) }) b"
Integer extend[b[^'i%1e'%{self}]]SequenceableCollection extend[b[^'l%1e'%{(self
collect:[:i|i b])join}]]String extend[b[^'%1:%2'%{self size.
self}]]Dictionary extend[b[^'d%1e'%{(self keys asSortedCollection
collect:[:k|k b,(self at:k)b])join}]]
haskell: 245 (233 bz2)
{- b$D$fromList[("foo",B 42),("bar",C[B 1,B 2,B 3])] -}
import Data.Map
data B=A String|B Integer|C[B]|D(Map String B)
b(A x)=(shows.length)x$':':x
b(B x)='i':shows x"e"
b(C x)='l':(x>>=b)++"e"
b(D x)='d':(toList x>>=(\(y,z)->b (A y)++b z))++"e"
erlang: 282 (272 bz2)
% b(dict:from_list([{"foo", 42}, {"bar", [1, 2, "3"]}]))
j(F,L)->string:join(lists:map(F,L),"").
i(I)->integer_to_list(I).
b(N)->if is_integer(N)->"i"++i(N)++"e";is_list(N)->case
lists:all(fun is_integer/1,N)of
true->i(string:len(N))++[$:|N];false->"l"++j(fun
b/1,N)++"e"end;true->"d"++j(fun({K,V})->b(K)++b(V)end,dict:to_list(N))++"e"end.
javascript: 346 (315 bz2)
// b({foo: 42, bar: [1, 2, 3]})
function b(n){var t=typeof n,d,i,j=0,k=[],s='';if(t=='object'){for(i in
n){if(d=/\D/.test(i))break;j++}if(d||j<n.length){for(i in
n)k.push(i);k.sort();for(i in
k)s+=(d=k[i]).length+':'+d+b(n[d]);return 'd'+s+'e'}while(j)s=b(n[--j])+s;return 'l'+s+'e'}return t=='string'||t=='number'&&Math.floor(n)!=n?(''+n).length+':'+n:t=='number'?'i'+n+'e':''}
php: 369 (301 bz2)
# b(array('foo' => 42, 'bar' => array(1, 2, 3)))
function s($s){$s="$s";return(strlen($s).":$s");}
function b($n){if(!isset($n))return'0:';if(is_array($n)){$i=0;$l=1;foreach($n
as$k=>$v){if(!is_int($k)||$k!=$i++){$l=0;break;}}if($l)return('l'.join('',array_map('b',$n)).'e');else{$s='d';ksort($n);foreach($n
as$k=>$v)$s.=s($k).b($v);return($s.'e');}}elseif(is_int($n))return"i${n}e";elseif(is_string($n))return
s($n);}