Cycymomo
7/22/2013 - 12:06 PM

140bytes - romanize (arabic to roman) http://www.developpez.net/forums/d1362763/webmasters-developpement-web/javascript/ludique-defis-code-e

console.log( romanize(12) + ' / ' + (romanize(12) === "XII") );
console.log( romanize(49) + ' / ' + (romanize(49) === "XLIX") );
console.log( romanize(74) + ' / ' + (romanize(74) === "LXXIV") );
console.log( romanize(383) + ' / ' + (romanize(383) === "CCCLXXXIII"));
console.log( romanize(1000) + ' / ' + (romanize(1000) === "M"));
console.log( romanize(3888) + ' / ' + (romanize(3888) === "MMMDCCCLXXXVIII"));
// 140bytes - http://www.developpez.net/forums/d1362763/webmasters-developpement-web/javascript/ludique-defis-code-en-tweet/

/* 98b: */
function romanize(n,a,b,c,d){
for(a='',b=0,c=5;n;b++,c^=7)for(d=n%c,n=n/c^0;d--;a='IVXLCDM'[d>2?b+n-(n&=-2)+(d=1):b]+a);return a
}

/* Explain */
function romanize(n){
  for(a='',                            // la chaine finale 
      b=0,                             // IVXLCDM[b]
      c=5;                             // initialisation de c à 5 pour commencer à diviser n par 5
      n;                               // tant que n n'est pas "falsy" (égal à 0 en l'occurrence). Il va subir une division par 5, puis 2, puis 5, etc ...
      b++,        
      c^=7) {                          // c^=7 fait 2, puis, au prochain tour de boucle, c^=7 refera 5, puis encore 2 ensuite, etc
    console.log('d='+(n%c)+'/n='+(n/c^0));
    for(d=n%c,                         // récupération du reste. Il ne peut jamais être > 4 !
        n=n/c^0;                       // division par 5 ou 2 puis arrondi à l'inférieur => équivaut à n=Math.floor(n/c) ou encore n=~~(n/c)
        d--;) {                        // tant que le reste de la division n'est pas "falsy" (égal à 0 en l'occurrence)
      console.log('n='+n+'/m='+(n&~1)+'/a='+a+'/b='+b+'/c='+c+'/d='+d+'/x='+(1+(d>2?b+n-(n&-2)+1:b)));
      a='IVXLCDM'[d>2?                 // pour un reste de 4, soit les 4 ou 9. 
                    b+                 // gestion des "cinquaines", dizaines, cinquantaines, etc
                    n-(n&=-2)          // ajoute 1 ou 0 et transforme n au nombre pair inférieur. n-(n&=-2) fait 0 si n pair et 1 si n impair. Car si n = 9 il faut taper dans la "cinquaine" suivante : IX. Tandis que si n = 4 on est dans la bonne cinquaine : ex. IV
                                       // si n est pair, (n&-2) === n. Par contre, si n est impair (n&-2) === n-1
                    +(d=1)             // il ne faut plus qu'un tour derrière (exemple : IV si 4, IX si 9, XC si 90)
                   :b]+a;              // pour tout le reste, répétition de la lettre pendant d
    }
  }
 
  return a;
}