Liczba całkowita zmienia się w czasie

17

Wejście:

Liczba całkowita.

Wynik:

  1. Najpierw przekonwertuj liczbę całkowitą na odpowiadającą jej liczbę rzymską.
  2. Następnie przekonwertuj każdą wielką literę tej cyfry rzymskiej na ich wartość dziesiętną ASCII / UNICODE.
  3. I wypisz ich sumę.

Przykład:

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

Cyfry rzymskie: Oto prawdopodobnie przydatny konwerter cyfr rzymskich.
wprowadź opis zdjęcia tutaj

Zasady konkursu:

  • Stosowane są standardowe reguły liczb rzymskich, więc nie ma alternatywnych form takich jak IIIIlub VIIIIzamiast IVi IX. *
  • Linie Macrona powyżej cyfr rzymskich powyżej 1000 to ¯(UNICODE nr. 175). Więc jedna linia liczy się jako, +175a dwie jak +350.
  • Możesz używać dowolnego rodzaju danych wejściowych i wyjściowych, o ile reprezentują one liczby całkowite.
  • Przypadki testowe będą w zakresie 1 - 2,147,483,647.

* Reguły cyfr rzymskich (cytat z Wikipedii):

Liczby są tworzone przez łączenie symboli i dodawanie wartości, podobnie jak IIdwa (dwa) i XIIItrzynaście (dziesięć i trzy). Ponieważ każda cyfra ma stałą wartość, a nie reprezentuje wielokrotność dziesięciu, stu itd., Zgodnie z pozycją, nie ma potrzeby zerowania miejsca, jak w liczbach takich jak 207 lub 1066; liczby te zapisano jako CCVII(dwieście, pięć i dwa) i MLXVI(tysiąc, pięćdziesiąt, dziesięć, pięć i jeden).

Symbole są umieszczane od lewej do prawej w kolejności wartości, zaczynając od największej. Jednak w kilku szczególnych przypadkach, aby uniknąć powtarzania się czterech znaków kolejno (takich jak IIIIlub XXXX), notacja odejmująca jest często stosowana w następujący sposób:

  • Iumieszczone przed Vlub Xwskazuje jeden mniej, więc cztery to IV(jeden mniej niż pięć), a dziewięć to IX(jeden mniej niż dziesięć)
  • Xumieszczone przed Llub Cwskazuje dziesięć mniej, więc czterdzieści to XL(dziesięć mniej niż pięćdziesiąt), a dziewięćdziesiąt to XC(dziesięć mniej niż sto)
  • Cumieszczone przed Dlub Mwskazuje sto mniej, więc czterysta to CD(sto mniej niż pięćset), a dziewięćset to CM(sto mniej niż tysiąc)
    Na przykład, MCMIVto tysiąc dziewięćset cztery, 1904 ( Mto tysiąc, CMto dziewięćset i IVcztery).

Niektóre przykłady współczesnego użycia cyfr rzymskich obejmują:
1954 as MCMLIV; 1990 jako MCMXC; 2014 jako MMXIV
ŹRÓDŁO

Główne zasady:

  • To jest , więc wygrywa najkrótsza odpowiedź w bajtach.
    Nie pozwól, aby języki gry w golfa zniechęcały Cię do publikowania odpowiedzi w językach niekodujących golfa. Spróbuj znaleźć możliwie najkrótszą odpowiedź na „dowolny” język programowania.
  • Do odpowiedzi mają zastosowanie standardowe reguły , więc możesz używać STDIN / STDOUT, funkcji / metody z odpowiednimi parametrami, pełnych programów. Twoja decyzja.
  • Domyślne luki są zabronione.
  • Jeśli to możliwe, dodaj link z testem swojego kodu.
  • W razie potrzeby dodaj również wyjaśnienie.

Przypadki testowe:

100          ->   67
1            ->   73
4            ->   159
22           ->   322
5000         ->   261
2016         ->   401
1000000000   ->   427
1991         ->   449
9999         ->   800
1111111111   ->   2344
2147483647   ->   5362
Kevin Cruijssen
źródło
Powiązane
Kevin Cruijssen
1
@martin 9999-> M(X)CMXCIX-> 77+263+67+77+88+67+73+88-> 800i 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. Więc poprawiłem drugi, ale 9999był poprawny.
Kevin Cruijssen
1
Przypadek testowy 2222222222nie znajduje się w podanym zakresie. Też się zgadzam 5362.
Neil,
1
Tytuł brzmi jak pytanie Stack Overflow C.
user6245072,
3
Czy słowo „czwarty” w tytule to gra słów? Jeśli nie, powinien być „czwarty”.
Monty Harder

Odpowiedzi:

4

Mathematica, 181 173 166 151 bajtów

Grał w golfa

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

Bez golfa

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

RomanNumeralImplementacja Mathematica daje (IX) CMXCIX dla 9999, więc program zwraca 971 dla tej liczby.

Jak napisano, cyfra rzymska typu ((...)) (...) ... zwraca zagnieżdżoną listę kodów ASCII dla cyfr rzymskich o długości 4, ((...)) ... zwraca listę o długości 3, (...) ... zwraca listę o długości 2 i ... zwraca listę o długości 1. Ostatni wiersz konwertuje te reguły na odpowiednią liczbę makronów dla każdej sekcji list, dodaje te makra do, a następnie sumuje całą zagnieżdżoną listę, aby zwrócić dane wyjściowe.

HiggstonRainbird
źródło
1
Witamy w PPCG!
betseg
@betseg Dziękujemy! To był zabawny pierwszy problem.
HiggstonRainbird
10

Python 3, 281 278 273 269 ​​bajtów

Moja pierwsza próba codegolf, proszę bardzo. Próbowałem to zrobić, nie patrząc na powiązane pytanie, więc prawdopodobnie jest to okropne :)

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 bajtów mniejszych, dzięki Gáborowi Fekete

Nie golfowany:

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
źródło
Można golf kilka bajtów, zastępując return 0 if n==0 elsezreturn 0if n<1else
Gábor Fekete
Twoja wersja gry w golfa zawiera wywołania f, gdy nazwa funkcji to g.
Gábor Fekete
Zmień, n//9*10>=10*laby n//9>=lzaoszczędzić trochę więcej.
Gábor Fekete
Naprawiono nazwę funkcji, zmieniłem ją, aby sprawdzić, czy poprawnie grałem w golfa i zapomniałem zmienić ją z powrotem.
jDomantas
3

Mathematica, 198 bajtów

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

Niestety, wbudowane niewiele tu pomaga, ale jestem pewien, że można w niego grać o wiele więcej.

Uwaga: ocenia 9999 -> 971zgodnie z tutaj .

jaskółka oknówka
źródło
2

Partia, 373 bajtów

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

Działa poprzez tłumaczenia każdą cyfrę numeru według tabeli odnośników do wartości 1, 4, 5 i 9. zastosowań M(V), M(X), (M(V))i (M(X)). Jeśli wolisz (IV), (IX), ((IV))a ((IX))następnie wykorzystać call:l 77 509 261 511i call:l 252 859 436 861odpowiednio.

Neil
źródło
1

JavaScript (ES6), 183 bajtów

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)

Uwaga: preferuje nie tylko (IV)do M(V), ale również preferuje (VI)się (V)M; w rzeczywistości użyje M tylko na samym początku numeru.

Neil
źródło
1

Python, 263 bajty

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.
źródło
Witamy w PPCG, fajna pierwsza odpowiedź!
Copper
1

R, 115 bajtów

Więc ... Publikuję swoje rozwiązanie, ponieważ uważam, że pytanie jest dość interesujące. Zrobiłem mój najlepszy z R 's zdolności do radzenia sobie z liczbami rzymskimi bez pakietów: można tylko wejście numery między 1i 3899, jako że as.romanjest dokumentacja wyjaśnia.

Właśnie dlatego oszukałem trochę, podając zakres od 1do w pętli: jest to długość wyjścia ( ) . W rzeczywistości, zgodnie z tą witryną , najdłuższa liczba rzymska to (14 znaków), co odpowiada11 14foras.roman(3899)MMMDCCCXCIX
MMDCCCLXXXVIII2888 .

Ponadto nie można obliczyć lengthwyniku tej funkcji.

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)

Jeśli ktoś widzi rozwiązanie tego problemu, prosimy o komentarz.

Frédéric
źródło
0

Python 3, 315 bajtów

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

Wersja bez golfa:

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

Wyjaśnienie: Ta wersja wykorzystuje inne podejście, zlicza występowanie cyfr rzymskich w liczbie.

[abs(((n-4)%5)-1)]jest liczbą Is cyfrą rzymską.

[((n+10**g)//(10**g*5))%2for g in r(10)] jest liczbą V,L,D,(V),(L),(D),((V)),((L)),((D)) s w liczbie.

[(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)] jest liczbą X,C,M,(X),(C),(M),((X)),((C)),((M)) s w liczbie.

Następnie mnoży wystąpienia przez wartość znaku i zwraca jego sumę.

Gábor Fekete
źródło