L'intero va avanti e indietro nel tempo


17

Ingresso:

Un numero intero.

Produzione:

  1. Per prima cosa converti il ​​numero intero nel suo equivalente numero romano.
  2. Quindi converti ogni lettera maiuscola di quel numero romano nel loro valore decimale ASCII / UNICODE.
  3. E produce la somma di quelli.

Esempio:

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

Numeri romani: ecco un forse utile convertitore di numeri romani.
inserisci qui la descrizione dell'immagine

Regole della sfida:

  • Vengono applicate le regole del Numero romano standard, quindi nessuna forma alternativa come IIIIo VIIIIinvece di IVe IX. *
  • Le linee di Macron sopra i numeri romani oltre 1.000 sono ¯(UNICODE nr. 175). Quindi una riga conta come +175e due come+350 .
  • È consentito utilizzare qualsiasi tipo di tipo di input e output, purché rappresenti gli interi.
  • I casi di test saranno nel range di 1 - 2,147,483,647.

* Regole dei numeri romani (citazione da Wikipedia):

I numeri si formano combinando i simboli e aggiungendo i valori, quindi IIsono due (due) e XIIItredici (dieci e tre). Poiché ogni numero ha un valore fisso anziché rappresentare multipli di dieci, cento e così via, in base alla posizione, non è necessario zeri di "mantenimento del posto", come in numeri come 207 o 1066; quei numeri sono scritti come CCVII(duecento, cinque e due) eMLXVI (mille, cinquanta, dieci, cinque e uno).

I simboli sono posizionati da sinistra a destra in ordine di valore, iniziando dal più grande. Tuttavia, in alcuni casi specifici, per evitare che quattro caratteri vengano ripetuti in successione (come IIIIo XXXX), la notazione sottrattiva viene spesso utilizzata come segue:

  • Iposto prima Vo Xindica uno in meno, quindi quattro è IV(uno in meno di cinque) e nove lo èIX (uno in meno di dieci)
  • Xposto prima Lo Cindica dieci in meno, quindi quaranta è XL(dieci meno di cinquanta) e novanta è XC(dieci meno di cento)
  • Cposto prima Do Mindica cento in meno, quindi quattrocento è CD(cento meno di cinquecento) e novecento è CM(cento meno di mille)
    Ad esempio, MCMIVè millenovecentoquattro, 1904 ( Mè mille, CMè novecento ed IVè quattro).

Alcuni esempi dell'uso moderno dei numeri romani includono:
1954 come MCMLIV; 1990 come MCMXC; 2014 come MMXIV
SOURCE

Regole generali:

  • Questo è , quindi vince la risposta più breve in byte.
    Non lasciare che le lingue di code-golf ti scoraggino dal pubblicare risposte con lingue non codegolfing. Prova a trovare una risposta il più breve possibile per "qualsiasi" linguaggio di programmazione.
  • Per la tua risposta valgono regole standard , quindi puoi usare STDIN / STDOUT, funzioni / metodo con i parametri corretti, programmi completi. La tua chiamata.
  • Sono vietate le scappatoie predefinite .
  • Se possibile, aggiungi un link con un test per il tuo codice.
  • Inoltre, si prega di aggiungere una spiegazione, se necessario.

Casi test:

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-> 800e 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. Quindi ho corretto il secondo, ma 9999era corretto.
Kevin Cruijssen,

1
Il caso di test 2222222222non rientra nell'intervallo indicato. Anche io sono d'accordo 5362.
Neil

1
Il titolo suona come una domanda Stack Overflow C.
user6245072

3
La parola "quarta" nel titolo è un gioco di parole? In caso contrario, dovrebbe essere "avanti".
Monty Harder,

Risposte:


4

Mathematica, 181 173 166 151 byte

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

Ungolfed

(
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' RomanNumeralimplementazione di Mathematica fornisce (IX) CMXCIX per 9999, e quindi il programma restituisce 971 per quel numero.

Come scritto, un numero romano del tipo ((...)) (...) ... restituisce un elenco nidificato dei codici ASCII per i numeri romani di lunghezza 4, ((...)) ... restituisce un elenco di lunghezza 3, (...) ... restituisce un elenco di lunghezza 2 e ... restituisce un elenco di lunghezza 1. La riga finale converte tali regole nel numero appropriato di macron per ogni sezione del list, aggiunge quei macron in e quindi somma l'intero elenco nidificato per restituire l'output.


1
Benvenuti in PPCG!
Betseg,

@betseg Grazie! Questo è stato un primo problema divertente.
HiggstonRainbird,

10

Python 3, 281 278 273 269 ​​byte

Il mio primo tentativo di codegolf, eccoci qui. Ho provato a farlo senza guardare la domanda collegata, quindi è probabilmente terribile :)

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 byte più piccoli, grazie a Gábor Fekete

Ungolfed:

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)

È possibile golf alcuni byte sostituendo return 0 if n==0 elseconreturn 0if n<1else
Gábor Fekete

La tua versione golfata contiene chiamate fquando il nome della funzione è g.
Gábor Fekete,

Passa n//9*10>=10*la n//9>=lper salvarne ancora.
Gábor Fekete,

Risolto il problema con il nome della funzione, l'ho cambiato per verificare se l'ho giocato a golf correttamente e ho dimenticato di cambiarlo.
jDomantas,


3

Mathematica, 198 byte

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

Sfortunatamente, il builtin non aiuta molto qui, anche se sono sicuro che questo può essere giocato molto di più.

Nota: valuta 9999 -> 971come qui .


2

Lotto, 373 byte

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

Opere traducendo ogni cifra del numero secondo una tabella di ricerca per i valori 1, 4, 5 e 9. usi M(V), M(X), (M(V))e (M(X)). Se si preferisce (IV), (IX), ((IV))e ((IX))quindi utilizzare call:l 77 509 261 511e call:l 252 859 436 861, rispettivamente.


1

JavaScript (ES6), 183 byte

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: non solo preferisce (IV)a M(V), ma preferisce anche (VI)a (V)M; infatti utilizzerà M solo all'inizio del numero.


1

Python, 263 byte

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

Benvenuto in PPCG, bella prima risposta!
Rame

1

R, 115 byte

Quindi ... sto pubblicando la mia soluzione perché trovo la domanda piuttosto interessante. Ho fatto del mio meglio con R 's capacità di trattare con numeri romani senza imballaggi: è possibile solo i numeri di ingresso tra 1e 3899, come la as.roman' s documentazione spiega.

Ecco perché ho barato un po 'dando un intervallo tra 1a nel loop: è la lunghezza dell'output ( ) . Infatti, secondo questo sito Web , il numero romano più lungo è (14 caratteri), che corrisponde a11 14foras.roman(3899)MMMDCCCXCIX
MMDCCCLXXXVIII2888 .

Inoltre, non è possibile calcolare lengthl'output di questa funzione.

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)

Se qualcuno vede una soluzione per affrontare i problemi di cui sopra, non esitate a commentare.


0

Python 3, 315 byte

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

Versione non golfata:

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

Spiegazione: Questa versione utilizza un approccio diverso, conta le occorrenze di numeri romani nel numero.

[abs(((n-4)%5)-1)]è il numero di Is nel numero romano.

[((n+10**g)//(10**g*5))%2for g in r(10)]è il numero di V,L,D,(V),(L),(D),((V)),((L)),((D))s nel numero.

[(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)]è il numero di X,C,M,(X),(C),(M),((X)),((C)),((M))s nel numero.

Quindi moltiplica le occorrenze per il valore del personaggio e ne restituisce la somma.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.