How does the modulus operator handle strings in Javascript - javascript

I know how modulus works in general, but it is not clear to me how the operator handles strings.
Recently, I had to write a script which checks if a name (string) contains an even number of letters. This actually worked, using modulus 2 and checking if result was 1 or 0:
function isNameEven(firstName) {
if (firstName % 2 === 0) {
return true;
}
else {
return false;
}
}
So I'm assuming the letters in the string were counted?

The result is always NaN
const oneLetter = "a";
const twoLetters = "ab";
const threeLetters = "abc";
console.log(oneLetter % 2);
console.log(twoLetters % 2);
console.log(threeLetters % 2);
Your function doesn't work if you pass it a string that can't be implicitly converted to a number that isn't NaN.
function isNameEven(firstName) {
if (firstName % 2 === 0) {
return true;
} else {
return false;
}
}
const oneLetter = "a";
const twoLetters = "ab";
const threeLetters = "abc";
console.log(isNameEven(oneLetter));
console.log(isNameEven(twoLetters));
console.log(isNameEven(threeLetters));
You could check the length property of the string though.
function isNameEven(firstName) {
if (firstName.length % 2 === 0) {
return true;
} else {
return false;
}
}
const oneLetter = "a";
const twoLetters = "ab";
const threeLetters = "abc";
console.log(isNameEven(oneLetter));
console.log(isNameEven(twoLetters));
console.log(isNameEven(threeLetters));

Related

Why is my code returning the else statement and undefined and not the totalBasketballScore?

I really thought I had this code correct. I am trying to calculate basketball score with free throws, 2 pointers and 3 pointers. The output when I console.log the totalBasketballScore ends up being 'All entries must be numbers' and undefined. What do I need to change so I get the score when I put the 3 values in the parameters?
function totalBasketballScore(numberFreeThrows, numberMidRange, numberThreePointers) {
const freeThrows = 1;
const midRange = 2;
const threePointers = 3;
if (typeof numberFreeThrows === 'number' && numberMidRange === 'number' && numberThreePointers === 'number') {
let totalFreeThrows = freeThrows * numberFreeThrows;
let totalMidRange = midRange * numberMidRange;
let totalThreePointers = threePointers * numberThreePointers;
let gameTotal = totalFreeThrows + totalMidRange + totalThreePointers;
return gameTotal;
} else {
console.log('All Entries Must Be a Number');
}
}
console.log(totalBasketballScore(1, 2, 4));
Another approach that can be used is isNaN(). isNaN can be used to check if the value is Not a Number. If isNaN() returns false, the value is a number.
function totalBasketballScore(numberFreeThrows, numberMidRange, numberThreePointers) {
const freeThrows = 1;
const midRange = 2;
const threePointers = 3;
if(isNaN(numberFreeThrows)=== false && isNaN(numberMidRange)=== false && isNaN(numberThreePointers)=== false) {
let totalFreeThrows = freeThrows * numberFreeThrows;
let totalMidRange = midRange * numberMidRange;
let totalThreePointers = threePointers * numberThreePointers;
let gameTotal = totalFreeThrows + totalMidRange + totalThreePointers;
return gameTotal;
} else {
console.log('All Entries Must Be a Number');
}
}
console.log(totalBasketballScore(1, 2, 4));
You should use typeof per each parameter, like this:
if(typeof numberFreeThrows === 'number' && typeof numberMidRange === 'number' && typeof numberThreePointers === 'number'){
} else {
}

Error in true false output in Array Problem

Here's the question:
A Narcissistic Number is a positive number which is the sum of its own digits, each raised to the power of the number of digits in a given base. In this Kata, we will restrict ourselves to decimal (base 10).
For example, take 153 (3 digits), which is narcisstic:
1^3 + 5^3 + 3^3 = 1 + 125 + 27 = 153
Your code must return true or false (not 'true' and 'false') depending upon whether the given number is a Narcissistic number in base 10.
My Code is:
function narcissistic(value) {
let vLen = value.length;
let sum = 0;
for (let i = 0; i < vLen; i++) {
sum += Math.pow(value[i], vLen);
}
if (sum == value) {
return true;
} else {
return false;
}
}
But I'm getting errors. What should I do?
Numbers don't have .length, convert to string first
vLen[i], you cant treat a number as array, again, convert to string to use that syntax.
The return can be simplefied to return (sum === value);
function narcissistic(value) {
let sVal = value.toString();
let vLen = sVal.length;
let sum = 0;
for (let i = 0; i < vLen; i++) {
sum += Math.pow(sVal[i], vLen);
}
return (sum === value);
}
console.log(narcissistic(153));
console.log(narcissistic(111));
Well... There are several things wrong with this code, but I think there is mostly a problem with the types of your input.
I'll show you how you can cast the types of your input to make sure you work with the types you need:
Also... You should try to avoid using the == operator and try to use === instead (same goes for != and !==), because the == and != don't try to match the types, resulting in sometimes unpredictable results
function narcissistic(value) {
valueStr = String(value);
let vLen = valueStr.length;
let sum = 0;
for (let i = 0; i < vLen; i++) {
sum += Number(valueStr[i]) ** vLen;
}
if (sum === value) {
return true;
} else {
return false;
}
}
if(narcissistic(153)) {
console.log("narcissistic(153) is true!") // expected value: true
}
All the first 9 digits from 1 to 9 is Narcissistic number as there length is 1 and there addition is always same.
So, first we are checking weather the number is greater than 9 or not.
if(num>9) =>false than it's a narcissistic number.
-if(num>9) =>true than we have to split number into digits for that I have used x = num.toString().split('');. Which is first converting number to String and than using split() function to split it.
Than , we are looping through each digit and digitsSum += Math.pow(Number(digit), x.length); adding the power of digit to const isNarcissistic = (num) => { let x = 0; let digitsSum.
at the end, we are comparing both num & digitsSum if there are matched than number is narcissistic else not.
const isNarcissistic = (num) => {
let x = 0;
let digitsSum = 0;
if (num > 9) {
x = num.toString().split('');
x.forEach(digit => {
digitsSum += Math.pow(Number(digit), x.length);
});
if (digitsSum == num) {
return true;
} else {
return false;
}
} else {
return true;
}
}
console.log(isNarcissistic(153));
console.log(isNarcissistic(1634));
console.log(isNarcissistic(1433));
console.log(isNarcissistic(342));

how to check 3 possibilities using only 2 if statements

Create a function that receives an integer as an argument and returns a string such as:
if the number is multiple of 4, return "Foo"
if the number is multiple of 7, return "Bar"
if the number is multiple of 4 and 7, return "FooBar"
This can be done using 3 if statements like below but can this be done only using 2 if statements?
const intToStr = (intVal) => {
if (intVal % 4 == 0 && intVal % 7 == 0) {
return "FooBar";
}
if (intVal % 7 == 0) {
return "Bar";
}
if (intVal % 4 == 0) {
return "Foo";
}
}
console.log(intToStr(4*7));
console.log(intToStr(7));
console.log(intToStr(4));
Yes, it can be done with just 2 if statements.
const intToStr = (intVal) => {
let str = '';
if (intVal % 4 === 0) {
str += "Foo";
}
if (intVal % 7 === 0) {
str += "Bar";
}
return str;
}
console.log(intToStr(4*7));
console.log(intToStr(7));
console.log(intToStr(4));
Remember that you can sum strings. As value returned in case input is dividable by the same values as in two other ifs, you can just add strings in case input fulfills that condition.
To make it more clear:
var output = '';
if(intVal % 4 === 0)
{
output = output + 'Foo' ;
}
if(intVal % 7 === 0)
{
output = output + 'Bar' ;
}
return output;
That way you have two conditions and their cumulative values returned.

Convert LaTeX to dynamic Javascript function

I have a user input for an equation - this input generates LaTeX code using a separate API which I did not code (namely, Mathquill, not that it matters).
My problem is best illustrated by an example: suppose the LaTeX code generated from the user input was this:
x^2+3x-10sin\left(2x\right)
How would I convert this (on the fly of course) into a JavaScript function which, hard-coded, would look like this:
function(x) {
return Math.pow(x, 2) + 3 * x - 10 * Math.sin(2 * x);
}
Are there any APIs or am I looking at writing something which will interpret the LaTeX symbols and make a function, somehow? Or what?
I have written a (by no means general purpose) solution, heavily based on George's code.
Here it is:
var CALC_CONST = {
// define your constants
e: Math.E,
pi: Math.PI
};
var CALC_NUMARGS = [
[/^(\^|\*|\/|\+|\-)$/, 2],
[/^(floor|ceil|(sin|cos|tan|sec|csc|cot)h?)$/, 1]
];
var Calc = function(expr, infix) {
this.valid = true;
this.expr = expr;
if (!infix) {
// by default treat expr as raw latex
this.expr = this.latexToInfix(expr);
}
var OpPrecedence = function(op) {
if (typeof op == "undefined") return 0;
return op.match(/^(floor|ceil|(sin|cos|tan|sec|csc|cot)h?)$/) ? 10
: (op === "^") ? 9
: (op === "*" || op === "/") ? 8
: (op === "+" || op === "-") ? 7
: 0;
}
var OpAssociativity = function(op) {
return op.match(/^(floor|ceil|(sin|cos|tan|sec|csc|cot)h?)$/) ? "R" : "L";
}
var numArgs = function(op) {
for (var i = 0; i < CALC_NUMARGS.length; i++) {
if (CALC_NUMARGS[i][0].test(op)) return CALC_NUMARGS[i][1];
}
return false;
}
this.rpn_expr = [];
var rpn_expr = this.rpn_expr;
this.expr = this.expr.replace(/\s+/g, "");
// This nice long regex matches any valid token in a user
// supplied expression (e.g. an operator, a constant or
// a variable)
var in_tokens = this.expr.match(/(\^|\*|\/|\+|\-|\(|\)|[a-zA-Z0-9\.]+)/gi);
var op_stack = [];
in_tokens.forEach(function(token) {
if (/^[a-zA-Z]$/.test(token)) {
if (CALC_CONST.hasOwnProperty(token)) {
// Constant. Pushes a value onto the stack.
rpn_expr.push(["num", CALC_CONST[token]]);
}
else {
// Variables (i.e. x as in f(x))
rpn_expr.push(["var", token]);
}
}
else {
var numVal = parseFloat(token);
if (!isNaN(numVal)) {
// Number - push onto the stack
rpn_expr.push(["num", numVal]);
}
else if (token === ")") {
// Pop tokens off the op_stack onto the rpn_expr until we reach the matching (
while (op_stack[op_stack.length - 1] !== "(") {
rpn_expr.push([numArgs(op_stack[op_stack.length - 1]), op_stack.pop()]);
if (op_stack.length === 0) {
this.valid = false;
return;
}
}
// remove the (
op_stack.pop();
}
else if (token === "(") {
op_stack.push(token);
}
else {
// Operator
var tokPrec = OpPrecedence(token),
headPrec = OpPrecedence(op_stack[op_stack.length - 1]);
while ((OpAssociativity(token) === "L" && tokPrec <= headPrec) ||
(OpAssociativity(token) === "R" && tokPrec < headPrec)) {
rpn_expr.push([numArgs(op_stack[op_stack.length - 1]), op_stack.pop()]);
if (op_stack.length === 0) break;
headPrec = OpPrecedence(op_stack[op_stack.length - 1]);
}
op_stack.push(token);
}
}
});
// Push all remaining operators onto the final expression
while (op_stack.length > 0) {
var popped = op_stack.pop();
if (popped === ")") {
this.valid = false;
break;
}
rpn_expr.push([numArgs(popped), popped]);
}
}
/**
* returns the result of evaluating the current expression
*/
Calc.prototype.eval = function(x) {
var stack = [], rpn_expr = this.rpn_expr;
rpn_expr.forEach(function(token) {
if (typeof token[0] == "string") {
switch (token[0]) {
case "var":
// Variable, i.e. x as in f(x); push value onto stack
//if (token[1] != "x") return false;
stack.push(x);
break;
case "num":
// Number; push value onto stack
stack.push(token[1]);
break;
}
}
else {
// Operator
var numArgs = token[0];
var args = [];
do {
args.unshift(stack.pop());
} while (args.length < numArgs);
switch (token[1]) {
/* BASIC ARITHMETIC OPERATORS */
case "*":
stack.push(args[0] * args[1]);
break;
case "/":
stack.push(args[0] / args[1]);
break;
case "+":
stack.push(args[0] + args[1]);
break;
case "-":
stack.push(args[0] - args[1]);
break;
// exponents
case "^":
stack.push(Math.pow(args[0], args[1]));
break;
/* TRIG FUNCTIONS */
case "sin":
stack.push(Math.sin(args[0]));
break;
case "cos":
stack.push(Math.cos(args[0]));
break;
case "tan":
stack.push(Math.tan(args[0]));
break;
case "sec":
stack.push(1 / Math.cos(args[0]));
break;
case "csc":
stack.push(1 / Math.sin(args[0]));
break;
case "cot":
stack.push(1 / Math.tan(args[0]));
break;
case "sinh":
stack.push(.5 * (Math.pow(Math.E, args[0]) - Math.pow(Math.E, -args[0])));
break;
case "cosh":
stack.push(.5 * (Math.pow(Math.E, args[0]) + Math.pow(Math.E, -args[0])));
break;
case "tanh":
stack.push((Math.pow(Math.E, 2*args[0]) - 1) / (Math.pow(Math.E, 2*args[0]) + 1));
break;
case "sech":
stack.push(2 / (Math.pow(Math.E, args[0]) + Math.pow(Math.E, -args[0])));
break;
case "csch":
stack.push(2 / (Math.pow(Math.E, args[0]) - Math.pow(Math.E, -args[0])));
break;
case "coth":
stack.push((Math.pow(Math.E, 2*args[0]) + 1) / (Math.pow(Math.E, 2*args[0]) - 1));
break;
case "floor":
stack.push(Math.floor(args[0]));
break;
case "ceil":
stack.push(Math.ceil(args[0]));
break;
default:
// unknown operator; error out
return false;
}
}
});
return stack.pop();
};
Calc.prototype.latexToInfix = function(latex) {
/**
* function: converts latex notation to infix notation (human-readable, to be converted
* again to prefix in order to be processed
*
* Supported functions / operators / notation:
* parentheses, exponents, adding, subtracting, multipling, dividing, fractions
* trigonometric (including hyperbolic) functions, floor, ceil
*/
var infix = latex;
infix = infix
.replace(/\\frac{([^}]+)}{([^}]+)}/g, "($1)/($2)") // fractions
.replace(/\\left\(/g, "(") // open parenthesis
.replace(/\\right\)/g, ")") // close parenthesis
.replace(/[^\(](floor|ceil|(sin|cos|tan|sec|csc|cot)h?)\(([^\(\)]+)\)[^\)]/g, "($&)") // functions
.replace(/([^(floor|ceil|(sin|cos|tan|sec|csc|cot)h?|\+|\-|\*|\/)])\(/g, "$1*(")
.replace(/\)([\w])/g, ")*$1")
.replace(/([0-9])([A-Za-z])/g, "$1*$2")
;
return infix;
};
Example of usage:
var latex = "e^x+\\frac{2}{3}x-4sin\\left(x\\right)";
var calc = new Calc(latex);
var test = calc.eval(3.5); // 36.85191820278412
Well, you're going to have to decide on exactly which operations you support at some point. After that it shouldn't be hard to implement an evaluator using a parser like the Shunting-yard algorithm to yield a representation of the equation that is more easy to evaluate (that is, an abstract syntax tree).
I have a simple example of this kind of evaluator written in JavaScript at: http://gjp.cc/projects/logic_tables.html It takes logical expressions like !(p ^^ q) & ~(p || q) instead of LaTeX, but it might still be a useful example for you.
The JavaScript (http://gpittarelli.com/projects/logic_tables.js):
var CALCULATOR_CONSTANTS = {
/* True values. */
't': true,
'true': true,
/* False values. */
'c': false,
'false': false
};
// The Calculator constructor takes an expression and parses
// it into an AST (refered to as rpn_expr)
var Calculator = function(expr) {
this.valid = true;
var OpPrecedence = function(op) {
return (op === "!" || op === "~")? 9
: (op === "&" || op === "&&")? 7
: (op === "|" || op === "||" )? 7
: (op === "^" || op === "^^")? 7
: (op === "->")? 5
: (op === "<-")? 5
: 0;
}
var OpAssociativity = function(op) {
return (op === "!" || op === "~")? "R":"L";
}
this.rpn_expr = [];
this.variables = [];
var rpn_expr = this.rpn_expr;
var variables = this.variables;
expr = expr.replace(/\s+/g, "");
// This nice long regex matches any valid token in a user
// supplied expression (e.g. an operator, a constant or
// a variable)
var in_tokens = expr.match(/(\!|\~|\|+|&+|\(|\)|\^+|(->)|(<-)|[a-zA-Z0-9]+)/gi);
var op_stack = [];
in_tokens.forEach(function(token) {
if (/[a-zA-Z0-9]+/.test(token)) {
if (CALCULATOR_CONSTANTS.hasOwnProperty(token)) {
// Constant. Pushes a boolean value onto the stack.
rpn_expr.push(CALCULATOR_CONSTANTS[token]);
} else {
// Variables
rpn_expr.push(token);
variables.push(token);
}
}
else if (token === ")") {
// Pop tokens off the op_stack onto the rpn_expr until we
// reach the matching (
while (op_stack[op_stack.length-1] !== "(") {
rpn_expr.push(op_stack.pop());
if (op_stack.length === 0) {
this.valid = false;
return;
}
}
// Remove the (
op_stack.pop();
}
else if (token === "(") {
op_stack.push(token);
}
else {
// Operator
var tokPrec = OpPrecedence( token ),
headPrec = OpPrecedence( op_stack[op_stack.length-1] );
while ((OpAssociativity(token) === "L" && tokPrec <= headPrec)
|| (OpAssociativity(token) === "R" && tokPrec < headPrec) ) {
rpn_expr.push(op_stack.pop());
if (op_stack.length === 0)
break;
headPrec = OpPrecedence( op_stack[op_stack.length-1] );
}
op_stack.push(token);
}
});
// Push all remaining operators onto the final expression
while (op_stack.length > 0) {
var popped = op_stack.pop();
if (popped === ")") {
this.valid = false;
break;
}
rpn_expr.push(popped);
}
this.optimize();
}
/** Returns the variables used in the currently loaded expression. */
Calculator.prototype.getVariables = function() { return this.variables; }
Calculator.prototype.optimize = function() {
// Single-pass optimization, mainly just to show the concept.
// Looks for statements that can be pre computed, eg:
// p | true
// q & false
// r ^ r
// etc...
// We do this by reading through the RPN expression as if we were
// evaluating it, except instead rebuild it as we go.
var stack = [], rpn_expr = this.rpn_expr;
rpn_expr.forEach(function(token) {
if (typeof token === "boolean") {
// Constant.
stack.push(token);
} else if (/[a-zA-Z0-9]+/.test(token)) {
// Identifier - push onto the stack
stack.push(token);
} else {
// Operator - The actual optimization takes place here.
// TODO: Add optimizations for more operators.
if (token === "^" || token === "^^") {
var a = stack.pop(), b = stack.pop();
if (a === b) { // p ^ p == false
stack.push(false);
} else {
stack.push(b);
stack.push(a);
stack.push(token);
}
} else if (token === "|" || token === "||") {
var a = stack.pop(), b = stack.pop();
if (a === true || b === true) {
// If either of the operands is a tautology, OR is
// also a tautology.
stack.push(true);
} else if (a === b) { // p | p == p
stack.push(a);
} else {
stack.push(b);
stack.push(a);
stack.push(token);
}
} else if (token === "!" || token === "~") {
var p = stack.pop();
if (typeof p === "boolean") {
// NOT of a constant value can always
// be precalculated.
stack.push(!p);
} else {
stack.push(p);
stack.push(token);
}
} else {
stack.push(token);
}
}
});
this.rpn_expr = stack;
}
/**
* returns the result of evaluating the current expressions
* with the passed in <code>variables</code> object. <i>variables</i>
* should be an object who properties map from key => value
*/
Calculator.prototype.eval = function(variables) {
var stack = [], rpn_expr = this.rpn_expr;
rpn_expr.forEach(function(token) {
if (typeof token === "boolean") {
// Constant.
stack.push(token);
} else if (/[a-zA-Z0-9]+/.test(token)) {
// Identifier - push its boolean value onto the stack
stack.push(!!variables[token]);
} else {
// Operator
var q = stack.pop(), p = stack.pop();
if (token === "^" || token === "^^") {
stack.push((p? 1:0) ^ (q? 1:0));
} else if (token === "|" || token === "||") {
stack.push(p || q);
} else if (token === "&" || token === "&&") {
stack.push(p && q);
} else if (token === "!" || token === "~") {
stack.push(p);
stack.push(!q);
} else if (token === "->") {
stack.push((!p) || q);
} else if (token === "<-") {
stack.push((!q) || p);
}
}
});
return stack.pop()? 1:0;
};
Maybe you could try LatexJS. LatexJS is an API service that I put together in order to convert latex math notation into Javascript functions. So you would input latex expressions and get back Javascript functions dynamically. For example:
Input
x^2+3x-10sin\left(2x\right)
Output
{
"func": "(x)=>{return Math.pow(x,2)+3*x-10*Math.sin(2*x)};",
"params": ["x"]
}
Evaluation
> func = (x)=>{return Math.pow(x,2)+3*x-10*Math.sin(2*x)};
> func(2)
< 17.56802495307928

Define isEven in terms of isOdd in JavaScript

I'm working on a Codecademy exercise:
Remember the functions isOdd and isEven from Exercise 3.4?
We'd like you to code them here again! But this time, the aim is to define one function in terms of the other using the ! symbol.
Define isOdd, and then define isEven in terms of isOdd.
I tried a few different ways that I though would work,
like console.log(!isOdd(1));
and
(n !% 2 ===),
none of them are right.
Here is the code that I have:
var isOdd = function (n)
{
if (n % 2 ===0)
{
return false;
} else {
return true;
}
};
var isEven =function (n)
{
if (n % 2 === 0)
{
return true;
} else {
return false;
}
};
console.log(isOdd(1));
console.log(isOdd(2));
console.log(isOdd(999));
It's straightforward:
var isEven = function (n)
{
return !isOdd(n);
}
var isOdd = function(n){
if (n % 2 !== 0) {
return true;
} else {
return false;}
};
var isEven = function(n){
return !isOdd(n) ;
};
console.log(isOdd(11));
var isOdd = function(){
if(isEven){
return isEven();
} else {
return false;
}
};
var isEven = function (){
return true;
};
console.log(isOdd());
These answers are wrong by definition.
A number is an integer and float.
All submitted answers are good for integers.
Here are proper tailored responses.
function isEven(n) { // covers all
return (n).toString(2).endsWith(‘0’) // binary format
}
function isEven_integer(n) {
return (n & 1) === 0;
}
function isEven_float(n) {
// floats only, but works on integers.// faster for floats
return ((n).toString()[(n).toString().length-1] % 2) === 0; // base 10
}
var isOdd = function(n)
{
if(n%2 !== 0)
{ return ("odd");}
};
var isEven = function (n)
{
return !isOdd(n);
};
console.log(isEven(8));

Categories