How to find degree of a polynomial equation in JavaScript? - javascript

I want to find the degree of polynomial equation
den = a^2+a+1
The output of equation should be
2
or
den=a^2+a^3+a+1
The output of the equation should be
3
But I am unable to find the correct solution for JavaScript

You can use a regexp to get all the exponents and calculate the maximum
var r = /a(\^\d)?/g;
var t = 'a^2+a^3+a+1';
var order = t.match(r).reduce((m, d) => {
var ex = d.split('^')[1];
if(ex && (ex > m)){
return ex;
}
return m;
},0);
console.log(order); // Logs '3'
You can also do the same without using Array.prototype.reduce (have used a simple for loop and avoided ES6 syntax for simplicity)
var r = /a(\^\d)?/g;
var t = 'a^2+a^3+a+1';
var order = 0;
var matches = t.match(r);
for(var i = 0, j = matches.length ; i< j; i++){
var exp = matches[i].split('^')[1];
if(exp && (exp > order)){
order = exp;
}
}
console.log(order); // Logs '3'

Related

Optimal verification if a number is Palindrom in JS

I have a problem I am sitting on for the past few days.
I want to write an optimal (in JS) program for verifying if a number is a Palindrome.
My current approach:
function isPalidrom2(pali){
//MOST time consuming call - I am splitting the digit into char array.
var digits = (""+pali).split("");
//To get the length of it.
var size = digits.length;
var isPali = true;
for(var i = 0; i<Math.floor(size/2); i++){
//I am comparing digits (first vs last, second vs last-1, etc.) one by one, if ANY of the pars is not correct I am breaking the loop.
if(parseInt(digits[i]) != parseInt(digits[size-i-1])){
isPali = false;
break;
}
}
return isPali;
}
It's not optimal. The biggest amount of time I am waisting is the change from INT to STRING.
And I am out of ideas
- I tried to understand the BIT operators but I can't.
- I tried to google and look for alternative approaches - but I can't find anything.
- I tried to play with different algorithms - but this one is the fastest I was able to apply.
So in short - my question is:
"how can I make it faster?"
EDIT:
So the task I want to solve:
Find all of the prime numbers within the range of all five digit numbers.
Among all of the multiplies (i*j) they are between them, find the most significant palindrome.
My current approach:
function isPrime(number){
var prime = true;
var i
for(i = 2; i<= number/2; i++){
if((number%i)==0){
prime = false;
break;
}
}
return prime;
}
function get5DigitPrimeNr(){
var a5DigitsPrime = [];
var i;
for(i = 10000; i<100000; i++){
if(isPrime(i)){
a5DigitsPrime.push(i)
}
}
return a5DigitsPrime;
}
function isPalidrom(pali){
var digits = (""+pali).split("");
//we check if first and last are the same - if true, we can progress
size = digits.length;
return
(digits[0]==digits[size-1]) &&
(parseInt(digits.slice(1, Math.floor(size/2)).join("")) ==
parseInt(digits.reverse().slice(1, Math.floor(size/2)).join("")))
}
function isPalidrom2_48s(str) {
var str = str.toString();
const lower = str.substr(0, Math.floor(str.length / 2));
const upper = str.substr(Math.ceil(str.length / 2));
return lower.split("").reverse().join("") === upper;
}
function isPalidrom_22s(pali){
var digits = (""+pali).split("");
var size = digits.length;
for(var i = 0; i<Math.floor(size/2); i++){
//console.log("I am comparing: "+i+", and "+(size-i-1)+" elements in array")
//console.log("I am comparing digit: "+digits[i]+", and "+digits[(size-i-1)]+"")
if(digits[i] !== digits[size-i-1]){
//console.log('nie sa rowne, koniec')
return false;
}
}
return true;
}
function isPalidrom2_80s(pali){
return parseInt(pali) == parseInt((""+pali).split("").reverse().join(""))
}
function runme(){
var prime5digits = get5DigitPrimeNr();
var size = prime5digits.length;
var max = 0;
var message = "";
for(var i = 0; i<size; i++){
for(var j = 0; j<size; j++){
var nr = prime5digits[i]*prime5digits[j];
if(nr>max && isPalidrom2(nr)){
max = nr;
message = 'biggest palidrome nr: '+nr+', made from numbers: '+prime5digits[i]+' x '+prime5digits[j];
}
}
}
console.log(message)
}
function timeMe(){
var t0 = performance.now();
runme();
var t1 = performance.now();
console.log("Function took " + millisToMinutesAndSeconds(t1 - t0) + " s to find the perfect palindrom.")
}
//helper functons:
function millisToMinutesAndSeconds(millis) {
var minutes = Math.floor(millis / 60000);
var seconds = ((millis % 60000) / 1000).toFixed(0);
return minutes + ":" + (seconds < 10 ? '0' : '') + seconds;
}
To keep the spirit of you code, you could exit the loop with return instead of break and use the string directly without converting to an array. Strings have, as arrays, the possibility of an access single character with an index.
function isPalidrom2(value) {
var digits = value.toString(),
length = digits.length,
i, l;
for (i = 0, l = length >> 1; i < l; i++) {
if (digits[i] !== digits[length - i - 1]) {
return false;
}
}
return true;
}
console.log(isPalidrom2(1));
console.log(isPalidrom2(12));
console.log(isPalidrom2(1221));
console.log(isPalidrom2(123));
The fastest is probably to rely on javascripts native methods:
function isPalindrome(str) {
const lower = str.substr(0, Math.floor(str.length / 2));
const upper = str.substr(Math.ceil(str.length / 2));
return lower.split("").reverse().join("") === upper;
}
Or leave away all unneccessary conversions from your code:
function isPlaindrome(str) {
const half = str.length / 2;
for(var i = 0; i < half; i++)
if(str[i] !== str[str.length - i - 1])
return false;
return true;
}
If you're trying to speed things up, you could shave a few more seconds off by optimising your isPrime(n) function.
You don't need to check every factor, only the prime factors less than sqrt(n)
If you check every number from 2 to 99999 in ascending order, you can store the results as you go, so you don't need to keep re-calculating the list of previous primes
Something like this:
var savedPrimes = [2]
function isPrime(n){
// call this method with increasing values of n (starting at 2), saving primes as we go,
// so we can safely assume that savedPrimes contains all primes less than n
for(var i=0; i<savedPrimes.length; i++)
{
var f = savedPrimes[i];
if ((n % f) == 0)
return false; // found a factor
if (f*f>=n)
break; // stop checking after f >= sqrt(n)
}
// no prime factors - we found a new prime
savedPrimes.push(n);
return true;
}
function get5DigitPrimeNr(){
var a5DigitsPrime = [];
var i;
// first find all the primes less than 10000
for(i = 3; i<10000; i++){
isPrime(i);
}
// now find (and keep) the rest of the primes up to 99999
for(i = 10000; i<100000; i++){
if(isPrime(i)){
a5DigitsPrime.push(i)
}
}
return a5DigitsPrime;
}
EDIT - when I run your code with this method, I get a time of 10 sec
Code :
There are multiple methods that you can use (dunno if they are optimal) :
Palindrom = _ => (_=''+_) === [..._].sort(_=>1).join``
Some more :
let isPalindrome = __ => (_=(__=__+'').length)==0||_==1?!0:__[0]==__.slice(-1)?isPalindrome(__.slice(1,-1)):!1
let isPalindrome = (s,i) => (i=i||0)<0||i>=(s=''+s).length>>1||s[i]==s[s.length-1-i]&&isPalindrome(s,++i);
let isPalindrome = (str) => {
var len = ~~((str=str+'').length / 2);
for (var i = 0; i < len; i++)
if (str[i] !== str[str.length - i - 1])
return false;
return true;
}
Updated now takes numbers as input

Create complex SVG without intermediate strings

I'm creating/editing a lot (100s to 1000s) of SVG path elements, with integer coordinates, in real time in response to user input (dragging).
var pathElement = document.createElementNS('http://www.w3.org/2000/svg', 'path');
var coords = [[0,0], [1,0], [1,1], [0,1]]; // In real case can be list of 1000s, dynamically generated
var d = '';
for (var i = 0; i < coords.length; ++i) {
d += (i == 0 ? 'M' : 'L') + coords[i][0] + ',' + coords[i][1];
}
d += 'z';
pathElement.setAttributeNS(null, 'd', d);
I can and do pool the path elements, so it minimises creation of objects + garbage in that respect. However, it seems to be that a lot of intermediate strings are created with the repeated use of +=. Also, it seems a bit strange to have the coordinates as numbers, convert them to strings, and then the system has to parse them back into numbers internally.
This seems a bit wasteful, and I fear jank since the above is repeated during dragging for every mousemouse. Can any of the above be avoided?
Context: this is part of a http://projections.charemza.name/
, source at https://github.com/michalc/projections, that can rotate the world map before applying the Mercator projection to it.
Try this:
var pathElement = document.createElementNS('http://www.w3.org/2000/svg', 'path');
var coords = [[0,0], [1,0], [1,1], [0,1]]; // In real case can be list of 1000s, dynamically generated
var d = [];
for (var i = 0; i < coords.length; ++i) {
d.push((i == 0 ? 'M' : 'L') + coords[i][0] + ',' + coords[i][1]);
}
d.push('z');
pathElement.setAttributeNS(null, 'd', d.join(''));
There is a method, using Uint8Array and TextDecoder that seems faster than string concatenation in Firefox, but slower than string concatenation in Chrome: https://jsperf.com/integer-coordinates-to-svg-path/1.
Intermediate strings are not created, but it does create a Uint8Array (a view on an a re-useable ArrayBuffer)
You can...
Manually find the ASCII characters from a number
Set the characters in an Uint8Array
Use new TextDecoder.decode(.... to get a Javascript string from the buffer
As below
// Each coord pair is 6 * 2 chars (inc minuses), commas, M or L, and z for path
var maxCoords = 1024 * 5;
var maxChars = maxCoords * (2 + 6 + 1 + 1) + 1
var coordsString = new Uint8Array(maxChars);
var ASCII_ZERO = 48;
var ASCII_MINUS = 45;
var ASCII_M = 77;
var ASCII_L = 76;
var ASCII_z = 122;
var ASCII_comma = 44;
var decoder = new TextDecoder();
var digitsReversed = new Uint8Array(6);
function concatInteger(integer, string, stringOffset) {
var newInteger;
var asciiValue;
var digitValue;
var offset = 0;
if (integer < 0) {
string[stringOffset] = ASCII_MINUS;
++stringOffset;
}
integer = Math.abs(integer);
while (integer > 0 || offset == 0) {
digitValue = integer % 10;
asciiValue = ASCII_ZERO + digitValue;
digitsReversed[offset] = asciiValue;
++offset;
integer = (integer - digitValue) / 10;
}
for (var i = 0; i < offset; ++i) {
string[stringOffset] = digitsReversed[offset - i - 1];
++stringOffset
}
return stringOffset;
}
var pathElement = document.createElementNS('http://www.w3.org/2000/svg', 'path');
var coordsStringOffset = 0;
var coords = [[0,0], [1,0], [1,1], [0,1]]; // In real case can be list of 1000s, dynamically generated
for (var i = 0; i < coords.length; ++i) {
coordsString[coordsStringOffset] = (i == 0) ? ASCII_M : ASCII_L;
++coordsStringOffset;
coordsStringOffset = concatInteger(coords[i][0], coordsString, coordsStringOffset);
coordsString[coordsStringOffset] = ASCII_comma
++coordsStringOffset;
coordsStringOffset = concatInteger(coords[i][1], coordsString, coordsStringOffset);
}
coordsString[coordsStringOffset] = ASCII_z;
++coordsStringOffset;
var d = decoder.decode(new Uint8Array(coordsString.buffer, 0, coordsStringOffset));
pathElement.setAttributeNS(null, 'd', d);

Sequential strings javascript

I'm stuck on sequential string generation, the last iteration of the code below, is trying to return ac.
var charcode = 'abcdefghijklmnopqrstuvwxyz0123456789_';
var arr = [];
var len = 1;
var current = 0;
for(var i = 0; i < 40; i++) {
if(current == charcode.length) {
current = 0
len++
}
var tmpStr = ''
for(var l = 0; l < len; l++) {
tmpStr = tmpStr + charcode[current];
}
console.log(tmpStr)
current++
}
However, it produces cc.
Sorry, somehow deleted the intended output
a, b, c ... aa, ab, ac ... ba, bc, bb ... ∞
My current understanding suggests within the l < len loop I should check if len > 1 and if so break out and loop for the current charcode[x] but I just can't wrap my head around breaking in and out as it grows.
You can do it like this:
var charcode = 'abcdefghijklmnopqrstuvwxyz0123456789_';
var arr = [];
var len = 0;
var current = 0;
for(var i = 0; i < 40; i++) {
if(current == charcode.length) {
current = 0;
len++;
}
var tmpStr = (len===0) ? '' : charcode[len-1];
tmpStr = tmpStr + charcode[current];
current++;
console.log(tmpStr);
}
In brief, you didn't need a second loop, but an iteration instead (which is achieved through charcode[len-1]).
JS Bin here.
UPDATE
If you need a continuos loop until the very end of the charset, you can use this:
This one introduces a third variable (digits) to the iteration and choses a .substr() instead of a single character out of the charset, so that everytime the end of the charset is reached, another digit will be added. The variable called x sets the limit. I have tried 4000 and it looks like it is working.
var charcode = 'abcdefghijklmnopqrstuvwxyz0123456789_',
arr = [],
len = 0,
digits = 2,
current = 0,
tmpStr = '';
var x = 4000;
for(var i=0; i<x; i++) {
if(current === charcode.length) {
current = 0;
len++;
if(tmpStr.substr(0,1) === charcode.substr(-digits,1) || tmpStr === charcode.substr(-1) + '' + charcode.substr(-1)) {
len = 1;
digits++;
}
}
if(digits === charcode.length) {
console.log(charcode);
console.log(i + ' results found');
break;
}
tmpStr = (len===0) ? '' : charcode.substr([len-1], digits-1);
tmpStr += charcode[current];
current++;
console.log(tmpStr);
}
Final JS Bin here.
Unless I'm failing to understand your question, which is highly likely, functional programming solves this problem in an incredibly easy way
const stringSequence = xs =>
flatMap (x => map (add (x)) (xs)) (xs);
let chars = 'abcdefghijklmnopqrstuvwxyz0123456789_'
console.log (stringSequence (chars));
// ["aa","ab","ac","ad","ae","af","ag","ah","ai","aj","ak","al","am","an","ao","ap","aq","ar","as","at","au","av","aw","ax","ay","az","a0","a1","a2","a3","a4","a5","a6","a7","a8","a9","a_","ba","bb","bc","bd","be","bf","bg","bh","bi","bj","bk","bl","bm","bn","bo","bp","bq","br","bs","bt","bu","bv","bw","bx","by","bz","b0","b1","b2","b3","b4","b5","b6","b7","b8","b9","b_","ca","cb","cc","cd","ce","cf","cg","ch","ci","cj","ck","cl","cm","cn","co","cp","cq","cr","cs","ct","cu","cv","cw","cx","cy","cz","c0","c1","c2","c3","c4","c5","c6","c7","c8","c9","c_","da","db","dc","dd","de","df","dg","dh","di","dj","dk","dl","dm","dn","do","dp","dq","dr","ds","dt","du","dv","dw","dx","dy","dz","d0","d1","d2","d3","d4","d5","d6","d7","d8","d9","d_","ea","eb","ec","ed","ee","ef","eg","eh","ei","ej","ek","el","em","en","eo","ep","eq","er","es","et","eu","ev","ew","ex","ey","ez","e0","e1","e2","e3","e4","e5","e6","e7","e8","e9","e_","fa","fb","fc","fd","fe","ff","fg","fh","fi","fj","fk","fl","fm","fn","fo","fp","fq","fr","fs","ft","fu","fv","fw","fx","fy","fz","f0","f1","f2","f3","f4","f5","f6","f7","f8","f9","f_","ga","gb","gc","gd","ge","gf","gg","gh","gi","gj","gk","gl","gm","gn","go","gp","gq","gr","gs","gt","gu","gv","gw","gx","gy","gz","g0","g1","g2","g3","g4","g5","g6","g7","g8","g9","g_","ha","hb","hc","hd","he","hf","hg","hh","hi","hj","hk","hl","hm","hn","ho","hp","hq","hr","hs","ht","hu","hv","hw","hx","hy","hz","h0","h1","h2","h3","h4","h5","h6","h7","h8","h9","h_","ia","ib","ic","id","ie","if","ig","ih","ii","ij","ik","il","im","in","io","ip","iq","ir","is","it","iu","iv","iw","ix","iy","iz","i0","i1","i2","i3","i4","i5","i6","i7","i8","i9","i_","ja","jb","jc","jd","je","jf","jg","jh","ji","jj","jk","jl","jm","jn","jo","jp","jq","jr","js","jt","ju","jv","jw","jx","jy","jz","j0","j1","j2","j3","j4","j5","j6","j7","j8","j9","j_","ka","kb","kc","kd","ke","kf","kg","kh","ki","kj","kk","kl","km","kn","ko","kp","kq","kr","ks","kt","ku","kv","kw","kx","ky","kz","k0","k1","k2","k3","k4","k5","k6","k7","k8","k9","k_","la","lb","lc","ld","le","lf","lg","lh","li","lj","lk","ll","lm","ln","lo","lp","lq","lr","ls","lt","lu","lv","lw","lx","ly","lz","l0","l1","l2","l3","l4","l5","l6","l7","l8","l9","l_","ma","mb","mc","md","me","mf","mg","mh","mi","mj","mk","ml","mm","mn","mo","mp","mq","mr","ms","mt","mu","mv","mw","mx","my","mz","m0","m1","m2","m3","m4","m5","m6","m7","m8","m9","m_","na","nb","nc","nd","ne","nf","ng","nh","ni","nj","nk","nl","nm","nn","no","np","nq","nr","ns","nt","nu","nv","nw","nx","ny","nz","n0","n1","n2","n3","n4","n5","n6","n7","n8","n9","n_","oa","ob","oc","od","oe","of","og","oh","oi","oj","ok","ol","om","on","oo","op","oq","or","os","ot","ou","ov","ow","ox","oy","oz","o0","o1","o2","o3","o4","o5","o6","o7","o8","o9","o_","pa","pb","pc","pd","pe","pf","pg","ph","pi","pj","pk","pl","pm","pn","po","pp","pq","pr","ps","pt","pu","pv","pw","px","py","pz","p0","p1","p2","p3","p4","p5","p6","p7","p8","p9","p_","qa","qb","qc","qd","qe","qf","qg","qh","qi","qj","qk","ql","qm","qn","qo","qp","qq","qr","qs","qt","qu","qv","qw","qx","qy","qz","q0","q1","q2","q3","q4","q5","q6","q7","q8","q9","q_","ra","rb","rc","rd","re","rf","rg","rh","ri","rj","rk","rl","rm","rn","ro","rp","rq","rr","rs","rt","ru","rv","rw","rx","ry","rz","r0","r1","r2","r3","r4","r5","r6","r7","r8","r9","r_","sa","sb","sc","sd","se","sf","sg","sh","si","sj","sk","sl","sm","sn","so","sp","sq","sr","ss","st","su","sv","sw","sx","sy","sz","s0","s1","s2","s3","s4","s5","s6","s7","s8","s9","s_","ta","tb","tc","td","te","tf","tg","th","ti","tj","tk","tl","tm","tn","to","tp","tq","tr","ts","tt","tu","tv","tw","tx","ty","tz","t0","t1","t2","t3","t4","t5","t6","t7","t8","t9","t_","ua","ub","uc","ud","ue","uf","ug","uh","ui","uj","uk","ul","um","un","uo","up","uq","ur","us","ut","uu","uv","uw","ux","uy","uz","u0","u1","u2","u3","u4","u5","u6","u7","u8","u9","u_","va","vb","vc","vd","ve","vf","vg","vh","vi","vj","vk","vl","vm","vn","vo","vp","vq","vr","vs","vt","vu","vv","vw","vx","vy","vz","v0","v1","v2","v3","v4","v5","v6","v7","v8","v9","v_","wa","wb","wc","wd","we","wf","wg","wh","wi","wj","wk","wl","wm","wn","wo","wp","wq","wr","ws","wt","wu","wv","ww","wx","wy","wz","w0","w1","w2","w3","w4","w5","w6","w7","w8","w9","w_","xa","xb","xc","xd","xe","xf","xg","xh","xi","xj","xk","xl","xm","xn","xo","xp","xq","xr","xs","xt","xu","xv","xw","xx","xy","xz","x0","x1","x2","x3","x4","x5","x6","x7","x8","x9","x_","ya","yb","yc","yd","ye","yf","yg","yh","yi","yj","yk","yl","ym","yn","yo","yp","yq","yr","ys","yt","yu","yv","yw","yx","yy","yz","y0","y1","y2","y3","y4","y5","y6","y7","y8","y9","y_","za","zb","zc","zd","ze","zf","zg","zh","zi","zj","zk","zl","zm","zn","zo","zp","zq","zr","zs","zt","zu","zv","zw","zx","zy","zz","z0","z1","z2","z3","z4","z5","z6","z7","z8","z9","z_","0a","0b","0c","0d","0e","0f","0g","0h","0i","0j","0k","0l","0m","0n","0o","0p","0q","0r","0s","0t","0u","0v","0w","0x","0y","0z","00","01","02","03","04","05","06","07","08","09","0_","1a","1b","1c","1d","1e","1f","1g","1h","1i","1j","1k","1l","1m","1n","1o","1p","1q","1r","1s","1t","1u","1v","1w","1x","1y","1z","10","11","12","13","14","15","16","17","18","19","1_","2a","2b","2c","2d","2e","2f","2g","2h","2i","2j","2k","2l","2m","2n","2o","2p","2q","2r","2s","2t","2u","2v","2w","2x","2y","2z","20","21","22","23","24","25","26","27","28","29","2_","3a","3b","3c","3d","3e","3f","3g","3h","3i","3j","3k","3l","3m","3n","3o","3p","3q","3r","3s","3t","3u","3v","3w","3x","3y","3z","30","31","32","33","34","35","36","37","38","39","3_","4a","4b","4c","4d","4e","4f","4g","4h","4i","4j","4k","4l","4m","4n","4o","4p","4q","4r","4s","4t","4u","4v","4w","4x","4y","4z","40","41","42","43","44","45","46","47","48","49","4_","5a","5b","5c","5d","5e","5f","5g","5h","5i","5j","5k","5l","5m","5n","5o","5p","5q","5r","5s","5t","5u","5v","5w","5x","5y","5z","50","51","52","53","54","55","56","57","58","59","5_","6a","6b","6c","6d","6e","6f","6g","6h","6i","6j","6k","6l","6m","6n","6o","6p","6q","6r","6s","6t","6u","6v","6w","6x","6y","6z","60","61","62","63","64","65","66","67","68","69","6_","7a","7b","7c","7d","7e","7f","7g","7h","7i","7j","7k","7l","7m","7n","7o","7p","7q","7r","7s","7t","7u","7v","7w","7x","7y","7z","70","71","72","73","74","75","76","77","78","79","7_","8a","8b","8c","8d","8e","8f","8g","8h","8i","8j","8k","8l","8m","8n","8o","8p","8q","8r","8s","8t","8u","8v","8w","8x","8y","8z","80","81","82","83","84","85","86","87","88","89","8_","9a","9b","9c","9d","9e","9f","9g","9h","9i","9j","9k","9l","9m","9n","9o","9p","9q","9r","9s","9t","9u","9v","9w","9x","9y","9z","90","91","92","93","94","95","96","97","98","99","9_","_a","_b","_c","_d","_e","_f","_g","_h","_i","_j","_k","_l","_m","_n","_o","_p","_q","_r","_s","_t","_u","_v","_w","_x","_y","_z","_0","_1","_2","_3","_4","_5","_6","_7","_8","_9","__"]
Oh but you don't have flatMap? Easy, just make your own, as well as any other simple procedures that describe the computations you would like to perform
const add = x => y => x + y;
const map = f => xs =>
Array.prototype.map.call(xs, x => f (x));
const reduce = f => i => xs =>
Array.prototype.reduce.call(xs, (x,y) => f (x) (y));
const concat = xs => x =>
xs.concat(x);
const flatMap = f => xs =>
reduce (concat) ([]) (map (f) (xs));
These procedures are highly reusable and free you from the shackles of imperative code that looks like this
var charcode = 'abcdefghijklmnopqrstuvwxyz0123456789_';
// setup several state variables
var arr = [];
var len = 1; // 6 months later, why did we initialize len at 1?
var current = 0;
// manual looping, with arbitrary static input of 40 (why 40?)
for(var i = 0; i < 40; i++) {
// logic with potential for human error
if(current == charcode.length) {
// variable mutations
current = 0
len++
}
// temporary variables
var tmpStr = ''
// move manual looping
for(var l = 0; l < len; l++) {
// more variable mutation
tmpStr = tmpStr + charcode[current];
}
// IO side effects
console.log(tmpStr)
// manual iteration
current++
}

Trying to square every digit of a number, but my algorithm is not working?

I'm trying to square every digit of a number;
for example:
123 should return 149
983 --> 81649 and so on
I messed it up somewhere in the following Javascript code and I'm looking for some guidance.
function splitNumber(num){
var arr = [];
while(num>0){
var c = num%10;
arr[arr.length]=c;
num=num/10;}
return arr;
}
function squareArrToNumber(arr){
var c = 0;
for(var i=arr.length-1;i>=0;i--){
arr[i]=arr[i]^2;
if(arr[i]^2>10)
c = c*100+arr[i];
else
c = c*10+arr[i];
}
return c;
}
function squareDigits(num){
squareArrToNumber(splitNumber(num));
}
Try out this code
function numToSqr(num){
var i, sqr=[],n;
num = num.toString();
for(i=0;i<num.length;i++){
n = Number(num[i]);
sqr.push(n*n);
}
return Number(sqr.join(""));
}
There are multiple things wrong with your code, starting with an overcomplication to split a string of numbers into its consituant characters just use .splt(""):
var str = "123";
var arr = str.split("");
for(var i = 0;i<arr.length;i++)
alert(arr[i]);
Next, the code num ^ 2 does not square a number. To do a square, simply multiply a number by itself (num * num)
This leaves us with a rather simple solution
function splitNumber(num){
return num.split("");
}
function joinArray(arr){
return arr.join("");
}
function squareArrToNumber(arr){
var newArr = [];
for(var i=0;i<arr.length;i++){
newArr.push(arr[i] * arr[i]);
}
return joinArray(newArr);
}
function squareDigits(num){
return squareArrToNumber(splitNumber(num));
}
alert(squareDigits("123"));
alert(squareDigits("983"));
Here is how I would do such a thing:
var num = 123;
var numArray = num.toString().split("");
var result = "";
for(var i = 0; i < numArray.length; i++){
result += parseInt(numArray[i]) * parseInt(numArray[i]);
}
function squareNum(number) {
var array = [];
// Split number into an array of numbers that make it up
array = String(number).split('');
for (let i = 0; i < array.length; i++) {
// Take each number in that array and square it (in place)
// Also can be done with forEach depending on what es version you're targetting
array[i] = Math.pow(array[i], 2);
}
// combine and return the elements of the array
return Number(array.join(''));
}
squareNum(123);
squareNum(983);
try this example
function squareDigits(n) {
return +(n.toString().split('').map(val => val * val).join(''));
}
console.log(squareDigits(4444));
here + sign is convert the string into an integer.
if(arr[i]^2>10)
should be
if(arr[i]>10)
And, as #Luaan noted, it should be
arr[i] *= arr[i]

String with the highest frequency of recurring letters in a word

This is a challenge for coderbyte I thought I'd try to do it using a different method for solving it than loops, objects. It passed but it isn't perfect. The directions for the challenge are:
Have the function LetterCountI(str) take the str parameter being passed and return the first word with the greatest number of repeated letters. For example: "Today, is the greatest day ever!" should return greatest because it has 2 e's (and 2 t's) and it comes before ever which also has 2 e's. If there are no words with repeating letters return -1. Words will be separated by spaces.
function LetterCountI(str){
var wordsAndLetters = {};
var count = 0;
var finalword;
str = str.split(" ");
for(var i = 0; i < str.length; i++){
wordsAndLetters[str[i]] = wordsAndLetters[str[i]] || 0;
}
function countWordLetters(strs){
strs = strs.split("");
var lettercount = {};
for(var i = 0; i <strs.length; i++){
lettercount[strs[i]] = lettercount[strs[i]] || 0;
lettercount[strs[i]]++;
}
return lettercount;
}
for(var words in wordsAndLetters){
wordsAndLetters[words] = countWordLetters(words);
var highestLetterFrequency = wordsAndLetters[words];
for(var values in highestLetterFrequency){
if(highestLetterFrequency[values] > count){
count = highestLetterFrequency[values];
finalword = words;
}
if(count !== 1){
return finalword;
}
}
}
return -1;
}
LetterCountI("today is the greatest day ever!");
Sorry if some of the variable names are confusing I've been up for far too long trying to figure out what I did wrong. If you use the parameters at the bottom of the code it returns 'greatest' like it should however change the parameters to
LetterCountI("toddday is the greatttttest day ever!");
and it logs 'toddday' when it should log 'greatttttest'. Is my code completely wrong? I realize if the parameters were ("caatt dooog") it should log 'caatt' since there are 4 recurring letters but I'm not worried about that I just am concerned about it finding the most recurrence of one letter(but by all means if you have a solution I would like to hear it!). Any changes to the variables if needed to make this code more readable would be appreciated!
The problem with your code is the positioning of the following section of code:
if(count !== 1){
return finalword;
}
Move it from where it currently is to just before the return -1, like so:
for(var words in wordsAndLetters){
wordsAndLetters[words] = countWordLetters(words);
var highestLetterFrequency = wordsAndLetters[words];
for(var values in highestLetterFrequency){
if(highestLetterFrequency[values] > count){
count = highestLetterFrequency[values];
finalword = words;
}
}
}
if(count !== 1){
return finalword;
}
return -1;
The problem with your original code is that your were returning the first word that had repeating characters, which meant your code didn't get far enough to check if any subsequent words had more repeating characters.
Also, just for fun, here is my alternative solution.
Here you go
Array.prototype.getUnique = function(){
var u = {}, a = [];
for(var i = 0, l = this.length; i < l; ++i){
if(u.hasOwnProperty(this[i])) {
continue;
}
a.push(this[i]);
u[this[i]] = 1;
}
return a;
}
function LetterCountI(str){
var temp = str.split(" ");
var final = '', weight = 0;
for(var i = 0; i < temp.length; ++i) {
var word = temp[i].split("");
if(word.getUnique().length < word.length) {
var diff = word.length - word.getUnique().length;
if(diff > weight){
weight = diff;
final = temp[i];
}
}
}
return final;
}
console.log(LetterCountI("Catt dooog"));
console.log(LetterCountI("toddday is the greatttttest day ever!"));
Viva LinQ !!!!!
var resultPerWord = new Dictionary<string, int>();
var S = "toddday is the greatttttest day ever!";
foreach(var s in S.Split(' '))
{
var theArray =
from w in s
group w by w into g
orderby g.Count() descending
select new { Letter = g.Key, Occurrence = g.Count() };
resultPerWord.Add(s, theArray.First().Occurrence);
}
var r = "-1";
if (resultPerWord.Any(x => x.Value >1))
{
r = resultPerWord.OrderByDescending(x => x.Value).First().Key;
}

Categories