Login [Register]
Don't have an account? Register now to chat, post, use our tools, and much more.

The smallest Roman Numeral to Decimal Converter is…
>100 bytes
 0%  [ 0 ]
<=100 and >80 bytes
 0%  [ 0 ]
<=80 and >70 bytes
 0%  [ 0 ]
<=70 and >60 bytes
 16%  [ 1 ]
<=60 and >50 bytes
 16%  [ 1 ]
<=50 bytes
 16%  [ 1 ]
Don't care.
 50%  [ 3 ]
Total Votes : 6

Because so many people have expressed interest in another code golf to follow up my first, I am proud to present:

LJ Open: The Second Hole - Roman Numeral to Decimal Converter.

This program should take a roman numeral in a string in Ans and return the Decimal (Base 10) equivalent in Ans. Because this program does not output anything during execution, it is an "invisible" program. This program only needs to accept the traditional Roman Numerals (I V X L C D M), output for non-numerals can vary (be undefined) and invalid sequences can also output whatever you like (i.e. IIII or VIV).

Here's how it should look on the home:
Code:
"VI":prgmR[:Ans]
6

I quite enjoyed golfing this myself, and I can provide some bloated example code:

Code:
seq(inString("IVXLCDM",sub(Ans+".",A,1)),A,1,1+length(Ans->L1
{1,5,10,50,100,500,1000->L2
sum(seq(L2(L1(X)),X,1,dim(L1)-1->B
For(A,1,dim(L1)-1
If L1(A+1)>L1(A
B-2L2(L1(A->B
End
B

Restrictions wrote:
Restricted tokens: prgm
Can only accept the Ans variable in roman-numeral format

Size: The program's size is measured as:

Code:
on-calc-size - 9 - length(name)

You can read the Roman Numeral wikipedia here.
The poll will be open for a week. I will post my solution as soon as someone beats it or the week is up
Good luck!

Current Results:
lirtosiast: 54
PT_: 59
Weregoose: 61
commandblockguy: 65 | 263
kg583: 71
LogicalJoe: 76
MateoConLechuga: 244
Here's a better example program than the obfuscated thing above: (244 bytes)


Code:
Ans+" ->Str1
For(I,1,length(Str1)-1
sub(Str1,I,1→Str2
If Str2="I
1→Y
If Str2="V
5→Y
If Str2="X
10→Y
If Str2="L
50→Y
If Str2="C
100→Y
If Str2="D
500→Y
If Str2="M
1000→Y
sub(Str1,I+1,1→Str2
If Str2="I
1→W
If Str2="V
5→W
If Str2="X
10→W
If Str2="L
50→W
If Str2="C
100→W
If Str2="D
500→W
If Str2="M
1000→W
If Y≥W
Y+V→V
If Y<W
V-Y→V
End
V
Here is my 69 65 64 61 59 bytes solution, 3 lines:

// Get indexes of input, range = [0,0.5,1,1.5,2,2.5,3]
.5seq(inString("VXLCDM",sub(Ans,A,1)),A,1,length(Ans
// Convert to the Roman values, output = 1+8fPart(Ans) [1,5] times 10^int(Ans)
(1+8fPart(Ans))10^(int(Ans
// Get the DeltaList of Ans; if it's greater than 0, the next value is more than the current one, so subtract it twice from the sum
sum(Ans-2Ansaugment(0<DeltaList(Ans),{0


Here's a 2-liner, but in 60 bytes:
.5seq(inString("VXLCDM",sub(Ans,A,1)),A,1,length(Ans
sum((1+8fPart(Ans))10^(int(Ans))(1-2augment(0<DeltaList(Ans),{0


If we can assume the calculator is set in Radian mode (which is the default after a reset anyway), I got it down to 58 bytes:
.5seq(inString("VXLCDM",sub(Ans,A,1)),A,1,length(Ans
sum((1+8fPart(Ans))10^(int(Ans))cos(piaugment(0<DeltaList(Ans),{0
Here's my 76 byte solution:
DelVar ADelVar CAns->Str1
For(B,length(Ans),1,-1
inString("IVXLCDM",sub(Str1,B,1
gcd(Ans,2)^^-110^(int(Ans/2
If ~Ans<=C
~Ans->C
A-Ans->A
End

GG PT_.
Alright, got a reasonably good entry. Size: 65
seq(inString("IVXLCDM",sub(Ans,A,1)),A,1,length(Ans
10^(int(Ans/2))/(2-remainder(Ans,2
sum(Ans*(1-2(0<deltaList(augment(Ans,{0
I wrote a Roman Numeral routine a couple of years ago on Code Review, and it turned out to be golfy once optimized. 54 bytes, expects Radian mode.


.5seq(inString("VXLCDM",sub(Ans,X,1)),X,1,length(Ans
sum(10^(Ans)2.5^fPart(Ans)cos(angle(~DeltaList(augment(Ans,{0
Well, mine looks very much like lirtosiast's. (Such trickery coming from him, I swear...)

My attempt at 61 bytes:

.5seq(inString("IVXLCDM",sub(Ans,X,1)),X,1,length(Ans
sum(10^(Ans)/√(4+12fPart(Ans))(1-2(0<ΔList(augment(Ans,{0
I'm annoyed that I can't get it smaller right now, but 71 bytes:


:Ans->Str1:"XCMVLD
:"4^^-1inString(Ans,sub(Str1,Y,1->u
:seq(5^int(u)10^^(4fPart(u)),Y,1,length(Str1
:sum(Anstanh(|E9augment(1-deltaList(Ans),{9


There's a trick to shrink reading the input that I'm lost on.
This is kinda over already but I got kinda bored and wrote a new entry which exclusively uses For( loops, End, letters, integer literals, Input, and Disp. It's only 263 bytes, so just a bit larger than Mateo's.

Code:
For(T,0,-1:End
For(L,0,-1:End
For(C,1,0,-1
 For(V,1,0:End
 Input C
 //If x<=C:V=y
 For(A,2,C:For(V,5,1:End:End
 For(A,3,C:For(V,10,1:End:End
 For(A,4,C:For(V,50,1:End:End
 For(A,5,C:For(V,100,1:End:End
 For(A,6,C:For(V,500,1:End:End
 For(A,7,C:For(V,1000,1:End:End
 // T+=V
 For(T,T,T,V:End
 // if L+1<V:T-=2*L
 For(L,L,L,1:End
 For(A,L,V,10000
  // D=-2V
  For(B,1,L
   For(T,T,T,-2:End
  End
 End
 For(L,V,0:End
End
For(T,T,T,-1:End
Disp T


This is violating the rules a bit, but that's only because of the limitations of For( loops. Rather than taking input in a string, you pass the numerals one at a time, using this chart:

Code:
I = 1
V = 2
X = 3
L = 4
C = 5
D = 6
M = 7
So, to input 2019 (MMXIX), you would type 7 7 3 1 3.
There's no other way to take input without using strings, which would require sub(, length(, and either Ans or →, which would mean this is not "pure" for loops.

The answer is also not output to Ans, but is displayed with Disp. This is because For( loops cannot modify Ans.
  
Register to Join the Conversation
Have your own thoughts to add to this or any other topic? Want to ask a question, offer a suggestion, share your own programs and projects, upload a file to the file archives, get help with calculator and computer programming, or simply chat with like-minded coders and tech and calculator enthusiasts via the site-wide AJAX SAX widget? Registration for a free Cemetech account only takes a minute.

» Go to Registration page
Page 1 of 1
» All times are GMT - 5 Hours
 
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum

 

Advertisement