So, if pi < lndx I want to "goto" the ith label and do all the operations starting there to the end thru p1, since we know that if pi < lndx then all the pi-1,2,..etc < lndx will also be true.
The way I've done it was the shortest/fastest way I was able to do this correctly, writing, I believe, the smallest amount of repetitive code.
> So, if pi < lndx I want to "goto" the ith label and do all the > operations > starting there to the end thru p1, since we know that if pi < lndx > then > all the pi-1,2,..etc < lndx will also be true.
> The way I've done it was the shortest/fastest way I was able to do > this > correctly, writing, I believe, the smallest amount of repetitive code.
> Is there a shorter/faster way to do this?
Instead of p1 ... p8, use array p.
Something like this (untested).
Ruby:
p = Array.new(8){ 0 }
top = nil 7.downto(0){|i| if p[i] < lndx top = i break end
> > So, if pi < lndx I want to "goto" the ith label and do all the > > operations > > starting there to the end thru p1, since we know that if pi < lndx > > then > > all the pi-1,2,..etc < lndx will also be true.
> > The way I've done it was the shortest/fastest way I was able to do > > this > > correctly, writing, I believe, the smallest amount of repetitive code.
> > Is there a shorter/faster way to do this?
> Instead of p1 ... p8, use array p.
> Something like this (untested).
> Ruby:
> p = Array.new(8){ 0 }
> top = nil > 7.downto(0){|i| > if p[i] < lndx > top = i > break > end}
> top.downto(0){|i| > sieve[ p[i] ] = 0
> }
Maybe you haven't noticed but this is a Forth group and NOT Ruby.
FYI I use Ruby, and the Ruby versions of this code does not use nor need these constructs because Ruby has dynamics arrays, which I can grow or shrink to my hearts content. ONLY because arrays in Forth are static do I have to resort to the described mechanism to fit stuff into the array size domain of the "sieve" array, otherwise I could let the array grow (as I do in Ruby) and then shrink it back to the desired length when it matters.
Also FYI, you are not making Ruby friends by being a PITA about posting none germain Ruby code to a specific Forth coding request. I was hoping maybe there is some nice CASE structure, et al, that can do what I want, in a more elegant and/or faster way.
> Maybe you haven't noticed but this is a Forth group and NOT Ruby.
> FYI I use Ruby, and the Ruby versions of this code does not use nor > need these constructs because Ruby has dynamics arrays, which I can > grow or shrink to my hearts content. ONLY because arrays in Forth are > static do I have to resort to the described mechanism to fit stuff > into the array size domain of the "sieve" array, otherwise I could let > the array grow (as I do in Ruby) and then shrink it back to the > desired length when it matters.
> Also FYI, you are not making Ruby friends by being a PITA about > posting none germain Ruby code to a specific Forth coding request. I > was hoping maybe there is some nice CASE structure, et al, that can do > what I want, in a more elegant and/or faster way.
> When in Forthland speak Forth, please.
> Jabari
whoa, i think someone needs a chill pill, stat.
is something like this the same as what you want to do?
: carray create allot does> swap + ;
8 carray p
: clearsome lndx 0 do 0 i p c! loop ;
i would try to do the other part, the begin/while loop, but i don't understand what 'sieve' is supposed to do. does it influence 'lndx'?
> > Maybe you haven't noticed but this is a Forth group and NOT Ruby.
> > FYI I use Ruby, and the Ruby versions of this code does not use nor > > need these constructs because Ruby has dynamics arrays, which I can > > grow or shrink to my hearts content. ONLY because arrays in Forth are > > static do I have to resort to the described mechanism to fit stuff > > into the array size domain of the "sieve" array, otherwise I could let > > the array grow (as I do in Ruby) and then shrink it back to the > > desired length when it matters.
> > Also FYI, you are not making Ruby friends by being a PITA about > > posting none germain Ruby code to a specific Forth coding request. I > > was hoping maybe there is some nice CASE structure, et al, that can do > > what I want, in a more elegant and/or faster way.
> > When in Forthland speak Forth, please.
> > Jabari
> whoa, i think someone needs a chill pill, stat.
> is something like this the same as what you want to do?
> : carray create allot does> swap + ;
> 8 carray p
> : clearsome > lndx 0 do 0 i p c! loop ;
> i would try to do the other part, the begin/while loop, but i don't > understand what 'sieve' is supposed to do. does it influence 'lndx'?
--------------------
> whoa, i think someone needs a chill pill, stat.
It was late (actually early morning), I was tired/irritated, and that response just crossed my threshold for patronizing irrelevance to my very specific request. Also contributing to my irritation was that in my 29 Forth years I believe I've seen ways to do what I was asking (Forth Dimensions?) and was really irked by such an out of leftfield response. But I meant no "personal" harm. :-)
OK, now the code.
"lndx" is the array length (last index +1) for byte array "sieve" The pi are index values into the "sieve" array.
I can functionally perform the same code equivalently like this:
begin p8 lndx < while 0 p8 sieve c! x1 p8 + to p8 repeat begin p7 lndx < while 0 p7 sieve c! x1 p7 + to p7 repeat begin p6 lndx < while 0 p6 sieve c! x1 p6 + to p6 repeat begin p5 lndx < while 0 p5 sieve c! x1 p5 + to p5 repeat begin p4 lndx < while 0 p4 sieve c! x1 p4 + to p4 repeat begin p3 lndx < while 0 p3 sieve c! x1 p3 + to p3 repeat begin p2 lndx < while 0 p2 sieve c! x1 p2 + to p2 repeat begin p1 lndx < while 0 p1 sieve c! x1 p1 + to p1 repeat
This is shorter but MUCH slower on a single core/single threaded cpu system. HOWEVER, this code represent CONCEPTUALLY exactly what I would want to do if I had a system which could perform each line as a separate independent simultaneous thread, ala a parallel processor/ threaded system. (For my Ruby friend, I performed a Ruby threaded version using this approach which, because Ruby threads ARE NOT really simultaneous parallel processes, is slower.)
So, when p8 < lndx is true, then all the other pi are < lndx too. But when p8 >= lndx then pi < lndx will still be true for some pi and what I want to do is find the pi for which pi < lndx is true and then use all those pi to do 0 pi sieve c! one last time. So a "jump to/goto" structure would be ideal, to enable me to not have to check for each pi < lndx. Comprendes toto?
And for my Ruby friend again, in the Ruby version all I have to do is: while p1 < lndx ....end and let the array grow past the real size I need, and then I "squeeze" it to eliminate "nils" when its time to do final processing of the "sieve" array.
: clearsome lndx 0 do 0 i p c! loop ; sets all the array elements of "0" which is not want I want.
I hope this now provides sufficient understanding of my code,
You could use a drop-through CASE statement: your code would look about the same, but would skip the redundant conditionals, so it might be faster; you'd have to measure.
: CS-SWAP 1 CS-ROLL ;
: CASE FALSE ; IMMEDIATE
: ?OF >R POSTPONE IF POSTPONE DROP R> IF CS-SWAP POSTPONE THEN THEN TRUE ; IMMEDIATE
: OF POSTPONE OVER POSTPONE = POSTPONE ?OF ; IMMEDIATE
: ENDOF >R POSTPONE ELSE R> ; IMMEDIATE
: ENDCASE DROP POSTPONE DROP POSTPONE THEN ; IMMEDIATE
lndx case p7 over < ?of 0 p7 sieve c! endof p6 over < ?of 0 p6 sieve c! endof p5 over < ?of 0 p5 sieve c! endof p4 over < ?of 0 p4 sieve c! endof p3 over < ?of 0 p3 sieve c! endof p2 over < ?of 0 p2 sieve c! endof p1 over < ?of 0 p1 sieve c! endof endcase
Or you could use Wil Baden's GOTO and LABEL, which would be more wordy, but very likely faster.
p7 lndx < if goto 7 then p6 lndx < if goto 6 then p5 lndx < if goto 5 then p4 lndx < if goto 4 then p3 lndx < if goto 3 then p2 lndx < if goto 2 then p1 lndx < if goto 1 then
> On Oct 15, 1:28 am, "roger.l...@gmail.com" <roger.l...@gmail.com> > wrote:
> > > Maybe you haven't noticed but this is a Forth group and NOT Ruby.
> > > FYI I use Ruby, and the Ruby versions of this code does not use nor > > > need these constructs because Ruby has dynamics arrays, which I can > > > grow or shrink to my hearts content. ONLY because arrays in Forth are > > > static do I have to resort to the described mechanism to fit stuff > > > into the array size domain of the "sieve" array, otherwise I could let > > > the array grow (as I do in Ruby) and then shrink it back to the > > > desired length when it matters.
> > > Also FYI, you are not making Ruby friends by being a PITA about > > > posting none germain Ruby code to a specific Forth coding request. I > > > was hoping maybe there is some nice CASE structure, et al, that can do > > > what I want, in a more elegant and/or faster way.
> > > When in Forthland speak Forth, please.
> > > Jabari
> > whoa, i think someone needs a chill pill, stat.
> > is something like this the same as what you want to do?
> > : carray create allot does> swap + ;
> > 8 carray p
> > : clearsome > > lndx 0 do 0 i p c! loop ;
> > i would try to do the other part, the begin/while loop, but i don't > > understand what 'sieve' is supposed to do. does it influence 'lndx'?
> --------------------
> > whoa, i think someone needs a chill pill, stat.
> It was late (actually early morning), I was tired/irritated, and that > response just crossed my threshold for patronizing irrelevance to my > very specific request. Also contributing to my irritation was that in > my 29 Forth years I believe I've seen ways to do what I was asking > (Forth Dimensions?) and was really irked by such an out of leftfield > response. But I meant no "personal" harm. :-)
> OK, now the code.
> "lndx" is the array length (last index +1) for byte array "sieve" > The pi are index values into the "sieve" array.
> I can functionally perform the same code equivalently like this:
> begin p8 lndx < while 0 p8 sieve c! x1 p8 + to p8 repeat > begin p7 lndx < while 0 p7 sieve c! x1 p7 + to p7 repeat > begin p6 lndx < while 0 p6 sieve c! x1 p6 + to p6 repeat > begin p5 lndx < while 0 p5 sieve c! x1 p5 + to p5 repeat > begin p4 lndx < while 0 p4 sieve c! x1 p4 + to p4 repeat > begin p3 lndx < while 0 p3 sieve c! x1 p3 + to p3 repeat > begin p2 lndx < while 0 p2 sieve c! x1 p2 + to p2 repeat > begin p1 lndx < while 0 p1 sieve c! x1 p1 + to p1 repeat
> This is shorter but MUCH slower on a single core/single threaded cpu > system. HOWEVER, this code represent CONCEPTUALLY exactly what I would > want to do if I had a system which could perform each line as a > separate independent simultaneous thread, ala a parallel processor/ > threaded system. (For my Ruby friend, I performed a Ruby threaded > version using this approach which, because Ruby threads ARE NOT really > simultaneous parallel processes, is slower.)
> So, when p8 < lndx is true, then all the other pi are < lndx too. > But when p8 >= lndx then pi < lndx will still be true for some pi and > what I want to do is find the pi for which pi < lndx is true and then > use all those pi to do 0 pi sieve c! one last time. > So a "jump to/goto" structure would be ideal, to enable me to not have > to check for each pi < lndx. Comprendes toto?
> And for my Ruby friend again, in the Ruby version all I have to do > is: while p1 < lndx ....end and let the array grow past the real > size I need, and then I "squeeze" it to eliminate "nils" when its time > to do final processing of the "sieve" array.
> : clearsome lndx 0 do 0 i p c! loop ; > sets all the array elements of "0" which is not want I want.
> I hope this now provides sufficient understanding of my code,
> Jabari
hmm, well, now i understand better i think. i still think you should change those p-words to one word, p, but also have access to the pointers themselves. if sieve and p are conceptually coupled, you want to hide sieve. why mention sieve if you are only ever accessing that array in this, right?
In another part of the begin-while loop it seems you're adding another value to your pointers. This should become another def.
It seems that there must be a clearer way to express what you're doing in code. Couldn't you precalculate the number of times we'd be going through this loop and use a DO-LOOP?
: inc-referenced lndx 7 pointer[] @ - x1 / \ not sure but i think this is equivalent ... i'd have given it a name but i have no hint as to what x1 means or what/where sieve is (physically/conceptually) 0 do 8 0 do x1 i pointer[] +! loop clear loop ;
I have no idea what the next part is for, but, I think it can be reduced to:
: ?clear-lasts 7 0 do i pointer[] @ lndx < if 0 p c! then loop ;
Hope this gets you somewhat closer. If you can clarify what the goal is here, I could maybe help you get to a more ideal factoring. I'll do my best...
jzakiya <jzak...@mail.com> wrote: > I have a string of integer values:
> p1<p2<p3<p4...<p8 and a reference value lndx
> I have a code snippet that I have to do this way
> begin p8 lndx < while > 0 p1 sieve c! 0 p2 sieve c! 0 p3 sieve c! 0 p4 sieve c! > 0 p5 sieve c! 0 p6 sieve c! 0 p7 sieve c! 0 p8 sieve c! > x1 p1 + to p1 x1 p2 + to p2 x1 p3 + to p3 x1 p4 + to p4 > x1 p5 + to p5 x1 p6 + to p6 x1 p7 + to p7 x1 p8 + to p8 > repeat > p7 lndx < if 0 p7 sieve c! then > p6 lndx < if 0 p6 sieve c! then > p5 lndx < if 0 p5 sieve c! then > p4 lndx < if 0 p4 sieve c! then > p3 lndx < if 0 p3 sieve c! then > p2 lndx < if 0 p2 sieve c! then > p1 lndx < if 0 p1 sieve c! then > The way I've done it was the shortest/fastest way I was able to do > this correctly, writing, I believe, the smallest amount of repetitive > code.
> Is there a shorter/faster way to do this?
Slightly faster,
p1 lndx < if 0 p1 sieve c! p2 lndx < if 0 p2 sieve c! p3 lndx < if 0 p3 sieve c! p4 lndx < if 0 p4 sieve c! p5 lndx < if 0 p5 sieve c! p6 lndx < if 0 p6 sieve c! p7 lndx < if 0 p7 sieve c! then then then then then then then
When you find one that's too big, quit.
If you put p1-p8 into an array then you can loop through them to make the code shorter. But depending on how well your values are optimised it might likely be slower.
\ I haven't tested this but only desk-checked it. \ p is an array containing values of p1..p8
lndx 7 p1 @ - x1 /mod swap 0= 1+ + x1 + dup 0 do \ n*x1 0 p 8 bounds do 0 i @ j + sieve c! 1 cells +loop x1 +loop
0 p 8 bounds do dup i @ + lndx over < if drop leave then 0 swap sieve c! 1 cells +loop drop
The p array lets us remove redundant code by using a loop. Presumably the array is slower than values. Possibly some optimisation in the DO loops might help make up for it?
It saves time not to update the values, but if you need them updated then that time has to be lost.
\ n*x1 0 p 8 bounds do dup i ! 1 cells + loop drop
Is it faster to compute n*x1 and add it to the values once rather than add x1 n times? It depends.
Jonah Thomas <jethom...@gmail.com> wrote: > \ I haven't tested this but only desk-checked it. > \ n*x1 > 0 p 8 bounds do > dup i ! > 1 cells + loop > drop
Of course right after I posted it one of the errors jumped out at me.
\ n*x1 0 p 8 bounds do dup i +! 1 cells + loop drop