ส่วนของตัวเลขโรมัน


10

เขียนโปรแกรมหรือฟังก์ชั่นที่รับจำนวนเต็มในช่วง 1..3999 เป็นอินพุตและส่งกลับจำนวนของส่วนของบรรทัดที่จำเป็นในการแสดงจำนวนเต็มนั้นในตัวเลขโรมันมาตรฐาน (ดังนั้นคุณจะใช้ XL แต่ไม่ใช่ VM) ตัวอย่าง:

   1 -> 1
   4 -> 3
   5 -> 2
   9 -> 3
  10 -> 2
  40 -> 4
  50 -> 2
  90 -> 3
 100 -> 1
 400 -> 3
 500 -> 2
 900 -> 5
1000 -> 4

ตัวเลขโรมัน builtins แปลงจะได้รับอนุญาต แต่คุณสามารถแก้ปัญหาได้โดยไม่ต้องให้พวกเขาด้วยซ้ำลบจำนวนที่เหลือที่ใหญ่ที่สุดจากรายการดังกล่าวข้างต้น ตัวอย่าง: 1234 = 4 + 1 + 1 + 2 + 2 + 2 + 3 = 15

นี่คือดังนั้นโปรแกรมที่สั้นที่สุดชนะ


เหตุใด 10 ส่วนของเส้นตรงสองเส้นแทนที่จะเป็นสี่ส่วน เมื่อเขียน X คุณจะเขียนแค่สองบรรทัดเท่านั้น แต่การตัดกันของเส้นไม่ทำให้มันเป็นสี่ส่วน?
Alex A.

@AlexA คำจำกัดความของส่วนของเส้นตรงมักจะเป็นดังนี้: "ชุดของจุดที่ตามเส้นทางที่สั้นที่สุดระหว่างสองจุด" ดูเหมือนจะไม่มีเหตุผลใด ๆ ที่จะตัด X ตามนี้คุณต้องมีจุดสิ้นสุดสองชุดเพื่อกำหนด (สมมติว่าชาวโรมันส่วนใหญ่เขียนไว้ในรูปเรขาคณิตแบบยุคลิดผมเดา)
FryAmTheEggman

@FryAmTheEggman อืมโอเค ดีที่จะรู้ขอบคุณ
Alex A.

คำตอบ:


2

Pyth, 92 76 70 ไบต์

KsMc."/9hæ²z³Þ§ªW×Oû[Tnè,O¤"\/WQ=Q-Q=Nef!>TQ%2K aY@KhxKN;sY

ลองที่นี่!

ขอบคุณ @FryAmTheEggman สำหรับคำแนะนำเกี่ยวกับการจัดเรียงสตริงซึ่งช่วยให้ฉันได้รับไบต์!

ฉันยังสงสัยว่ามีวิธีการเข้ารหัสรายการนี้ทางคณิตศาสตร์หรือไม่ จะพยายามคิดอะไรบางอย่างออกมา

คำอธิบาย

สิ่งนี้ใช้อัลกอริทึมที่กำหนด Kมีรายการที่กำหนดพร้อมกับหมายเลขและหมายเลขการกัดกร่อนของเซกเมนต์ของบรรทัดในการสลับ รายการนี้ได้รับการสร้างขึ้นโดยการแยกสตริงที่บรรจุซึ่งได้รับการถอดรหัสไป0/0/1/1/4/3/5/2/9/3/10/2/40/4/50/2/90/3/100/1/400/3/500/2/900/5/1000/4ที่/และการทำแผนที่แต่ละองค์ประกอบเป็นจำนวนเต็ม

KsMc. "... " \ / WQ = QQ = Nef!> TQ% 2K aY @ KhxKN; sY # Q = อินพุต

   c. "... " \ / # แยกสตริงบน /
KsM # ทำแผนที่ทุกหมายเลขให้เป็น int และกำหนดให้กับ K
            WQ # ในขณะที่ Q! = 0
                     f% 2K # ใช้ทุกองค์ประกอบที่ 2 ของ K เท่านั้นและกรองด้วย T
                      !> TQ # T <= Q
                  = Ne # ใช้องค์ประกอบสุดท้ายของสิ่งนั้นและกำหนดให้กับ N
              = QQ # Q = Q - N
                                   ดัชนี xKN # ของการเกิดขึ้นครั้งแรกของ N ใน K
                                  h # เพิ่มค่าดัชนีนั้นเพราะเราต้องการส่วนของเส้นตรง
                              aA @ K # รับส่วนของเส้นตรงจากดัชนีนั้นและผนวกเข้ากับ Y
                                      ; sY # จบการวนซ้ำและพิมพ์ผลรวมของทุกส่วนของเส้นใน Y

3

C, 148 129 ตัวอักษร

d,x,n[]={1000,900,500,400,100,90,50,40,10,9,5,4,1,4,5,2,3,1,3,2,4,2,3,2,3,1};f(c){while(d+=(c/n[x])*n[x+13],c%=n[x++]);return d;}

code-golf ครั้งแรกของฉัน: ^) ตั้งแต่คำถามที่ฉันสามารถใช้ฟังก์ชั่นฉันได้เปลี่ยนหลักเป็นฟังก์ชั่นเพื่อตัดตัวอักษรบางตัว (ที่สำคัญที่สุด: ผ่าน c เป็นพารามิเตอร์ที่ค่อนข้าง scanf)

ไม่ห่อ

d,x,n[]={1000,900,500,400,100,90,50,40,10,9,5,4,1,4,5,2,3,1,3,2,4,2,3,2,3,1};
f(c){
  while(d+=(c/n[x])*n[x+13],
        c%=n[x++]);
  return d;
}

2

Mathematica, 80 72 ไบต์

Tr[Characters[#~IntegerString~"Roman"]/.{"I"|"C"->1,"M"->4,_String->2}]&

ฟังก์ชั่นไม่ระบุชื่อที่เพิ่งแปลงตัวเลขเป็นตัวเลขโรมันแทนที่แต่ละตัวละครด้วยจำนวนของกลุ่มและใช้เวลาทั้งหมด


2

เรติน่า 128 ไบต์

. +
$ *
1 {1000}
เสื้อ'
1 {900}
td
1 {500}
d
1 {400}
เสื้อ
1 {100}
'
1 {90}
เสื้อ
1 {50}
d
1 {40}
เสื้อ'
1 {10}
d
1 {9}
เสื้อ
1 {5}
d
1 {4}
เสื้อ
1
'
เสื้อ
d'
d
''
'+
$ 0.0

เปลี่ยนง่าย ๆ จนกระทั่งไม่มีอะไรเหลือให้เปลี่ยน จากนั้นอะพอสโทรฟีจะถูกนับและนั่นคือจำนวนเซ็กเมนต์บรรทัดของเรา

หากอนุญาตให้อินพุตและเอาต์พุตเป็น unary จะเป็น 115 ไบต์ (แม้ว่าใครจะต้องการพิมพ์ 1234?)

ลองออนไลน์!
ลองออนไลน์! (unary IO)


2

Python 3, 95 ไบต์

def f(a,b=0):
 for e in'᝴ᔝ஺ॣəȟĮô>9 ':e=ord(e);d=e//6;b+=a//d*(e%6);a%=d
 return b

สตริง Unicode ประกอบด้วยจุดรหัส:

6004 5405 3002 2403 601 543 302 244 62 57 32 27 7

หากคุณเปลี่ยนสตริงนั้นเป็นตัวอักษรไบต์คุณสามารถละเว้นe=ord(e);
xsot

ฉันไม่คิดว่าจะทำงานได้ในกรณีของฉัน ฉันต้องการ Unicode string :( นั่นคือฉันวนลูปมากกว่า codepoints ในสตริงนั้นไม่เกิน bytes
Lynn

1
อ้อเข้าใจแล้ว. คุณสนใจที่จะให้การถ่ายโอนข้อมูลแบบเลขฐานสิบหกของสตริงหรือไม่? มันแสดงไม่ถูกต้องในโทรศัพท์ของฉัน
xsot

1

Java, 152 ไบต์

เพราะคุณรู้ชวา

n->{int c=0;int[]r={999,4,899,5,499,2,399,3,99,1,89,3,49,2,39,4,9,2,8,3,4,2,3,3,0,1};for(int i=0;i<26;i+=2)while(n>r[i]){n-=r[i]+1;c+=r[i+1];}return c;}

การใช้ตัวอักษรอย่างง่ายของอัลกอริทึมที่กำหนด Array จะบรรจุข้อมูลการแปลง: แม้ดัชนีจะน้อยกว่าตัวเลขโรมันและดัชนีคี่จะนับจำนวนสำหรับตัวเลขนั้น

นี่คือแลมบ์ดาที่ใช้เวลาและผลตอบแทนต่อ A /int Integerซึ่งรวมถึงการหรือIntUnaryOperatorUnaryOperator<Integer>


1

JavaScript (ES6), 79 ไบต์

n=>"0123323453"[[,a,b,c,d]=1e4+n+'',d]-(-"0246424683"[c]-"0123323455"[b])+a*4

สตริงแสดงจำนวนของเซ็กเมนต์บรรทัดสำหรับหน่วยหลักสิบและหลักร้อย (หลักพันเป็นสี่เท่าหลักพัน) วิธีนี้ดูเหมือนว่าจะสั้นกว่าตัวเลือกอื่น ๆ เช่นอัลกอริทึมที่แนะนำในคำถาม

แก้ไข: บันทึก 2 ไบต์ด้วย @ user81655


นี่เป็นอัลกอริธึมที่ยอดเยี่ยม การจัดเรียง casts ใหม่สามารถบันทึก 2 ไบต์ได้เช่นกัน:n=>"0123323453"[[,a,b,c,d]=1e4+n+'',d]-(-"0246424683"[c]-"0123323455"[b])+a*4
81655

@ user81655 โอ้มันดี: เพียงแค่เปลี่ยน+s -เป็นอนุญาตให้ฉันลบผู้นำ+แต่แล้วการจัดกลุ่มบันทึกไบต์อื่น
Neil
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.