Entier va et vient dans le temps

17

Contribution:

Un nombre entier.

Production:

  1. Convertissez d'abord l'entier en son chiffre romain équivalent.
  2. Convertissez ensuite chaque lettre majuscule de ce chiffre romain en leur valeur décimale ASCII / UNICODE.
  3. Et produire la somme de ceux-ci.

Exemple:

1991 -> MCMXCI -> 77+67+77+88+67+73 -> 449
^ input                                ^ output

Chiffres romains: voici un convertisseur de chiffres romains peut-être utile.
entrez la description de l'image ici

Règles du défi:

  • Les règles standard du chiffre romain sont appliquées, donc aucune autre forme comme IIIIou VIIIIau lieu de IVet IX. *
  • Les lignes Macron au-dessus des 1000 chiffres romains sont ¯(UNICODE nr. 175). Donc une ligne compte +175et deux comme +350.
  • Vous êtes autorisé à utiliser tout type de type d'entrée et de sortie, tant qu'il représente les entiers.
  • Les cas de test seront de l'ordre de 1 - 2,147,483,647.

* Règles du chiffre romain (citation de Wikipedia):

Les nombres sont formés en combinant des symboles et en ajoutant les valeurs, il en IIest de même de deux (deux) et de XIIItreize (dix et trois). Parce que chaque chiffre a une valeur fixe plutôt que de représenter des multiples de dix, cent et ainsi de suite, selon la position, il n'est pas nécessaire de mettre des zéros de "placement", comme dans les nombres comme 207 ou 1066; ces nombres sont écrits comme CCVII(deux centaines, cinq et deux) et MLXVI(mille, cinquante, dix, cinq et un).

Les symboles sont placés de gauche à droite par ordre de valeur, en commençant par le plus grand. Cependant, dans quelques cas spécifiques, pour éviter que quatre caractères ne se répètent successivement (comme IIIIou XXXX), la notation soustractive est souvent utilisée comme suit:

  • Iplacé avant Vou Xindique un de moins, donc quatre est IV(un de moins de cinq) et neuf est IX(un de moins de dix)
  • Xplacé avant Lou Cindique dix de moins, donc quarante est XL(dix de moins de cinquante) et quatre-vingt-dix est XC(dix de moins de cent)
  • Cplacé avant Dou Mindique cent de moins, donc quatre cents est CD(cent de moins de cinq cents) et neuf cents est CM(cent de moins de mille)
    Par exemple, MCMIVest mille neuf cent quatre, 1904 ( Mest un millier, CMest neuf cent IVquatre).

Voici quelques exemples de l'utilisation moderne des chiffres romains:
1954 as MCMLIV; 1990 comme MCMXC; 2014 comme MMXIV
SOURCE

Règles générales:

  • C'est le , donc la réponse la plus courte en octets l'emporte.
    Ne laissez pas les langues de golf de code vous décourager de publier des réponses avec des langues autres que le golf de code. Essayez de trouver une réponse aussi courte que possible pour «n'importe quel» langage de programmation.
  • Des règles standard s'appliquent à votre réponse, vous êtes donc autorisé à utiliser STDIN / STDOUT, des fonctions / méthodes avec les paramètres appropriés, des programmes complets. Ton appel.
  • Les failles par défaut sont interdites.
  • Si possible, veuillez ajouter un lien avec un test pour votre code.
  • Veuillez également ajouter une explication si nécessaire.

Cas de test:

100          ->   67
1            ->   73
4            ->   159
22           ->   322
5000         ->   261
2016         ->   401
1000000000   ->   427
1991         ->   449
9999         ->   800
1111111111   ->   2344
2147483647   ->   5362
Kevin Cruijssen
la source
Connexes
Kevin Cruijssen
1
@martin 9999-> M(X)CMXCIX-> 77+263+67+77+88+67+73+88-> 800et 2147483647-> ((MMCXLV)MMCDLXXX)MMMDCXLVII-> 427+427+417+438+426+436 + 252+252+242+243+251+263+263+263 + 77+77+77+68+67+88+76+86+73+73-> 5362. J'ai donc corrigé la seconde, mais 9999c'était correct.
Kevin Cruijssen
1
Le cas de test 2222222222n'est pas dans la plage donnée. Je suis également d'accord avec 5362.
Neil
1
Le titre ressemble un peu à une question Stack Overflow C.
user6245072
3
Le mot «quatrième» dans le titre est-il un jeu de mots? Sinon, il devrait être "en avant".
Monty Harder

Réponses:

4

Mathematica, 181 173 166 151 151 octets

Golfé

(q=Select[ToCharacterCode@#,64<#<99&]&/@StringSplit[RomanNumeral[#],"_"];p=PadLeft;l=Length;Total[p[q,4]+p[{350,350*Mod[l@q,2],175,0}[[-l@q;;]],4],2])&

Non golfé

(
q = Select[
     ToCharacterCode@#,
     64<#<99&
    ]&/@StringSplit[RomanNumeral@#,"_"];
p=PadLeft;
l=Length;
Total[
   p[q,4]+
   p[{350,350*Mod[l@q,2],175,0}[[-l@q;;]],4]
   ,2]
)&

L' RomanNumeralimplémentation de Mathematica donne (IX) CMXCIX pour 9999, et donc le programme renvoie 971 pour ce nombre.

Tel qu'écrit, un chiffre romain du type ((...)) (...) ... renvoie une liste imbriquée des codes ASCII pour les chiffres romains de longueur 4, ((...)) ... renvoie une liste de longueur 3, (...) ... renvoie une liste de longueur 2, et ... retourne une liste de longueur 1. La dernière ligne convertit ces règles en le nombre approprié de macrons pour chaque section de la , ajoute ces macrons, puis additionne toute la liste imbriquée pour renvoyer la sortie.

HiggstonRainbird
la source
1
Bienvenue chez PPCG!
betseg
@betseg Merci! C'était un premier problème amusant.
HiggstonRainbird
10

Python 3, 281 278 273 269 ​​octets

Ma première tentative de codegolf, c'est parti. J'ai essayé de le faire sans regarder la question liée, donc c'est probablement terrible :)

def f(n):d=len(str(n))-1;l=10**d;return 0if n<1else(n<l*4and[73,88,67,77,263,242,252,438,417,427][d]+f(n-l))or(l<=n//9and[161,155,144,340,505,494,690,855,844][d]+f(n-9*l))or(n<l*5and[159,164,135,338,514,485,688,864,835][d]+f(n-4*l))or[86,76,68][d%3]+(d//3*175)+f(n-5*l)

8 octets de moins, grâce à Gábor Fekete

Non golfé:

def f(n):
d = len(str(n)) - 1 # number of digits minus one
l = 10 ** d         # largest power of 10 that is not larger than parameter
if n == 0:
    return 0
elif n < 4 * l: # starts with X, C, M, ...
    return [
        ord('I'),
        ord('X'),
        ord('C'),
        ord('M'),
        ord('X') + 175, 
        ord('C') + 175, 
        ord('M') + 175, 
        ord('X') + 350, 
        ord('C') + 350, 
        ord('M') + 350
    ][d] + f(n - l)
elif n // 9 * 10 >= 10 * l: # starts with IX, XC, ...
    return [
        ord('I') + ord('X'), 
        ord('X') + ord('C'), 
        ord('C') + ord('M'),
        ord('M') + ord('X') + 175,
        ord('X') + ord('C') + 350,
        ord('C') + ord('M') + 350,
        ord('M') + ord('X') + 525,
        ord('X') + ord('C') + 700,
        ord('C') + ord('M') + 700
    ][d] + f(n - 9*l)
elif n < 5 * l: # starts with IV, XL, CD, ... 
    return [
        ord('I') + ord('V'),
        ord('X') + ord('L'),
        ord('C') + ord('D'),
        ord('M') + ord('V') + 175,
        ord('X') + ord('L') + 350,
        ord('C') + ord('D') + 350,
        ord('M') + ord('V') + 525,
        ord('X') + ord('L') + 700,
        ord('C') + ord('D') + 700
    ][d] + f(n - 4 * l)
else: # starts with V, L, D, ...
    return [
        ord('V'), 
        ord('L'), 
        ord('D'),
        ord('V') + 175, 
        ord('L') + 175, 
        ord('D') + 175,
        ord('V') + 350, 
        ord('L') + 350, 
        ord('D') + 350
    ][d] + f(n - 5 * l)
jDomantas
la source
Vous pouvez jouer au golf quelques octets en remplaçant return 0 if n==0 elseparreturn 0if n<1else
Gábor Fekete
Votre version golfée contient des appels florsque le nom de la fonction est g.
Gábor Fekete
Passez n//9*10>=10*là n//9>=lpour en enregistrer davantage.
Gábor Fekete
Correction du nom de la fonction, je l'ai changé pour vérifier si je l'ai joué correctement et j'ai oublié de le changer.
jDomantas
3

Mathematica, 198 octets

Tr[Tr@Flatten[ToCharacterCode/@#]+Length@#*Tr@#2&@@#&/@Partition[Join[SplitBy[Select[Characters@#/."\&"->1,MemberQ[Join["A"~CharacterRange~"Z",{1}],#]&],LetterQ]/. 1->175,{{0}}],2]]&@RomanNumeral@#&

Malheureusement, la fonction intégrée n'aide pas beaucoup ici, même si je suis sûr que cela peut être joué beaucoup plus.

Remarque: Évalue 9999 -> 971selon ici .

Martin
la source
2

Lot, 373 octets

@echo off
set/an=%1,t=0,p=1
call:l 73 159 86 161
call:l 88 164 76 155
call:l 67 135 68 144
call:l 77 338 261 340
call:l 263 514 251 505
call:l 242 485 243 494
call:l 252 688 436 690
call:l 438 864 426 855
call:l 417 835 418 844
call:l 427 0 0 0
echo %t%
exit/b
:l
set/ad=n/p%%10,p*=10,c=d+7^>^>4,d-=9*c,t+=%4*c,c=d+3^>^>3,d-=5*c,t+=%3*c+%2*(d^>^>2)+%1*(d^&3)

Fonctionne en traduisant chaque chiffre du numéro en fonction d'une table de consultation pour les valeurs 1, 4, 5 et 9. Les utilisations M(V), M(X), (M(V))et (M(X)). Si vous préférez (IV), (IX), ((IV))et ((IX))puis utiliser call:l 77 509 261 511et call:l 252 859 436 861respectivement.

Neil
la source
1

JavaScript (ES6), 183 octets

f=(n,a=0)=>n<4e3?[256077,230544,128068,102535,25667,23195,12876,10404,2648,2465,1366,1183,329].map((e,i)=>(d=e>>8,c=n/d|0,n-=c*d,r+=c*(e%256+a*-~(i&1))),r=0)|r:f(n/1e3,a+175)+f(n%1e3)

Note: préfère non seulement (IV)à M(V), mais préfère aussi (VI)à (V)M; en fait, il n'utilisera M qu'au tout début du numéro.

Neil
la source
1

Python, 263 octets

def g(m):x=0;r=[73,86,88,76,67,68,77,261,263,251,242,243,252,436,438,426,417,418,427,0,0];return sum([b%5%4*r[i+(i*1)]+((b==9)*(r[i+(i*1)]+r[(i+1)*2]))+((b==4)*(r[i+(i*1)]+r[i+1+(i*1)]))+((b in [5,6,7,8])*r[i+1+(i*1)])for i,b in enumerate(map(int,str(m)[::-1]))])
Elly G
la source
Bienvenue chez PPCG, belle première réponse!
Copper
1

R, 115 octets

Alors ... je poste ma solution parce que je trouve la question assez intéressante. Je faisais de mon mieux avec R « s capacités pour faire face aux chiffres romains sans paquets: vous ne pouvez saisir les numéros entre 1et 3899, comme le as.roman» s documentation explique.

C'est pourquoi j'ai un peu triché en donnant une plage entre 1to dans la boucle: c'est la longueur de la sortie de ( ) . En fait, selon ce site , le plus long chiffre romain est (14 caractères), ce qui correspond à .11 14foras.roman(3899)MMMDCCCXCIX
MMDCCCLXXXVIII2888

De plus, vous ne pouvez pas calculer lengthla sortie de cette fonction.

a=scan();v=0;for(i in 1:14){v=c(v,as.numeric(charToRaw(substring(as.character(as.roman(a)),1:14,1:14)[i])))};sum(v)

Si quelqu'un voit une solution pour résoudre les problèmes ci-dessus, n'hésitez pas à commenter.

Frédéric
la source
0

Python 3, 315 octets

def p(n=int(input()),r=range):return sum([f*g for f,g in zip([abs(((n-4)%5)-1)]+[t for T in zip([((n+10**g)//(10**g*5))%2for g in r(10)],[(n%(10**g*5))//(10**g*4)+max((n%(10**g*5)%(10**g*4)+10**(g-1))//(10**g),0)for g in r(1,10)])for t in T],[73,86,88,76,67,68,77,261,263,251,242,243,252,436,438,426,417,418,427])])

Version non golfée:

def p(n=int(input()),r=range):
    return sum([f*g for f,g in zip(
        [abs(((n-4)%5)-1)]+
        [t for T in zip(
            [((n+10**g)//(10**g*5))%2for g in r(10)],
            [(n%(10**g*5))//(10**g*4)+max((n%(10**g*5)%(10**g*4)+10**(g-1))//(10**g),0)for g in r(1,10)]
        )for t in T],
        [73,86,88,76,67,68,77,261,263,251,242,243,252,436,438,426,417,418,427])])

Explication: Cette version utilise une approche différente, elle compte les occurrences de chiffres romains dans le nombre.

[abs(((n-4)%5)-1)]est le nombre de Is dans le chiffre romain.

[((n+10**g)//(10**g*5))%2for g in r(10)]est le nombre de V,L,D,(V),(L),(D),((V)),((L)),((D))s dans le nombre.

[(n%(10**g*5))//(10**g*4)+max((n%(10**g*5)%(10**g*4)+10**(g-1))//(10**g),0)for g in r(1,10)]est le nombre de X,C,M,(X),(C),(M),((X)),((C)),((M))s dans le nombre.

Il multiplie ensuite les occurrences par la valeur du caractère et renvoie la somme de celui-ci.

Gábor Fekete
la source