JavaScript binary operators - javascript

Working on a WebGL project and I am looking over code from a class example. In one of the loops this code was given:
var c = (((i & 0x8) == 0) ^ ((j & 0x8) == 0));
The variables i and j go up to a certain value in a for loop. What does this statement mean? Does this make sure that the variable c is in hexadecimal form?
var texSize = 64;
var image1 = new Array();
for (var i =0; i<texSize; i++)
image1[i] = new Array();
for (var i =0; i<texSize; i++)
for ( var j = 0; j < texSize; j++)
image1[i][j] = new Float32Array(4);
for (var i =0; i<texSize; i++)
for (var j=0; j<texSize; j++)
{
var c = (((i & 0x8) == 0) ^ ((j & 0x8) == 0));
image1[i][j] = [c, c, c, 1];
}

SMchrohan's answer is correct. The code is basically making a checkerboard texture.
The ?? & 0x8 means it that expression will be true when bit 3 (0,1,2,3) is true. bit 3 in binary is true every other set of 8 values (0-7 it's false, 8-15 it's true, 16-23 it's false, etc).
Then the code takes the opposite of that with == 0.
It does it for both i and j.
The ^ means exclusive-or which is true when both parts are the different (true, false or false, true) and false when they are both the same (false, false, or true, true). Because ^ is a bitwise operator both values are first converted to integers so false becomes 0 and true becomes 1. The 2 int values then have their bits exclusive-ored so
0 ^ 0 = 0
1 ^ 0 = 1
0 ^ 1 = 1
1 ^ 1 = 0
that means each entry in image1 is either [0, 0, 0, 1] or [1, 1, 1, 1]
here's some code to plot it
var texSize = 64;
var image1 = new Array();
for (var i =0; i<texSize; i++)
image1[i] = new Array();
for (var i =0; i<texSize; i++)
for ( var j = 0; j < texSize; j++)
image1[i][j] = new Float32Array(4);
for (var i =0; i<texSize; i++)
for (var j=0; j<texSize; j++)
{
var c = (((i & 0x8) == 0) ^ ((j & 0x8) == 0));
image1[i][j] = [c, c, c, 1];
}
// lets plot it
var ctx = document.createElement("canvas").getContext("2d");
document.body.appendChild(ctx.canvas);
ctx.canvas.width = texSize;
ctx.canvas.height = texSize;
for (var i =0; i<texSize; i++)
for (var j=0; j<texSize; j++)
{
var c = image1[i][j][0]
ctx.fillStyle = c ? "red" : "yellow";
ctx.fillRect(i, j, 1, 1);
}
canvas { border: 1px solid black; }
<body></body>
Note that the code doesn't appear to make much sense. It says texSize so it seems to be making a texture but it's making one Float32Array per pixel (the line that says)
image1[i][j] = new Float32Array(4);
and then it's replacing each of those individual Float32Arrays with a JavaScript native array on this line
image1[i][j] = [c, c, c, 1];
Which makes the Float32Array line useless.
On top of that I have no idea what an array or arrays of 1 pixel Float32Arrays is good for. You can't upload it like that to WebGL.
Normally I'd make one Uint8Array for the entire texture like this
var texSize = 64;
var pixels = new Uint8Array(texSize * texSize * 4);
for (var i =0; i<texSize; i++) {
for (var j=0; j<texSize; j++) {
var c = (((i & 0x8) == 0) ^ ((j & 0x8) == 0));
var p = c ? 255 : 0;
var offset = (i * texSize + j) * 4;
pixels[offset + 0] = p; // red
pixels[offset + 1] = p; // green
pixels[offset + 2] = p; // blue
pixels[offset + 3] = 255;// alpha
}
}
Or I'd use the 2D canvas API to make the texture
without some context though I don't know what the final purpose of the code is.

& is bitwise and.
^ is bitwise xor.
0x8 is the hex expression of the integer 8.
c will be 1 if either i or j BUT NOT BOTH have a 1 in their 4th bit - that is, a bitwise and with 0x8 (binary 1000) returns 0.
To walk through this a little more:
i & 0x8 will return either 0 (if the value of i has a 0 in bit 4) or 8 (if it has a 1 in that position).
(i & 0x8) == 0 will be either true or false.
(((i & 0x8) == 0) ^ ((j & 0x8) == 0)) will be 1 if either ((i & 0x8) == 0) or ((j & 0x8) == 0) is true, or 0 if both are false OR both are true.

Related

The algorithm problem: Unique Paths III. Using backtracing pattern in javascript and not work

On a 2-dimensional grid, there are 4 types of squares:
1 represents the starting square.  There is exactly one starting square.
2 represents the ending square.  There is exactly one ending square.
0 represents empty squares we can walk over.
-1 represents obstacles that we cannot walk over.
Return the number of 4-directional walks from the starting square to the ending square, that walk over every non-obstacle square exactly once.
source:力扣(LeetCode)
link:https://leetcode-cn.com/problems/unique-paths-iii
i'm trying to use backtrack pattern to solve this problem
here is my code
/**
* #param {number[][]} grid
* #return {number}
*/
var uniquePathsIII = function(grid) {
let m = grid.length,
n = grid[0].length;
let start, targetIndex1,targetIndex2;
let res = 0;
let zero_counts = 0;
for(let i = 0; i < m; i++){
for(let j = 0; j < n; j++){
if(grid[i][j] == 1){
start = [i,j]
}
else if(grid[i][j] == 0){
zero_counts += 1;
}
else if(grid[i][j] == 2){
targetIndex1 = i;
targetIndex2 = j;
}
}
}
const backtrace = (i, j, zero_count) => {
if( i < 0 || i >= m ||
j < 0 || j >= n ||
grid[i][j] == -1 || zero_count < 0)
{
return;
}
if(i == targetIndex1 && j == targetIndex2 ){
if(zero_count == 0)
{
console.log("yes")
res += 1;
}
return
}
grid[i][j] = -1;
backtrace(i+1, j, zero_count - 1)
backtrace(i-1, j, zero_count - 1)
backtrace(i, j+1, zero_count - 1)
backtrace(i, j-1, zero_count - 1)
grid[i][j] = 0;
}
backtrace(start[0], start[1], zero_counts);
return res;
};
test sample:
[[1,0,0,0],[0,0,0,0],[0,0,2,-1]]
expect result:
2
acutal result:
0
Perhaps a simpler solution is to use Depth First Search to solve Unique Paths III, as shown here.
The concept is that you take a point and then traverse in all directions until you hit an obstacle.
The guts are as follows:
int totalPaths = dfs(grid, x+1, y, zero) +
dfs(grid, x, y+1, zero) +
dfs(grid, x-1, y, zero) +
dfs(grid, x, y-1, zero);

JavaScript: Improve performance inside nested loops

how can I optimize the incredibly slow code shown below to speed? I think, JS converts the ints to floats and vise-versa all the time. How can I spot such performance killers? I think, there is much space left to optimize :-). I think, there is a better way to handle the nibble values.
At first, I tried to ditch the &15 operation for the higher nibble. That just slowed more down instead of speed up.
(The code is incomplete. It is just a part taken from a bigger one. It is filling a buffer for createBufferSource(). It should be processed an played as soon as possible after a click event. Currently, on a mobile, it takes up to 2s for an average audio file.)
for (var len = adpcm.length, i = 0; i < len; i++) {
n = [
adpcm.charCodeAt(i) & 15,
(adpcm.charCodeAt(i) >> 4) & 15
];
for (var j = 0; j < 2; j++) {
s = n[j];
stp = imaStepTable[index];
diff = stp >> 3;
if (s & 4) diff += stp;
if (s & 2) diff += (stp >> 1);
if (s & 1) diff += (stp >> 2);
if (s & 8) diff = 0 - diff;
pred += diff;
if (pred > 32760) pred = 32760;
else if (pred < -32760) pred = -32760; //limiter
index += imaIndexTable[s];
if (index < 0) index = 0;
else if (index > 88) index = 88;
for (var k = 0; k < sampleScale; k++) { //resampler
if (!k) {
lPcm[c] = pred / 32768;
rPcm[c] = (c - shift) < 0 ? 0 : lPcm[(c - shift)];
} else {
lPcm[c] = lPcm[c - k];
rPcm[c] = rPcm[c - k];
}
c++;
}
}
}

String Search Algorithm Implementation

I have implemented the string search algorithm using the naive method to count the number of times a substring occurs in a string. I did the implementation in javascript and python.
Algorithm (From Topcoder):
function brute_force(text[], pattern[])
{
// let n be the size of the text and m the size of the
// pattern
count = 0
for(i = 0; i < n; i++) {
for(j = 0; j < m && i + j < n; j++)
if(text[i + j] != pattern[j]) break;
// mismatch found, break the inner loop
if(j == m) // match found
count+=1
return count
}
}
Javascript Implementation:
a = "Rainbow";
b = "Rain";
count = 0;
function findSubStr(Str, SubStr){
for (i = 0; i<a.length; i++){
//document.write(i, '<br/>');
for (j = 0; j < b.length; j++)
//document.write('i = ',i, '<br/>');
//document.write(j, '<br/>');
if(a[i + j] != b[j]) break;
document.write('j = ', j, '<br/>')
//document.write('i = ',i, '<br/>');
if (j == b.length)
count+=1;
}
return count;
}
document.write("Count is ",findSubStr(a,b), '<br/>');
Python Implementation:
a = "Rainbow"
b = "Rain"
def SubStrInStr(Str, SubStr):
count = 0
for i in range(len(Str)):
for j in range(len(SubStr)):
print j
if (a[i + j] != b[j]):
break
if (j+1 == len(SubStr)):
count+=1
return count
print(SubStrInStr(a, b))
Now my question is for the line that implements if (j == b.length): It works well in javascript but for python I need to add 1 to the value of j or deduct 1 from the length of b. I don't know why this is happening.
for x in range(4)
Unlike Javascript in Python for loop is used for every element in the list. Last value x will take is the last element of the list [0, 1, 2, 3] which is 3.
for(x = 0; x < 4; x++)
In Javascript x will take value for 4 and the loop will end because x < 4 condition no longer can be applied. Last value x will take is 4.
You have this confusion because your code isn't identical. Executing for (j = 0; j < b.length; j++) the final value for j will be b.length (in case that b is a substring of a), but for Python, things are a little bit different. Running range(len("1234")) will result in [0, 1, 2, 3], so your for is more like a foreach, j storing the last value from the array and this is the reason why you have to add one. I hope that I was clear enough. If not, please ask for details.
I don't know about javascript , But I have implemented naive search in Python with all the cases with easiest way.
Take a glance on it as below.
It will return no of time pattern got found.
def naive_pattern_search(data,search):
n = len(data) #Finding length of data
m = len(search) #Finding length of pattern to be searched.
i = 0
count = c = 0 #Taking for counting pattern if exixts.
for j in range(m-1):#Loop continue till length of pattern to be Search.
while i <= (n-1):#Data loop
#if searched patten length reached highest index at that time again initilize with 0.
if j > (m-1):
j = 0
#Data and search have same element then both Index increment by 1.
if data[i]==search[j]:
#print(f"\n{ data[i] } { search[j] }")
#print(f"i : {i} {data[i]} j : {j} {search[j]}")
i+=1
j+=1
count+=1
#If one pattern compared and found Successfully then Its Counter for pattern.
if count== (m-1):
c = c + 1
#Initilise pattern again with 0 for searching with next element in data.
else:
j = 0 #Direct move to 0th index.
i+=1
count=0 #If data not found as per pattern continuously then it will start counting from 0 again.
#Searched pattern occurs more then 0 then its Simply means that pattern found.
if c > 0:
return c;
else:
return -1;
Input : abcabcabcabcabc
Output: Pattern Found : 5 Times
I find your python implementation has some problem. If you set the b = "raiy", the function will incorrectly return 1. You may misunderstand the edge condition.
Those two condition statements should be in the same level.
a = "Rainbow"
b = "Rain"
def SubStrInStr(Str, SubStr):
count = 0
for i in range(len(Str)):
for j in range(len(SubStr)):
# print (j)
if (a[i + j] != b[j]):
break
if (j+1 == len(SubStr)):
count+=1
return count
print(SubStrInStr(a, b))here

Peak and Flag Codility latest chellange

I'm trying to solve the latest codility.com question (just for enhance my skills). I tried allot but not getting more than 30 marks there so now curious what exactly I am missing in my solution.
The question says
A non-empty zero-indexed array A consisting of N integers is given. A peak is an array element which is larger than its neighbours. More precisely, it is an index P such that
0 < P < N − 1 and A[P − 1] < A[P] > A[P + 1]
For example, the following array A:
A[0] = 1
A[1] = 5
A[2] = 3
A[3] = 4
A[4] = 3
A[5] = 4
A[6] = 1
A[7] = 2
A[8] = 3
A[9] = 4
A[10] = 6
A[11] = 2
has exactly four peaks: elements 1, 3, 5 and 10.
You are going on a trip to a range of mountains whose relative heights are represented by array A. You have to choose how many flags you should take with you. The goal is to set the maximum number of flags on the peaks, according to certain rules.
Flags can only be set on peaks. What's more, if you take K flags, then the distance between any two flags should be greater than or equal to K. The distance between indices P and Q is the absolute value |P − Q|.
For example, given the mountain range represented by array A, above, with N = 12, if you take:
> two flags, you can set them on peaks 1 and 5;
> three flags, you can set them on peaks 1, 5 and 10;
> four flags, you can set only three flags, on peaks 1, 5 and 10.
You can therefore set a maximum of three flags in this case.
Write a function that, given a non-empty zero-indexed array A of N integers, returns the maximum number of flags that can be set on the peaks of the array.
For example, given the array above
the function should return 3, as explained above.
Assume that:
N is an integer within the range [1..100,000];
each element of array A is an integer within the range [0..1,000,000,000].
Complexity:
expected worst-case time complexity is O(N);
expected worst-case space complexity is O(N), beyond input storage (not counting the
storage required for input arguments).
So I tried this code according to my understanding of question
var A = [1,5,3,4,3,4,1,2,3,4,6,2];
function solution(A) {
array = new Array();
for (i = 1; i < A.length - 1; i++) {
if (A[i - 1] < A[i] && A[i + 1] < A[i]) {
array.push(i);
}
}
//console.log(A);
//console.log(array);
var position = array[0];
var counter = 1;
var len = array.length;
for (var i = 0; i < len; i++) {
if (Math.abs(array[i+1] - position) >= len) {
position = array[i+1];
counter ++;
}
}
console.log("total:",counter);
return counter;
}
The above code works for sample array elements: [1,5,3,4,3,4,1,2,3,4,6,2]
Get peaks at indices: [1, 3, 5, 10] and set flags at 1, 5, and 10 (total 3)
But codility.com says it fails on array [7, 10, 4, 5, 7, 4, 6, 1, 4, 3, 3, 7]
My code get peaks at indices: [1, 4, 6, 8] and set flags at 1 and 6 (total 2)
but coditity.com says it should be 3 flags. (no idea why)
Am I miss-understanding the question ?
Please I am only looking for the hint/algo. I know this question is already asked by someone and solved on private chatroom but on that page I tried to get the help with that person but members rather flagging my posts as inappropriate answer so I am asking the question here again.
P.S: You can try coding the challenge yourself here!
This is a solution with better upper complexity bounds:
time complexity: O(sqrt(N) * log(N))
space complexity: O(1) (over the original input storage)
Python implementation
from math import sqrt
def transform(A):
peak_pos = len(A)
last_height = A[-1]
for p in range(len(A) - 1, 0, -1):
if (A[p - 1] < A[p] > last_height):
peak_pos = p
last_height = A[p]
A[p] = peak_pos
A[0] = peak_pos
def can_fit_flags(A, k):
flag = 1 - k
for i in range(k):
# plant the next flag at A[flag + k]
if flag + k > len(A) - 1:
return False
flag = A[flag + k]
return flag < len(A) # last flag planted successfully
def solution(A):
transform(A)
lower = 0
upper = int(sqrt(len(A))) + 2
assert not can_fit_flags(A, k=upper)
while lower < upper - 1:
next = (lower + upper) // 2
if can_fit_flags(A, k=next):
lower = next
else:
upper = next
return lower
Description
O(N) preprocessing (done inplace):
A[i] := next peak or end position after or at position i
(i for a peak itself, len(A) after last peak)
If we can plant k flags then we can certainly plant k' < k flags as well.
If we can not plant k flags then we certainly can not plant k' > k flags either.
We can always set 0 flags.
Let us assume we can not set X flags.
Now we can use binary search to find out exactly how many flags can be planted.
Steps:
1. X/2
2. X/2 +- X/4
3. X/2 +- X/4 +- X/8
...
log2(X) steps in total
With the preprocessing done before, each step testing whether k flags can be planted can be performed in O(k) operations:
flag(0) = next(0)
flag(1) = next(flag(1) + k)
...
flag(k-1) = next(flag(k-2) + k)
total cost - worst case - when X - 1 flags can be planted:
== X * (1/2 + 3/4 + ... + (2^k - 1)/(2^k))
== X * (log2(X) - 1 + (<1))
<= X * log(X)
Using X == N would work, and would most likely also be sublinear, but is not good enough to use in a proof that the total upper bound for this algorithm is under O(N).
Now everything depends on finding a good X, and it since k flags take about k^2 positions to fit, it seems like a good upper limit on the number of flags should be found somewhere around sqrt(N).
If X == sqrt(N) or something close to it works, then we get an upper bound of O(sqrt(N) * log(sqrt(N))) which is definitely sublinear and since log(sqrt(N)) == 1/2 * log(N) that upper bound is equivalent to O(sqrt(N) * log(N)).
Let's look for a more exact upper bound on the number of required flags around sqrt(N):
we know k flags requires Nk := k^2 - k + 3 flags
by solving the equation k^2 - k + 3 - N = 0 over k we find that if k >= 3, then any number of flags <= the resulting k can fit in some sequence of length N and a larger one can not; solution to that equation is 1/2 * (1 + sqrt(4N - 11))
for N >= 9 we know we can fit 3 flags
==> for N >= 9, k = floor(1/2 * (1 + sqrt(4N - 11))) + 1 is a strict upper bound on the number of flags we can fit in N
for N < 9 we know 3 is a strict upper bound but those cases do not concern us for finding the big-O algorithm complexity
floor(1/2 * (1 + sqrt(4N - 11))) + 1
== floor(1/2 + sqrt(N - 11/4)) + 1
<= floor(sqrt(N - 11/4)) + 2
<= floor(sqrt(N)) + 2
==> floor(sqrt(N)) + 2 is also a good strict upper bound for a number of flags that can fit in N elements + this one holds even for N < 9 so it can be used as a generic strict upper bound in our implementation as well
If we choose X = floor(sqrt(N)) + 2 we get the following total algorithm upper bound:
O((floor(sqrt(N)) + 2) * log(floor(sqrt(N)) + 2))
{floor(...) <= ...}
O((sqrt(N) + 2) * log(sqrt(N) + 2))
{for large enough N >= 4: sqrt(N) + 2 <= 2 * sqrt(N)}
O(2 * sqrt(N) * log(2 * sqrt(N)))
{lose the leading constant}
O(sqrt(N) * (log(2) + loq(sqrt(N)))
O(sqrt(N) * log(2) + sqrt(N) * log(sqrt(N)))
{lose the lower order bound}
O(sqrt(N) * log(sqrt(N)))
{as noted before, log(sqrt(N)) == 1/2 * log(N)}
O(sqrt(N) * log(N))
QED
Missing 100% PHP solution :)
function solution($A)
{
$p = array(); // peaks
for ($i=1; $i<count($A)-1; $i++)
if ($A[$i] > $A[$i-1] && $A[$i] > $A[$i+1])
$p[] = $i;
$n = count($p);
if ($n <= 2)
return $n;
$maxFlags = min(intval(ceil(sqrt(count($A)))), $n); // max number of flags
$distance = $maxFlags; // required distance between flags
// try to set max number of flags, then 1 less, etc... (2 flags are already set)
for ($k = $maxFlags-2; $k > 0; $k--)
{
$left = $p[0];
$right = $p[$n-1];
$need = $k; // how many more flags we need to set
for ($i = 1; $i<=$n-2; $i++)
{
// found one more flag for $distance
if ($p[$i]-$left >= $distance && $right-$p[$i] >= $distance)
{
if ($need == 1)
return $k+2;
$need--;
$left = $p[$i];
}
if ($right - $p[$i] <= $need * ($distance+1))
break; // impossible to set $need more flags for $distance
}
if ($need == 0)
return $k+2;
$distance--;
}
return 2;
}
import java.util.Arrays;
import java.lang.Integer;
import java.util.ArrayList;
import java.util.List;
public int solution(int[] A)
{
ArrayList<Integer> array = new ArrayList<Integer>();
for (int i = 1; i < A.length - 1; i++)
{
if (A[i - 1] < A[i] && A[i + 1] < A[i])
{
array.add(i);
}
}
if (array.size() == 1 || array.size() == 0)
{
return array.size();
}
int sf = 1;
int ef = array.size();
int result = 1;
while (sf <= ef)
{
int flag = (sf + ef) / 2;
boolean suc = false;
int used = 0;
int mark = array.get(0);
for (int i = 0; i < array.size(); i++)
{
if (array.get(i) >= mark)
{
used++;
mark = array.get(i) + flag;
if (used == flag)
{
suc = true;
break;
}
}
}
if (suc)
{
result = flag;
sf = flag + 1;
}
else
{
ef = flag - 1;
}
}
return result;
}
C++ solution, O(N) detected
#include <algorithm>
int solution(vector<int> &a) {
if(a.size() < 3) return 0;
std::vector<int> peaks(a.size());
int last_peak = -1;
peaks.back() = last_peak;
for(auto i = ++a.rbegin();i != --a.rend();i++)
{
int index = a.size() - (i - a.rbegin()) - 1;
if(*i > *(i - 1) && *i > *(i + 1))
last_peak = index;
peaks[index] = last_peak;
}
peaks.front() = last_peak;
int max_flags = 0;
for(int i = 1;i*i <= a.size() + i;i++)
{
int next_peak = peaks[0];
int flags = 0;
for(int j = 0;j < i && next_peak != -1;j++, flags++)
{
if(next_peak + i >= a.size())
next_peak = -1;
else
next_peak = peaks[next_peak + i];
}
max_flags = std::max(max_flags, flags);
}
return max_flags;
}
100% Java solution with O(N) complexity.
https://app.codility.com/demo/results/trainingPNYEZY-G6Q/
class Solution {
public int solution(int[] A) {
// write your code in Java SE 8
int[] peaks = new int[A.length];
int peakStart = 0;
int peakEnd = 0;
//Find the peaks.
//We don't want to traverse the array where peaks hasn't started, yet,
//or where peaks doesn't occur any more.
//Therefore, find start and end points of the peak as well.
for(int i = 1; i < A.length-1; i++) {
if(A[i-1] < A[i] && A[i+1] < A[i]) {
peaks[i] = 1;
peakEnd = i + 1;
}
if(peakStart == 0) {
peakStart = i;
}
}
int x = 1;
//The maximum number of flags can be √N
int limit = (int)Math.ceil(Math.sqrt(A.length));
int prevPeak = 0;
int counter = 0;
int max = Integer.MIN_VALUE;
while(x <= limit) {
counter = 0;
prevPeak = 0;
for(int y = peakStart; y < peakEnd; y++) {
//Find the peak points when we have x number of flags.
if(peaks[y] == 1 && (prevPeak == 0 || x <= (y - prevPeak))) {
counter++;
prevPeak = y;
}
//If we don't have any more flags stop.
if(counter == x ) {
break;
}
}
//if the number of flags set on the peaks starts to reduce stop searching.
if(counter <= max) {
return max;
}
//Keep the maximum number of flags we set on.
max = counter;
x++;
}
return max;
}
}
There is a ratio between the number of flags we can take with us and
the number of flags we can set. We can not set more than √N number of
flags since N/√N = √N. If we set more than √N, we will end up with
decreasing number of flags set on the peaks.
When we increase the numbers of flags we take with us, the number of
flags we can set increases up to a point. After that point the number
of flags we can set will decrease. Therefore, when the number of
flags we can set starts to decrease once, we don't have to check the
rest of the possible solutions.
We mark the peak points at the beginning of the code, and we also
mark the first and the last peak points. This reduces the unnecessary
checks where the peaks starts at the very last elements of a large
array or the last peak occurs at the very first elements of a large
array.
Here is a C++ Solution with 100% score
int test(vector<int> &peaks,int i,int n)
{
int j,k,sum,fin,pos;
fin = n/i;
for (k=0; k< i; k++)
{
sum=0;
for (j=0; j< fin; j++)
{ pos = j + k * fin;
sum=sum + peaks[ pos ];
}
if (0==sum) return 0;
}
return 1;
}
int solution(vector<int> &A) {
// write your code in C++98
int i,n,max,r,j,salir;
n = A.size();
vector<int> peaks(n,0);
if (0==n) return 0;
if (1==n) return 0;
for (i=1; i< (n-1) ; i++)
{
if ( (A[i-1] < A[i]) && (A[i+1] < A[i]) ) peaks[i]=1;
}
i=1;
max=0;
salir =0;
while ( ( i*i < n) && (0==salir) )
{
if ( 0== n % i)
{
r=test(peaks,i,n);
if (( 1==r ) && (i>max)) max=i;
j = n/i;
r=test(peaks,j,n);
if (( 1==r ) && (j>max)) max=j;
if ( max > n/2) salir =1;
}
i++;
}
if (0==salir)
{
if (i*i == n)
{
if ( 1==test(peaks,i,n) ) max=i;
}
}
return max;
}
The first idea is that we cannot set more than sqrt(N) flags. Lets imagine that we've taken N flags, in this case we should have at least N * N items to set all the flags, because N it's the minimal distance between the flags. So, if we have N items its impossible to set more than sqrt(N) flags.
function solution(A) {
const peaks = searchPeaks(A);
const maxFlagCount = Math.floor(Math.sqrt(A.length)) + 1;
let result = 0;
for (let i = 1; i <= maxFlagCount; ++i) {
const flagsSet = setFlags(peaks, i);
result = Math.max(result, flagsSet);
}
return result;
}
function searchPeaks(A) {
const peaks = [];
for (let i = 1; i < A.length - 1; ++i) {
if (A[i] > A[i - 1] && A[i] > A[i + 1]) {
peaks.push(i);
}
}
return peaks;
}
function setFlags(peaks, flagsTotal) {
let flagsSet = 0;
let lastFlagIndex = -flagsTotal;
for (const peakIndex of peaks) {
if (peakIndex >= lastFlagIndex + flagsTotal) {
flagsSet += 1;
lastFlagIndex = peakIndex;
if (flagsSet === flagsTotal) {
return flagsSet;
}
}
}
return flagsSet;
}
Such solution has O(N) complexity. We should iterate over A to find peaks and iterate from 1 to sqrt(N) flag counts trying to set all the flags. So we have O(N + 1 + 2 + 3 ... sqrt(N)) = O(N + sqrt(N*N)) = O(N) complexity.
Above solution is pretty fast and it gets 100% result, but it can be even more optimized. The idea is to binary search the flag count. Lets take F flags and try to set them all. If excess flags are left, the answer is less tan F. But, if all the flags have been set and there is space for more flags, the answer is greater than F.
function solution(A) {
const peaks = searchPeaks(A);
const maxFlagCount = Math.floor(Math.sqrt(A.length)) + 1;
return bSearchFlagCount(A, peaks, 1, maxFlagCount);
}
function searchPeaks(A) {
const peaks = [];
for (let i = 1; i < A.length - 1; ++i) {
if (A[i] > A[i - 1] && A[i] > A[i + 1]) {
peaks.push(i);
}
}
return peaks;
}
function bSearchFlagCount(A, peaks, start, end) {
const mid = Math.floor((start + end) / 2);
const flagsSet = setFlags(peaks, mid);
if (flagsSet == mid) {
return mid;
} else if (flagsSet < mid) {
return end > start ? bSearchFlagCount(A, peaks, start, mid) : mid - 1;
} else {
return bSearchFlagCount(A, peaks, mid + 1, end);
}
}
function setFlags(peaks, flagsTotal) {
let flagsSet = 0;
let lastFlagIndex = -flagsTotal;
for (const peakIndex of peaks) {
if (peakIndex >= lastFlagIndex + flagsTotal) {
flagsSet += 1;
lastFlagIndex = peakIndex;
// It only matters that we can set more flags then were taken.
// It doesn't matter how many extra flags can be set.
if (flagsSet > flagsTotal) {
return flagsSet;
}
}
}
return flagsSet;
}
Here is the official Codility solutions of the task.
My C++ solution with 100% result
bool check(const vector<int>& v, int flags, int mid) {
if (not v.empty()) {
flags--;
}
int start = 0;
for (size_t i = 1; i < v.size(); ++i) {
if (v[i] - v[start] >= mid) {
--flags;
start = i;
}
}
return flags <= 0;
}
int solution(vector<int> &A) {
vector<int> peaks;
for (size_t i = 1; i < A.size() - 1; ++i) {
if (A[i] > A[i - 1] and A[i] > A[i + 1]) {
peaks.push_back(i);
}
}
int low = 0;
int high = peaks.size();
int res = 0;
while (low <= high) {
int mid = high - (high - low) / 2;
if (check(peaks, mid, mid)) {
low = mid + 1;
res = mid;
} else {
high = mid - 1;
}
}
return res;
}
public int solution(int[] A) {
int p = 0;
int q = 0;
int k = 0;
for (int i = 0; i < A.length; i++) {
if (i > 0 && i < A.length && (i + 1) < A.length - 1) {
if (A[i] > A[i - 1] && A[i] > A[i + 1]) {
p = i;
if (i < A.length / 2)
k++;
}
if (i > 0 && i < A.length && (A.length - i + 1) < A.length) {
if (A[A.length - i] > A[A.length - i - 1]
&& A[A.length - i] > A[A.length - i + 1] ) {
q = A.length - i;
if (i < A.length / 2)
k++;
else {
if (Math.abs(p - q) < k && p != q)
k--;
}
}
}
}
}
return k;
}
import sys
def get_max_num_peaks(arr):
peaks = [i for i in range(1, len(arr)-1, 1) if arr[i]>arr[i-1] and arr[i]>arr[i+1]]
max_len = [1 for i in peaks]
smallest_diff = [0 for i in peaks]
smallest_diff[0] = sys.maxint
for i in range(1, len(peaks), 1):
result = 1
for j in range(0, i, 1):
m = min(smallest_diff[j], peaks[i]-peaks[j])
if smallest_diff[j]>0 and m>=max_len[j]+1:
max_len[i] = max_len[j]+1
smallest_diff[i] = m
result = max(result, max_len[i])
return result
if __name__ == "__main__":
result = get_max_num_peaks([7, 10, 4, 5, 7, 4, 6, 1, 4, 3, 3, 7])
print result
I used DP to solve this problem. Here is the python code:
The max num of flags can be set for array ending at i is the max num of flags can be set on j if min(min_diff(0 .. j), j to i) is no less than max_len(0 .. j)+1
Please correct me if I'm wrong or there is a O(N) solution
I know that the answer had been provided by francesco Malagrino, but i have written my own code. for the arrays {1,5,3,4,3,4,1,2,3,4,6,2} and { 7, 10, 4, 5, 7, 4, 6, 1, 4, 3, 3, 7 } my code is working just fine. and when I took my code on the codility exams i had failed on {9, 9, 4, 3, 5, 4, 5, 2, 8, 9, 3, 1}
my answer resulted to 3 maximum flags. the way I understand it it supposed to be 3 but instead
the correct answer is 2, and also with also in respect to francesco Malagrino's solution.
what seems to be wrong in my code and how come the answer should only be 2 the fact that
distances between peaks 4, 6, 9 followed the rule.
private static int getpeak(int[] a) {
List<Integer> peak = new ArrayList<Integer>();
int temp1 = 0;
int temp2 = 0;
int temp3 = 0;
for (int i = 1; i <= (a.length - 2); i++) {
temp1 = a[i - 1];
temp2 = a[i];
temp3 = a[i + 1];
if (temp2 > temp1 && temp2 > temp3) {
peak.add(i);
}
}
Integer[] peakArray = peak.toArray(new Integer[0]);
int max = 1;
int lastFlag = 0;
for (int i = 1; i <= peakArray.length - 1; i++) {
int gap = peakArray[i] - peakArray[lastFlag];
gap = Math.abs(gap);
if (gap >= i+1) {
lastFlag = i;
max = max + 1;
}
}
return max;
}
I cam up with an algorithm for this problem that is both of O(N) and passed all of the codility tests. The main idea is that the number of flags can not be more than the square root of N. So to keep the total order linear, each iteration should be less than the square root of N too, which is the number of flags itself.
So first, I built an array nextPeak that for each index of A provides the closest flag after the index.
Then, in the second part, I iterate f over all possible number of flags from root of N back to 0 to find the maximum number of flags that can be applied on the array. In each iteration, I try to apply the flags and use the nextPeak array to find the next peak in constant time.
The code looks like this:
public int solution(int[] A){
if( A==null || A.length<3){
return 0;
}
int[] next = new int[A.length];
int nextPeak=-1;
for(int i =1; i<A.length; i++){
if(nextPeak<i){
for(nextPeak=i; nextPeak<A.length-1; nextPeak++){
if(A[nextPeak-1]<A[nextPeak] && A[nextPeak]>A[nextPeak+1]){
break;
}
}
}
next[i] = nextPeak;
}
next[0] = next[1];
int max = new Double(Math.sqrt(A.length)).intValue();
boolean failed = true ;
int f=max;
while(f>0 && failed){
int v=0;
for(int p=0; p<A.length-1 && next[p]<A.length-1 && v<f; v++, p+=max){
p = next[p];
}
if(v<f){
f--;
} else {
failed = false;
}
}
return f;
}
Here is a 100% Java solution
class Solution {
public int solution(int[] A) {
int[] nextPeaks = nextPeaks(A);
int flagNumebr = 1;
int result = 0;
while ((flagNumebr-1)*flagNumebr <= A.length) {
int flagPos = 0;
int flagsTaken = 0;
while (flagPos < A.length && flagsTaken < flagNumebr) {
flagPos = nextPeaks[flagPos];
if (flagPos == -1) {
// we arrived at the end of the peaks;
break;
}
flagsTaken++;
flagPos += flagNumebr;
}
result = Math.max(result, flagsTaken);
flagNumebr++;
}
return result;
}
private boolean[] createPeaks(int[] A) {
boolean[] peaks = new boolean[A.length];
for (int i = 1; i < A.length-1; i++) {
if (A[i - 1] < A[i] && A[i] > A[i + 1]) {
peaks[i] = true;
}
}
return peaks;
}
private int[] nextPeaks (int[] A) {
boolean[] peaks = createPeaks(A);
int[] nextPeaks = new int[A.length];
// the last position is always -1
nextPeaks[A.length-1] = -1;
for (int i = A.length-2; i >= 0 ; i--) {
nextPeaks[i] = peaks[i] ? i : nextPeaks[i+1];
}
return nextPeaks;
}
}
to solve this problem:
you have to find peaks
calculate distance (indices differences) between every 2 peaks
Initially the number of flags is the same number of peaks
compare distance between every 2 peaks with the initially specified number of flags ([P - Q] >= K)
after the comparison you will find that you have to avoid some peaks
the final number of maximum flags is the same number of remain peaks
** I'm still searching for how to write the best optimized code for this problem
C# Solution with 100% points.
using System;
using System.Collections.Generic;
class Solution {
public int solution(int[] A) {
// write your code in C# 6.0 with .NET 4.5 (Mono)
List<int> peaks = new List<int>();
for (int i = 1; i < A.Length - 1; i++)
{
if (A[i - 1] < A[i] && A[i + 1] < A[i])
{
peaks.Add(i);
}
}
if (peaks.Count == 1 || peaks.Count == 0)
{
return peaks.Count;
}
int leastFlags = 1;
int mostFlags = peaks.Count;
int result = 1;
while (leastFlags <= mostFlags)
{
int flags = (leastFlags + mostFlags) / 2;
bool suc = false;
int used = 0;
int mark = peaks[0];
for (int i = 0; i < peaks.Count; i++)
{
if (peaks[i] >= mark)
{
used++;
mark = peaks[i] + flags;
if (used == flags)
{
suc = true;
break;
}
}
}
if (suc)
{
result = flags;
leastFlags = flags + 1;
}
else
{
mostFlags = flags - 1;
}
}
return result;
}
}
100% working JS solution:
function solution(A) {
let peaks = [];
for (let i = 1; i < A.length - 1; i++) {
if (A[i] > A[i - 1] && A[i] > A[i + 1]) {
peaks.push(i);
}
}
let n = peaks.length;
if (n <= 2) {
return n;
}
let maxFlags = Math.min(n, Math.ceil(Math.sqrt(A.length)));
let distance = maxFlags;
let rightPeak = peaks[n - 1];
for (let k = maxFlags - 2; k > 0; k--) {
let flags = k;
let leftPeak = peaks[0];
for (let i = 1; i <= n - 2; i++) {
if (peaks[i] - leftPeak >= distance && rightPeak - peaks[i] >= distance) {
if (flags === 1) {
return k + 2;
}
flags--;
leftPeak = peaks[i];
}
if (rightPeak - peaks[i] <= flags * (distance + 1)) {
break;
}
}
if (flags === 0) {
return k + 2;
}
distance--;
}
return 2;
}
100 % python O(N) detected.
import math
def solution(A):
N=len(A)
#Trivial cases
if N<3:
return 0
Flags_Idx=[]
for p in range(1,N-1):
if A[p-1]<A[p] and A[p]>A[p+1] :
Flags_Idx.append(p)
if len(Flags_Idx)==0:
return 0
if len(Flags_Idx)<=2:
return len(Flags_Idx)
Start_End_Flags=Flags_Idx[len(Flags_Idx)-1]-Flags_Idx[0]
#Maximum number of flags N is such that Start_End_Flags/(N-1)>=N
#After solving a second degree equation we obtain the maximal value of N
num_max_flags=math.floor(1.0+math.sqrt(4*Start_End_Flags+1.0))/2.0
#Set the current number of flags to its total number
len_flags=len(Flags_Idx)
min_peaks=len(Flags_Idx)
p=0
#Compute the minimal number of flags by checking each indexes
#and comparing to the maximal theorique value num_max_flags
while p<len_flags-1:
add = 1
#Move to the next flag until the condition Flags_Idx[p+add]-Flags_Idx[p]>=min(num_max_flags,num_flags)
while Flags_Idx[p+add]-Flags_Idx[p]<min(num_max_flags,min_peaks):
min_peaks-=1
if p+add<len_flags-1:
add+=1
else:
p=len_flags
break
p+=add
if num_max_flags==min_peaks:
return min_peaks
#Bisect the remaining flags : check the condition
#for flags in [min_peaks,num_max_flags]
num_peaks=min_peaks
for nf in range (min_peaks,int(num_max_flags)+1):
cnt=1
p=0
while p<len_flags-1:
add = 1
while Flags_Idx[p+add]-Flags_Idx[p]<nf:
if p+add<len_flags-1:
add+=1
else:
cnt-=1
p=len_flags
break
p+=add
cnt+=1
num_peaks=max(min(cnt,nf),num_peaks)
return num_peaks
I first computed the maximal possible number of flags verifying the condition
Interval/(N-1) >= N , where Interval is the index difference between first and last flag. Then browsing all the flags comparing with the minimum of this value and the current number of flags. Subtract if the condition is not verified.
Obtained the minimal number of flags and use it as a starting point to check the condition
on the remaining ones (in interval [min_flag,max_flag]).
100% python solution which is far simpler than the one posted above by #Jurko Gospodnetić
https://github.com/niall-oc/things/blob/master/codility/flags.py
https://app.codility.com/demo/results/training2Y78NP-VHU/
You don't need to do a binary search on this problem. MAX flags is the (square root of the (spread between first and last flag)) +1. First peak at index 9 and last peak at index 58 means the spread is sqrt(49) which is (7)+1. So try 8 flags then 7 then 6 and so on. You should break after your solution peaks! no need to flog a dead horse!
def solution(A):
peak=[x for x in range(1,len(A))if A[x-1]<A[x]>A[x+1]]
max_flag=len(peak)
for x in range(1,max_flag+1):
for y in range(x-1):
if abs(peak[y]-peak[y+1])>=max_flag:
max_flag=max_flag-1
print(max_flag)**strong text**
I got 100% with this solution in Java. I did one thing for the first loop to find peaks, i.e. after finding the peak I am skipping the next element as it is less than the peak.
I know this solution can be further optimized by group members but this is the best I can do as of now, so please let me know how can I optimize this more.
Detected time complexity: O(N)
https://app.codility.com/demo/results/trainingG35UCA-7B4/
public static int solution(int[] A) {
int N = A.length;
if (N < 3)
return 0;
ArrayList<Integer> peaks = new ArrayList<Integer>();
for (int i = 1; i < N - 1; i++) {
if (A[i] > A[i - 1]) {
if (A[i] > A[i + 1]) {
peaks.add(i);
i++;// skip for next as A[i + 1] < A[i] so no need to check again
}
}
}
int size = peaks.size();
if (size < 2)
return size;
int k = (int) Math.sqrt(peaks.get(size - 1) - peaks.get(0))+1; // added 1 to round off
int flagsLeft = k - 1; // one flag is used for first element
int maxFlag = 0;
int prevEle = peaks.get(0);
while (k > 0) { // will iterate in descending order
flagsLeft = k - 1; // reset first peak flag
prevEle = peaks.get(0); // reset the flag to first element
for (int i = 1; i < size && flagsLeft > 0; i++) {
if (peaks.get(i) - prevEle >= k) {
flagsLeft--;
prevEle = peaks.get(i);
}
if ((size - 1 - i) < flagsLeft) { // as no. of peaks < flagsLeft
break;
}
}
if (flagsLeft == 0 && maxFlag < k) {
maxFlag = k;
break; // will break at first highest flag as iterating in desc order
}
k--;
}
return maxFlag;
}
int solution(int A[], int N) {
int i,j,k;
int count=0;
int countval=0;
int count1=0;
int flag;
for(i=1;i<N-1;i++)
{`enter code here`
if((A[i-1]<A[i]) && (A[i]>A[i+1]))
{
printf("%d %d\n",A[i],i);
A[count++]=i;
i++;
}
}
j=A[0];
k=0;
if (count==1 || count==0)
return count;
if (count==2)
{
if((A[1]-A[0])>=count)
return 2;
else
return 1;
}
flag=0;
// contval=count;
count1=1;
countval=count;
while(1)
{
for(i=1;i<count;i++)
{
printf("%d %d\n",A[i],j);
if((A[i]-j)>=countval)
{
printf("Added %d %d\n",A[i],j);
count1++;
j=A[i];
}
/* if(i==count-1 && count1<count)
{
j=A[0];
i=0;
count1=1;
}*/
}
printf("count %d count1 %d \n",countval,count1);
if (count1<countval)
{
count1=1;
countval--;
j=A[0];
}
else
{
break; }
}
return countval;
}

obfuscation in javascript

im trying to obfuscate a string in vb.net and deobfuscate in javascript.
For i = 0 To Len(sData) / 4
For j = 1 To 4
ConvertData2 = ConvertData2 & Mid$(sData, (4 * i) + 5 - j, 1)
Next j
Next i
the above said code works well in vb.net. I need the equivalent code in javascript
i tried the below one but not working.
for (i = 0; i<(sData.length)/4; i++)
{
for (j = 1;j<4;j++)
s=s+sData.substr((4 * i) + 5 - j,1)
}
anyone can suggest where i made mistake..
Well, for one thing, Javascript string indices start at 0, not 1. And your for (j=1; j<4; j++) loop will only count from 1 to 3 anyway; you want to go either from 0 to 3 (j=0 and j<4) or 1 to 4 (j=1 and j<=4).
A direct translation of the VB looks like this:
convertData2 = ''
for (var i=0; i < sData.length / 4; ++i) {
for (var j=1; j <= 4; ++j) {
convertData2 += sData.substr(4 * i + 4 - j, 1)
}
}
the first glaring difference is that in vb.net you use integer division while in javascript you are not...
use
for(var i = 0, len = Math.floor(sData.length / 4); i<=len; i++)
The second is that Mid starts counting from 1 while subst starts from 0
so use
s = s + sData.substr((4 * i) + 5 - j -1,1)
or simplified
s = s + sData.substr((4 * i) + 4 - j,1)
Lastly the loops, when using < do not use the final number ... while the from.. to uses the last number as well (so use <=)
so alltogether
var s = ''; // define s (if not yet defined) other wise use s = '' to make sure it starts empty..
for(var i = 0, len = Math.floor(sData.length / 4); i <= len; i++) {
for (var j = 1 ; j <= 4; j++) {
s = s + sData.substr( (4 * i) + 4 - j,1);
}
}

Categories

Resources