Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]


Groups > comp.lang.javascript > #25395 > unrolled thread

General solution to get the previous value

Started byjonas.thornvall@gmail.com
First post2014-07-15 17:25 -0700
Last post2014-07-16 22:45 +0200
Articles 10 — 4 participants

Back to article view | Back to comp.lang.javascript


Contents

  General solution to get the previous value jonas.thornvall@gmail.com - 2014-07-15 17:25 -0700
    Re: General solution to get the previous value jonas.thornvall@gmail.com - 2014-07-15 21:25 -0700
      Re: General solution to get the previous value Ben Bacarisse <ben.usenet@bsb.me.uk> - 2014-07-16 13:06 +0100
    Re: General solution to get the previous value Scott Sauyet <scott.sauyet@gmail.com> - 2014-07-16 07:23 -0700
      Re: General solution to get the previous value jonas.thornvall@gmail.com - 2014-07-16 07:58 -0700
        Re: General solution to get the previous value jonas.thornvall@gmail.com - 2014-07-16 13:35 -0700
      Re: General solution to get the previous value Ben Bacarisse <ben.usenet@bsb.me.uk> - 2014-07-16 17:05 +0100
        Re: General solution to get the previous value jonas.thornvall@gmail.com - 2014-07-16 11:07 -0700
        Re: General solution to get the previous value Scott Sauyet <scott.sauyet@gmail.com> - 2014-07-16 12:13 -0700
        Re: General solution to get the previous value "Evertjan." <exxjxw.hannivoort@inter.nl.net> - 2014-07-16 22:45 +0200

#25395 — General solution to get the previous value

Fromjonas.thornvall@gmail.com
Date2014-07-15 17:25 -0700
SubjectGeneral solution to get the previous value
Message-ID<314cbe9e-975c-4bb1-9e95-b2c90eca3388@googlegroups.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?

[toc] | [next] | [standalone]


#25398

Fromjonas.thornvall@gmail.com
Date2014-07-15 21:25 -0700
Message-ID<a0b92f1c-b6e9-44c6-9fdc-3038f52a648c@googlegroups.com>
In reply to#25395
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?  

[toc] | [prev] | [next] | [standalone]


#25399

FromBen Bacarisse <ben.usenet@bsb.me.uk>
Date2014-07-16 13:06 +0100
Message-ID<0.2b004a7541cffece28b9.20140716130628BST.87a98933uj.fsf@bsb.me.uk>
In reply to#25398
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.

[toc] | [prev] | [next] | [standalone]


#25402

FromScott Sauyet <scott.sauyet@gmail.com>
Date2014-07-16 07:23 -0700
Message-ID<e71a7d67-0ecc-456c-8510-0a8a0152825c@googlegroups.com>
In reply to#25395
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

[toc] | [prev] | [next] | [standalone]


#25403

Fromjonas.thornvall@gmail.com
Date2014-07-16 07:58 -0700
Message-ID<6c3f5661-ffb5-4d36-ab28-e6b4efed5bfc@googlegroups.com>
In reply to#25402
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. 

[toc] | [prev] | [next] | [standalone]


#25408

Fromjonas.thornvall@gmail.com
Date2014-07-16 13:35 -0700
Message-ID<7d4db1e4-f596-4d60-ad23-a6bc68698415@googlegroups.com>
In reply to#25403
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>

[toc] | [prev] | [next] | [standalone]


#25405

FromBen Bacarisse <ben.usenet@bsb.me.uk>
Date2014-07-16 17:05 +0100
Message-ID<0.d611526054996c5a40b5.20140716170550BST.87y4vt1e75.fsf@bsb.me.uk>
In reply to#25402
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.

[toc] | [prev] | [next] | [standalone]


#25406

Fromjonas.thornvall@gmail.com
Date2014-07-16 11:07 -0700
Message-ID<4b868325-9fb8-4091-ab4c-0589b73466eb@googlegroups.com>
In reply to#25405
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.

[toc] | [prev] | [next] | [standalone]


#25407

FromScott Sauyet <scott.sauyet@gmail.com>
Date2014-07-16 12:13 -0700
Message-ID<3dbb4df5-61b5-4e1a-8ee8-ca4a233234e5@googlegroups.com>
In reply to#25405
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

[toc] | [prev] | [next] | [standalone]


#25409

From"Evertjan." <exxjxw.hannivoort@inter.nl.net>
Date2014-07-16 22:45 +0200
Message-ID<XnsA36CE7824C1DCeejj99@194.109.133.133>
In reply to#25405
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)

[toc] | [prev] | [standalone]


Back to top | Article view | comp.lang.javascript


csiph-web