El número entero va y viene a través del tiempo


17

Entrada:

Un entero

Salida:

  1. Primero convierta el entero a su número romano equivalente.
  2. Luego convierta cada letra mayúscula de ese número romano a su valor decimal ASCII / UNICODE.
  3. Y generar la suma de esos.

Ejemplo:

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

Números romanos: Aquí hay un convertidor de números romanos quizás útil.
ingrese la descripción de la imagen aquí

Reglas de desafío:

  • Se aplican las reglas estándar de números romanos, por lo que no hay formas alternativas como IIIIo en VIIIIlugar de IVy IX. *
  • Las líneas de Macron sobre los números romanos más allá de 1,000 son ¯(UNICODE nr. 175). Entonces una línea cuenta como +175y dos como +350.
  • Puede usar cualquier tipo de entrada y salida, siempre que represente los enteros.
  • Los casos de prueba estarán en el rango de 1 - 2,147,483,647.

* Reglas de números romanos (cita de Wikipedia):

Los números se forman combinando símbolos y sumando los valores, entonces IIson dos (dos unos) y XIIItrece (diez y tres unos). Debido a que cada número tiene un valor fijo en lugar de representar múltiplos de diez, cien y así sucesivamente, según la posición, no hay necesidad de ceros de "mantenimiento de lugar", como en números como 207 o 1066; esos números se escriben como CCVII(dos cientos, cinco y dos unidades) y MLXVI(mil, cincuenta, diez, cinco y uno).

Los símbolos se colocan de izquierda a derecha en orden de valor, comenzando por el más grande. Sin embargo, en algunos casos específicos, para evitar que se repitan cuatro caracteres en sucesión (como IIIIo XXXX), la notación sustractiva se usa a menudo de la siguiente manera:

  • Icolocado antes Vo Xindica uno menos, entonces cuatro es IV(uno menos que cinco) y nueve es IX(uno menos que diez)
  • Xcolocado antes Lo Cindica diez menos, entonces cuarenta es XL(diez menos de cincuenta) y noventa es XC(diez menos de cien)
  • Ccolocado antes Do Mindica cien menos, entonces cuatrocientos es CD(cien menos de quinientos) y novecientos es CM(cien menos de mil)
    Por ejemplo, MCMIVes mil novecientos cuatro, 1904 ( Mes mil, CMes novecientos y IVes cuatro).

Algunos ejemplos del uso moderno de los números romanos incluyen:
1954 como MCMLIV; 1990 como MCMXC; 2014 como MMXIV
FUENTE

Reglas generales:

  • Este es el , por lo que la respuesta más corta en bytes gana.
    No permita que los lenguajes de código de golf lo desalienten de publicar respuestas con idiomas que no sean de código. Trate de encontrar una respuesta lo más breve posible para 'cualquier' lenguaje de programación.
  • Se aplican reglas estándar para su respuesta, por lo que puede usar STDIN / STDOUT, funciones / método con los parámetros adecuados, programas completos. Tu llamada.
  • Las lagunas predeterminadas están prohibidas.
  • Si es posible, agregue un enlace con una prueba para su código.
  • Además, agregue una explicación si es necesario.

Casos de prueba:

100          ->   67
1            ->   73
4            ->   159
22           ->   322
5000         ->   261
2016         ->   401
1000000000   ->   427
1991         ->   449
9999         ->   800
1111111111   ->   2344
2147483647   ->   5362


1
@martin 9999-> M(X)CMXCIX-> 77+263+67+77+88+67+73+88-> 800y 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. Así que he corregido el segundo, pero 9999fue correcto.
Kevin Cruijssen

1
El caso de prueba 2222222222no está en el rango dado. También estoy de acuerdo con 5362.
Neil

1
El título suena como una pregunta de Stack Overflow C.
user6245072

3
¿Es la palabra "cuarto" en el título un juego de palabras? Si no, debería ser "adelante".
Monty Harder

Respuestas:


4

Mathematica, 181 173 166 151 bytes

Golfed

(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])&

Sin 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]
)&

La RomanNumeralimplementación de Mathematica proporciona (IX) CMXCIX para 9999, por lo que el programa devuelve 971 para ese número.

Tal como está escrito, un número romano del tipo ((...)) (...) ... devuelve una lista anidada de los códigos ASCII para los números romanos de longitud 4, ((...)) ... devuelve una lista de longitud 3, (...) ... devuelve una lista de longitud 2 y ... devuelve una lista de longitud 1. La línea final convierte esas reglas en el número apropiado de macrones para cada sección del lista, agrega esos macrones y luego suma toda la lista anidada para devolver la salida.


1
Bienvenido a PPCG!
betseg

@betseg ¡Gracias! Este fue un primer problema divertido.
HiggstonRainbird

10

Python 3, 281 278 273 269 ​​bytes

Mi primer intento de codegolf, aquí vamos. Intenté hacerlo sin mirar la pregunta vinculada, por lo que probablemente sea 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 bytes más pequeños, gracias a Gábor Fekete

Sin 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)

Puedes jugar algunos bytes reemplazando return 0 if n==0 elseconreturn 0if n<1else
Gábor Fekete

Su versión de golf tiene llamadas fcuando el nombre de la función es g.
Gábor Fekete

Cambie n//9*10>=10*la n//9>=lpara guardar un poco más.
Gábor Fekete

Se corrigió el nombre de la función, lo cambié para comprobar si jugaba correctamente y olvidé volver a cambiarlo.
jDomantas


3

Mathematica, 198 bytes

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@#&

Desafortunadamente, la construcción no ayuda mucho aquí, aunque estoy seguro de que esto se puede jugar mucho más.

Nota: Evalúa 9999 -> 971según aquí .


2

Lote, 373 bytes.

@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)

Funciona mediante la traducción de cada dígito del número de acuerdo con una tabla de consulta para los valores de 1, 4, 5 y 9. Usos M(V), M(X), (M(V))y (M(X)). Si lo prefiere (IV), (IX), ((IV))y ((IX))luego usar call:l 77 509 261 511y call:l 252 859 436 861respectivamente.


1

JavaScript (ES6), 183 bytes

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)

Nota: no sólo prefiere (IV)a M(V), pero también prefiere (VI)a (V)M; de hecho solo usará M al comienzo del número.


1

Python, 263 bytes

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]))])

Bienvenido a PPCG, buena primera respuesta!
Cobre

1

R, 115 bytes

Entonces ... estoy publicando mi solución porque la pregunta me parece bastante interesante. Hice todo lo posible con R 's capacidades para hacer frente a los números romanos sin paquetes: Sólo puede introducir números entre 1y 3899, como el as.roman' s documentación explica.

Es por eso que hice un poco de trampa al dar un rango entre 1a en el bucle: es la longitud de la salida de ( ) . De hecho, según este sitio web , el número romano más largo es (14 caracteres), que corresponde a11 14foras.roman(3899)MMMDCCCXCIX
MMDCCCLXXXVIII2888 .

Además, no puede calcular lengthla salida de esta función.

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 alguien ve una solución para resolver los problemas anteriores, no dude en comentar.


0

Python 3, 315 bytes

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])])

Versión sin golf:

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])])

Explicación: Esta versión utiliza un enfoque diferente, cuenta las apariciones de números romanos en el número.

[abs(((n-4)%5)-1)]es el número de Is en el número romano.

[((n+10**g)//(10**g*5))%2for g in r(10)]es el número de V,L,D,(V),(L),(D),((V)),((L)),((D))s en el número.

[(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)]es el número de X,C,M,(X),(C),(M),((X)),((C)),((M))s en el número.

Luego, multiplica las ocurrencias con el valor del personaje y devuelve la suma del mismo.

Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.