Je précise que la fonction doit marcher pour n entre 1 et 3999 en effet.
Une question me taraude, je ne connais pas très bien la numérotation romaine, mais est-ce qu'on est pas supposés écrire 490 comme "XD" ou 99 comme "IC" ?
Je précise que la fonction doit marcher pour n entre 1 et 3999 en effet.
Une question me taraude, je ne connais pas très bien la numérotation romaine, mais est-ce qu'on est pas supposés écrire 490 comme "XD" ou 99 comme "IC" ?
49 s'écrit XLIX et non pas IL.
Sinon, j'ai pas encore essayé mais je tenterai de proposer un code d'ici demain.
Il y a pas mal de libertés prises avec l’énoncé
Les unités à intégrer sont :
I 1
V 5
X 10
L 50
C 100
D 500
M 1 000pile dans les clou sauf qu'elle ne marche pas sur 49 par exemple
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3 function fct(v){ s='';r='I,V,X,L,C,D,M,1,5,10,50,100,500,1e3'.split(',');for(i=6;v;i--){d=~~(v/r[i+7]);if(d>=1){for(g=0;g<d;g++)s+=r[i]}v%=r[i+7]}return s; }![]()
Les joies du CSS | Réponses sur forum | Simple comme JS | Essais libres autour de l'API G$$gle Maps
✂ ---------------------------------------------
developpez.net c'est aussi :
✔ Les meilleurs cours et tutoriels pour apprendre le CSS
✔ Les meilleurs cours et tutoriels pour apprendre le (X)HTML
✔ Les meilleurs cours et tutoriels pour apprendre le JavaScript
Dans l'énoncé il y a surtout les 4 assertions à vérifier. Si une ne passe pas, c'est refusé![]()
Foi de fabricant d'usines à gaz![]()
Cela dit... je suis admiratif !vous êtes tous des MALADES !!!![]()
![]()
Comme à mon habitude, je fais le rapia en économisant 1 caractère sur la meilleure solution
124 caractères
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9 function romain(n){ r='';for(x in(a={M:100,CM:90,D:50,CD:40,C:10,XC:9,L:5,XL:4,X:1,IX:.9,V:.5,IV:.4,I:.1}))for(i=a[x]*10;n>=i;n-=i)r+=x;return r } console.log( romain(12) + ' / ' + (romain(12) === "XII") ); console.log( romain(49) + ' / ' + (romain(49) === "XLIX") ); console.log( romain(74) + ' / ' + (romain(74) === "LXXIV") ); console.log( romain(383) + ' / ' + (romain(383) === "CCCLXXXIII")); console.log( romain(1000) + ' / ' + (romain(1000) === "M")); console.log( romain(3888) + ' / ' + (romain(3888) === "MMMDCCCLXXXVIII")); // le plus long possible !
Mouhéhéhé 98(fonctionne si n > 0 et n < 4000)
Explications :
Code javascript : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9 function romain(n){ 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 } console.log( romain(12) + ' / ' + (romain(12) === "XII") ); console.log( romain(49) + ' / ' + (romain(49) === "XLIX") ); console.log( romain(74) + ' / ' + (romain(74) === "LXXIV") ); console.log( romain(383) + ' / ' + (romain(383) === "CCCLXXXIII")); console.log( romain(1000) + ' / ' + (romain(1000) === "M")); console.log( romain(3888) + ' / ' + (romain(3888) === "MMMDCCCLXXXVIII")); // le plus long possible !
Je suis parti de cette base : ça serait cool de pouvoir "piocher" dans la chaine "IVXLCDM" comme ceci : "IVXLCDM"[0] === "I".
Et ça pourrait marcher, car imaginons cet algo :
- On recherche le romain de 5
- On divise par 5. Reste 0, Résultat : 1
- "IVXLCDM"[Résultat] === "V"
Pour 10 ?
- On recherche le romain de 10
- On divise par 5. Reste 0, Résultat : 2
- "IVXLCDM"[Résultat] === "X"
Pour 50 ?
- On recherche le romain de 50
- On divise par 5. Reste 0, Résultat : 10
- "IVXLCDM"[Résultat] === "c'était trop beau pour être vrai"
Mais y'a de l'espoir ! Creusons un peu plus :
J'ai remarqué que pour passer de I à V puis de V à X puis de X à L, etc, il faut respectivement multiplier par 5 puis par 2 puis par 5, etc
Il faudrait donc faire une boucle qui divise le nombre à chercher par 5, puis 2, puis 5, puis 2, etc
Parti de ce postulat, c'est "bouclable" en se servant de XOR alias ^.
Exemple :
Cool ! Imaginons que l'on recherche le romain de 1000, cela veut dire que diviser 1000, par 5, puis 2, puis 5, etc jusqu'à 0 se fait en 7 fois !
Code javascript : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11 for(a=5,i=0;i<5;i++,a^=7) console.log(a); /* Va afficher : 5 2 5 2 5 .... */
Que vaut "IVXLCDM"[6] ?
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13 n=1000 for(b=0,c=5;n;b++,c^=7) console.log((n=n/c^0) + ' / indice : ' + b); /* Donne : 200 / 0 100 / 1 20 / 2 10 / 3 2 / 4 1 / 5 0 / 6 */
on a notre algo. Il suffit ensuite de jongler avec les divisions, les modulo pour récupérer les restes et construire ainsi notre chaine romaine.
Une version de dév commentée qui m'a aidé à construire le code :
ps : oui, ça m'a pris la soirée d'hier, et j'ai eu mal au crâne en me relisant aujourd'hui après manger
Code javascript : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23 function romain(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&-2)+'/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 : ex 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; }![]()
![]()
![]()
Grand fou... J'avais tenté de faire la même chose avec la chaîne "IVXLCDM", mais je n'ai pas eu assez de temps pour arriver à une version aussi optimisée que la tienne. Moi j'utilisais deux variables, une pour l'unité et une pour la cinquaine. Mais basculer entre les deux via l'opérateur ^=, c'est du grand art. Bravo et merci d'avoir pris le temps de rédiger toute l'explication![]()
Impressionnant !!
J'ai pas réussi à faire mieux que toi d'où le fait de ne pas avoir donné de réponse. J'avais aussi tenté de faire un truc avec la chaîne "IVXLCDM" mais mon approche était différente et trop longue en nombre de caractères.
Pour afficher par exemple 4, je me disais il faut d'abord afficher 1 "I" puis ajouter ce 1 à 4 ce qui donne 5 puis afficher 5 "V" ce qui donne au final "IV". J'avais une idée fixe sur cette méthode et j'ai pas trouvé comment la concrétiser. Je la garde cependant en tête, je m'y replongerai à l'occasion même si le résultat doit dépasser le tien en nombre de caractères.
Démonstration ESPOUSTOUFLANTE
J'avais remarqué cette séquence 5-2-5-2... et prévue de l'exploiter avec un classique k=7-k, mais j'en suis resté là, de plus le c^=7 +1, euh! -1 caractère
Quoiqu'il en soit encore un grand coup de chapeau pour ce code et les explications qui vont avec
Ces 98 caractères méritent de rester dans les annales du javascript.
Les joies du CSS | Réponses sur forum | Simple comme JS | Essais libres autour de l'API G$$gle Maps
✂ ---------------------------------------------
developpez.net c'est aussi :
✔ Les meilleurs cours et tutoriels pour apprendre le CSS
✔ Les meilleurs cours et tutoriels pour apprendre le (X)HTML
✔ Les meilleurs cours et tutoriels pour apprendre le JavaScript
Remercions également la période estivale sans qui tout ceci n'aurait pu être possible![]()
La période estivale n'est pas profitable à tous, y'en a qui bossent et qui ont droit à une canicule en prime
Puisque le sujet des nombres romains vous a plu, et comme je doute qu'on puisse faire mieux que 98 caractères, je vous propose le sujet inverse:
Numéro 7: décoder les chiffres romains de I à MMMCMXCIX (3999)
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9 function decodeRomain(s){ //votre code ici, retourne un entier de 1 à 3999 } console.log( decodeRomain("XII") + ' / ' + (decodeRomain("XII") === 12) ); console.log( decodeRomain("XLIX") + ' / ' + (decodeRomain("XLIX") === 49) ); console.log( decodeRomain("LXXIV") + ' / ' + (decodeRomain("LXXIV") === 74) ); console.log( decodeRomain("CCCLXXXIII") + ' / ' + (decodeRomain("CCCLXXXIII") === 383) ); console.log( decodeRomain("M") + ' / ' + (decodeRomain("M") === 1000) ); console.log( decodeRomain("MMMDCCCLXXXVIII") + ' / ' + (decodeRomain("MMMDCCCLXXXVIII") === 3888) );
Salut,
je propose ça :
106 caractères
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3 function decodeRomain(str){ y=0for(s in a={M:1000,D:500,C:100,L:50,X:10,V:5,I:1}){y+=str.match(new RegExp(s,'g')).length*a[s]}return y }
EDIT : Oups, j'avais oublié le V:5
Version plus courte :
94 caractères
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3 function decodeRomain(str){ y=0for(s in a={M:1000,D:500,C:100,L:50,X:10,V:5,I:1}){y+=(str.split(s).length-1)*a[s]}return y }
si on change le nom de la variable = -2 charfunction decodeRomain(str){
y=0for(s in a={M:1000,D:500,C:100,L:50,X:10,V:5,I:1}){y+=(str.split(s).length-1)*a[s]}return y
}
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3 function decodeRomain(n){ y=0for(s in a={M:1000,D:500,C:100,L:50,X:10,V:5,I:1}){y+=(n.split(s).length-1)*a[s]}return y }
On ne peut pas changer l'énoncé
Par contre, tu peux enlever les {} et ajouter un ; pour que ça fonctionne :
Par contre, ça ne marche pas. Par exemple, test decodeRomain("IV") et decodeRomain("VI"), cela renverra 6. Alors qu'on attend 4 et 6. Idem pour le reste : XC, IX, etc
Code javascript : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3 function decodeRomain(str){ y=0;for(s in a={M:1000,D:500,C:100,L:50,X:10,V:5,I:1})y+=(str.split(s).length-1)*a[s];return y }
C'est là toute la problématique
Bon,
et bien je me suis vautré![]()
Oui ce n'est pas aussi simple qu'un remplacement regexp, la règle de la numérotation romaine IV = V - I reste à indiquer.
Pour le nom de la variable vous pouvez la remplacer par s, c'est purement indicatif dans l'énoncé.
52 !
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3 function decodeRomain(str){ open('http://fr.wikipedia.org/wiki/Nombres_romains') }![]()
Pas de question technique par MP !
Tout le monde peut participer à developpez.com, vous avez une idée, contactez-moi !
Mes formations video2brain : La formation complète sur JavaScript • JavaScript et le DOM par la pratique • PHP 5 et MySQL : les fondamentaux
Mon livre sur jQuery
Module Firefox / Chrome d'intégration de JSFiddle et CodePen sur le forum
Blog
Sans l'analyse et la conception, la programmation est l'art d'ajouter des bogues à un fichier texte vide.
(Louis Srygley : Without requirements or design, programming is the art of adding bugs to an empty text file.)
Bovino
Malin le bouc![]()
Partager