Javascript square function - javascript

I want to write a function that checks if the given number has a certain order.
The second number has to be the square of the previous number.
The first number can only be 0 - 9.
So for example 2439 would return 'true' because 4 is the square of 2 and 9 is the square of 3.
39416 would also give 'true', and for example 1624 would return 'false'.
I don't really have an idea how to do this. It should be a recursive function but an example of how to do it without recursion would be helpfull too.

I would try something like this:
function isOrdered(input){
var position = 0;
while(position<input.length-2)
{
var currentFirstNumber = parseInt(input[position]);
if(currentFirstNumber<=2) {
if (Math.sqrt(parseInt(input[position + 1])) !== currentFirstNumber)
return false;
else
position+=2;
}
if(currentFirstNumber>=4 && currentFirstNumber<=9)
{
var squared = input.substring(position+1,position+3);
if(Math.sqrt(parseInt(squared))!==currentFirstNumber)
return false;
else
position=position+3;
}
}
return true;
}
console.log(isOrdered("2439")); // outputs true
console.log(isOrdered("39416")); // outputs true
console.log(isOrdered("1624")); // outputs false
I pass the number to the function as a string.

Take a look at this recursive function
function detectOrder(input)
{
var input = input.toString()
var first = input.substr(0,1);
var power = Math.pow(parseInt(first), 2);
var powerLength = power.toString().length;
if ( parseInt(input.substr(1, powerLength)) == power )
{
if (input.length <= 1+powerLength)
{
return true;
}
else
{
return detectOrder(input.substr(1+powerLength));
}
}
else
{
return false;
}
}

As mention in the comment section, OP said that the 'firsts' are limited to 0..9. So the easiest way to accomplish this is by going through the power function instead of the square root function.
UPDATE: Sorry, you asked for JavaScript code. Be careful with the FIRST CALL. if you manually pass to the function the last position, it will return true.
function verification(number, position){
var str = String(number); // Cast number to String
if(str.length > position){ // Verify valid position
var value = str.substr(position, 1); // take the 'first' value
var pow = Math.pow(value, 2); // Calculate the power
// Verify if the next value is equivalent to the power
if(str.indexOf(pow, position) == position + 1){
// Recursive call to verify the next position
return verification(number, position + String(pow).length + 1);
} else {
// If not equivalent, you found an inconsistency.
return false;
}
// If you ran it until you reached the last position, you're good to go.
}else if(str.length == position){
return true;
}
}
console.log(verification(39416, 0)); // True
console.log(verification(39415, 0)); // True
console.log(verification(981524, 0)); // false
console.log(verification(981525, 0)); // true
console.log(verification(98525, 0)); // false

Related

Recursive approach to Persistent bugger problem returns undefined

I've been trying to solve the following problem in codewars using recursion:
Write a function, persistence, that takes in a positive parameter num and returns its multiplicative persistence, which is the number of times you must multiply the digits in num until you reach a single digit.
For example (Input --> Output):
39 --> 3 (because 3*9 = 27, 2*7 = 14, 1*4 = 4 and 4 has only one digit)
999 --> 4 (because 9*9*9 = 729, 7*2*9 = 126, 1*2*6 = 12, and finally 1*2 = 2)
4 --> 0 (because 4 is already a one-digit number)
Here's what I've tried:
var numOfIterations = 0;
function persistence(num) {
//code me
var i;
var digits=[];
var result = 1;
if (num.toString().length==1) {
return numOfIterations;
} else {
numOfIterations++;
digits = Array.from(String(num), Number);
for (i=0;i<digits.size;i++) {
result=result*digits[i];
}
persistence(result);
}
}
But for some reason, instead of returning the number of iterations, it returns undefined. I've been told that I'm not using recursion correctly, but I just can't find the problem.
Other answers have explained what's wrong with your code. I just want to point out a simpler implementation:
const multiplyDigits = (n) =>
n < 10 ? n : (n % 10) * multiplyDigits (n / 10 | 0);
const persistence = (n) =>
n < 10 ? 0 : 1 + persistence (multiplyDigits (n));
[39, 999, 4] .forEach (t => console .log (`${t}:\t${persistence (t)}`));
multiplyDigits does just what it says, recursively multiplying the final digit by the number left when you remove that last digit (Think of | 0 as like Math .floor), and stopping when n is a single digit.
persistence checks to see if we're already a single digit, and if so, returns zero. If not, we add one to the value we get when we recur on the multiple of the digits.
I've been told that I'm not using recursion correctly
You're recursing, but you're not returning the result of that recursion. Imagine for a moment just this structure:
function someFunc() {
if (someCondition) {
return 1;
} else {
anotherFunc();
}
}
If someCondition is false, what does someFunc() return? Nothing. So it's result is undefined.
Regardless of any recursion, at its simplest if you want to return a result from a function then you need to return it:
function persistence(num) {
//...
if (num.toString().length==1) {
//...
} else {
//...
return persistence(result); // <--- here
}
}
As #David wrote in his answer, you were missing the return of the recursive call to itself.
Plus you were using digits.size instead of digits.length.
Anyway consider that one single digit being zero will collpse the game because that's enough to set the result to zero despite how many digits the number is made of.
To deal with the reset of numOfIterations, at first I tried using function.caller to discriminate between recursive call and direct call and set the variable accordingly. Since that method is deprecated as shown here:
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Function/caller
I opted for the optional argument iteration that gets set to zero as default, to keep track of that value while it goes down the call stack. This solution still fulfills the fact that the caller doesn't need to know a new interface for the function to work.
//var numOfIterations = 0;
function persistence(num, iteration=0) {
/*
Commented strategy using the function.caller
working but deprecated so I can't recommend anymore
used optional argument iteration instead
//gets the name of the caller scope
let callerName = persistence.caller?.name;
//if it's different from the name of this function
if (callerName !== 'persistence')
//reset the numOfIterations
numOfIterations = 0;
*/
var digits=[];
if (num.toString().length==1){
return iteration;
} else {
var result = 1;
digits = Array.from(String(num), Number);
for (let i=0;i<digits.length;i++) {
result = result * digits[i];
}
return persistence(result, iteration+1);
}
}
console.log( persistence(39) ); //-> 3
console.log( persistence(999 ) ); //-> 4
console.log( persistence(4) ); //-> 0
You can do something like this
const persistenceTailRecursive = (num, iterations = 0) => {
const str = '' + num;
if(str.length === 1){
return iterations;
}
return persistenceTailRecursive(str.split('').reduce((res, a) => res * parseInt(a), 1), iterations + 1)
}
const persistence = (num) => {
const str = '' + num;
if(str.length === 1){
return 0;
}
return 1 + persistence(str.split('').reduce((res, a) => res * parseInt(a), 1))
}
console.log(persistenceTailRecursive(93))
console.log(persistenceTailRecursive(999))
console.log(persistence(93))
console.log(persistence(999))
There are 2 versions
1 tailRecursive call the same method with the exact signature (preventing stackoverflow in some languages like scala)
2 basic the result is calculated at the end

JS chaining functions

I'm writing a function that should work like this:
checker(3).equals(3) // true
checker(3).not().equals(3) // false
checker(3).not().equals(4) // true
checker(3).not().not().equals(4) // false
The code I came up with:
function checker(num) {
let number = num
return {
not() {
number = !number
return this
},
equals(nmb) {
return number === nmb
}
}
}
I can't wrap my head around what should not() do so as to make checker(num) work as it is supposed to.
You can add another boolean property that changes how equals works depending on it's value.
function checker(num) {
let number = num
let not = false
return {
not() {
not = !not
return this
},
equals(nmb) {
return not ? number !== nmb : number === nmb
}
}
}
console.log(checker(3).equals(3)) // true
console.log(checker(3).not().equals(3)) // false
console.log(checker(3).not().equals(4)) // true
console.log(checker(3).not().not().equals(4)) // false
Maybe somthing like this:
function checker(num) {
let number = num
let beTrue = true;
return {
not() {
beTrue = !beTrue;
return this
},
equals(nmb) {
return (number === nmb) === beTrue;
}
}
}
It seems to fullfil your requirements. Hope it helps
An ES6 approach
const checker=(number, negate)=>{
const neg = negate || false;
return {
not(){
return checker(number, !neg);
},
equals(number2){
if (neg) return number != number2;
return number == number2;
}
}
}
what should not() do so as to make checker(num) work as it is supposed to.
not could return a new checker.
I think i would let the notfunction control the operator, something like
function checker(num) {
let operator = 'equals';
let number = num
return {
not() {
if(operator==='equals')
operator = 'not equals';
else
operator = 'equals';
return this
},
equals(nmb) {
if(operator==='equals')
return number === nmb
else
return number !== nmb
}
}
}
just using a string as operator for clarity, a proberly better solution could be to use a boolean or number value

what does a recursive closure returns to?

I want to write a function (persistence) that takes in a positive parameter num and returns its multiplicative persistence, which is the number of times you must multiply the digits in num until you reach a single digit.
For example:
persistence(39) === 3 // because 3*9 = 27, 2*7 = 14, 1*4=4
// and 4 has only one digit
persistence(999) === 4 // because 9*9*9 = 729, 7*2*9 = 126,
// 1*2*6 = 12, and finally 1*2 = 2
persistence(4) === 0 // because 4 is already a one-digit number
I wrote this:
function persistence(num) {
//code me
var f;
f= countPersistence(num);
var toReturn= f(num); console.log("received value: "+toReturn);
return toReturn;
}
function countPersistence(num){
var count=0;
return function g(num){
var numt=num+"";
numt=numt.split("");
if(numt.length>1){
count++;
for(var i=0; i<numt.length-1; i++){
numt[i+1]=numt[i]*numt[i+1];
}
arguments.callee(numt[numt.length-1]);
}
else
{ console.log("returned value: "+count); return count;}
}
}
As you can see running this code, the returned value of the inner function is not exactly what expected.
Indeed, a function should return to where it is called from, right?. But in this case since it's recursive it is called from itself.
I have no idea how to retrieve the actual value (without using global variable)
You do not return a value when you call your inner function recursively. You could fix it like this (removing the else block and making it common code), so that always the last updated value of count is returned:
function persistence(num) {
//code me
var f;
f= countPersistence(num);
var toReturn= f(num);
return toReturn;
}
function countPersistence(num){
var count=0;
return function g(num){
var numt=num+"";
numt=numt.split("");
if(numt.length>1){
count++;
for(var i=0; i<numt.length-1; i++){
numt[i+1]=numt[i]*numt[i+1];
}
arguments.callee(numt[numt.length-1]);
}
return count;
}
}
console.log(persistence(39)); // 3
console.log(persistence(999)); // 4
console.log(persistence(4)); // 0
But arguments.callee is deprecated, and moreover you are making things overly complicated with nested functions.
You can do it like this:
function persistence(num){
return num < 10 ? 0
: 1 + persistence(String(num).split('').reduce((a, b) => a*b));
}
console.log(persistence(39)); // 3
console.log(persistence(999)); // 4
console.log(persistence(4)); // 0
You are not returning on the recursion line
return arguments.callee(numt[numt.length-1]);
and as I stated in the comments arguments.callee is deprecated so you should use the function name.
return g(numt[numt.length-1]);

for loop unintentionally breaking at if statement

I am trying to determine the largest prime factor of a number by working backwards from the largest possible factor. Once a factor is found, I test to see if it is prime by using the PrimeTest3 function within the original function.
However, it is not giving me the answer I am expecting for the number 13195. When I test the code as shown above using the 'this passed the test' statement, I can see that it is skipping from the first factor found (2639) to the last factor found (5), and strangely, when logging the the result of passing i through PrimeTest3, it shows up as false, even though it had to have been true to pass the if statement in the first place.
var largestPrimeFactor3 = function (num) {
function PrimeTest3(a){
if (a<=1 || a%1!=0)
return false;
limit = Math.ceil(Math.pow(a,.5));
if (a%2==0 || a%3==0)
return false;
if (a==2 || a==3)
return true;
for (i=6;i<limit;i+=6){
if (a%(i-1)==0)
return false;
if (a%(i+1)==0)
return false;
}
return true;
}
for(var i = Math.floor(num/2); i>0; i--){
console.log(i);
if(num % i === 0 && PrimeTest3(i)){
console.log('this passed the test:' + PrimeTest3(i));
return true;
}
}
}
console.log(largestPrimeFactor3(13195));
Would really appreciate any help or clarification. Thanks!!
The for loop inside PrimeTest3 is using the same variable i as the loop in largestPrimeFactor3. You need to declare this variable as local to the internal function, with a var declaration.
var largestPrimeFactor3 = function (num) {
function PrimeTest3(a){
if (a<=1 || a%1!=0)
return false;
limit = Math.ceil(Math.pow(a,.5));
if (a%2==0 || a%3==0)
return false;
if (a==2 || a==3)
return true;
for (var i=6;i<limit;i+=6){
if (a%(i-1)==0)
return false;
if (a%(i+1)==0)
return false;
}
return true;
}
for(var i = Math.floor(num/2); i>0; i--){
console.log(i);
if(num % i === 0 && PrimeTest3(i)){
console.log('this passed the test:' + PrimeTest3(i));
return true;
}
}
}
console.log(largestPrimeFactor3(13195));
You're having unexpected results because you're changing the value of i in PrimeTest3.
if(num % i === 0 && PrimeTest3(i)){ // i changed in PrimeTest3
// now i is not what it was when originally passed in PrimeTest3
console.log('this passed the test:' + PrimeTest3(i));
A fix would be to change:
for (i=6;i<limit;i+=6){
To:
for (var i=6;i<limit;i+=6){
This will localize the i variable to not change the other i variable outside PrimeTest3's function scope.
While you're at it, localize limit to the scope of PrimeTest3 by doing var limit = ... instead of just limit = ....

Unique number counter function?

This undoubtedly already exists but I can't find it anywhere after 20 min of looking.
All I want is a function that counts up so the first time you call uniqueNum() it returns 0, then 1, then 2 etc.
function uniqueNum(){
if (typeof x !== 'number') {
var x = 0;
} else {
x++;
}
return x
}
I don't want any globals or vars outside of the function hopefully.
What I've got always returns 0;
A closure can do that:
var uniqueNum = (function(){
var num = 0;
return function(){
return num++;
}
}());
uniqueNum(); // 0
uniqueNum(); // 1
A "static" variable works too, as suggested in other answers.
You can implement a "static" variable like this:
function uniqueNum() {
return uniqueNum.counter = (uniqueNum.counter || 0)+1;
}
The following will use the function itself for storing the counter:
function uniqueNum() {
if (uniqueNum.x == null) {
uniqueNum.x = 0;
} else {
uniqueNum.x++;
}
return uniqueNum.x;
}
console.log(uniqueNum()); // 0
console.log(uniqueNum()); // 1
console.log(uniqueNum.x); // 1

Categories

Resources