While looking through Stack Exchange I found a two-way number to Roman Numeral converter by a user named FlyAwayBirdie: http://codereview.stackexchange.com/questions/79734/ti-basic-roman-numeral-converter:

Code:
DelVar IDelVar VDelVar XDelVar LDelVar CDelVar DDelVar M"?->Str2
"IVXLCDM->Str3
ClrHome
Input Str1
expr(Str1->N
If N
Then
For(I,0,log(N
10fPart(.1N->A
While A
sum({4.1,4.1,9.2}(A={4,5,9->B
sub(Str3,2I+10fPart(B)+1,1)+Str2->Str2
abs(A-1-int(B->A
End
int(.1N->N
End
sub(Str2,1,length(Str2)-1
Else
Str2+Str1+"?->Str1
For(I,0,5
inString(Str1,sub("IVIXXLXCCDCM",2I+1,2
If Ans
Then
sub(Str1,1,Ans-1)+sub(Str1,Ans+2,length(Str1)-Ans-1->Str1
C+(4+10fPart(I/2))10^(iPart(I/2->C
End
End
For(I,1,length(Str1
inString(Str3,sub(Str1,I,1
If Ans
C+(5-8fPart(.5Ans))10^(iPart(.5Ans-.5->C
End
C
End
Ans


The routine to convert a number to a Roman numeral is probably solid (it was written by Ed H in the routines thread) but the other way looks like it has some room for optimization. Here are the optimizations I have. My code subtracts a letter any time the next letter has greater value, so it will work for some invalid Roman numberals like VL="45" and XIC="109":

Code:
"IVXLCDM->Str3
ClrHome
Input Str1
expr("0"+Str1->N
"?->Str2
If N
Then
//Ed H's routine
Else
"inString(Str3,sub(Ans,n,1"->u //doesn't change Ans
Str1+Ans
sum(seq(iPart((.5+fPart(.5u))10^(int(.5u))(1-2(u<u(n+1)))),n,1,length(Str1 //"?" has a value of zero, so the last letter will always be added
End
Ans


Can anyone go even smaller?

By the way, I found a bug with seq(: if you have both u and u(X, with X an expression, inside a seq( loop with n as the index, all occurences of u after the u(X) in the body of the seq( loop will be evaulated as u(X+1) rather than u(n). Or something like that; I don't know why or exactly what it does.

EDIT: Optimized. This is not the fastest possible because u is recomputed every time, but it is fast enough.
How about this? Razz

Code:

" "→Str0
For(X,0,log(N
10fPart(.1N→Z
While Z
sum({4.1,4.1,9.2}(Z={4,5,9→T
sub("IVXLCDMvxlcdmni",2X+10fPart(T)+1,1)+Str0→Str0
abs(Z-1-int(T→Z
End
int(.1N→N
End
Str0

N is the number and Ans and Str0 the Roman one.
Yep, looks good. It's good to link where you found it though, so as to not make it seem like you came up with it.
Here's a quick-and-dirty way of doing it. Doesn't work with subtraction like in IV, though.

Code:

1->I:5->V:10->X:50->L:2Ans->C:5Ans->D:2Ans->M
Input Str9
Σ(expr(sub(Str9,A,1),A,1,length(Str9

edit: I'm an idiot, was using X as sigma's iteration variable

Edit 2: I have a version that works with subtraction, but I'm pretty sure it can be optimized more.

Code:

1->I:5->V:10->X:50->L:2Ans->C:5Ans->D:2Ans->M
Input Str9
seq(expr(sub(Str9,A,1),A,1,length(Str9
sum(Ans-2Ans*(Ans<augment(ΔList(cumSum(Ans)),{Ans(dim(Ans
Wright: If you're doing it that way, your last line can be
Code:
sum(Ans-Ans2(Ans<augment(cumSum(ΔList(Ans)),{0

because the last letter should always be added. Or if you want speed you can do sum(Ans*(1-2( so you don't add lists.

You're also missing the expr('s close-paren.

EDIT: I have this now for decimal->Roman, saving five bytes from Ed H's routine. It wasn't necessary to remove the clever decimal method, but it was the same size (if I counted right) and there may be further golfing potential.

Code:
For(I,0,log(N
.1int(N->N
For(A,10fPart(N),1,-1
sub(Str3,2I+1+(A=4 or A=5)+2(A=9),1)+Str2->Str2
(A≠5)A^(A≠4 and A≠9->A
End
End
sub(Str2,1,length(Str2)-1


EDIT: I have a working two-way converter in 190 bytes.

Code:
"IVXLCDM"→Str3
ClrHome
Input Str1
expr("0"+Str1→N
If N
Then
" "→Str1
For(I,0,log(N
.1int(N→N
10fPart(N→A
While A
.1sum({22,42,74}(A={4,5,9→B
A-1-int(B→A
sub(Str3,2I+5fPart(B)+1,1)+Str1→Str1
End
End
Else
.5seq(inString(Str3,sub(Str1,X,1)),X,1,length(Str1
sum(10^(int(Ans))(.5+fPart(Ans)-2(Ans<augment(ΔList(cumSum(Ans)),{0
End
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 UTC - 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