Is this DFS time complexity On? If not, how to optimize it? Can it be On? - foreach

function findPaths(data, start) {
var paths = [];
var stack = [];
var map = {};
data.forEach(d=>map[d.id] = d);
stack.push({
node: start,
path: [],
cid: '*'
});
var j = 0;
while (stack.length > 0) {
j++;
var {node, path, cid} = stack.pop();
path.push(node.id);
if (!node.children || !node.children.length) {
if (!paths.includes(path + '')) {
paths.push(path + '');
}
} else {
for (var i = node.children.length - 1; i >= 0; i--) {
var children = node.children[i];
var target = map[children.p];
if (target) {
stack.push({
node: target,
path: path.slice(),
cid: children.cid
});
} else {
path.push(children.p);
if (!paths.includes(path + '')) {
paths.push(path + '');
}
path.pop();
}
}
}
}
console.log(j);
return paths;
}
var all = [{id: 10000, children: [{cid:10001, p:20000}, {cid: 10002, p:40000}]},
{id: 20000, children: [{cid:20001, p:30000}]},
{id: 30000, children: [{cid:30001, p:40000}]},
{id: 40000,}]
console.log(findPaths(all, all[0]));
When the length of all reaches the order of 100, it takes about 10 seconds to get the result.
Is my method inappropriate? Or is it true that the full path printing problem has such a high time complexity? Any help is greatly appreciated

Related

Convert google sheet Row and column in JSON using app script

Is there any way to convert this=> google sheet into the below given JSON object using AppScript. I'm new to AppScript I dont have idea how to make this row and column in the below given object. Thanks in advance.
{
"data":[
{
"insurer":"CompanyName1",
"products":[
{
"name":"product1",
"UIN":"104N079V01"
},
{
"name":"product2",
"UIN":"104N079V02"
}
]
},
{
"insurer":"CompanyName2",
"products":[
{
"name":"product1",
"UIN":"104N079V01"
},
{
"name":"product2",
"UIN":"104N079V02"
}
]
}
]
}
Try
function data2json() {
var sh = SpreadsheetApp.getActiveSheet()
var values = sh.getRange('A1').getDataRegion().getValues()
// Logger.log(values)
var jsn = {}
jsn['data'] = []
var n = -1
var m = 0
values.forEach(function (r, i) {
if (i > 0) {
if (r[1] != '') {
n++
jsn['data'][n] = {}
jsn['data'][n]['insurer'] = r[1]
jsn['data'][n]['products'] = []
m = -1
}
m++
jsn['data'][n]['products'][m] = {}
jsn['data'][n]['products'][m]['name'] = r[2]
jsn['data'][n]['products'][m]['UIN'] = r[3]
}
})
Logger.log(JSON.stringify(jsn))
}
example
result
{"data":[{"insurer":"CompanyName1","products":[{"name":"product1","UIN":"A"},{"name":"product2","UIN":"B"},{"name":"product3","UIN":"C"},{"name":"product4","UIN":"D"}]},{"insurer":"CompanyName2","products":[{"name":"product5","UIN":"E"},{"name":"product6","UIN":"F"},{"name":"product7","UIN":"G"},{"name":"product8","UIN":"H"}]},{"insurer":"CompanyName3","products":[{"name":"product9","UIN":"I"},{"name":"product10","UIN":"J"},{"name":"product11","UIN":"K"}]}]}

Dart how to get max duplicated element in a list

I have List list= [1,2,3,4,4,4,9,6,7,7,7,8,8,8,8,8,8,8];
how can i return 8 as max repeated value
Something like this?
void main() {
final list = [1, 2, 3, 4, 4, 4, 9, 6, 7, 7, 7, 8, 8, 8, 8, 8, 8, 8];
print(findMaxDuplicatedElementInList(list)); // 8
}
T findMaxDuplicatedElementInList<T>(Iterable<T> list) => list
.fold<Map<T, int>>(
{},
(map, element) =>
map..update(element, (value) => value + 1, ifAbsent: () => 1))
.entries
.reduce((e1, e2) => e1.value > e2.value ? e1 : e2)
.key;
I'd just write it out, as straight-forward as possible:
Assuming the equal elements are always adjacent, and list cannot be empty, return arbitrary element with maximal count if there is more than one:
T maxDuplicated<T>(List<T> elements) {
var element = elements.count;
var count = 1;
var maxElement = element;
var maxCount = count;
for (var i = 1; i < elements.length; i++) {
var nextElement = elements[i];
if (element != nextElement) {
element = nextElement;
count = 1;
} else {
count += 1;
if (count > maxCount) {
maxElement = element;
maxCount = count;
}
}
}
return maxElement;
}
Assuming elements come in random order, so we need to remember every element we have seen,
still not allowing an empty list as input:
T maxDuplicated<T>(List<T> elements) {
var maxCount = 1;
var maxElement = elements.first
var seen = <T, int>{maxElement: maxCount};
for (var i = 1; i < elements.length; i++) {
var element = elements[i];
var count = seen[element] = (seen[element] ?? 0) + 1;
if (count > maxCount) {
maxCount = count;
maxElement = element;
}
}
return maxElement;
}
(Alternatively, I'd sort the list first, if allowed, to always be in the former situation. It's not faster than using a map, if we assume hash map lookup to be a constant time operation, but it will be more memory efficient.)

Automatic hiding columns based on cell value in google spreadsheets

I have too many columns in the sheet and so many columns to hide as well, but while executing the script it runs half way and stopped saying maximum time reached.
When I again tried to execute it stopped exactly where I stopped previously. So I would like to have some customization that if the column is already hidden can skip that column and work on the others.
Is there any way to do it.
Here is the code I used:
function hideColumns() {
var ss = SpreadsheetApp.getActiveSpreadsheet();
var sh = ss.getSheetByName('ANALYTIC');
var data = sh.getRange('6:6').getValues();
var numCols = sh.getMaxColumns();
var numRows = sh.getMaxRows();
for(var i = 0; i <= numCols; i++){
if(data[0][i] == ""){
sh.hideColumns(i+1);
} else {
sh.unhideColumn(sh.getRange(1, i+1, numRows, 1));
}
}
}
Please help me.
You can use the documentProperties to store the last column before the end of the execution. To prevent the run from stopping abruptly you stop the run a little prematurely at 5min (execution will terminate at 6min mark) mark and store the column number in the documentProperty. You also display an alert asking you rerun the script.
Then retrieve the column number on the next run and start from there. If the program gets through the complete loop you delete the said properties. So you start from zero if you rerun the script next time.
Below is the code for the same
function hideColumns() {
var ss = SpreadsheetApp.getActiveSpreadsheet();
var sh = ss.getSheetByName('ANALYTIC');
var data = sh.getRange('6:6').getValues();
var numCols = sh.getMaxColumns();
var numRows = sh.getMaxRows();
var docProp = PropertiesService.getDocumentProperties()
var startCol = Number(docProp.getProperty("startCol")) //if there is no propert called startCol will return Null, Number(Null) = 0
Logger.log(startCol)
var startTime = new Date().getTime()
var ms5min = 5*60*1000 //5min in millseconds
for(var i = startCol; i <= numCols; i++){
if(data[0][i] == ""){
sh.hideColumns(i+1);
} else {
sh.unhideColumn(sh.getRange(1, i+1, numRows, 1));
}
var curTime = new Date().getTime()
var elasped = curTime-startTime
if (elasped >= ms5min){
docProp.setProperty("startCol", i)
SpreadsheetApp.getUi().alert("Please restart Run, exceeded 5min mark")
return
}
}
Logger.log(elasped)
docProp.deleteAllProperties()
}
If your sheet has under 10,000 columns (PropertiesService limit) you can use this script:
function hideColumns() {
var ss = SpreadsheetApp.getActiveSpreadsheet();
var sh = ss.getSheetByName('ANALYTIC');
var data = sh.getRange('6:6').getValues();
var documentProperties = PropertiesService.getDocumentProperties()
var documentPropertiesVals = documentProperties.getProperties();
var numCols = sh.getMaxColumns();
for(var i = 0; i < numCols; i++){
if (!(cPlusInt(i) in documentPropertiesVals)) {
documentPropertiesVals[cPlusInt(i)] === 'empty';
}
if (documentPropertiesVals[cPlusInt(i)] === 'hidden' && data[0][i] == "") continue;
if (documentPropertiesVals[cPlusInt(i)] === 'unhidden' && data[0][i] != "") continue;
if(data[0][i] == ""){
sh.hideColumns(i+1);
documentProperties.setProperty(cPlusInt(i), 'hidden')
} else {
sh.unhideColumn(sh.getRange(1, i+1, 1, 1));
documentProperties.setProperty(cPlusInt(i), 'unhidden')
}
}
}
function cPlusInt(num) {
return 'c'+num.toString()
}
You at first you may need to run this few times (many write operation to PropertiesService may be sluggish) but later it's "blazingly" fast (0.1 s per new column).
Better answer using #Jack Brown's idea
It is possible to make single save to PropertiesService - you would need to incorporate time limit from #Jack Brown's answer, this way:
function hideColumns() {
var ss = SpreadsheetApp.getActiveSpreadsheet();
var sh = ss.getSheetByName('ANALYTIC');
var data = sh.getRange('6:6').getValues();
var documentProperties = PropertiesService.getDocumentProperties()
var documentPropertiesVals = documentProperties.getProperties();
var numCols = sh.getMaxColumns();
var startTime = new Date().getTime()
var ms5min = 5*60*1000 //5min in millseconds
for(var i = 0; i < numCols; i++){
if (!(cPlusInt(i) in documentPropertiesVals)) {
documentPropertiesVals[cPlusInt(i)] === 'empty';
}
if (documentPropertiesVals[cPlusInt(i)] === 'hidden' && data[0][i] == "") continue;
if (documentPropertiesVals[cPlusInt(i)] === 'unhidden' && data[0][i] != "") continue;
if(data[0][i] == ""){
sh.hideColumns(i+1);
documentPropertiesVals[cPlusInt(i)] = 'hidden'
} else {
sh.unhideColumn(sh.getRange(1, i+1, 1, 1));
documentPropertiesVals[cPlusInt(i)] = 'unhidden'
}
var curTime = new Date().getTime()
var elapsed = curTime-startTime
if (elapsed >= ms5min){
break;
}
}
documentProperties.setProperties(documentPropertiesVals)
if (elapsed >= ms5min){
SpreadsheetApp.getUi().alert("Please restart Run, exceeded 5min mark")
}
}
cPlusInt function explanation
cPlusInt is necessary because of weird problems with google's PropertiesService. Object gotten from PropertiesService returns undefined at integer keys. To see problem use this code:
function test() {
var obj = {};
for (var i=0; i<10; i++) {
obj[i.toString()] = 'aa' + i.toString();
}
var documentProperties = PropertiesService.getScriptProperties();
documentProperties.deleteAllProperties();
documentProperties.setProperties(obj);
obj = documentProperties.getProperties();
Logger.log(obj)
for (var i in obj) {
Logger.log('%s %s %s', i, obj[i], i === '1');
}
}

mongoid - mongodb, mapreduce get scope varriable or pass it to output

In mapreduce I have a scope total_count to calculate something after grouping something.
How can I get back the that scope varriable in output?
EDIT:
map = %Q{
function() {
ttotal_commission += this.commission;
tuniq_commission += this.commission; // add first if it not goto reduce
emit({ip: this.ip, campaign_id: this.campaign_id}, {commission: this.commission, abc: this.commission});
}
}
reduce = %Q{
function(key, values) {
tuniq_commission += values[0].commission; // add 1 and substract laster for uniq
var total_commission = 0;
values.forEach(function(value) {
tuniq_commission -= value.commission;
total_commission += value.commission;
});
return {};
}
}
final = %Q{
function(key, reduceVal){
reduceVal.ttotal_commission = ttotal_commission;
reduceVal.tuniq_commission = tuniq_commission;
return reduceVal;
}
}
temp = Transaction.all.limit(45000).map_reduce(map, reduce).scope(ttotal_commission: 0, tuniq_commission: 0).finalize(final).out(inline: true).first

How to sort the items within each stacking column?

How to sort the items within each stacking column? Asc or desc.
Each series added to a chart is drawn on the chart in the order it was received. To change the order of the chart series you will need to change which series is the first in your list of series items.
That being said - what I think you want to do is to, independently of the series order, sort on each stack by value. I do not think this is possible in HighCharts.
You can only set global index of serie, but you cannot position each single "stack".
http://api.highcharts.com/highcharts#series.index
You may use the script below to sort the Stacked Chart Bars by category name.
var sortData = function(chartSource) {
var series = chartSource.series;
var axis = chartSource.xAxis[0];
var categories = [];
if($.isArray(series)) {
var ser =
$.grep(series, function(ser, seriesIndex)
{
return ser.visible;
})[0];
$.each(ser.data,
function(dataIndex, datum)
{
console.log(datum.category + ':' + datum.stackTotal);
var obj = {
name: datum.category,
index: dataIndex,
stackTotal: datum.stackTotal
}
categories.push(obj);
}
);
}
categories.sort(function(a, b) {
var aName = a.name.toLowerCase();
var bName = b.name.toLowerCase();
var aTotal = a.stackTotal;
var bTotal = b.stackTotal;
//if(aTotal === bTotal) {
return ((aName < bName) ? -1 : ((aName > bName) ? 1 : 0));
//} else {
// return ((aTotal > bTotal) ? -1 : ((aTotal < bTotal) ? 1 : 0));
//}
});
var mappedIndex = $.map(categories, function(category, index) {
return category.index;
});
categories = $.map(categories, function(category, index) {
return category.name;
});
console.log(categories);
console.log(mappedIndex);
axis.setCategories(categories);
var newDataArray = [];
$.each(series, function(seriesIndex, ser) {
newDataArray = [];
var data = $.map(mappedIndex, function(mappedIndex2, origIndex) {
var ydata = ser.data[mappedIndex2];
if(ydata.y!=null){
var y = ydata.y
newDataArray.push(y);
return y;
}
else
{
newDataArray.push(null);
return null;
}
});
ser.setData(newDataArray);
});
};

Resources