Integer bolak-balik sepanjang waktu

17

Memasukkan:

Bilangan bulat.

Keluaran:

  1. Pertama-tama, konversi bilangan bulat ke Angka Romawi yang setara.
  2. Kemudian konversikan setiap huruf kapital Angka Romawi itu dengan nilai desimal ASCII / UNICODE mereka.
  3. Dan hasilkan jumlah itu.

Contoh:

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

Angka Romawi: Berikut ini adalah Penghitung Angka Romawi yang mungkin berguna.
masukkan deskripsi gambar di sini

Aturan tantangan:

  • Aturan Angka Romawi standar diterapkan, jadi tidak ada bentuk alternatif suka IIIIatau VIIIIbukan IVdan IX. *
  • Garis Macron di atas Angka Romawi melewati 1.000 adalah ¯(UNICODE no. 175). Jadi satu baris diperhitungkan sebagai +175dan dua sebagai +350.
  • Anda diizinkan menggunakan segala jenis input dan output, asalkan itu mewakili bilangan bulat.
  • Kasus uji akan berada dalam kisaran 1 - 2,147,483,647.

* Aturan Angka Romawi (kutipan dari Wikipedia):

Bilangan dibentuk dengan menggabungkan simbol-simbol dan menambahkan nilainya, demikian IIjuga dua (dua) dan XIIItiga belas (sepuluh dan tiga). Karena setiap angka memiliki nilai tetap dan bukan mewakili kelipatan sepuluh, seratus dan seterusnya, sesuai posisi, tidak perlu untuk "menjaga tempat" nol, seperti dalam angka seperti 207 atau 1066; angka-angka itu ditulis sebagai CCVII(dua ratus, lima dan dua) dan MLXVI(seribu, lima puluh, sepuluh, lima dan satu).

Simbol ditempatkan dari kiri ke kanan dalam urutan nilai, dimulai dengan yang terbesar. Namun, dalam beberapa kasus tertentu, untuk menghindari empat karakter diulang secara berurutan (seperti IIIIatau XXXX), notasi subtraktif sering digunakan sebagai berikut:

  • Iditempatkan sebelum Vatau Xmenunjukkan satu kurang, jadi empat adalah IV(satu kurang dari lima) dan sembilan adalah IX(satu kurang dari sepuluh)
  • Xditempatkan sebelum Latau Cmenunjukkan sepuluh kurang, jadi empat puluh adalah XL(sepuluh kurang dari lima puluh) dan sembilan puluh adalah XC(sepuluh kurang dari seratus)
  • Cditempatkan sebelum Datau Mmenunjukkan seratus lebih sedikit, jadi empat ratus adalah CD(seratus kurang dari lima ratus) dan sembilan ratus adalah CM(seratus kurang dari seribu)
    Misalnya, MCMIVseribu sembilan ratus empat, 1904 ( Mseribu, CMadalah sembilan ratus IVempat).

Beberapa contoh penggunaan modern angka Romawi meliputi:
1954 sebagai MCMLIV; 1990 sebagai MCMXC; 2014 sebagai MMXIV
SUMBER

Aturan umum:

  • Ini adalah , jadi jawaban tersingkat dalam byte menang.
    Jangan biarkan bahasa kode-golf mencegah Anda memposting jawaban dengan bahasa non-codegolf. Cobalah untuk memberikan jawaban sesingkat mungkin untuk bahasa pemrograman 'apa saja'.
  • Aturan standar berlaku untuk jawaban Anda, jadi Anda diperbolehkan menggunakan STDIN / STDOUT, fungsi / metode dengan parameter yang tepat, program lengkap. Panggilanmu.
  • Celah Default tidak diperbolehkan.
  • Jika memungkinkan, silakan tambahkan tautan dengan tes untuk kode Anda.
  • Juga, silakan tambahkan penjelasan jika perlu.

Kasus uji:

100          ->   67
1            ->   73
4            ->   159
22           ->   322
5000         ->   261
2016         ->   401
1000000000   ->   427
1991         ->   449
9999         ->   800
1111111111   ->   2344
2147483647   ->   5362
Kevin Cruijssen
sumber
Terkait
Kevin Cruijssen
1
@martin 9999-> M(X)CMXCIX-> 77+263+67+77+88+67+73+88-> 800dan 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. Jadi saya sudah mengoreksi yang kedua, tetapi yang 9999benar.
Kevin Cruijssen
1
Kasing uji 2222222222tidak dalam kisaran yang diberikan. Saya juga setuju 5362.
Neil
1
Judulnya agak terdengar seperti pertanyaan Stack Overflow C.
user6245072
3
Apakah kata "keempat" dalam judul permainan kata-kata? Jika tidak, harus "maju".
Monty Harder

Jawaban:

4

Mathematica, 181 173 166 151 byte

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

Tidak disatukan

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

RomanNumeralImplementasi Mathematica memberikan (IX) CMXCIX untuk 9999, dan karenanya program mengembalikan 971 untuk angka itu.

Seperti yang tertulis, angka romawi dari tipe ((...)) (...) ... mengembalikan daftar kode ASCII bersarang untuk angka romawi dengan panjang 4, ((...)) ... mengembalikan daftar panjang 3, (...) ... mengembalikan daftar panjang 2, dan ... mengembalikan daftar panjang 1. Baris terakhir mengubah aturan-aturan tersebut ke dalam jumlah makron yang tepat untuk setiap bagian dari daftar, tambahkan makron-makron itu, dan kemudian jumlah seluruh daftar bersarang untuk mengembalikan output.

HiggstonRainbird
sumber
1
Selamat datang di PPCG!
betseg
@betseg Terima kasih! Ini adalah masalah pertama yang menyenangkan.
HiggstonRainbird
10

Python 3, 281 278 273 269 ​​byte

Upaya pertama saya di codegolf, ini dia. Mencoba melakukannya tanpa melihat pertanyaan terkait, jadi mungkin sangat buruk :)

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 lebih kecil, berkat Gábor Fekete

Tidak Disatukan:

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
sumber
Anda dapat bermain golf beberapa byte dengan menggantinya return 0 if n==0 elsedenganreturn 0if n<1else
Gábor Fekete
Versi golf Anda memiliki panggilan ke fdalamnya ketika nama fungsi adalah g.
Gábor Fekete
Ubah n//9*10>=10*luntuk n//9>=lmenyimpan lebih banyak.
Gábor Fekete
Memperbaiki nama fungsi, saya mengubahnya untuk memeriksa apakah saya golf dengan benar dan lupa mengubahnya kembali.
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@#&

Sayangnya, builtin tidak banyak membantu di sini, meskipun saya yakin ini bisa bermain golf lebih jauh.

Catatan: Evaluasi 9999 -> 971sesuai di sini .

martin
sumber
2

Batch, 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)

Bekerja dengan menerjemahkan setiap digit nomor sesuai dengan tabel pencarian untuk nilai 1, 4, 5 dan 9. Penggunaan M(V), M(X), (M(V))dan (M(X)). Jika Anda lebih suka (IV), (IX), ((IV))dan ((IX))kemudian menggunakan call:l 77 509 261 511dan call:l 252 859 436 861masing-masing.

Neil
sumber
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)

Catatan: tidak hanya lebih suka (IV)untuk M(V), tetapi juga lebih suka (VI)untuk (V)M; sebenarnya itu hanya akan menggunakan M di awal nomor.

Neil
sumber
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]))])
Elly G
sumber
Selamat datang di PPCG, jawaban pertama yang bagus!
Tembaga
1

R, 115 byte

Jadi ... Saya memposting solusi saya karena saya menemukan pertanyaan yang cukup menarik. Saya melakukan yang terbaik dengan R 'kapasitas s untuk berurusan dengan angka romawi tanpa paket: Anda hanya dapat nomor masukan antara 1dan 3899, sebagai as.roman' s dokumentasi menjelaskan.

Itu sebabnya saya sedikit curang dengan memberikan rentang antara 1ke dalam loop: itu adalah panjang dari output ( ) . Bahkan, menurut situs web ini , angka romawi terpanjang adalah (14 karakter), yang sesuai dengan11 14foras.roman(3899)MMMDCCCXCIX
MMDCCCLXXXVIII2888 .

Selain itu, Anda tidak dapat menghitung lengthoutput dari fungsi ini.

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)

Jika ada yang melihat solusi untuk mengatasi masalah di atas, jangan ragu untuk berkomentar.

Frédéric
sumber
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])])

Versi tidak disatukan:

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

Penjelasan: Versi ini menggunakan pendekatan yang berbeda, menghitung jumlah angka romawi dalam angka tersebut.

[abs(((n-4)%5)-1)]adalah jumlah Is dalam angka romawi.

[((n+10**g)//(10**g*5))%2for g in r(10)]adalah jumlah V,L,D,(V),(L),(D),((V)),((L)),((D))s dalam angka.

[(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)]adalah angka X,C,M,(X),(C),(M),((X)),((C)),((M))s dalam angka.

Itu kemudian mengalikan kejadian dengan nilai karakter dan mengembalikan jumlah itu.

Gábor Fekete
sumber