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));
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]]
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.