String Search, Replace or Delete Routine (Method 1)
Input: Str0 = the full/original string
Input: Str1 = the string to search for (can be any length)
Input: Str2 = the string that replaces all occurrences of Str1 in Str0. (can be any length) (If you want to delete all occurrences of instead of replacing them, then make the length of Str2 to be zero, and it will do just that.)

Output: Str3 = the resulting string.

Variables used: L,M,Z, Str0, Str1, Str2, Str3.



Code:
:length(Str0→L
:length(Str1→M
:" →Str3
:1→Z
:While Z+M-1≤L
:    If Str1=sub(Str0,Z,M
:    Then
:        If 0≠length(Str2
:            Str3+Str2→Str3
:        Z+M→Z
:    Else
:        Str3+sub(Str0,Z,1→Str3
:        Z+1→Z
:    End
:   
:    If Z+M-1>L and M>1
:        1→M
:End
:
:If 1<length(Str3
:sub(Str3,2,length(Str3)-1→Str3

Note that I can tell that this code is quite slow, so I was hoping that someone could optimize it or translate it to asm?

I programmed this search routine in 3 other ways, one of them I believe to also be bug free, but it's a lot longer and it's slower for a longer Str0 which has many spaced out occurrences of Str1. (Shown below).

String Search, Replace or Delete Routine (Method 2)

It has the same input and output as the program above, and it uses all of the same variables plus the following:

lists: P, S, T, X
Reals: C,N

Basically instead of searching and replacing simultaneously, this approach searches first and stores data in lists P, S, and T (list X is just a temporary list).

List P = the indexed locations of the first character of each occurrence of string Str1 in Str0.
List T = the start index(es) where Str1 is not in Str0.
List S = the number of spaces between each occurrence of Str1 in Str0.

So that we can literally construct Str0 using data from lists P,T, and S, as far as the search Str1 is concerned when we want to replace occurrences of the search.

Starting from Lbl 1, is the replace routine which replaces all Str1 occurrences in Str0 with Str2 or it deletes them if the length of Str2 (N) is zero.



Code:
:0→dim(∟P
:0→dim(∟T
:0→dim(∟S
:length(Str0→L
:length(Str1→M
:length(Str2→N
:
:1→C:1→Z
:While Z+M-1≤L
:    If Str1=sub(Str0,Z,M
:    Then
:        Z→∟P(C
:        C+1→C:Z+M→Z
:    Else
:        Z+1→Z
:    End
:End
:
:If 0=dim(∟P
:Then
:    Str0→Str3
:    Return
:End
:
:If 1=dim(∟P
:Then
:    If 1=∟P(1
:    Then
:        If L≠M
:        Then
:            M+1→∟T(1
:            L-M→∟S(1
:        End
:    Else
:        {∟P(1)-1→S
:        {1→T
:        If L≠M-1+∟P(1
:        Then
:            L-M-∟S(1→∟S(2
:            M+∟P(1→∟T(2
:        End
:    End
:    Goto 1
:End
:
:DeltaList(∟P→X
:
:For(Z,1,dim(∟X
:    If M≠∟X(Z
:    Then
:        If Z=1 and 1≠∟P(1
:            {M-1+∟P(1→S
:        1+dim(∟S→dim(∟S
:        ∟X(Z→∟S(dim(∟S
:    End
:End
:
:If L≠M-1+∟P(dim(∟P
:Then
:    1+dim(∟S→dim(∟S
:    L+1-∟P(dim(∟P→∟S(dim(∟S
:End
:
:If 0≠dim(∟S
:Then
:    ∟S-M→S
:Else
:    Goto 1
:End
:
:∟P+M→X
:1+dim(∟P→dim(∟P
:For(Z,1,dim(∟X
:    If ∟X(Z)≠∟P(Z+1
:    Then
:        If Z=1 and 1≠∟P(1
:            {1→T
:        1+dim(∟T→dim(∟T
:        ∟X(Z→∟T(dim(∟T
:    End
:End
:
:If L<∟T(dim(∟T
:    dim(∟T)-1→dim(∟T
:dim(∟P)-1→dim(∟P
:
:Lbl 1
:" →Str3
:If 0=dim(∟T
:Then
:    1→Z
:    While Z≤dim(∟P
:        If N≠0
:            Str3+Str2→Str3
:        Z+1→Z
:    End
:
:    If N=0
:        "→Str3
:    Goto 3
:End
:
:1→C:1→Z
:Lbl 2
:While Z≤dim(∟P) and C≤dim(∟T
:    If ∟P(Z)<∟T(C
:    Then
:        If N≠0
:            Str3+Str2→Str3
:        1+Z→Z
:    Else
:        Str3+sub(Str0,∟T(C),∟S(C→Str3
:        1+C→C
:    End
:    Goto 2
:End
:
:If L=M-1+∟P(dim(∟P
:Then
:    1+L-∟T(dim(∟T))-∟S(dim(∟S→C
:    C/M→C
:    While C≠0
:        If N≠0
:            Str3+Str2→Str3
:        C-1→C
:    End
:Else
:    Str3+sub(Str0,∟T(dim(∟T)),∟S(dim(∟S→Str3
:End
:
:Lbl 3
:If 0≠length(Str3
:    sub(Str3,2,length(Str3)-1→Str3


I doubt experienced coders will need comments for the first program, but if anyone is interested in full comments for the second program, I can submit them.

I have been a member for a little while, but this is my first post! I have made several routines that have been useful for me over the years, but I have seen some impressive routines in this thread.
Here's my take on it:

Code:
:length(Str1→U
:length(Str2→V
:"?"+Str0+"?→Str0
:inString(Ans,Str1,2→W
:While Ans
:sub(Str0,1,W-1
:If V:Ans+Str2
:Ans+sub(Str0,U+W,length(Str0)-U-W+1→Str0
:inString(Ans,Str1,V+W→W
:End
:sub(Str0,2,length(Str0)-2→Str3
Weregoose wrote:
Here's my take on it:

Code:
:length(Str1→U
:length(Str2→V
:"?"+Str0+"?→Str0
:inString(Ans,Str1,2→W
:While Ans
:sub(Str0,1,W-1
:If V:Ans+Str2
:Ans+sub(Str0,U+W,length(Str0)-U-W+1→Str0
:inString(Ans,Str1,V+W→W
:End
:sub(Str0,2,length(Str0)-2→Str3

First of all, wow. This code works pretty fast for very long strings with many occurrences of the search.

Second, did you come up with this code by optimizing mine, or did you code this from scratch? The reason I ask is because I'm new to lines of code like "If V" and "If ans", and I always wanted to learn it (I've seen this type of code before...is there a place I can learn what that type of BASIC code means?), and so I wasn't sure.

Third, in the process of programming "Method 2" (I actually programmed that before I programmed "Method 1"...and I wasn't happy about that because I made things much more difficult than they were), I created a set of 7 different tests which the program must pass to verify that it is bug free. Your code works for all of the tests for every situation except with the search string Str1 is = "?"

Your code does do the replacement/deletion of Str1="?", but the last iteration of the loop generates a domain error.

I made a fix, but I wonder if there is a better way to fix it (if my fix slows down the code by a lot).

Lastly, I haven't really looked at your code in detail yet, but it seems like the output of the program is Str2 and not Str3, as I believe the last line of your code is attempting to do. So the way you programmed it, we don't even need an extra string Str3 to store the output in (we just need the three input strings, obviously), but I wonder if this might not be as user-friendly if someone wants all of the input strings to be preserved.


Code:
:length(Str1→U
:length(Str2→V
:"?"+Str0+"?→Str0
:inString(Ans,Str1,2→W
:While Ans
:sub(Str0,1,W-1
:If V:Ans+Str2
:
:If W=length(Str0) and Str1 = "?"
:Goto 0
:
:Ans+sub(Str0,U+W,length(Str0)-U-W+1→Str0
:inString(Ans,Str1,V+W→W
:End
:
:Lbl 0
:
:sub(Str0,2,length(Str0)-2→Str3
cmowla wrote:
Second, did you come up with this code by optimizing mine, or did you code this from scratch? The reason I ask is because I'm new to lines of code like "If V" and "If ans", and I always wanted to learn it (I've seen this type of code before...is there a place I can learn what that type of BASIC code means?), and so I wasn't sure.

Scratch. Re: If V, the condition's argument evaluates to one of two states: zero, or otherwise. In the realm of reals, this is all If cares about.

cmowla wrote:
I created a set of 7 different tests which the program must pass to verify that it is bug free.

This, I strongly feel, is the enthusiasm upon which mastery depends. To intuit how to fit the units with one another to represent that soft-spoken, much-implied-from-little dialect of TI-BASIC, you must scope out all of their figures on an individual basis as assiduously as you have done with this utter whole.

cmowla wrote:
Your code does do the replacement/deletion of Str1="?", but the last iteration of the loop generates a domain error.

I made a fix, but I wonder if there is a better way to fix it (if my fix slows down the code by a lot).

I tacked "and Ans+U-1≠length(Str0" onto the end of the While in the original just now to put a safety on the overzealous W. Each of the string's bookends may now be any one token, and they don't even have to be copies of each other.

cmowla wrote:
Lastly, I haven't really looked at your code in detail yet, but it seems like the output of the program is Str2 and not Str3, as I believe the last line of your code is attempting to do. So the way you programmed it, we don't even need an extra string Str3 to store the output in (we just need the three input strings, obviously), but I wonder if this might not be as user-friendly if someone wants all of the input strings to be preserved.

I did attempt to match variables with yours to improve recognition, but that is the only reason.

You, sir, have made a rather stellar debut.
cmowla wrote:
Lastly, I haven't really looked at your code in detail yet, but it seems like the output of the program is Str2 and not Str3, as I believe the last line of your code is attempting to do. So the way you programmed it, we don't even need an extra string Str3 to store the output in (we just need the three input strings, obviously), but I wonder if this might not be as user-friendly if someone wants all of the input strings to be preserved.

Oops. I realized that I typed sto Str2 as the last two characters of the program into the programming editor. No wonder why the output was Str2 instead of Str3!

Weregoose wrote:
I did attempt to match variables with yours to improve recognition, but that is the only reason.

You, sir, have made a rather stellar debut.

I appreciate your help and the warm welcome! I'll study your code in detail to see if I can apply the same principal to other routines I have coded in the past as well as what I will code in the future.
Quadrilateral Rasterizer/Fill
Enter points in order: lower-left, lower-right, upper-left, upper-right. Performs an efficient fill that fills all pixels inside quadrilateral without using barycentric-style bounds checking.


Code:
4->dim(L1
4->dim(L2
For(A,1,4
Text(0,0,"POINT ",A
Input
X->L1(A
Y->L2(A
End
1/max(L1(2)-L1(1),L1(4)-L1(3->C
1/max(L2(3)-L2(1),L2(4)-L2(2->D
For(A,0,1,D
For(B,0,1,C
Pt-On(AL1(3)+(1-A)L1(1)+A(L1(4)-L1(3))B+(1-A)(L1(2)-L1(1))B,AL2(3)+(1-A)L2(1)+A(L2(4)-L2(3))B+(1-A)(L2(2)-L2(1))B
End
End


Sample output:
Simplified:

Code:
(fetch coordinates for L1,L2)
:For(A,0,1,1/max(abs(ΔList({1,-1,1}ΔList(L2
:1-A
:Line(AnsL1(1)+AL1(3),AnsL2(1)+AL2(3),AnsL1(2)+AL1(4),AnsL2(2)+AL2(4
:End

This also makes the selection order more lax, though in what direction, I'm not sure.
Ah yes, I didn't bother optimizing to a line because I actually wrote this code to rasterize quadrilaterals over their textures in Python. For that, I need to scan each pixel. Your solution is much better for the calculator, and of course the Ans optimization helps too. Your ΔList trick is beyond clever, of course.
Compute Width of Non-Negative Integer

Homescreen:

Code:
1+max(0,int(log(X+.1


TI-83+/TI-84+ graphscreen:

Code:
4+4max(0,int(log(X+.1


TI-84 Plus C Silver Edition graphscreen:

Code:
8+8max(0,int(log(X+.1
Bitwise XOR/AND/OR of Two Integers

The following code was created by Weregoose (see this topic) for XORing two integers together. A and B are the arguments, and the output is returns in Ans.
Weregoose wrote:
If you want to retool this into another bitwise operation, go to the "=" and substitute it with "<" for AND, or "≤" for OR.

Code:
:int(log(2)⁻¹log(max({A,B
:2^cumSum(binomcdf(Ans,0
:sum(Ans.5(1=abs(int(2fPart(Ans⁻¹(A+Bi
Numpad To List

Here is a short one that is a little different than the other ones out there... Not really anything to special about it.

It will convert a number on the keypad to the corresponding number.


Code:

:Repeat Ans
:sum(cumSum(getKey={74,73,72,84,83,82,94,93,92,102
:End:Ans-1


This one is without the 0.


Code:

:Repeat Ans
:sum(cumSum(getKey=seq(74-X+13int(X/3),X,0,8
:End


The output is in Ans.
Decimal to Fraction Converter
Inputs:
Ans = Real number
Outputs:
Ans = {Numerator,Denominator} (sign is kept in the denominator)


Code:
:Ans→X
:abs(Ans→Y
:Ans→Z
:While Ans-round(Ans,0
:1/fPart(Y→Y
:conj(Zi+real(Zint(Ans→Z
:real(Ans
:End
:round({Ans,Ans/X
List with values increasing by one
Inputs:
S = Starting value
V = S-V=1
E = Ending number

Outputs:
L1 with numbers increasing by one.

Code:

3->V
2->S    //Initialize starting variable.
For(S,V+1,E
S->L1(S-V)
End
http://tibasicdev.wikidot.com/seq-list
I'm not quite sure I understand the initialization of that code. V is never initialized, and the value stored to S is immediately overwritten when S is used as the for loop variable.

I believe that the simplest method of generating a list of increasing values only needs the magical seq command, which Weregoose linked to. Here's how it would look:

seq(<seq_var>,<seq_var>,<start>,<end>

If the starting value is stored in a variable, you could also use it as both the <seq_var> and the <start> arguments.
Thanks for teaching me something, and also for pointing out my mistake.
Text Wrapper/Letter Wrapper on a graphscreen

Edit: Please refer to the post after this one. This routine has been fixed with newer code.

Input: Ans or Str1=string to be displayed on the graphscreen with ° as new line characters
Destroyed: Graphscreen and a few variables

This takes a string and displays it on the graphscreen while detecting when a new line is needed. The text can be defined within or outside the routine. Here are three versions:

Monochrome calculators (e.g. TI-83(+/SE) and TI-84(+/SE)):

Code:
"INSERT TEXT HERE.^^oTHE DEGREE SYMBOL INDICATES A NEW LINE^^oTHIS SENTENCE WILL AUTOMATICALLY START A NEW LINE BECAUSE IT IS LONG.
Ans->Str1
ClrDraw
1->X:0->A
While X<length(Str1) and A<=54
inString(Str1,"^^o",X
min({23,Ans-X->C
Text(A,0,sub(Str1,X,Ans
If Ans!=23:X+1->X
X+C->X:A+6->A
End


TI-84+CSE:

Code:
"INSERT TEXT HERE.^^oTHE DEGREE SYMBOL INDICATES A NEW LINE^^oTHIS SENTENCE WILL AUTOMATICALLY START A NEW LINE BECAUSE IT IS LONG.
Ans->Str1
ClrDraw
1->X:0->A
While X<length(Str1) and A<=228
inString(Str1,"^^o",X
min({30,Ans-X->C
Text(A,0,sub(Str1,X,Ans
If Ans!=30:X+1->X
X+C->X:A+12->A
End


Cross compatibility (all TI-8x calculators):

Code:
Xmin+|E2DeltaX<Xmax->|N
"INSERT TEXT HERE.^^oTHE DEGREE SYMBOL INDICATES A NEW LINE^^oTHIS SENTENCE WILL AUTOMATICALLY START A NEW LINE BECAUSE IT IS LONG.
Ans->Str1
ClrDraw
1->X:0->A
While X<length(Str1) and A<=54(|N+1
inString(Str1,"^^o",X
min({23+7|N,Ans-X->C
Text(A,0,sub(Str1,X,Ans
If Ans!=23+7|N:X+1->X
X+C->X:A+6(|N+1->A
End
[/b]
Text Wrapper/Letter Wrapper on a graphscreen

Input: Ans or Str1=string to be displayed on the graphscreen with ° as new line characters
Destroyed: Graphscreen and two variables

This takes a string and displays it on the graphscreen while detecting when a new line is needed. The text can be defined within or outside the routine. This version addresses the issue where a line could not be preceded by a 23 or 30 character line, depending on the model. Also, it has been optimized. Here are three versions:

Monochrome calculators (e.g. TI-83(+/SE) and TI-84(+/SE)):

Code:
"INSERT TEXT HERE.^^oTHE DEGREE SYMBOL INDICATES A NEW LINE^^oTHIS SENTENCE WILL AUTOMATICALLY START A NEW LINE BECAUSE IT IS LONG.^^oTHIS STRING MUST END WITH A DEGREE SYMBOL^^o
Ans->Str1
ClrDraw
1->X:0->A
While X<length(Str1) and A<=54
inString(Str1,"^^o",X)-X->B
min({23,Ans
Text(A,0,sub(Str1,X,Ans
X+Ans+(B<=Ans->X:A+6->A
End


TI-84+CSE:

Code:
"INSERT TEXT HERE.^^oTHE DEGREE SYMBOL INDICATES A NEW LINE^^oTHIS SENTENCE WILL AUTOMATICALLY START A NEW LINE BECAUSE IT IS LONG.^^oTHIS STRING MUST END WITH A DEGREE SYMBOL^^o
Ans->Str1
ClrDraw
1->X:0->A
While X<length(Str1) and A<=228
inString(Str1,"^^o",X)-X->B
min({30,Ans
Text(A,0,sub(Str1,X,Ans
X+Ans+(B<=Ans->X:A+12->A
End


Cross compatibility (all TI-8x calculators):

Code:
Xmin+|E2DeltaX<Xmax->|N
"INSERT TEXT HERE.^^oTHE DEGREE SYMBOL INDICATES A NEW LINE^^oTHIS SENTENCE WILL AUTOMATICALLY START A NEW LINE BECAUSE IT IS LONG.^^oTHIS STRING MUST END WITH A DEGREE SYMBOL^^o
Ans->Str1
ClrDraw
1->X:0->A
While X<length(Str1) and A<=54(|N+1
inString(Str1,"^^o",X)-X->B
min({23+7|N,Ans
Text(A,0,sub(Str1,X,Ans
X+Ans+(B<=Ans->X:A+6(|N+1->A
End
I'm just looking to see if anyone can either simplify my code or do it in any easier way. I noticed a while back something about filling in a box, but i was trying to take it a step forward by filling in any quadrilateral. here is the code:

Code:
For(A,1,4
 Input
 X->L2(A
 Y->L3(A
End
0->A
0->B
0->C
0->D
(L2(2)-L2(1))/30->E
(L3(2)-L3(1))/30->H
(L2(3)-L2(4))/30->F
(L3(4)-L3(3))/30->G
Repeat A>(L2(2)-L2(1))
 Line(L2(1)+A,L3(1)+B,L2(4)+C,L3(4)+D
 A+E->A
 B+H->B
 C+F->C
 D-G->D
End

Any suggestions?
Compare Strings

Not sure if this is the best way to do it, but this compares Str1 to Str0.
Inputs:
[Str0] - String 1
[Str1] - String 2

Outputs:
Ans - 1 if same, 0 if not same


Code:
length(Str1)=length(Str0
If Ans
prod(seq(A=inString(Str0,sub(Str1,A,1)),A,1,length(Str1
  
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
» Goto page Previous  1, 2, 3 ... 9, 10, 11 ... 13, 14, 15  Next
» View previous topic :: View next topic  
Page 10 of 15
» 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