Which point makes difference of execution speed in JS? - algorithm

im studying Algorithm with Javascript.
It is a problem abt dijkstra algorith.
but i always meet TLE(Time Limit Exceeded) in the last case.
could i know which point makes my code slower.
i tried many ways like below
without function constructor
console output with forEach
take input with require('readline')
without recursive heapify
it is the problem link.
https://onlinejudge.u-aizu.ac.jp/courses/lesson/1/ALDS1/12/ALDS1_12_C
It is my solution.
function MinPQ() {
this.heap = [];
}
MinPQ.prototype.swap = function (i, j) {
const temp = this.heap[i];
this.heap[i] = this.heap[j];
this.heap[j] = temp;
};
MinPQ.prototype.insert = function (n) {
const parentIdx = (idx) => Math.floor((idx - 1) * 0.5);
this.heap.push(n);
let curr = this.heap.length - 1;
let parent = parentIdx(curr);
while (curr > 0 && this.compare(curr, parent)) {
this.swap(curr, parent);
curr = parent;
parent = parentIdx(curr);
}
};
MinPQ.prototype.shift = function () {
const heapify = (idx) => {
let l = idx * 2 + 1;
let r = idx * 2 + 2;
let minIdx = idx;
if (l < this.heap.length && this.compare(l, minIdx)) {
minIdx = l;
}
if (r < this.heap.length && this.compare(r, minIdx)) {
minIdx = r;
}
if (minIdx !== idx) {
this.swap(idx, minIdx);
heapify(minIdx);
}
};
this.swap(0, this.heap.length - 1);
const root = this.heap.pop();
heapify(0);
return root;
};
MinPQ.prototype.compare = function (i, j) {
return this.heap[i][1] < this.heap[j][1];
};
function solution(input) {
const n = Number(input.shift());
const G = Array(n);
for (let i = 0; i < n; i++) {
const [u, k, ...adjs] = input.shift().split(' ').map(Number);
G[u] = [];
for (let j = 0; j < k; j++) {
const v = adjs[2 * j];
const c = adjs[2 * j + 1];
G[u][v] = c;
}
}
return dijkstra(n, G)
.map((e, idx) => `${idx} ${e}`)
.join('\n');
}
function dijkstra(n, G) {
const minPQ = new MinPQ();
const d = Array(n).fill(Infinity);
let count = 0;
minPQ.insert([0, 0]);
while (count < n) {
const node = minPQ.shift();
const [u, cost] = node;
if (d[u] < Infinity) continue;
d[u] = cost;
count++;
G[u].forEach((e, idx) => {
minPQ.insert([idx, cost + e]);
});
}
return d;
}
(function (test) {
const printSolution = (input) => console.log(solution(input));
if (test) {
printSolution([
'5',
'0 3 2 3 3 1 1 2',
'1 2 0 2 3 4',
'2 3 0 3 3 1 4 1',
'3 4 2 1 0 1 1 4 4 3',
'4 2 2 1 3 3',
]);
console.log('--');
printSolution([
'9',
'0 2 1 1 3 13',
'1 3 0 1 2 1 4 11',
'2 2 5 1 1 1',
'3 3 4 1 0 13 6 1',
'4 4 1 11 5 1 3 1 7 4',
'5 3 2 1 8 7 4 1',
'6 2 3 1 7 1',
'7 3 4 4 6 1 8 1',
'8 2 5 7 7 1',
]);
return;
}
printSolution(
require('fs').readFileSync('/dev/stdin', 'utf-8').split('\n')
);
})(0);
It is the solution what passed last case.
var h = [],hs = 0;
h[0] = new Array(2);
h[0][0] = -1;h[0][1] = -1;
function insert(key){
h[++hs] = key;
var i = hs;
while(h[i][1] < h[Math.floor(i / 2)][1]){
var ex = h[i];
h[i] = h[Math.floor(i / 2)];
h[Math.floor(i / 2)] = ex;
i = Math.floor(i / 2);
}
}
function extract(){
if(hs <= 0)
return;
var ret = h[1];
h[1] = h[hs--];
i = 1;
while((i * 2 <= hs && h[i][1] > h[i * 2][1]) || (i * 2 + 1 <= hs && h[i][1] > h[i * 2 + 1][1])){
var l = i * 2;var r = i * 2;
if(i * 2 + 1 <= hs)
r++;
var m = h[l][1] <= h[r][1] ? l : r;
var ex = h[i];
h[i] = h[m];
h[m] = ex;
i = m;
}
return ret;
}
function Main(input){
input = input.split("\n");
var n = parseInt(input[0],10);
var graph = new Array(n);
for(var i = 0;i < n;i++){
input[i + 1] = input[i + 1].split(" ");
var u = parseInt(input[i + 1][0],10);
var k = parseInt(input[i + 1][1],10);
graph[u] = new Array(k);
for(var j = 0;j < k;j++)
graph[u][j] = new Array(2);
for(var j = 0;j < k;j++){
graph[u][j][0] = parseInt(input[i + 1][j * 2 + 2],10);
graph[u][j][1] = parseInt(input[i + 1][j * 2 + 3],10);
}
}
var count = 1;
var sum = Array(n);
for(var i = 0;i < n;i++)
sum[i] = 1000000000;
sum[0] = 0;
for(var i = 0;i < graph[0].length;i++){
insert(graph[0][i]);
}
while(count < n){
var aa = extract();
if(sum[aa[0]] < 1000000000)
continue;
sum[aa[0]] = aa[1];
count++;
for(var i = 0;i < graph[aa[0]].length;i++){
graph[aa[0]][i][1] += sum[aa[0]];
insert(graph[aa[0]][i]);
}
}
for(var i = 0;i < n;i++){
console.log(i + " " + sum[i]);
}
}
Main(require("fs").readFileSync("/dev/stdin","utf8"));

Related

resetting the particular sudoku box in p5?

I am trying to implement a Sudoku table in p5.js, I am able to implement a cell where I can write a number (1-9) down. But I cannot remove a number, i.e. if I write '1' first on a cell and write '2', it writes on top of it.
So, how can I remove the existing number and write a different one?
EDIT:
my code till now:
//make a grid
function makegrid(rows, cols) {
var regrid = new Array(rows);
for (var i = 0; i < rows; i++) {
regrid[i] = new Array(cols);
}
return regrid;
}
var numrec = [];
var rows = 9;
var grid = [];
var cols = 9;
var w = 50;
var input;
//show the boxes
function show(i, j) {
this.i = i;
this.j = j;
var x = w * this.i;
var y = w * this.j;
noFill();
//input = createInput();
//input.position(x+5,y+5,w);
strokeWeight(1);
rect(x + 5, y + 5, w, w); //just to see line clearly
}
//there must be a better way to do it but for now ---> here we go for separation
// of tables
function boldlines() {
strokeWeight(4);
stroke(51);
line(5, 5, 5, w * 9 + 5);
line(w * 3 + 5, 5, w * 3 + 5, w * 9 + 5);
line(w * 6 + 5, 5, w * 6 + 5, w * 9 + 5);
line(5, w * 9 + 5, w * 9 + 5, w * 9 + 5);
line(5, 5, w * 9 + 5, 5);
line(w * 9 + 5, 5, w * 9 + 5, w * 9 + 5);
line(5, w * 3 + 5, w * 9 + 5, w * 3 + 5);
line(5, w * 6 + 5, w * 9 + 5, w * 6 + 5);
}
function setup() {
createCanvas(600, 600);
grid = makegrid(rows, cols);
numrec = makegrid(rows, cols);
for (var i = 0; i < rows; i++) {
for (var j = 0; j < cols; j++) {
numrec[i][j] = 1;
}
}
}
function draw() {
boldlines();
for (var i = 0; i < rows; i++) {
for (var j = 0; j < cols; j++) {
show(i, j);
//console.log(mouseX,mouseY);
}
}
}
function numput(x, y, num) {
//background(0);
if (num === 0) {
num = "";
}
textSize(30);
//textAlign(CENTER);
text(num, x + 30, y + 40);
}
function mousePressed() {
var mx = mouseX;
var my = mouseY;
var i = floor((mx + 5) / w);
var j = floor((my + 5) / w);
if (i >= 0 && j >= 0 && i < rows && j < cols) {
//console.log(i, j);
var num = numrec[i][j];
if (num === 10) {
num = 0;
}
numrec[i][j] = num + 1;
numput(i * w, j * w, num);
}
}
I figured out a way to hide old number in that cell and retain the content of all the other cells. I hid the previous number by drawing a rectangle on top of it with the same dimensions of that of a cell and then updating the cell with new number.
function numput(x, y, num) {
//background(0);
if (num === 0) {
num = "";
}
textSize(30);
//textAlign(CENTER);
//Newly added
strokeWeight(0);
fill(255,255,255);
rect(x+4 , y+4 , w, w);
boldlines();
text(num, x + 30, y + 40);
}
I have done some changes in function numput() to achieve it.

Slickgrid paging issue for search - page number is wrong when pagesize = search item count on second page

If I do a search on a page greater than 1 and if the number of items returned from the search are equal to the pagesize then the page does not flip back to the previous page and says the wrong page number.
For example if I have 5 items and the page size is set to 4. If I do a search on the second page that returns 4 items then the page won't flip back to page 1 and the grid says Page 2 of 1.
I also get the same error if I change example4 -
http://mleibman.github.io/SlickGrid/examples/example4-model.html
Replace this code -
for (var i = 0; i < 50000; i++) {
var d = (data[i] = {});
d["id"] = "id_" + i;
d["num"] = i;
d["title"] = "Task " + i;
d["duration"] = "5 days";
d["percentComplete"] = Math.round(Math.random() * 100);
d["start"] = "01/01/2009";
d["finish"] = "01/05/2009";
d["effortDriven"] = (i % 5 == 0);
}
with this -
var x;
for (var i = 0; i < 5; i++) {
var d = (data[i] = {});
if (i == 0)
x = "1";
if (i == 1)
x = "11";
if (i == 2)
x = "111";
if (i == 3)
x = "1111";
if (i == 4)
x = "2";
d["id"] = "id_" + i;
d["num"] = i;
d["title"] = "Task " + x;
d["duration"] = "5 days";
d["percentComplete"] = Math.round(Math.random() * 100);
d["start"] = "01/01/2009";
d["finish"] = "01/05/2009";
d["effortDriven"] = (i % 5 == 0);
}
Add this line -
dataView.setPagingOptions({pageSize: 4});
Go to page 2 and search for Task 1. It should say Showing Page 2 of 1.
I think your rowCount was not updated. Have you added this on your script?
dataView.onRowCountChanged.subscribe(function (e, args) {
grid.updateRowCount();
grid.render();
});
dataView.onRowsChanged.subscribe(function (e, args) {
grid.invalidateRows(args.rows);
grid.render();
});
Update: Add this code on your slick.dataview.js. Find this around line 750
var paged;
if (pagesize) {
if (filteredItems.length < pagenum * pagesize) {
pagenum = Math.floor(filteredItems.length / pagesize);
}
//.. add this code
// START
if (filteredItems.length == pagenum * pagesize && pagenum > 0)
pagenum --;
// END
paged = filteredItems.slice(pagesize * pagenum, pagesize * pagenum + pagesize);
} else {
paged = filteredItems;
}

Making your own wildcard and recognize patterns to zip your list

I have an algorithm trouble, I don't know how to do it and how to call it (Does it have any specific name?)
For example, if I have this sequence:
000 CASE_01
001 CASE_02
010 CASE_03
011 CASE_02
100 CASE_02
101 CASE_01
110 CASE_01
111 CASE_01
I want to convert it in something like this:
000 CASE_01
0-1 CASE_02
010 CASE_03
100 CASE_02
1-1 CASE_01
11- CASE_01
I have called it wildcard because I think is the most correct way...
They not necessarily have 3 bits, you must do it with n bits
If only I had the psudo-code I could write it to any language (Python in my way)
The code below generates all possible wildcard strings for the number of bits encountered in the input (e.g. --, -0, -1, 0-, 00, 01, 1-, 10 and 11 for 2 bits), and also creates patterns where numbers are inverted and wildcards become 1 (so wildcard 0-1 has pattern 110), and masks where numbers become 1 and wildcards become 0 (so wildcard 0-1 has mask 101).
The binary numbers in the input are then XOR-ed with the patterns and AND-ed with the masks to check whether they fit a certain wildcard. If a wildcard has the required number of matching numbers (2 ^ number_of_wildcards), it is added to the output and the matching numbers are removed from the input.
Run the code snippet to see the algorithm in action with your example input, to which I added a fourth case with larger binary numbers.
function wildcard(input) {
var output = [], cases = [], wilds = [], patts = [], masks = [];
var bits = groupCases(cases);
for (var i = 0; i <= bits; i++) wilds[i] = [];
wildStrings(bits);
convertStrings(wilds, patts, "-01", "110");
convertStrings(wilds, masks, "-01", "011");
for (var c = 0; c < cases.length; c++) {
for (var i = 0, j = Math.pow(2, bits); i <= bits; i++, j /= 2) {
for (var k = 0; k < patts[i].length; k++) {
var patt = patts[i][k];
var mask = masks[i][k];
var matches = [];
for (var d = 0; d < cases[c].nums.length; d++) {
var num = cases[c].nums[d];
if (((num ^ patt) & mask) == mask) matches.push(d);
}
if (matches.length == j) {
output.push(wilds[i][k] + " " + cases[c].id);
for (var l = j - 1; l >= 0; l--) cases[c].nums.splice(matches[l], 1);
}
}
}
}
return output;
function groupCases(cases) {
var max = 0;
for (var i = 0; i < input.length; i++) {
var num = parseInt(input[i], 2);
if (num > max) max = num;
var id = input[i].slice(input[i].indexOf(" ") + 1);
var pos = 0;
while (cases[pos] != undefined && cases[pos].id != id) ++pos;
if (cases[pos] == undefined) cases[pos] = {id: id, nums: []};
cases[pos].nums.push(num);
}
return Math.ceil(Math.log(max) / Math.log(2));
}
function wildStrings(len, wild, str) {
wild = wild || 0;
str = str || "";
for (var i = 0; i < 3; i++) {
var w = (i == 0) ? 1 : 0;
var s = str + ["-","0","1"][i];
if (len > 1) wildStrings(len - 1, wild + w, s)
else wilds[bits - wild - w].push(s);
}
}
function convertStrings(input, output, from, to) {
for (var i = 0; i < input.length; i++) {
output[i] = [];
for (var j = 0; j < input[i].length; j++) {
var str = input[i][j], s = "";
for (var k = 0; k < str.length; k++) {
s += to.charAt(from.indexOf(str.charAt(k)));
}
output[i].push(parseInt(s, 2));
}
}
}
}
var a = ["000 CASE_01", "001 CASE_02", "010 CASE_03", "1010 CASE_04",
"011 CASE_02", "100 CASE_02", "1110 CASE_04", "101 CASE_01",
"110 CASE_01", "1100 CASE_04", "1000 CASE_04", "111 CASE_01"];
var w = wildcard(a);
document.write(w.length + " wildcards:<BR><PRE>");
for (var i in w) document.write(w[i] + "<BR>");

Replacing recursion with iteration

I have a recursive function which I need to convert to an iterative function but I am quite stuck. Can anyone help or point me in the right direction?
f :: Int -> Int
f(0) = 5
f(1) = 8
f(2) = 3
f(n) = (f(n-3)) * (f(n-1))
Cheers
The following code snippet should do the trick:
int output[1000];
output[0] = 5;
output[1] = 8;
output[2] = 3;
for (int i=3; i < 1000; ++i) {
output[i] = output[i-3] * output[i-1];
}
Bonus: Implementing your function non-recursively in this manner is called dynamic programming.
This looks like it works. Essentially it keeps the most recent 3 numbers and walks them upwards until we hit n.
public int rf(int n) {
return n == 0 ? 5
: n == 1 ? 8
: n == 2 ? 3
: rf(n - 3) * rf(n - 1);
}
public int nrf(int n) {
int[] v = {5, 8, 3};
int x = n == 0 ? 5
: n == 1 ? 8
: n == 2 ? 3
: 0;
for (int i = 2; i < n; i++) {
x = v[0] * v[2];
v[0] = v[1];
v[1] = v[2];
v[2] = x;
}
return x;
}
public void test() {
for (int i = 0; i < 10; i++) {
System.out.println(rf(i) + " = " + nrf(i));
}
}
Correctly prints:
5 = 5
8 = 8
3 = 3
15 = 15
120 = 120
360 = 360
5400 = 5400
648000 = 648000
233280000 = 233280000
1286582272 = 1286582272

Algorithm for finding smallest number with given number of factors

What's the most efficient algorithm anyone can think of that, given a natural number n, returns the least natural number x with n positive divisors (including 1 and x)? For example, given 4 the algorithm should result in 6 (divisors: 1,2,3,6); i.e. 6 is the smallest number having 4 distinct factors. Similarly, given 6, the algorithm should result in 12 (divisors: 1,2,3,4,6,12); i.e. 12 is the smallest number having 6 distinct factors
In terms of real-world performance, I'm looking for a scalable algorithm which can give answers of the order of 1020 within 2 seconds on a machine which can do 107 computations per second.
http://www.primepuzzles.net/problems/prob_019.htm
b) Jud McCranie, T.W.A. Baumann & Enoch Haga sent basically the same
procedure to find N(d) for a given d:
Factorize d as a product of his prime divisors: d = p1a1 * p2a2 *p3a3 *...
convert this factorization in another arithmetically equivalent factorization, composed of non-powered monotonically decreasing and not
necesarilly prime factors... (uf!...) d = p1a1 * p2a2 *p3a3 *... =
b1 * b2 * b3... such that b1 ≥ b2 ≥ b3...
You must realize that for every given d, there are several
arithmetically equivalent factorizations that can be done: by example:
if d = 16 = 24 then there are 5 equivalent factorizations:
d = 2*2*2*2 = 4*2*2 = 4*4 = 8*2 = 16
N is the minimal number resulting of computing 2b1-1 * 3b2-1 * 5b3-1 * ... for all the equivalent factorizations of d. Working the same example:
N(16) = the minimal of these {2 * 3 * 5 * 7, 23 * 3 * 5, 23 * 33, 27 * 3, 215} = 23 * 3 * 5 = 120
Update: With numbers around 1020, pay attention to the notes by Christian Bau quoted on the same page.
//What is the smallest number with X factors?
function smallestNumberWithThisManyFactors(factorCount) {
Number.prototype.isPrime = function() {
let primeCandidate = this;
if(primeCandidate <= 1 || primeCandidate % 1 !== 0) return false
let i = 2;
while(i <= Math.floor(Math.sqrt(primeCandidate))){
if(primeCandidate%i === 0) return false;
i++;
}
return true;
}
Number.prototype.nextPrime = function() {
let currentPrime = this;
let nextPrimeCandidate = currentPrime + 1
while(nextPrimeCandidate < Infinity) {
if(nextPrimeCandidate.isPrime()){
return nextPrimeCandidate;
} else {
nextPrimeCandidate++;
}
}
}
Number.prototype.primeFactors = function() {
let factorParent = this;
let primeFactors = [];
let primeFactorCandidate = 2;
while(factorParent !== 1){
while(factorParent % primeFactorCandidate === 0){
primeFactors.push(primeFactorCandidate);
factorParent /= primeFactorCandidate;
}
primeFactorCandidate = primeFactorCandidate.nextPrime();
}
return primeFactors;
}
Number.prototype.factors = function() {
let parentNumber = this.valueOf();
let factors = []
let iterator = parentNumber % 2 === 0 ? 1 : 2
let factorCandidate = 1;
for(factorCandidate; factorCandidate <= Math.floor(parentNumber/2); factorCandidate += iterator) {
if(parentNumber % factorCandidate === 0) {
factors.push(factorCandidate)
}
}
factors.push(parentNumber)
return factors
}
Array.prototype.valueSort = function() {
return this.sort(function (a,b){ return a-b })
}
function clone3DArray(arrayOfArrays) {
let cloneArray = arrayOfArrays.map(function(arr) {
return arr.slice();
});
return cloneArray;
}
function does3DArrayContainArray(arrayOfArrays, array){
let aOA = clone3DArray(arrayOfArrays);
let a = array.slice(0);
for(let i=0; i<aOA.length; i++){
if(aOA[i].sort().join(',') === a.sort().join(',')){
return true;
}
}
return false;
}
function removeDuplicateArrays(combinations) {
let uniqueCombinations = []
for(let c = 0; c < combinations.length; c++){
if(!does3DArrayContainArray(uniqueCombinations, combinations[c])){
uniqueCombinations[uniqueCombinations.length] = combinations[c];
}
}
return uniqueCombinations;
}
function generateCombinations(parentArray) {
let generate = function(n, src, got, combinations) {
if(n === 0){
if(got.length > 0){
combinations[combinations.length] = got;
}
return;
}
for (let j=0; j<src.length; j++){
generate(n - 1, src.slice(j + 1), got.concat([src[j]]), combinations);
}
return;
}
let combinations = [];
for(let i=1; i<parentArray.length; i++){
generate(i, parentArray, [], combinations);
}
combinations.push(parentArray);
return combinations;
}
function generateCombinedFactorCombinations(primeFactors, primeFactorCombinations) {
let candidates = [];
for(let p=0; p<primeFactorCombinations.length; p++){
let product = 1;
let primeFactorsCopy = primeFactors.slice(0);
for(let q=0; q<primeFactorCombinations[p].length; q++){
product *= primeFactorCombinations[p][q];
primeFactorsCopy.splice(primeFactorsCopy.indexOf(primeFactorCombinations[p][q]), 1);
}
primeFactorsCopy.push(product);
candidates[candidates.length] = primeFactorsCopy.valueSort().reverse();
}
return candidates;
}
function determineMinimumCobination (candidates){
let minimumValue = Infinity;
let bestFactorCadidate = []
for(let y=0; y<candidates.length; y++){
let currentValue = 1;
let currentPrime = 2;
for(let z=0; z<combinedFactorCandidates[y].length; z++){
currentValue *= Math.pow(currentPrime,(combinedFactorCandidates[y][z])-1);
currentPrime = currentPrime.nextPrime();
}
if(currentValue < minimumValue){
minimumValue = currentValue;
bestFactorCadidate = combinedFactorCandidates[y];
}
}
return minimumValue;
}
let primeFactors = factorCount.primeFactors();
let primeFactorCombinations = removeDuplicateArrays(generateCombinations(primeFactors));
let combinedFactorCandidates = generateCombinedFactorCombinations(primeFactors, primeFactorCombinations);
let smallestNumberWithFactorCount = determineMinimumCobination(combinedFactorCandidates);
console.log('The smallest number with ' + factorCount + ' factors is: ')
console.log(smallestNumberWithFactorCount)
console.log('With these factors being: ')
console.log(smallestNumberWithFactorCount.factors())
return smallestNumberWithFactorCount;
}
smallestNumberWithThisManyFactors(10)

Resources