We could use subscripts for the lists L₁, L₂, L₃, L₄, L₅, L₆. This would be a better solution in code boxes (I originally read the first line as DelVar L:21→A and was very confused).
Date: 03 Feb 2008 16:47
Number of posts: 7
RSS: New posts
The code fails to work correctly for a run of length 10 or more (12 fours will be recorded as 4+.1*12 or 5.2, same as 2 fives). In such a case, the code should record a run of length 9, then another run of the same symbol.
Also, I think the routine would be better done in-place, overwriting the list L1 instead of creating a different list. There's no reason not to, and aren't we after all compressing to save memory?
(Incidentally, I'm still not certain that RLE in the form it's presented here is at all effective; why not use digit extraction-like methods instead?)
I actually knew about that bug, but I just decided it would be better to post the routine and worry about it later. The easiest way to fix it would be to do what you are talking about, but you could also use the 1+int(log(# trick to multiply by .01 when there are 10 or more consecutive numbers (or .001 when there are 100 or more consecutive numbers).
The reason I decided to use another list is because that way I don't have to worry about checking for consecutive numbers at the beginning or ending of the list. As far as this routine being effective, I figured we didn't have any routines on compression algorithms, and for most people, RLE is fairly easy to understand. If you want to create routines for any of the other more complex compression algorithms, that would be great.
I changed the routine so that it just uses the L₁ list, but the problem now is that the For( loop just checks the arguments at the beginning of the loop, and so it always returns an invalid dimension error. The easiest way to fix this is to add an additional check for seeing if I is less than the dimensions of the list, but I was wondering if there is a more clever way to fix this problem?
:For(I,1,dim(L₁ :If I<dim(L₁:Then :If L₁(I)=L1(I+1:Then :I→J :While L₁(I)=L₁(J :J+1→J :End :J-1→J:J-I+1 :L₁(I)+Ans/10^(1+int(log(Ans→L₁(I :augment(seq(L₁(A),A,1,I),seq(L₁(A),A,J+1,dim(L₁)→L₁ :End:End:End
You want to keep an index J to the last element of the list that's actually part of the result. Then you always compare L1(I) to L1(J) and never to L1(I+1).
Also, the code *still* doesn't work — there's no distinction made between 5.2 or 5.20 or 5.200. The easiest thing to do would be to use thousandths in all cases: two fives are 5.002, 20 fives are 5.02=5.020, and 999 fives are 5.999. There's obviously never going to be a run longer than 999.
Edit: I fixed up the code. The if statements inside could be optimized, but that would make the code far too confusing, so I'm hesitant to do it.
2 questions: can this program be changed to work with strings, and does this now work for runs longer than 999?, if so, you could make the ultimate graphscreen compression program, and store pictures using 100 or less bytes. :)