EDIT
Thank you guys, and i apologize for not being more specific in my question.
This code was written to check if a characters in the second string is in the first string. If so, it'll return true, otherwise a false.
So my code works, I know that much, but I am positive there's gotta be a better way to implement this.
Keep in mind this is a coding challenge from Freecodecamp's Javascript tree.
Here's my code:
function mutation(arr) {
var stringOne = arr[0].toLowerCase();
var stringTwo = arr[1].toLowerCase().split("");
var i = 0;
var truthyFalsy = true;
while (i < arr[1].length && truthyFalsy) {
truthyFalsy = stringOne.indexOf(stringTwo[i]) > -1;
i++
}
console.log(truthyFalsy);
}
mutation(["hello", "hey"]);
//mutation(["hello", "yep"]);
THere's gotta be a better way to do this. I recently learned about the map function, but not sure how to use that to implement this, and also just recently learned of an Array.prototype.every() function, which I am going to read tonight.
Suggestions? Thoughts?
the question is very vague. however what i understood from the code is that you need to check for string match between two strings.
Since you know its two strings, i'd just pass them as two parameters. additionally i'd change the while into a for statement and add a break/continue to avoid using variable get and set.
Notice that in the worst case its almost the same, but in the best case its half computation time.
mutation bestCase 14.84499999999997
mutation worstCase 7.694999999999993
bestCase: 5.595000000000027
worstCase: 7.199999999999989
// your function (to check performance difference)
function mutation(arr) {
var stringOne = arr[0].toLowerCase();
var stringTwo = arr[1].toLowerCase().split("");
var i = 0;
var truthyFalsy = true;
while (i < arr[1].length && truthyFalsy) {
truthyFalsy = stringOne.indexOf(stringTwo[i]) > -1;
i++
}
return truthyFalsy;
}
function hasMatch(base, check) {
var strOne = base.toLowerCase();
var strTwo = check.toLowerCase().split("");
var truthyFalsy = false;
// define both variables (i and l) before the loop condition in order to avoid getting the length property of the string multiple times.
for (var i = 0, l = strTwo.length; i < l; i++) {
var hasChar = strOne.indexOf(strTwo[i]) > -1;
if (hasChar) {
//if has Char, set true and break;
truthyFalsy = true;
break;
}
}
return truthyFalsy;
}
var baseCase = "hello";
var bestCaseStr = "hey";
var worstCaseStr = "yap";
//bestCase find match in first iteration
var bestCase = hasMatch("hello", bestCaseStr);
console.log(bestCase);
//worstCase loop over all of them.
var worstCase = hasMatch("hello", worstCaseStr);
console.log(worstCase);
// on your function
console.log('mutation bestCase', checkPerf(mutation, [baseCase, bestCaseStr]));
console.log('mutation worstCase', checkPerf(mutation, [baseCase, worstCaseStr]));
// simple performance check
console.log('bestCase:', checkPerf(hasMatch, baseCase, bestCaseStr));
console.log('worstCase:', checkPerf(hasMatch, baseCase, worstCaseStr));
function checkPerf(fn) {
var t1 = performance.now();
for (var i = 0; i < 10000; i++) {
fn(arguments[1], arguments[2]);
}
var t2 = performance.now();
return t2 - t1;
}
1
11
12
1121
122111
112213
122211
....
I was trying to solve this problem. It goes like this.
I need to check the former line and write: the number and how many time it was repeated.
ex. 1 -> 1(number)1(time)
var antsArr = [[1]];
var n = 10;
for (var row = 1; row < n; row++) {
var lastCheckedNumber = 0;
var count = 1;
antsArr[row] = [];
for (var col = 0; col < antsArr[row-1].length; col++) {
if (lastCheckedNumber == 0) {
lastCheckedNumber = 1;
antsArr[row].push(lastCheckedNumber);
} else {
if (antsArr[row-1][col] == lastCheckedNumber) {
count++;
} else {
lastCheckedNumber = antsArr[row-1][col];
}
}
}
antsArr[row].push(count);
antsArr[row].push(lastCheckedNumber);
}
for (var i = 0; i < antsArr.length; i++) {
console.log(antsArr[i]);
}
I have been on this since 2 days ago.
It it so hard to solve by myself. I know it is really basic code to you guys.
But still if someone who has a really warm heart help me out, I will be so happy! :>
Try this:
JSFiddle Sample
function lookAndSay(seq){
var prev = seq[0];
var freq = 0;
var output = [];
seq.forEach(function(s){
if (s==prev){
freq++;
}
else{
output.push(prev);
output.push(freq);
prev = s;
freq = 1;
}
});
output.push(prev);
output.push(freq);
console.log(output);
return output;
}
// Sample: try on the first 11 sequences
var seq = [1];
for (var n=0; n<11; n++){
seq = lookAndSay(seq);
}
Quick explanation
The input sequence is a simple array containing all numbers in the sequence. The function iterates through the element in the sequence, count the frequency of the current occurring number. When it encounters a new number, it pushes the previously occurring number along with the frequency to the output.
Keep the iteration goes until it reaches the end, make sure the last occurring number and the frequency are added to the output and that's it.
I am not sure if this is right,as i didnt know about this sequence before.Please check and let me know if it works.
var hh=0;
function ls(j,j1)
{
var l1=j.length;
var fer=j.split('');
var str='';
var counter=1;
for(var t=0;t<fer.length;t++)
{
if(fer[t]==fer[t+1])
{
counter++;
}
else
{
str=str+""+""+fer[t]+counter;
counter=1;
}
}
console.log(str);
while(hh<5) //REPLACE THE NUMBER HERE TO CHANGE NUMBER OF COUNTS!
{
hh++;
//console.log(hh);
ls(str);
}
}
ls("1");
You can check out the working solution for in this fiddle here
You can solve this by splitting your logic into different modules.
So primarily you have 2 tasks -
For a give sequence of numbers(say [1,1,2]), you need to find the frequency distribution - something like - [1,2,2,1] which is the main logic.
Keep generating new distribution lists until a given number(say n).
So split them into 2 different functions and test them independently.
For task 1, code would look something like this -
/*
This takes an input [1,1,2] and return is freq - [1,2,2,1]
*/
function find_num_freq(arr){
var freq_list = [];
var val = arr[0];
var freq = 1;
for(i=1; i<arr.length; i++){
var curr_val = arr[i];
if(curr_val === val){
freq += 1;
}else{
//Add the values to the freq_list
freq_list.push([val, freq]);
val = curr_val;
freq = 1;
}
}
freq_list.push([val, freq]);
return freq_list;
}
For task 2, it keeps calling the above function for each line of results.
It's code would look something like this -
function look_n_say(n){
//Starting number
var seed = 1;
var antsArr = [[seed]];
for(var i = 0; i < n; i++){
var content = antsArr[i];
var freq_list = find_num_freq(content);
//freq_list give an array of [[ele, freq],[ele,freq]...]
//Flatten so that it's of the form - [ele,freq,ele,freq]
var freq_list_flat = flatten_list(freq_list);
antsArr.push(freq_list_flat);
}
return antsArr;
}
/**
This is used for flattening a list.
Eg - [[1],[1,1],[1,2]] => [1,1,1,1,2]
basically removes only first level nesting
**/
function flatten_list(li){
var flat_li = [];
li.forEach(
function(val){
for(ind in val){
flat_li.push(val[ind]);
}
}
);
return flat_li;
}
The output of this for the first 10 n values -
OUTPUT
n = 1:
[[1],[1,1]]
n = 2:
[[1],[1,1],[1,2]]
n = 3:
[[1],[1,1],[1,2],[1,1,2,1]]
n = 4:
[[1],[1,1],[1,2],[1,1,2,1],[1,2,2,1,1,1]]
n = 5:
[[1],[1,1],[1,2],[1,1,2,1],[1,2,2,1,1,1],[1,1,2,2,1,3]]
n = 6:
[[1],[1,1],[1,2],[1,1,2,1],[1,2,2,1,1,1],[1,1,2,2,1,3],[1,2,2,2,1,1,3,1]]
n = 7:
[[1],[1,1],[1,2],[1,1,2,1],[1,2,2,1,1,1],[1,1,2,2,1,3],[1,2,2,2,1,1,3,1],[1,1,2,3,1,2,3,1,1,1]]
n = 8:
[[1],[1,1],[1,2],[1,1,2,1],[1,2,2,1,1,1],[1,1,2,2,1,3],[1,2,2,2,1,1,3,1],[1,1,2,3,1,2,3,1,1,1],[1,2,2,1,3,1,1,1,2,1,3,1,1,3]]
n = 9:
[[1],[1,1],[1,2],[1,1,2,1],[1,2,2,1,1,1],[1,1,2,2,1,3],[1,2,2,2,1,1,3,1],[1,1,2,3,1,2,3,1,1,1],[1,2,2,1,3,1,1,1,2,1,3,1,1,3],[1,1,2,2,1,1,3,1,1,3,2,1,1,1,3,1,1,2,3,1]]
I'm currently working on coderbyte's medium challenge entitled "Permutation Step."
The goal is to take user input, num, and to return the next number greater than num using the same digits So, for example, if user input is 123, then the number 132 should be returned. If user input is 12453, then 12534 should be returned...
Anywho, I have a correct model answer created by someone (probably a genius, cuz this stuff is pretty hard) and I'm trying to figure out how the answer works, line for line by having an example play out (I'm keeping it simple and playing out the function with user input 123).
The answer has 2 functions, but the 1st function used is what I'm currently trying to work out...
The relevant code is:
var PermutationStep1 = function(num) {
var num1 = num.toString();
var ar = [];
//return num1;
if (num1.length < 2) {
return num;
} else {
for(var i = 0; i < num1.length; i++) {
var num2 = num1[i];
var num3 = num1.substr(0,i) + num1.substr(i+1, num1.length -1);
var numAr = PermutationStep1(num3);
for(var j = 0; j < numAr.length; j++) {
ar.push(numAr[j] + num2);
}
}
ar.sort(function(a,b) {return a-b});
return ar;
}
}
Again, I'm trying to work thru this function with the inputted num as 123 (num = 123).
I'm pretty sure that this function should output an array with multiple elements, because the 2nd function merely compares those array elements with the original user input (in our case, 123), and returns the next greatest value.
So in our case, we should probably get an array, named 'ar', returned with a host of 3 digit values. But for some reason, I'm getting an array of 2 digit values. I can't seem to isolate my mistake and where I'm going wrong. Any help with where, specifically, I'm going wrong (whether it be the recursion, the use of substring-method, or the concating of strings together, whatever my problem may be) would be appreciated...
Here's some of my work so far:
PS1(123) / num1 = 123
i = 0;
num2 = (num1[i]) = '1';
num3 = (num1.substr(0, 0) + num1.substr(1, 2)) = ('0' + '23') = '23'
PS1(23)
i = 0;
num2 = '2';
num3 = '3'
PS1(3) -> numAr = 3 (since num1 is less than 2 digits, which is the recursion base case?)
(So take 3 into the 2nd for loop)...
ar.push(numAr[j] + num2) = ar.push('3' + '1') = 31
ar = [31] at this point
And then I go through the initial for-loop a couple more times, where i = 1 and then i = 2, and I eventually get....
ar = [31, 32, 33]...
But I'm thinking I should have something like ar = [131, 132, 133]? I'm not sure where I'm going wrong so please help. Because the answer is correctly spit out by this function, the correct answer being 132.
Note: if you need the 2nd part of the model answer (i.e. the 2nd function), here it is:
var arr = [];
function PermutationStep(num1) {
arr.push(PermutationStep1(num1));
var arrStr = arr.toString();
var arrStrSpl = arrStr.split(",");
//return arrStrSpl;
for(var p = 0; p < arrStrSpl.length; p++) {
if(arrStrSpl[p] > num1) {
return arrStrSpl[p];
}
}
return -1;
}
I'm sorry the first function i posted was under a mathematical logical mistake and i was to overhasty
I thought about it again and now i have the following function which definitley works
function getNextNumber (num)
{
var numberStr=num.toString (), l=numberStr.length, i;
var digits=new Array (), lighterDigits, digitAtWeight;
var weight,lightWeight, lighterDigits_l, value=0;
for (i=l-1;i>-1;i--)
digits.push (parseInt(numberStr.charAt(i)));
lighterDigits=new Array ();
lighterDigits.push (digits[0]);
for (weight=1;weight<l;weight++)
{
digitAtWeight=digits[weight];
lighterDigits_l=lighterDigits.length;
for (lightWeight=0;lightWeight<lighterDigits_l;lightWeight++)
{
if (digitAtWeight<lighterDigits[lightWeight])
{
lighterDigits.unshift (lighterDigits.splice (lightWeight,1,digitAtWeight)[0]);
lighterDigits.reverse ();
digits=lighterDigits.concat (digits.slice (weight+1,l));
for (weight=0;weight>l;weight++)
value+=Math.pow (10,weight)*digits[weight];
return value;
}
}
lighterDigits.push (digitAtWeight);
}
return NaN;
}
okay here is my solution i found it in 20 minutes ;)
//---- num should be a Number Object and not a String
function getNextNumber (num)
{
var numberStr=num.toString (), l=numberStr.length, i;
var digits=new Array (), digitA, digitB;
var weight,lightWeight;
var valueDifference,biggerValue;
for (i=l-1;i>-1;i--)
digits.push (parseInt(numberStr.charAt(i))); // 345 becomes a0=5 a1=4 a2=3 and we can say that num= a0*10^0+ a1*10^1+ a2*10^2, so the index becomes the decimal weight
for (weight=1;weight<l;weight++)
{
digitA=digits[weight];
biggerValue=new Array ();
for (lightWeight=weight-1;lightWeight>-1;lightWeight--)
{
digitB=digits[lightWeight];
if (digitB==digitA) continue;
valueDifference=(digitA-digitB)*(-Math.pow(10,weight)+Math.pow (10,lightWeight));
if (valueDifference>0) biggerValue.push(valueDifference);
}
if (biggerValue.length>0)
{
biggerValue.sort();
return (biggerValue[0]+num);
}
}
}
this is the solution I figured out for the problem without using a recursive function. It's passed all the tests on coderbyte. I am still new to this so using recursion is not the first thing I look for. hope this can help anyone else looking for a solution.
function PermutationStep(num) {
var numArr = (num + '').split('').sort().reverse();
var numJoin = numArr.join('');
for (var i = (num + 1); i <= parseInt(numJoin); i++){
var aaa = (i + '').split('').sort().reverse();
if (aaa.join('') == numJoin){
return i;
}
}
return -1;
}