From this codewars exercise, I've written the following code:
function encrypt(text, n) {
if(n <= 0) {
return text;
}
let en = text.split('');
for(let j = 0; j < n; j++) {
let odd = [];
let even = [];
en.forEach((el,i,arr) => {
if(i % 2 === 0) {
odd.push(el);
} else {
even.push(el);
}
})
en = even.concat(odd);
}
return en.join('');
}
function decrypt(encryptedText, n) {
if(n <= 0) {
return encryptedText;
}
let de = encryptedText.split('')
for(let j = 0; j < n; j++) {
let newArr = [];
de.forEach((el,i,arr) => {
i < Math.floor(arr.length/2) ?
newArr[2*i+1] = el
: newArr[2*(i-Math.floor(arr.length/2))] = el;
})
de = newArr;
}
return de.join('');
}
The challenge is to encrypt strings by taking every 2nd character and rearranging from the front and decrypting.
When I submitted the above code, I got 57 successes and only 1 failure saying >cannot read property split of null
(I do not know what the input was, and the test name is called null test).
What am I doing wrong?
From the instructions:
For both methods:
If the input-string is null or empty return exactly this value!
If n is <= 0 then return the input text.
"exactly this value" is a bit confusing, but what it means is that you need to change the initial test in both functions from
if(n <= 0) {
return text;
}
to
if(n <= 0 || text === null) {
return text;
}
Since you currently aren't checking if the input is null, the error cannot read property split of null will come up if it's null.
Related
So I'm doing a codewars challenge and I have no clue why my code isn't working. I'm a beginner so please don't hate on me.
This is my code:
function digital_root(n) {
let str = n.toString()
let arr = []
let sum = 0
for (let i = 0; i < str.length; i++) {
arr.push(str.charAt(i))
}
for (let i = 0; i < str.length; i++) {
sum += Number(arr[i])
}
let sumStr = sum.toString()
if (sumStr.length > 1) {
digital_root(sum)
} else if (sumStr.length == 1) {
return sum
}
}
It works when I console.log it but not when I return the value. I'm trying to learn recursion. Thanks for the help!
You need to return digital_root(sum) too, if sumStr.length > 1 in order to access recursive returned value.
you have to write return digital_root(sum) instead of just digital_root(sum).
check below:
function digital_root(n) {
let str = n.toString()
let arr = []
let sum = 0
for (let i = 0; i < str.length; i++) {
arr.push(str.charAt(i))
}
for (let i = 0; i < str.length; i++) {
sum += Number(arr[i])
}
let sumStr = sum.toString()
if (sumStr.length > 1) {
return digital_root(sum)
} else if (sumStr.length == 1) {
return sum
}
}
console.log("Digital Root :", digital_root('123456789'));
Ok, it seems you are missing dealing with the return value of digital_root when you call it recursively. See added "return" statement below.
function digital_root(n) {
let str = n.toString()
let arr = []
let sum = 0
for (let i = 0; i < str.length; i++) {
arr.push(str.charAt(i))
}
for (let i = 0; i < str.length; i++) {
sum += Number(arr[i])
}
let sumStr = sum.toString()
if (sumStr.length > 1) {
// ***** You need to deal with the return value of digital_root when you call it.
return digital_root(sum)
} else if (sumStr.length == 1) {
return sum
}
}
However, while JavaScript's functional coding style does support recursive functions, we need to be aware that most JavaScript compilers are not currently optimized to support them safely. Recursion is best applied when you need to call the same function repeatedly with different parameters from within a loop.
Please read this,
https://www.sitepoint.com/recursion-functional-javascript/#:~:text=However%2C%20while%20JavaScript's%20functional%20coding,parameters%20from%20within%20a%20loop.
My code works for many other test cases except for this
It runs a runtime error so I was wondering if someone could help me figure out why. Thanks, here's the code:
if(s.length <= 1){
return s.length
}
let lengths = []
s = s.split('')
function run(index){
if(index === s.length){
lengths.push(s.slice(0,index).length)
return
}
if(s.slice(0,index).indexOf(s[index]) >= 0){
lengths.push(s.slice(0,index).length)
s.splice(0, s.slice(0,index).indexOf(s[index]))
if( s.slice(0,index).indexOf(s[index]) === 0 ){
s.splice(0,1)
}
index = 0
}
run(index+1)
}
run(0)
return Math.max(...lengths)
};
var lengthOfLongestSubstring = function(str) {
if (str.length <=1){
return str.length;
}
var _max = 0;
do {
var obj_ = {};
var substrings = '';
var l = str.length;
//if (_max < l) - even i cannot add if condition here
// it cause time limit problem
for (var i = 0; i < l; i++) {
if (!obj_[str[i]]) {
obj_[str[i]] = 1;
} else {
obj_[str[i]] += 1;
}
if (obj_[str[i]] > 1) {
break;
} else {
substrings += str[i];
}
}
if (_max < substrings.length) {
_max = substrings.length;
}
var str = str.substring(1, str.length);
}
while (str.length > 0);
return _max;
};
This method only gives me output, others solutions gives me time limit exceeds.
LINK to input https://github.com/rinshankolayil/DUMMY_REPO/blob/main/leetcode/test_data.txt
OUTPUT
A string is called a palindrome if it may be read the same way in either direction. For example, “12321” is a palindrome, but “12341” is not. A palindrome string can itself compose of one or more palindrome sub-strings. Now, your task is to find out the length (denoted by L) of the longest palindrome sub-string, maximum-length contiguous substring of a given
string that is also a palindrome, and print "YES" if it is lucky otherwise print "NO". A palindrome sub-string is called lucky iff it's length is a prime number.
For example : Consider a string s =”122321”. The longest palindrome sub-strings in s is of length 3. Hence, you need to output "YES" (quotes only for clarity).
function solution(r) {
if (r.match(/[a-z]/g) || r.match(/[A-Z]/g) || r.match(/[0-9]/g)) {
for (var t = gettingPrimeList(r), o = "", n = 0; n < r.length; n++)
for (var e = t.length; t > 0; t--) {
var a = r.substr(n, t[e - 1]);
console.log(a);
for (var i = a.length; i > 0; i--) {
var g = a.substr(0, i);
console.log(g);
var s = g.split("").reverse().join("");
if (g == s) {
o = "YES";
break
}
o = "NO"
}
}
return o
}
}
function gettingPrimeList(r) {
for (var t = [], o = 2; o <= r.length; o++) {
for (var n = !1, e = 2; e <= o; e++) o % e == 0 && e !== o && (n = !0);
!1 === n && t.push(o)
}
return t
}
alert(solution("random12321random"));
You can do that in following steps:
Create two function isPrime() to check if number is prime or not. Second to check if string is a palindrome or not.
Get all the substrings starting from str.length - 1 then str.length - 2 and so on.
The way to get substrings is that create a variable l which will be length of substring.
Keep making substrings until the length of substring is greater than 1.
If the while loop create a nested for loop which will get all substrings.
Note: I am not sure that you want to check the whole string or not. If you want to check also the whole string then change let l = str.length - 1; to let l = str.length; in check function.
The code returns true and false. You can fix it according to your needs.
function isPal(str){
return [...str].reverse().join('') === str
}
function isPrime(num){
if(num === 3 || num === 2) return true;
if(num === 1) return false;
if(num % 2 === 0) return false;
for(let i = 3;i<Math.sqrt(num) + 1;i+=2){
if(num % i === 0) return false;
}
return true;
}
function check(str){
let l = str.length - 1;
while(l>1){
for(let i = 0;i<str.length-l;i++){
let temp = str.slice(i,l);
if(isPal(temp)) return isPrime(l)
}
l--;
}
return false;
}
console.log(check("122321")) //true
console.log(check("123454321")) // false
function solution(S) {
var max_length = 0,
maxp = '';
for(var i=0; i < S.length; i++){
var subs = S.substr(i, S.length);
for(var j=subs.length; j>=0; j--){
var sub_subs_str = subs.substr(0, j);
if (sub_subs_str.length <= 1)
continue;
if (is_Palindrome(sub_subs_str)){
if (sub_subs_str.length > max_length){
max_length = sub_subs_str.length;
maxp = sub_subs_str;
}
}
}
}
maxp = IsPrimeNumber(maxp.length);
return maxp;
}
function is_Palindrome(S) {
var rev = S.split("").reverse().join("");
return S == rev;
}
function IsPrimeNumber(n){
if (n===1){
return "NO";
}
else if(n === 2){
return "YES";
}
else{
for(var x = 2; x < n; x++)
{
if(n % x === 0)
{
return "NO";
}
}
return "YES";
}
}
console.log(solution('random12321random'))
I am trying to write a function that identifies if a word is an isogram or not. This is what I have done so far:
function isIsogram(word) {
var result;
var counter = 0;
var dubs = 0;
if (word.length === 0) {
result = false;
} else {
var lower = word.toLowerCase();
var array = Array.from(lower);
for (i = 0; i < array.length; i++) {
counter++;
for (j = i + 1; j < array.length; j++) {
if (array[i] === array[j]) {
dubs++;
}
}
}
if ((counter > 0) && (dubs === 0)) {
result = true;
} else if ((counter > 0) && (dubs > 0)) {
result = false;
}
}
console.log(result);
return result;
}
isIsogram("word");
When I run the above code in my browser's javascript console, it works pretty well. But when I post it onto the environment where I am being tested, it gives an error that "word" (the parameter) is undefined.
I even tried hard coding a parameter by declaring a string value for word outside the function, it still said undefined. What am i not doing right?
Seems to work as far as I can see.
Can you provide information about how you call your function isIsogramm('teststring');?
https://jsfiddle.net/TobiObeck/z15eos81/
The following error occours
Thu May 23 07:14:53.437 JavaScript execution failed: map reduce failed:{
"errmsg" : "exception: JavaScript execution failed: TypeError: Cannot read property 'product_category' of undefined near '(values[i].product_category)' (line 21)",
"code" : 16722,
"ok" : 0
at src/mongo/shell/collection.js:L970
My map and reduce function are:
map1 = function()
{
emit({Product_id:this.Product_id
},
{
product_category:this.product_category
});
}
reduce1 = function(key, values)
{
var ref = new Array();
var count = 0;
var tmp="";
var pdt_array = new Array();
for (var i = 1; i <= values.length; i++) {
if( i == 1 )
{
pdt_array_array[i] = values[i];
}
else
{
tmp = values[i];
while(i > 1)
{
if(tmp == pdt_array[i])
{
ref.push(values[i].product_category);
count++;
}
i--;
}
pdt_array[i] = tmp;
tmp = "";
}
}
return {product_category:ref, Count:count}
}
db.DummyReverse.mapReduce(map1, reduce1, {out:{reduce:"product_count_while"}})
The issue is that you are not returning the same format from reduce function as you are emitting as value. Since reduce function can be called 0, once or multiple times for each key you must use the exact same format in all of those cases and you cannot assume that your reduce function will be called only once.
Javascript arrays are 0-indexed. So your last for-run want to access a array index, which doesn't exist. I hope I interpret your code right.
[...]
for (var i = 0; i < values.length; i++) {
if ( i == 0) {
pdt_array_array[i] = values[i];
} else {
tmp = values[i];
while(i > 0) {
if(tmp == pdt_array[i]) {
ref.push(values[i].product_category);
count++;
}
i--;
}
pdt_array[i] = tmp;
tmp = "";
}
}
[...]
Take notice at for (var i = 0; i < values.length; i++). So the n-th element has the index n-1. The last element length-1.
Remarks: Are you sure you get no infinite loop with the for-loop increasing i and in the while decreasing it?