Segments de ligne de chiffre romain

10

Écrivez un programme ou une fonction qui accepte un entier compris entre 1 et 3 999 en entrée et renvoie le nombre de segments de ligne requis pour exprimer cet entier en chiffres romains standard (vous utiliserez donc XL mais pas VM). Exemples:

   1 -> 1
   4 -> 3
   5 -> 2
   9 -> 3
  10 -> 2
  40 -> 4
  50 -> 2
  90 -> 3
 100 -> 1
 400 -> 3
 500 -> 2
 900 -> 5
1000 -> 4

Les fonctions intégrées de conversion des nombres romains sont autorisées, mais vous pouvez résoudre le problème sans elles en soustrayant à plusieurs reprises le plus grand nombre restant de la liste ci-dessus. Exemple: 1234 = 4 + 1 + 1 + 2 + 2 + 2 + 3 = 15.

C'est le , donc le programme le plus court l'emporte.

Neil
la source
Pourquoi 10 segments de deux lignes au lieu de quatre? Lors de l'écriture de X, vous n'écrivez généralement que deux lignes, mais l'intersection des lignes ne fait-elle pas quatre segments?
Alex A.
@AlexA. La définition du segment de ligne est généralement quelque chose comme: "L'ensemble des points suivant le chemin le plus court entre deux points". Il ne semble pas y avoir de raison de couper X en fonction de cela, vous n'avez besoin que de deux ensembles de points d'extrémité pour le définir. (En supposant que les Romains ont principalement écrit sur les géométries euclidiennes, je suppose)
FryAmTheEggman
@FryAmTheEggman Hm ok. Bon à savoir, merci.
Alex A.

Réponses:

2

Pyth, 92 76 70 octets

KsMc."/9hæ²z³Þ§ªW×Oû[Tnè,O¤"\/WQ=Q-Q=Nef!>TQ%2K aY@KhxKN;sY

Essayez-le ici!

Merci à @FryAmTheEggman pour quelques suggestions d'emballage de chaînes qui m'ont fait économiser quelques octets!

Je me demande toujours s'il existe un moyen mathématique d'encoder cette liste. Va essayer de comprendre quelque chose.

Explication

Cela utilise l'algorithme donné. Kcontient la liste donnée avec les numéros et le nombre correspondant de segments de ligne en alternance. Cette liste est construite en divisant une chaîne compressée, qui est décodée 0/0/1/1/4/3/5/2/9/3/10/2/40/4/50/2/90/3/100/1/400/3/500/2/900/5/1000/4, /activée et mappée à chaque élément en un entier.

KsMc. "..." \ / WQ = QQ = Nef!> TQ% 2K aY @ KhxKN; sY # Q = entrée

   c. "..." \ / # divise la chaîne sur /
KsM # mappe chaque nombre à int et attribue à K
            WQ # tandis que Q! = 0
                     f% 2K # ne prend que chaque 2ème élément de K et filtre avec T
                      !> TQ # T <= Q
                  = Ne # Prenez le dernier élément de cela et affectez-le à N
              = QQ # Q = Q - N
                                   xKN # indice de la première occurrence de N dans K
                                  h # incrémente cet index parce que nous voulons que les segments de ligne
                              aA @ K # obtenir le segment de ligne de cet index et l'ajouter à Y
                                      ; sY # termine la boucle et imprime la somme de tous les segments de ligne en Y
Denker
la source
3

C, 148 129 caractères

d,x,n[]={1000,900,500,400,100,90,50,40,10,9,5,4,1,4,5,2,3,1,3,2,4,2,3,2,3,1};f(c){while(d+=(c/n[x])*n[x+13],c%=n[x++]);return d;}

Mon premier code-golf: ^). Étant donné que la question indique que je peux utiliser une fonction, j'ai changé main en une fonction pour couper certains caractères (surtout: passez c comme paramètre plutôt scanf)

déballé

d,x,n[]={1000,900,500,400,100,90,50,40,10,9,5,4,1,4,5,2,3,1,3,2,4,2,3,2,3,1};
f(c){
  while(d+=(c/n[x])*n[x+13],
        c%=n[x++]);
  return d;
}
STDQ
la source
2

Mathematica, 80 72 octets

Tr[Characters[#~IntegerString~"Roman"]/.{"I"|"C"->1,"M"->4,_String->2}]&

Fonction anonyme qui convertit simplement les nombres en chiffres romains, remplace chaque caractère par son nombre de segments et prend le total.

LegionMammal978
la source
2

Rétine, 128 octets

. +
$ *
1 {1000}
t '
1 {900}
td
1 {500}
ré
1 {400}
t
1 {100}
"
1 {90}
t
1 {50}
ré
1 {40}
t '
1 {10}
ré
1 {9}
t
1 {5}
ré
1 {4}
t
1
"
t
ré'
ré
''
'+
0,0 $

Remplacement simple jusqu'à ce qu'il ne reste plus rien à remplacer. Ensuite, les apostrophes sont comptées et c'est notre nombre de segments de ligne.

Si l'entrée et la sortie en unaire sont autorisées, c'est 115 octets (mais qui voudrait en taper 1234?).

Essayez-le en ligne!
Essayez-le en ligne! (IO unaire)

daavko
la source
2

Python 3, 95 octets

def f(a,b=0):
 for e in'᝴ᔝ஺ॣəȟĮô>9 ':e=ord(e);d=e//6;b+=a//d*(e%6);a%=d
 return b

La chaîne Unicode se compose des points de code:

6004 5405 3002 2403 601 543 302 244 62 57 32 27 7
Lynn
la source
Si vous transformez cette chaîne en un octet littéral, vous pouvez omettree=ord(e);
xsot
Je ne pense pas que cela fonctionne dans mon cas. J'ai besoin d'une chaîne Unicode :( c'est-à-dire que je boucle sur les points de code de cette chaîne, pas sur les octets.
Lynn
1
Oh je vois. Cela vous dérange de fournir un vidage hexadécimal de la chaîne? Il ne s'affiche pas correctement sur mon téléphone.
xsot
1

Java, 152 octets

Parce que, tu sais, Java.

n->{int c=0;int[]r={999,4,899,5,499,2,399,3,99,1,89,3,49,2,39,4,9,2,8,3,4,2,3,3,0,1};for(int i=0;i<26;i+=2)while(n>r[i]){n-=r[i]+1;c+=r[i+1];}return c;}

Implémentation littérale simple de l'algorithme donné. Le tableau contient les informations de transformation: les index pairs sont un de moins que le chiffre romain et les index impairs sont le compte de ce chiffre.

C'est un lambda qui prend et retourne un int/ Integer. Cela comprend IntUnaryOperatorou UnaryOperator<Integer>.

CAD97
la source
1

JavaScript (ES6), 79 octets

n=>"0123323453"[[,a,b,c,d]=1e4+n+'',d]-(-"0246424683"[c]-"0123323455"[b])+a*4

Les chaînes représentent le nombre de segments de ligne pour les unités, les dizaines et les centaines de chiffres. (Des milliers est tout simplement quatre fois le chiffre des milliers.) Cette méthode semble être plus courte que d'autres options telles que l'algorithme suggéré dans la question.

Edit: sauvé 2 octets grâce à @ user81655.

Neil
la source
Ceci est un algorithme cool. Réorganiser les conversions peut également économiser 2 octets:n=>"0123323453"[[,a,b,c,d]=1e4+n+'',d]-(-"0246424683"[c]-"0123323455"[b])+a*4
user81655
@ user81655 Oh, c'est bien: le simple fait de changer le +s en -s me permet de supprimer le début +, mais le regroupement enregistre un autre octet.
Neil