จำนวนเต็มย้อนกลับไปตามกาลเวลา


17

การป้อนข้อมูล:

จำนวนเต็ม

เอาท์พุท:

  1. ก่อนอื่นแปลงจำนวนเต็มเป็นตัวเลขโรมันที่เทียบเท่ากัน
  2. จากนั้นแปลงตัวอักษรพิมพ์ใหญ่ของตัวเลขโรมันแต่ละตัวให้เป็นค่าทศนิยม ASCII / UNICODE
  3. และเอาท์พุทผลรวมของสิ่งเหล่านั้น

ตัวอย่าง:

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

ตัวเลขโรมัน:นี่คือตัวแปลงตัวเลขโรมันที่มีประโยชน์
ป้อนคำอธิบายรูปภาพที่นี่

กฏท้าทาย:

  • มีการใช้กฎตัวเลขโรมันมาตรฐานดังนั้นจึงไม่มีรูปแบบอื่นที่เหมือนIIIIหรือVIIIIแทนIVและIX*
  • บรรทัด Macron ด้านบนตัวเลขโรมันที่ผ่าน 1,000 คือ¯(UNICODE nr. 175) ดังนั้นนับเป็นหนึ่งบรรทัดและสองเป็น+175+350
  • คุณได้รับอนุญาตให้ใช้ประเภทอินพุตและเอาต์พุตชนิดใดก็ได้ตราบใดที่มันแสดงถึงจำนวนเต็ม
  • 1 - 2,147,483,647กรณีทดสอบจะอยู่ในช่วงของ

* กฎตัวเลขโรมัน (อ้างอิงจาก Wikipedia):

ตัวเลขเกิดขึ้นจากการรวมสัญลักษณ์และการเพิ่มค่าดังนั้นจึงIIเป็นสอง (สองคน) และXIIIเป็นสิบสาม (สิบและสามคน) เนื่องจากแต่ละตัวเลขมีค่าคงที่แทนที่จะเป็นตัวแทนทวีคูณของสิบหนึ่งร้อยและต่อ ๆ ไปตามตำแหน่งไม่จำเป็นต้องมี "การเก็บรักษา" เป็นศูนย์เช่นเดียวกับในจำนวน 207 หรือ 1,066; ตัวเลขเหล่านั้นถูกเขียนเป็นCCVII(สองร้อย, ห้าและสอง) และMLXVI(หนึ่งพัน, ห้าสิบ, สิบ, ห้าและหนึ่ง)

สัญลักษณ์จะถูกวางจากซ้ายไปขวาตามลำดับของค่าเริ่มต้นที่ใหญ่ที่สุด อย่างไรก็ตามในบางกรณีเพื่อหลีกเลี่ยงอักขระสี่ตัวที่ถูกทำซ้ำอย่างต่อเนื่อง (เช่นIIIIหรือXXXX) มักใช้สัญกรณ์การลบดังนี้

  • Iวางไว้ก่อนหน้าVหรือXบ่งชี้หนึ่งน้อยกว่าดังนั้นสี่คือIV(หนึ่งน้อยกว่าห้า) และเก้าคือIX(หนึ่งน้อยกว่าสิบ)
  • Xวางไว้ก่อนหน้าLหรือCบ่งชี้ว่าน้อยกว่าสิบดังนั้นสี่สิบXL(สิบน้อยกว่าห้าสิบ) และเก้าสิบคือXC(สิบน้อยกว่าหนึ่งร้อย)
  • Cวางไว้ก่อนหน้าDหรือMระบุน้อยกว่าหนึ่งร้อยดังนั้นสี่ร้อยคือCD(หนึ่งร้อยน้อยกว่าห้าร้อย) และเก้าร้อยคือCM(หนึ่งร้อยน้อยกว่าหนึ่งพัน)
    ตัวอย่างเช่นMCMIVหนึ่งพันเก้าร้อยสี่ 1904 ( Mเป็นหนึ่งพันCMคือ เก้าร้อยและIVสี่)

ตัวอย่างของการใช้ตัวเลขโรมันสมัยใหม่ ได้แก่ :
1954 เป็นMCMLIV; 2533 เป็นMCMXC; 2014 เป็นMMXIV
แหล่งที่มา

กฎทั่วไป:

  • นี่คือดังนั้นคำตอบที่สั้นที่สุดในหน่วยไบต์ชนะ
    อย่าปล่อยให้ภาษาโค้ดกอล์ฟกีดกันคุณจากการโพสต์คำตอบด้วยภาษาที่ไม่ได้เข้ารหัส พยายามหาคำตอบสั้น ๆ ที่เป็นไปได้สำหรับภาษาโปรแกรม 'ใด ๆ '
  • กฎมาตรฐานจะใช้สำหรับคำตอบของคุณดังนั้นคุณจึงได้รับอนุญาตให้ใช้ STDIN / STDOUT ฟังก์ชัน / เมธอดพร้อมพารามิเตอร์ที่เหมาะสมโปรแกรมเต็มรูปแบบ การโทรของคุณ
  • ช่องโหว่เริ่มต้นเป็นสิ่งต้องห้าม
  • หากเป็นไปได้โปรดเพิ่มลิงค์พร้อมทดสอบรหัสของคุณ
  • นอกจากนี้โปรดเพิ่มคำอธิบายหากจำเป็น

กรณีทดสอบ:

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-> 800และ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ดังนั้นฉันจึงแก้ไขครั้งที่สอง แต่9999ถูกต้อง
Kevin Cruijssen

1
กรณีทดสอบ2222222222ไม่อยู่ในช่วงที่กำหนด 5362นอกจากนี้ผมเห็นด้วยกับ
Neil

1
ชื่อเรื่องดูเหมือนคำถาม Stack Overflow C
user6245072

3
คำว่า "สี่" ในชื่อเป็นปุนหรือไม่? ถ้าไม่ควรเป็น "ไป"
Monty Harder

คำตอบ:


4

Mathematica, 181 173 166 151 bytes

แข็งแรงเล่นกอล์ฟ

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

RomanNumeralการใช้งานของ Mathematica ให้ (IX) CMXCIX ในราคา 9999 และดังนั้นโปรแกรมจะคืนค่า 971 สำหรับหมายเลขนั้น

ตามที่เขียนตัวเลขโรมันของประเภท ((... )) (... ) ... ส่งคืนรายการซ้อนของรหัส ASCII สำหรับตัวเลขโรมันที่มีความยาว 4, ((... )) ... ส่งคืนรายการความยาว 3, (... ) ... ส่งคืนรายการความยาว 2 และ ... ส่งคืนรายการความยาว 1 บรรทัดสุดท้ายจะแปลงกฎเหล่านั้นเป็นจำนวน macrons ที่เหมาะสมสำหรับแต่ละส่วนของ รายการเพิ่ม macrons เหล่านั้นในนั้นรวมรายการที่ซ้อนกันทั้งหมดเพื่อส่งคืนผลลัพธ์


1
ยินดีต้อนรับสู่ PPCG!
betseg

@betseg ขอบคุณ! นี่เป็นปัญหาแรกที่สนุก
HiggstonRainbird

10

Python 3, 281 278 273 269 ​​ไบต์

ความพยายามครั้งแรกของฉันที่ codegolf ที่นี่เราไป พยายามที่จะทำโดยไม่ดูคำถามที่เชื่อมโยงดังนั้นมันอาจจะแย่มาก :)

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 ไบต์ขอบคุณ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)

คุณสามารถตีกอล์ฟด้วยการแทนที่return 0 if n==0 elseด้วยreturn 0if n<1else
Gábor Fekete

รุ่นแข็งแรงเล่นกอล์ฟของคุณมีการโทรไปยังในเมื่อชื่อฟังก์ชั่นคือf g
Gábor Fekete

เปลี่ยนn//9*10>=10*lเป็นn//9>=lบันทึกเพิ่มเติม
Gábor Fekete

ชื่อฟังก์ชั่นคงที่ฉันเปลี่ยนมันเพื่อตรวจสอบว่าฉันกอล์ฟมันถูกต้องและลืมเปลี่ยนกลับไป
jDomantas

3

Ruby, 188 ไบต์

การปรับตัวขึ้นอยู่กับคำตอบทับทิมเก่าของฉันสำหรับการแปลงตัวเลขโรมัน ลองออนไลน์!

f=->x,i=0{k=0;(x<t=1e3)?"CM900D500CD400C100XC90L50XL40X10IX9V5IV4I1".gsub(/(\D+)(\d+)/){v=$2.to_i;s=x/v;x%=v;($1*s).bytes.map{|c|k+=c==73&&i>0?77+175*~-i:c+175*i}}:k=f[x/t,i+1]+f[x%t,i];k}

3

Mathematica, 198 ไบต์

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

น่าเสียดายที่ตัวอาคารไม่ได้ช่วยอะไรมากที่นี่ แต่ฉันมั่นใจว่ามันสามารถเล่นกอล์ฟได้ไกลกว่านี้

หมายเหตุ: การประเมิน9999 -> 971ตามที่นี่


2

แบตช์ 373 ไบต์

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

ทำงานโดยการแปลหลักของตัวเลขแต่ละชนิดตามตารางการค้นหาสำหรับค่าที่ 1, 4, 5 และ 9 การใช้งานM(V), M(X), และ(M(V)) (M(X))หากคุณต้องการ(IV), (IX), ((IV))และ((IX))จากนั้นใช้call:l 77 509 261 511และcall:l 252 859 436 861ตามลำดับ


1

JavaScript (ES6), 183 ไบต์

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)

หมายเหตุ: ไม่เพียง แต่ชอบ(IV)ไปM(V)แต่ยังชอบ(VI)ที่จะ(V)M; ในความเป็นจริงมันจะใช้ M เมื่อเริ่มต้นของตัวเลขเท่านั้น


1

Python ขนาด 263 ไบต์

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

ยินดีต้อนรับสู่ PPCG คำตอบแรกที่ดี!
ทองแดง

1

R, 115 ไบต์

ดังนั้น ... ฉันกำลังโพสต์วิธีแก้ปัญหาของฉันเพราะฉันพบว่าคำถามน่าสนใจทีเดียว ผมทำดีที่สุดของฉันกับR 'ขีดความสามารถที่จะจัดการกับตัวเลขโรมันโดยไม่ต้องแพคเกจ: คุณสามารถป้อนตัวเลขเพียงอย่างเดียวระหว่าง1และ3899เป็นas.roman' s เอกสารอธิบาย

นั่นเป็นเหตุผลที่ผมโกงบิตโดยให้ช่วงระหว่าง1การในวง: มันเป็นความยาวของ's เอาท์พุท ( ) ในความเป็นจริงตามเว็บไซต์นี้หมายเลขโรมันที่ยาวที่สุดคือ11 14foras.roman(3899)MMMDCCCXCIX
MMDCCCLXXXVIII (14 ตัวอักษร) 2888ซึ่งสอดคล้องกับ

นอกจากนี้คุณไม่สามารถคำนวณlengthผลลัพธ์ของฟังก์ชันนี้ได้

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)

หากใครเห็นวิธีแก้ปัญหาเพื่อจัดการกับปัญหาข้างต้นโปรดแสดงความคิดเห็น


0

Python 3, 315 ไบต์

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

เวอร์ชันที่ไม่ถูกปรับแต่ง:

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

คำอธิบาย: รุ่นนี้ใช้วิธีการที่แตกต่างกันมันนับการเกิดขึ้นของตัวเลขโรมันในจำนวน

[abs(((n-4)%5)-1)]คือจำนวนIs ในตัวเลขโรมัน

[((n+10**g)//(10**g*5))%2for g in r(10)]คือจำนวนV,L,D,(V),(L),(D),((V)),((L)),((D))s ในจำนวน

[(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)] คือจำนวนของ X,C,M,(X),(C),(M),((X)),((C)),((M)) s ในจำนวน

จากนั้นคูณเหตุการณ์ที่เกิดขึ้นด้วยค่าของอักขระและส่งกลับผลรวมของมัน

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.