6
\$\begingroup\$

Program written in TI-Basic that works on TI-83/84/+/SE calculators. Automatically detects whether input is a number of a Roman numeral, and converts to the opposite. Please try to optimize for size, if possible.

DelVar IDelVar VDelVar XDelVar LDelVar CDelVar DDelVar MClrHome
Input Str1
expr(Str1->A
If A
Then
A->B
"?->Str2
For(I,1,iPart(A/|E3
Str2+"M->Str2
B-|E3->B
End
If B>899
Then
Str2+"CM->Str2
B-900->B
End
If B>499
Then
Str2+"D->Str2
B-500->B
End
If B>399
Then
Str2+"CD->Str2
B-400->B
End
B->A
For(I,1,iPart(A.01
Str2+"C->Str2
B-|E2->B
End
If B>89
Then
Str2+"XC->Str2
B-90->B
End
If B>49
Then
Str2+"L->Str2
B-50->B
End
If B>39
Then
Str2+"XL->Str2
B-40->B
End
B->A
For(I,1,iPart(A.1
Str2+"X->Str2
B-10->B
End
If B=9
Then
DelVar BStr2+"IX->Str2
End
If B>4
Then
Str2+"V->Str2
B-5->B
End
If B=4
Then
DelVar BStr2+"IV->Str2
End
For(I,1,B
Str2+"I->Str2
End
sub(Str2,2,length(Str2)-1
Else
"?"+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("IVXLCDM",sub(Str1,I,1
If Ans
C+(5-8fPart(Ans/2))10^(iPart(.5(Ans-1->C
End
C
End
Ans
\$\endgroup\$
1
  • \$\begingroup\$ Here's a really hacky short way of doing Roman → Decimal. Doesn't work with subtraction like in IV, though. 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 \$\endgroup\$
    – user74071
    Commented May 25, 2015 at 19:43

2 Answers 2

3
\$\begingroup\$

You have optimized this very well. However, using a different algorithm can reduce code size from 665 bytes to 411 bytes:

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
\$\endgroup\$
4
  • \$\begingroup\$ Wow, thanks for optimizing this. It's a lot smaller (and even faster) than my code. I doubt it will get much smaller than this. Fixed a typo by the way, thanks for the fast post. \$\endgroup\$
    – Timtech
    Commented Feb 6, 2015 at 23:37
  • 1
    \$\begingroup\$ @Timtech Glad you like it, I think I might be joining codegolf to beat your TI-BASIC answers ;) \$\endgroup\$ Commented Feb 6, 2015 at 23:51
  • \$\begingroup\$ Great, I'll see you (cough beat you cough) there. \$\endgroup\$
    – Timtech
    Commented Feb 6, 2015 at 23:58
  • \$\begingroup\$ I have Roman->decimal code that is slightly slower and much shorter, but the decimal->Roman part looks close to if not optimal. \$\endgroup\$
    – lirtosiast
    Commented May 24, 2015 at 23:58
2
\$\begingroup\$

Improving FlyAwayBirdie's answer from 411 bytes to 188 bytes:

This code has a much smaller Roman→decimal conversion. Rather than throwing an error when given an invalid Roman numeral like "VL", it will give an unpredictable result. It simply subtracts letters if the next letter has greater value, and adds the rest. It seems FlyAwayBirdie got the decimal→Roman conversion from here; I could only save seven bytes plus the substring command at the end. Close-quotes have been left on for formatting.

"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<ΔList(cumSum(augment(Ans,{0
End
Ans

Edit: Improved with ideas from M. I. Wright. I had thought of using the seq( method, which I knew would be faster, but I didn't realize it would be smaller as well.

Edit: Optimized the decimal->Roman part some more; I saved seven bytes plus the sub(Ans,1,length(Ans-1at the end, because removing the trailing space is unnecessary.

\$\endgroup\$
3
  • \$\begingroup\$ Nice improvements, glad to see someone talented with TI-Basic. \$\endgroup\$ Commented Jul 9, 2015 at 18:19
  • \$\begingroup\$ @FlyAwayBirdie Check out my code golf account if you want to see more like this! \$\endgroup\$
    – lirtosiast
    Commented Jul 9, 2015 at 18:24
  • \$\begingroup\$ Wow, looks great. Timtech challenged me to code golfing but he tends to dominate me in most challenges (private). Maybe I should start on the SE and see if I can beat his answers. \$\endgroup\$ Commented Jul 9, 2015 at 18:27

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.