can't convert undefined to object in javascript - javascript

Update: I have added the fiddle. Please refer here. use web console for error.
I am writing a code for traveling salesman problem. Here is the code :
var ind =[]; //values selected
var cp =[];
var X;
var Y;
var tour = [];
// no values selected in the starting
for(j=0;j<friends_cnt;j++) {
ind[j] = 0;
}
// distances at i,i infinity
for(i=0;i<friends_cnt;i++) {
distance[i][i] = 9999999999999;
}
var k = 0;
var X = 0;
tour[k] = X;
ind[X] = 1;
var i =1;
while(i<friends_cnt && ind[i] === 0) {
var min = 9999999999999;
// finding minimum of the undeleted values
for(j=0;j<friends_cnt;j++) {
if(ind[j] === 0) {
if(distance[X][j] < min) {
min = distance[X][j];
Y = j; // y is the min city
}
}
}
k = k+1; // counter for the starting city
tour[k] = Y; //city added
ind[Y] = 1;
X = Y;
i++;
}
k = k+1;
tour[k] = tour[1];
for(var q=0;q<k+1;q++) {
console.log(tour[q]);
}
});
});
now here whenever i run my program, it shows an error
TypeError: can't convert undefined to object
in the line
var min = 9999999999999;
My question is that is this because JavaScript cant handle large numbers or something else ?

Javascript's max number is 1.7976931348623157e+308 (aka the var Number.MAX_VALUE), so that shouldn't be an issue.
If you are trying to access an object of an object, it won't work.
You have distance[X][j]. That tries to access key j of distance[X]. To fix this, define distance[X] as an object:
distance[X] = [];
Other example:
var distance = [];
distance[i]
//undefined;
distance[i][i]
//syntax error
distance[i] = [];
distance[i][i]
//undefined;
For 2D arrays, see this question.

The problem is actually here:
distance[i][i] = 9999999999999;
If distance is undefined or an empty array, that statement will fail. This should fix it:
var distance = []; // <-- this is missing from the top of your code
// ...
if (!distance[i]) {
distance[i] = [];
}
distance[i][i] = 9999999999999;

Try this for minimum number
var min = int.MinValue
For max number
var max = int.MaxValue
Edited
Refer Reference
Number.Max_Value
Number.Min_Value
UPDATED
If you see your code you have filled the ind[] from 0
for(j=0;j<friends_cnt;j++) {
ind[j] = 0;
}
and in your while condition you have set value of i from 1. So for the last element it may be throwing error

Related

Algorithm to calculate if 'n' or more intervals intersect & the total of the respective intersections

I need help developing a weird algorithm. I have a JavaScript object containing people and an array for each person of start and end time intervals in milliseconds:
var person = [
(1533242595, 1533242999),
(1533242595, 1533242999),
(1533242595, 1533242999)
]
I need to determine if any intervals intersect/overlap, but for n or more intersections (for example, determining if 4+ intervals overlap) and calculate the total sum of the n or more intersecting intervals.
A function that takes a n parameter and the person object would be perfect.
First the person must be defined as list of lists:
var person = [
[1533242595, 1533242999],
[1533242595, 1533242999],
[1533242595, 1533242999]
];
Here you can find a sample of function:
function limit_intersection(limit, person) {
var arrayLength = person.length;
var intersections = 0;
var intersectionsum = 0;
var min, max = 0;
var tmp;
var intervals = [];
for (var i = 0; i < arrayLength-1; i++) {
if(person[i][0] > person[i][1]) {
tmp = person[i][1];
person[i][1] = person[i][0];
person[i][0] = tmp;
}
for (var j = i+1; j < arrayLength; j++) {
if(person[j][0] > person[j][1]) {
tmp = person[j][1];
person[j][1] = person[j][0];
person[j][0] = tmp;
}
min = 0;
max = 0;
if(person[i][1] <= person[j][0] || person[i][0] >= person[j][1]){
// no intersection
continue;
}
intersections +=1;
if(person[i][0] >= person[j][0]) {
min = person[i][0];
} else {
min = person[j][0];
}
if(person[i][1] >= person[j][1]) {
max = person[j][1];
} else {
max = person[i][1];
}
intervals.push([min,max]);
intersectionsum += max-min;
}
}
return {'n' : intersections, 'sum' : intersectionsum, 'intervals' : intervals};
}
An here the working demo on jsfiddle.net
Are you sure that's how your data is structured? Because that does not look like a Javascript object to me, correct me if I'm wrong.
Break your code in to bite sized problems. What is an overlap? How do we check if two intervals overlap each other? When you make that function, use that to loop through your person intervals. Make a variable that contains the sum of the matches and return that.
function overlaps(startX, endX, startY, endY) {
if(endX < startY || endY < startX) return false;
return true;
}
console.log(overlaps(1,2,1,4)) // true
console.log(overlaps(10,20,1,11)) // true
console.log(overlaps(1,2,3,4)) // false
console.log(overlaps(4,3,2,1)) // false
Now find a way to loop over your persons checking for overlaps with this bite sized function.
Edited, here's an example of answer with bite-sized readable functions instead of the spagetti code in the selected answer:
// Check if two intervals overlap
function overlaps(startX, endX, startY, endY) {
if(endX < startY || endY < startX) return false;
return true;
}
// Check how many times two person arrays overlap
function comparePersons(person1, person2){
var matches = 0;
person1.forEach(function(elementX) {
person2.forEach(function(elementY) {
if(overlaps(
elementX[0],elementX[1],
elementY[0],elementY[1]
)) matches +=1
});
});
return matches;
}
// Check how many times all persons overlap with another
function compareAll(persons, n){
var totalMatches = 0;
persons.forEach(function(element, index1) {
var compareMatches = 0;
persons.forEach(function(compareElement, index2) {
if(index1 !== index2) {
compareMatches += comparePersons(element, compareElement)
}
});
if(compareMatches >= n) totalMatches += 1;
});
return totalMatches;
}
// Create persons to test
var person1 = [
[10,20],
[100,200]
]
var person2 = [
[1,2000],
[50,1000]
]
var person3 = [
[10,200],
[0,1],
[1000,2000],
[100,2000]
]
// Create one array with all persons
var allPersons = [
person1, person2, person3
]
// Test by console logging
console.log(compareAll(allPersons, 5));

"Look and say sequence" in javascript

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]]

scriptProcessorNode.onaudioprocess not able to access global variables

I am building class around a scriptProcessorNode oscillator. I have wrapped my onaudioprocess event handler in a function Gendy.prototype.process. I can access global variables and functions from within this wrapper function, but they are not accessible from within the onaudioprocess function.
I devised a work around for the properties, to redefine them in the wrapper function, but this doesn't work when trying to call another method, a random walk method, with this.walk().
Here is my code:
Gendy.prototype.process = function(){
var point = 0;
var index = 0;
var y = 0;
var breakpoint = this.breakpoint;
var freq = this.freq;
var walk = this.walk();
this.scriptNode.onaudioprocess = function(audioProcessingEvent){
var outputBuffer = audioProcessingEvent.outputBuffer;
var outputData = outputBuffer.getChannelData(0);
for(var j = 0; j < outputData.length;j++){
// linearly interpolate between the new breakpoint positions
// get the interp point by comparing index to the x distance
var lerp = (index - breakpoint[point].x) / (breakpoint[point+1].x - breakpoint[point].x);
y = lerp * (breakpoint[point+1].y - breakpoint[point].y) + breakpoint[point].y;
if(point < breakpoint.length && index >= breakpoint[point+1].x) {
point++;
}
outputData[j] = y;
index+=freq;
if(index >= breakpoint[breakpoint.length-1].x){
index = 0;
point = 0;
walk();
}
}
}
}
This makes sound, but returns the errors:
Uncaught TypeError: walk is not a function
for few lines and then
Uncaught TypeError: undefined is not a function
forever.
Is this a bug with the scriptProcessorNode? Any insight would be appreciated!
no bug in scriptProcessorNode, the issue is the below line:
this.scriptNode.onaudioprocess = function(audioProcessingEvent){
the this varible inside the onaudioprocess would refer to this.scriptNode object by default, you can handle it in one of two ways:
Use bind( as you have done in your answer):
this.scriptNode.onaudioprocess = function(audioProcessingEvent){
...
}.bind(this)
use a local variable to hold the value of this, and use that local variable in place of this:
var self = this;
this.scriptNode.onaudioprocess = function(audioProcessingEvent){
...
I was able to access this from within the onaudioprocess function by attaching .bind(this) to it.
Here is the code:
Gendy.prototype.process = function(){
this.scriptNode.onaudioprocess = function(audioProcessingEvent){
var outputBuffer = audioProcessingEvent.outputBuffer;
var outputData = outputBuffer.getChannelData(0);
for(var j = 0; j < outputData.length;j++){
// linearly interpolate between the new breakpoint positions
// get the interp point by comparing index to the x distance
var lerp = (this.index - this.breakpoint[this.point].x) / (this.breakpoint[this.point+1].x - this.breakpoint[this.point].x);
this.y = lerp * (this.breakpoint[this.point+1].y - this.breakpoint[this.point].y) + this.breakpoint[this.point].y;
if(this.point < this.breakpoint.length && this.index >= this.breakpoint[this.point+1].x) {
this.point++;
}
outputData[j] = this.y;
this.index+=this.freq;
if(this.index >= this.breakpoint[this.breakpoint.length-1].x){
this.index = 0;
this.point = 0;
this.walk();
}
}
}.bind(this);
}

Javascript: reducing down to one number

So I need to take a date and convert it into one single number by adding up each digit, and when the sum exceeds 10, I need to add up the two digits. For the code below, I have 12/5/2000, which is 12+5+2000 = 2017. So 2+0+1+7 = 10 & 1+0 = 1. I get it down to one number and it works in Firebug (output of 1). However, it is not working in a coding test environment I am trying to use, so I suspect something is wrong. I know the code below is sloppy, so any ideas or help reformatting the code would be helpful! (Note: I am thinking it has to be a function embedded in a function, but haven't been able to get it to work yet.)
var array = [];
var total = 0;
function solution(date) {
var arrayDate = new Date(date);
var d = arrayDate.getDate();
var m = arrayDate.getMonth();
var y = arrayDate.getFullYear();
array.push(d,m+1,y);
for(var i = array.length - 1; i >= 0; i--) {
total += array[i];
};
if(total%9 == 0) {
return 9;
} else
return total%9;
};
solution("2000, December 5");
You can just use a recursive function call
function numReduce(numArr){
//Just outputting to div for demostration
document.getElementById("log").insertAdjacentHTML("beforeend","Reducing: "+numArr.join(","));
//Using the array's reduce method to add up each number
var total = numArr.reduce(function(a,b){return (+a)+(+b);});
//Just outputting to div for demostration
document.getElementById("log").insertAdjacentHTML("beforeend",": Total: "+total+"<br>");
if(total >= 10){
//Recursive call to numReduce if needed,
//convert the number to a string and then split so
//we will have an array of numbers
return numReduce((""+total).split(""));
}
return total;
}
function reduceDate(dateStr){
var arrayDate = new Date(dateStr);
var d = arrayDate.getDate();
var m = arrayDate.getMonth();
var y = arrayDate.getFullYear();
return numReduce([d,m+1,y]);
}
alert( reduceDate("2000, December 5") );
<div id="log"></div>
If this is your final code your function is not outputting anything. Try this:
var array = [];
var total = 0;
function solution(date) {
var arrayDate = new Date(date);
var d = arrayDate.getDate();
var m = arrayDate.getMonth();
var y = arrayDate.getFullYear();
array.push(d,m+1,y);
for(var i = array.length - 1; i >= 0; i--) {
total += array[i];
};
if(total%9 == 0) {
return 9;
} else
return total%9;
};
alert(solution("2000, December 5"));
It will alert the result in a dialog.

JavaScript TypeError with arrays and integers

So, I was having this problem with arrays in JavaScript.
I initialized some variables as shown here:
var world = new Array;
var monsters = new Array;
var items = new Array;
var x = 0;
var y = 0;
and tried to run this code on it:
while (y <= 49) { //generate world
world[x][y] = parseInt(Math.floor(Math.random()*2)); //0 = flatland, 1 = desert, 2 = mountain, 3 = swamp
x++;
if (x >= 49) {
x = 0;
y++;
}
}
x = 0;
y = 0;
but I get presented with this error:
"TypeError: can't convert undefined to object"
on the Math.random() line.
I've tried everything I can think of, but it still throws that error.
Any help will be greatly appreciated!
world[x][y] is not initialized. That's the problem. You need to intialize below the while statement
while (y <= 49) {
world[x] = new Array(); //add this
world[x] is not an array so you get an error when trying to assign a value to world[x][y], your method of filling the array seems strange to me, I'd do it this way
world = [];
for (x = 0; x <= 49; x++) { //generate world
world[x] = [];
for (y = 0; y <= 49; y++){
world[x][y] = parseInt(Math.floor(Math.random()*2)); //0 = flatland, 1 = desert, 2 = mountain, 3 = swamp
}
}
x = 0;
y = 0;
You are missing the (). World must be defined as a two dimensional array world[x] = new Array(); Using the [] notation is more convenient.

Categories

Resources