Écrivez un programme qui compte de 1 à 100 en chiffres romains et imprimez ces nombres par sortie standard. Chacun des nombres doit être séparé par des espaces.
Vous ne pouvez utiliser aucune fonction intégrée pour vous transformer en chiffres romains, ni aucune application ou bibliothèque externe pour ce faire.
Le résultat souhaité est
I II III IV V VI VII VIII IX X XI XII XIII XIV XV XVI XVII XVIII XIX XX XXI XXII XXIII XXIV XXV XXVI XXVII XXVIII XXIX XXX XXXI XXXII XXXIII XXXIV XXXV XXXVI XXXVII XXXVIII XXXIX XL XLI XLII XLIII XLIV XLV XLVI XLVII XLVIII XLIX L LI LII LIII LIV LV LVI LVII LVIII LIX LX LXI LXII LXIII LXIV LXV LXVI LXVII LXVIII LXIX LXX LXXI LXXII LXXIII LXXIV LXXV LXXVI LXXVII LXXVIII LXXIX LXXX LXXXI LXXXII LXXXIII LXXXIV LXXXV LXXXVI LXXXVII LXXXVIII LXXXIX XC XCI XCII XCIII XCIV XCV XCVI XCVII XCVIII XCIX C
Comme c'est un défi de golf de code, le code le plus court gagne .
Réponses:
Perl 69 octets
Fonctionne par formule magique. L'expression
"32e$&"%72726
transforme chaque chiffre de la manière suivante:0⇒32, 1⇒320, 2⇒3200, 3⇒32000, 4⇒29096, 5⇒56, 6⇒560, 7⇒5600, 8⇒56000, 9⇒50918
Après avoir appliqué la traduction
y/016/IXV/
, nous avons ceci à la place:0⇒32, 1⇒32 I , 2⇒32 II , 3⇒32 III , 4⇒29 I 9 V , 5⇒5 V , 6⇒5 VI , 7⇒5 VII , 8⇒5 VIII , 9⇒5 I 9 X 8
Les autres chiffres (
2-57-9
) sont supprimés. On notera que ce pourrait être améliorée par un octet en utilisant une formule qui se traduit à la012
place de016
, ce qui simplifie/XVI60-9/
à/XVI0-9/
. Je n'ai pas pu en trouver, mais peut-être aurez-vous plus de chance.Une fois qu'un chiffre a été transformé de cette manière, le processus se répète pour le chiffre suivant, en ajoutant le résultat et en traduisant les
XVI
s précédentsCLX
en même temps que la traduction du nouveau chiffre se produit.La
recherche exhaustive n'a rien révélé de plus court. J'ai cependant trouvé une solution alternative à 69 octets:
Celui-ci utilise une
0-2
substitution pourIXV
, mais a un modulo d'un chiffre de plus.Mise à jour:
6665 octetsCette version est notablement différente, donc je devrais probablement en dire quelques mots. La formule qu'il utilise est en fait un octet de plus!
Incapable de raccourcir la formule plus qu'elle ne l'est, j'ai décidé de jouer avec ce que j'avais. Il ne fallut pas longtemps pour que je me souvienne de mon vieil ami
$\
. Lorsqu'unprint
état est émis,$\
est automatiquement ajouté à la fin de la sortie. J'ai pu me débarrasser de la$a[$_]
construction maladroite pour une amélioration de deux octets:Beaucoup mieux, mais cela
$\=!print$"
semblait encore un peu bavard. Je me suis alors souvenu d'une formule alternative de longueur égale que j'avais trouvée qui ne contenait le nombre3
dans aucune de ses transformations de chiffres. Donc, il devrait être possible d'utiliser à la$\=2+print
place et de remplacer le résultat3
par un espace:Également 67 octets, en raison de l'espace nécessaire entre
print
etfor
.Mais, s'il y avait une formule qui n'utilisait pas
1
n'importe où,$\=2+print
devient$\=print
pour deux octets supplémentaires d'économies. Même si c'était un octet de plus, ce serait quand même une amélioration.En fait, une telle formule existe, mais elle est un octet de plus que l'original, ce qui donne un score final de 65 octets :
Méthodologie
La question a été posée de savoir comment procéder pour trouver une telle formule. En général, trouver une formule magique pour généraliser n'importe quel ensemble de données est une question de probabilité. C'est-à-dire que vous voulez choisir une forme qui est aussi susceptible que possible de produire quelque chose de similaire au résultat souhaité.
Examen des premiers chiffres romains:
il y a une certaine régularité à voir. Plus précisément, de 0 à 3 puis de 5 à 8 , chaque terme successif augmente de longueur d'un chiffre. Si nous voulions créer un mappage de chiffres à chiffres, nous voudrions avoir une expression qui augmente également en longueur d'un chiffre pour chaque terme successif. Un choix logique est k • 10 d où d est le chiffre correspondant et k est une constante entière.
Cela fonctionne pour 0-3 , mais 4 doit briser le modèle. Ce que nous pouvons faire ici, c'est coller sur un modulo:
k • 10 d % m , où m est quelque part entre k • 10 3 et k • 10 4 . Cela laissera la plage 0-3 intacte et modifiera 4 de sorte qu'elle ne contiendra pas quatre
I
s. Si nous contraignons en outre notre algorithme de recherche de sorte que le résidu modulaire de 5 , appelons-le j , soit inférieur à m / 1000 , cela garantira que nous avons également une régularité de 5-8 . Le résultat est quelque chose comme ceci:Comme vous pouvez le voir, si nous remplaçons
0
parI
, 0-3 et 5-8 sont tous garantis pour être correctement cartographiés! Les valeurs de 4 et 9 doivent cependant être forcées brutalement. Plus précisément, 4 doit contenir un0
et unj
(dans cet ordre) et 9 doit en contenir un0
, suivi d'un autre chiffre qui n'apparaît nulle part ailleurs. Certes, il existe un certain nombre d'autres formules qui, par un coup de hasard, pourraient produire le résultat souhaité. Certains d'entre eux peuvent même être plus courts. Mais je ne pense pas qu'il y en ait qui soient aussi susceptibles de réussir que celui-ci.J'ai également expérimenté plusieurs remplacements pour
I
et / ouV
avec un certain succès. Mais hélas, rien de plus court que ce que j'avais déjà. Voici une liste des solutions les plus courtes que j'ai trouvées (le nombre de solutions de 1 à 2 octets de plus est trop important pour être répertorié):la source
HTML + JavaScript + CSS (137)
HTML (9)
JavaScript (101)
CSS (27)
Sortie
...
Démo sur JSBin
la source
document.write('<ol>'+"<li style='list-style:upper-roman'/>".repeat(100)+'</ol>')
(ES6)document.write("<li style='list-style:upper-roman'/>".repeat(100))
Python 116
meilleur code golfé de la réponse de scleaver:
la source
Python, 139
la source
C,
177160147 caractèresIl existe des solutions plus courtes, mais aucune en C, alors voici mon essai.
Nouvelle solution, complètement différente de la précédente:
Solution précédente (160 caractères):
Logique:
1.
f
imprime un nombre de 1 à 10.c
est le chiffre utilisé, qui peut êtreIVX
ouXLC
. Appelé une fois pour les dizaines une fois pour celles.2. Si
n%5==0
- n'imprime rien ouc[n/5]
qui estI
ouV
(ouL
ouC
).3. Si
n%4==4
-4
ou9
- imprimerI
(ouX
), parn+1
.4. Si
n>4
- imprimer5
(c'estV
-à- dire ouL
) alorsn-5
.5. Si
n<4
- imprimezI
alorsn-1
(c.-à-d.n
FoisI
).la source
f(c,n){printf("%.*s",n%5>3?2:n%5+n/5,"XLXXXCIVIIIX "+c+(n%5>3?n%4*4:2-n/5));}main(i){for(;i<100;f(12,4))f(0,i/10),f(6,i++%10);puts("C");}
JavaScript, 123
Inspiré par une version plus longue, je suis tombé sur un groupe de discussion polonais (au moins, Chrome pensait que c'était polonais).
la source
Q (
8180)2ème coupe:
1ère coupe:
la source
Python, 168
Explication
En utilisant ces valeurs, prenez la plus grande valeur non supérieure à n et soustrayez-la de n. Répétez jusqu'à ce que n soit 0.
la source
r=lambda n,l,v:n and(n<v[0]and r(n,l[1:],v[1:])or l[0]+r(n-v[0],l,v))or""
enregistre deux caractères. Sinon très sympa.Rubis 1,9,
140132Cela compte littéralement de 1 à 100 en chiffres romains. Commence par une chaîne vide, puis passe par l'ajout de «I», puis par l'application répétée d'une série de règles de substitution, ajoutant effectivement 1.
Edit: Ajout du numéro de version, car
?I
ne fonctionne que dans 1.9, et a utilisé les modifications de @ Howard pour couper certains caractères.la source
r while
->0while
,r.sub!(*q)
->r.sub! *q
. Vous pouvez également faire glisser l'impression à l'intérieur de la boucle et l'utiliser à la100.times{...}
place de l'instruction map.(%w[IIII VIV XXXX LXL]<</(.)((?!\1)[^I])\1/).zip(%w(IV IX XL XC)<<'\2')
enregistre 7 caractères.Ruby 112 caractères
Fondamentalement, en utilisant la
to_roman
méthode expliquée ici , mais en utilisant un tableau zippé pour plus de brièveté.la source
Mathematica
159 150142Solution intégrée :
IntegerString
38 caractèresla source
perl 205
Golfé:
la source
MUMPS 184
Même algorithme que @cardboard_box, dont j'ai repris l'explication textuellement -
Explication
En utilisant ces valeurs, prenez la plus grande valeur non supérieure à n et soustrayez-la de n. Répétez jusqu'à ce que n soit 0.
la source
R , 85 octets
Essayez-le en ligne!
Utilise la
utils
variable de package aléatoire.romans
pour obtenir les valeurs des chiffres romains, mais effectue la conversion par elle-même; l'approche intégrée serait de 20 octets:cat(as.roman(1:100))
la source
cat(paste(as.roman(1:100)))
ou simplementas.roman(1:100)
. Bizarre.cat
indiquent qu'il effectue moins de conversion queprint
et ne fonctionne que sur desatomic
vecteurs - ce qui explique cela!APL 128
J'ai essayé une solution d'indexation en APL:
Il peut être de 4 octets plus court en origine d'index 0 au lieu de 1 mais le véritable porc spatial est la génération de la matrice d'index via:
Jusqu'à présent, je n'ai pas pu générer les indices à la volée!
la source
LaTeX (138)
la source
Python, 125
la source
PHP,
3837 octets<ol type=I><?=str_repeat("<li>",100);
-1 octet grâce à @manatwork
Même idée que la réponse de Patrick , mais dans un langage plus compact. Beats Mathematica !
Essayez-le en ligne!
la source
;
, alors pas besoin de?>
.VBA (Excel), 245 octets
fonction créée pour la répétition et le remplacement - 91 octets
Function s(a,b):s=String(a,b):End Function Function b(x,y,z):b=Replace(x,y,z):End Function
en utilisant la fenêtre immédiate ( 154 octets )
p="I":for x=1to 100:?b(b(b(b(b(b(b(b(s(x,p),s(100,p),"C"),s(90,p),"XC"),s(50,p),"L"),s(40,p),"XL"),s(10,p),"X"),s(9,p),"IX"),s(5,p),"V"),s(4,p),"IV"):next
la source
Java (OpenJDK 8) , 152 octets
Essayez-le en ligne!
Explication:
la source
TeX, 354 octets
Quelques explications: TeX fournit une commande intégrée
\romannumeral
pour convertir des nombres en chiffres romains. Comme la question ne permet pas d'utiliser les fonctions intégrées, le code ci-dessus est une version golfée du même algorithme que le compilateur TeX original de Knuth utilise pour\romannumeral
(voir TeX: The Program , § 69,print_roman_int
) réimplémenté dans TeX.Comme il veut laisser la joie de dérouter le fonctionnement de ce code au lecteur, Knuth refuse de donner une explication de cette partie du code. Je vais donc emboîter le pas et donner juste une version non golfée et légèrement modifiée, qui est plus proche de l'original que le code ci-dessus:
la source