[lnkForumImage]
TotalShareware - Download Free Software

Confronta i prezzi di migliaia di prodotti.
Asp Forum
 Home | Login | Register | Search 


 

Forums >

comp.lang.javascript

General solution to get the previous value

JT

7/16/2014 12:25:00 AM

number=29;
basemultip=1;
base=3;

while (basemultip < number)
{
prevmultip=basemultip;
basemultip = basemultip * base;

}
basemultip=prevbase;

What is the solution to have the previous value when you walk out from loop, i think my code look strange and i probably learned how to do this but forgot about it.

Can i do it without buffering the previous value?

9 Answers

JT

7/16/2014 4:25:00 AM

0

Den onsdagen den 16:e juli 2014 kl. 02:25:21 UTC+2 skrev jonas.t...@gmail.com:
> number=29;
>
> basemultip=1;
>
> base=3;
>
>
>
> while (basemultip < number)
>
> {
>
> prevmultip=basemultip;
>
> basemultip = basemultip * base;
>
>
>
> }
>
> basemultip=prevbase;
>
>
>
> What is the solution to have the previous value when you walk out from loop, i think my code look strange and i probably learned how to do this but forgot about it.
>
>
>
> Can i do it without buffering the previous value?

Sloppy written last line should be ***basemultip=prevmultip;*** , i want to catch the multip of base that is lower then 29 that would be 27 in this case that is stored in prevmultip, but it isn't that pretty look at.

Is there another way to get the value directly from basemultip?

Ben Bacarisse

7/16/2014 12:06:00 PM

0

jonas.thornvall@gmail.com writes:

> Den onsdagen den 16:e juli 2014 kl. 02:25:21 UTC+2 skrev jonas.t...@gmail.com:
>> number=29;
>> basemultip=1;
>> base=3;
>>
>> while (basemultip < number)
>> {
>> prevmultip=basemultip;
>> basemultip = basemultip * base;
>> }
>> basemultip=prevbase;
<snip>
> Sloppy written last line should be ***basemultip=prevmultip;***

You can write it in terms of logs and powers if you want.

>, i
> want to catch the multip of base that is lower then 29 that would be
> 27 in this case that is stored in prevmultip, but it isn't that pretty
> look at.
>
> Is there another way to get the value directly from basemultip?

Yes, just divide it by base.

--
Ben.

Scott Sauyet

7/16/2014 2:24:00 PM

0

jonas.thornvall@gmail.com wrote:
> number=29;
> basemultip=1;
> base=3;
>
> while (basemultip < number)
> {
> prevmultip=basemultip;
> basemultip = basemultip * base;
>
> }
> basemultip=prevbase;
>
> What is the solution to have the previous value when you walk
> out from loop, i think my code look strange and i probably
> learned how to do this but forgot about it.
>
> Can i do it without buffering the previous value?

Doing this in a function might help. One approach:

var findLast = function(base, number) {
var current = 1;
while (true) {
next = base * current;
if (next >= number) {return current;}
current = next;
}
}

findLast(3, 29); //=> 27

Note that this has no error checking. You might want to check that
your target is greater than 1, and that your base is greater than 1.

But note that this could easily be abstracted into a more general
pattern, which might itself be useful:

var findLast = function(start, getNext, predicate) {
var current = start;
while (true) {
next = getNext(current);
if (!predicate(next)) {return current;}
current = next;
}
}

var base = 3, number = 29;
findLast(1, function(n) {return base * n;},
function(n) {return n < number;}); //=> 27

Again this is missing some error checking. You might want to at
least test that the initial value passes the predicate:

if (!predicate(start)) {throw new Error('Illegal initial value');}

It would be harder in this general case though to ensure that we'll ever hit the termination condition.

-- Scott

JT

7/16/2014 2:58:00 PM

0

Den onsdagen den 16:e juli 2014 kl. 16:23:41 UTC+2 skrev Scott Sauyet:
> jonas.thornvall@gmail.com wrote:
>
> > number=29;
>
> > basemultip=1;
>
> > base=3;
>
> >
>
> > while (basemultip < number)
>
> > {
>
> > prevmultip=basemultip;
>
> > basemultip = basemultip * base;
>
> >
>
> > }
>
> > basemultip=prevbase;
>
> >
>
> > What is the solution to have the previous value when you walk
>
> > out from loop, i think my code look strange and i probably
>
> > learned how to do this but forgot about it.
>
> >
>
> > Can i do it without buffering the previous value?
>
>
>
> Doing this in a function might help. One approach:
>
>
>
> var findLast = function(base, number) {
>
> var current = 1;
>
> while (true) {
>
> next = base * current;
>
> if (next >= number) {return current;}
>
> current = next;
>
> }
>
> }
>
>
>
> findLast(3, 29); //=> 27
>
>
>
> Note that this has no error checking. You might want to check that
>
> your target is greater than 1, and that your base is greater than 1.
>
>
>
> But note that this could easily be abstracted into a more general
>
> pattern, which might itself be useful:
>
>
>
> var findLast = function(start, getNext, predicate) {
>
> var current = start;
>
> while (true) {
>
> next = getNext(current);
>
> if (!predicate(next)) {return current;}
>
> current = next;
>
> }
>
> }
>
>
>
> var base = 3, number = 29;
>
> findLast(1, function(n) {return base * n;},
>
> function(n) {return n < number;}); //=> 27
>
>
>
> Again this is missing some error checking. You might want to at
>
> least test that the initial value passes the predicate:
>
>
>
> if (!predicate(start)) {throw new Error('Illegal initial value');}
>
>
>
> It would be harder in this general case though to ensure that we'll ever hit the termination condition.
>
>
>
> -- Scott

It seem to use two conditional checks, While(true) and if(predicate) but maybe it still faster by not buffering the value each loop?

I think it kind of weird that there seem to be no loop construction that could catch this case.

Ben Bacarisse

7/16/2014 4:06:00 PM

0

Scott Sauyet <scott.sauyet@gmail.com> writes:
<snip>
> But note that this could easily be abstracted into a more general
> pattern, which might itself be useful:
>
> var findLast = function(start, getNext, predicate) {
> var current = start;
> while (true) {
> next = getNext(current);
> if (!predicate(next)) {return current;}
> current = next;
> }
> }

(aside: I think you want a "var next;" in there.)

Not being a fan of while (true) I'd write

var result = initial, next;
while (predicate(next = getNext(result))) result = next;
return result;

(names changed because the roles the variables play has altered a bit).

Translating back to the OP's names and making it specific again:

var basemultip, prevmultip = 1;
while ((basemultip = prevmultip * base) < number)
prevmultip = basemultip;
// prevmultip is as required here

but note that both your suggestion and this re-rewrite give different
answers to the OP's original for the degenerate case when the initial
value fails the condition. The OP's code returns 0 which seems a bit
odd in this case, so I don't see that as a problem.

<snip>
--
Ben.

JT

7/16/2014 6:08:00 PM

0

Den onsdagen den 16:e juli 2014 kl. 18:05:50 UTC+2 skrev Ben Bacarisse:
> Scott Sauyet <scott.sauyet@gmail.com> writes:
>
> <snip>
>
> > But note that this could easily be abstracted into a more general
>
> > pattern, which might itself be useful:
>
> >
>
> > var findLast = function(start, getNext, predicate) {
>
> > var current = start;
>
> > while (true) {
>
> > next = getNext(current);
>
> > if (!predicate(next)) {return current;}
>
> > current = next;
>
> > }
>
> > }
>
>
>
> (aside: I think you want a "var next;" in there.)
>
>
>
> Not being a fan of while (true) I'd write
>
>
>
> var result = initial, next;
>
> while (predicate(next = getNext(result))) result = next;
>
> return result;
>
>
>
> (names changed because the roles the variables play has altered a bit).
>
>
>
> Translating back to the OP's names and making it specific again:
>
>
>
> var basemultip, prevmultip = 1;
>
> while ((basemultip = prevmultip * base) < number)
>
> prevmultip = basemultip;
>
> // prevmultip is as required here
>
>
>
> but note that both your suggestion and this re-rewrite give different
>
> answers to the OP's original for the degenerate case when the initial
>
> value fails the condition. The OP's code returns 0 which seems a bit
>
> odd in this case, so I don't see that as a problem.
>
>
>
> <snip>
>
> --
>
> Ben.

I think this was somewhat, what i had in mind, easy code just a loop managing it all.
I have no idea about the effectivness of the different approach, but something tells me this may be the fastest.

Nice code Ben.

Scott Sauyet

7/16/2014 7:14:00 PM

0

Ben Bacarisse wrote:
> Scott Sauyet writes:

>> But note that this could easily be abstracted into a more general
>> pattern, which might itself be useful:
>>
>> var findLast = function(start, getNext, predicate) {
>> var current = start;
>> while (true) {
>> next = getNext(current);
>> if (!predicate(next)) {return current;}
>> current = next;
>> }
>> }
>
> (aside: I think you want a "var next;" in there.)

Yes, of course. Blame it on the beer last night... if only I had
had beer last night. :-)


> Not being a fan of while (true) I'd write
>
> var result = initial, next;
> while (predicate(next = getNext(result))) result = next;
> return result;

Yes, this is simpler, and I certainly prefer it to `while (true)`.

-- Scott

JT

7/16/2014 8:36:00 PM

0

Den onsdagen den 16:e juli 2014 kl. 16:58:29 UTC+2 skrev jonas.t...@gmail.com:
> Den onsdagen den 16:e juli 2014 kl. 16:23:41 UTC+2 skrev Scott Sauyet:
>
> > jonas.thornvall@gmail.com wrote:
>
> >
>
> > > number=29;
>
> >
>
> > > basemultip=1;
>
> >
>
> > > base=3;
>
> >
>
> > >
>
> >
>
> > > while (basemultip < number)
>
> >
>
> > > {
>
> >
>
> > > prevmultip=basemultip;
>
> >
>
> > > basemultip = basemultip * base;
>
> >
>
> > >
>
> >
>
> > > }
>
> >
>
> > > basemultip=prevbase;
>
> >
>
> > >
>
> >
>
> > > What is the solution to have the previous value when you walk
>
> >
>
> > > out from loop, i think my code look strange and i probably
>
> >
>
> > > learned how to do this but forgot about it.
>
> >
>
> > >
>
> >
>
> > > Can i do it without buffering the previous value?
>
> >
>
> >
>
> >
>
> > Doing this in a function might help. One approach:
>
> >
>
> >
>
> >
>
> > var findLast = function(base, number) {
>
> >
>
> > var current = 1;
>
> >
>
> > while (true) {
>
> >
>
> > next = base * current;
>
> >
>
> > if (next >= number) {return current;}
>
> >
>
> > current = next;
>
> >
>
> > }
>
> >
>
> > }
>
> >
>
> >
>
> >
>
> > findLast(3, 29); //=> 27
>
> >
>
> >
>
> >
>
> > Note that this has no error checking. You might want to check that
>
> >
>
> > your target is greater than 1, and that your base is greater than 1.
>
> >
>
> >
>
> >
>
> > But note that this could easily be abstracted into a more general
>
> >
>
> > pattern, which might itself be useful:
>
> >
>
> >
>
> >
>
> > var findLast = function(start, getNext, predicate) {
>
> >
>
> > var current = start;
>
> >
>
> > while (true) {
>
> >
>
> > next = getNext(current);
>
> >
>
> > if (!predicate(next)) {return current;}
>
> >
>
> > current = next;
>
> >
>
> > }
>
> >
>
> > }
>
> >
>
> >
>
> >
>
> > var base = 3, number = 29;
>
> >
>
> > findLast(1, function(n) {return base * n;},
>
> >
>
> > function(n) {return n < number;}); //=> 27
>
> >
>
> >
>
> >
>
> > Again this is missing some error checking. You might want to at
>
> >
>
> > least test that the initial value passes the predicate:
>
> >
>
> >
>
> >
>
> > if (!predicate(start)) {throw new Error('Illegal initial value');}
>
> >
>
> >
>
> >
>
> > It would be harder in this general case though to ensure that we'll ever hit the termination condition.
>
> >
>
> >
>
> >
>
> > -- Scott
>
>
>
> It seem to use two conditional checks, While(true) and if(predicate) but maybe it still faster by not buffering the value each loop?
>
>
>
> I think it kind of weird that there seem to be no loop construction that could catch this case.

I tried to get different timings, but i do something wrong evidently.


<SCRIPT language=Javascript>
basemultip=1;
prevmultip=1;

var prevone = function(base,number){
while (basemultip < number)
{
prevmultip=basemultip;
basemultip = basemultip * base;
}
return prevmultip;
}

var prevtwo = function(base, number) {
var current = 1;
while (true) {
next = base * current;
if (next >= number) {return current;}
current = next;
}
}

var prevthree = function(base,number){
var basemultip, prevmultip = 1;
while ((basemultip = prevmultip * base) < number) prevmultip = basemultip;
return basemultip
}

var start = new Date().getTime();
for(i=1;i<1000;i++){ prevone(7,i); document.write(prevmultip," ");}
//for(i=1;i<1000;i++){ prevtwo(7,i); document.write(basemultip," ");}
//for(i=1;i<1000;i++){ prevthree(7,i); document.write(prevmultip," ");}
var end = new Date().getTime();
var time = end - start;
alert('Execution time: ' + time);
</script>

Evertjan.

7/16/2014 8:45:00 PM

0

Ben Bacarisse <ben.usenet@bsb.me.uk> wrote on 16 jul 2014 in
comp.lang.javascript:

> var basemultip, prevmultip = 1;
> while ((basemultip = prevmultip * base) < number)
> prevmultip = basemultip;
> // prevmultip is as required here
>

Using a recursive function you don't need those variables:

<script type='text/javascript'>

function recur(prev) {
return (prev * base < number)
? recur(prev * base)
: prev;
};

var base = ...;
var number = ...;
alert( recur(1) );

</script>

--
Evertjan.
The Netherlands.
(Please change the x'es to dots in my emailaddress)