I am trying to translate some js code into python and having trouble converting bitwise operators. I already introduced ctypes.c_int in python but the results still do not match. For the >>> in js I used as suggested here.
A minimal example of my (not working) code:
Javascript:
let R = [7, 12, 17, 22, 7, 12, 17, 22, 7, 12, 17, 22, 7, 12, 17, 22, 5, 9, 14, 20, 5, 9, 14, 20, 5, 9, 14, 20, 5, 9, 14, 20, 4, 11, 16, 23, 4, 11, 16, 23, 4, 11, 16, 23, 4, 11, 16, 23, 6, 10, 15, 21, 6, 10, 15, 21, 6, 10, 15, 21, 6, 10, 15, 21]
let K = [3614090360, 3905402710, 606105819, 3250441966, 4118548399, 1200080426, 2821735955, 4249261313, 1770035416, 2336552879, 4294925233, 2304563134, 1804603682, 4254626195, 2792965006, 1236535329, 4129170786, 3225465664, 643717713, 3921069994, 3593408605, 38016083, 3634488961, 3889429448, 568446438, 3275163606, 4107603335, 1163531501, 2850285829, 4243563512, 1735328473, 2368359562, 4294588738, 2272392833, 1839030562, 4259657740, 2763975236, 1272893353, 4139469664, 3200236656, 681279174, 3936430074, 3572445317, 76029189, 3654602809, 3873151461, 530742520, 3299628645, 4096336452, 1126891415, 2878612391, 4237533241, 1700485571, 2399980690, 4293915773, 2240044497, 1873313359, 4264355552, 2734768916, 1309151649, 4149444226, 3174756917, 718787259, 3951481745]
let blocks = [1819043144, 1919899503, 8414316, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 80, 0];
let h0 = 1732584193, h1 = 4023233417, h2 = 2562383102, h3 = 271733878, length = blocks.length;
for (let i = 0; length > i; i += 16) {
var f, g, tmp, x, y, a = h0, b = h1, c = h2, d = h3;
for (let j = 0; 64 > j; ++j) {
if (16 > j) {
f = d ^ b & (c ^ d);
g = j;
tmp = d;
d = c;
c = b;
x = a + f + K[j] + blocks[i + g];
y = R[j];
b += x << y | x >>> 32 - y;
a = tmp;
}
}
}
Python:
import ctypes
R = [7, 12, 17, 22, 7, 12, 17, 22, 7, 12, 17, 22, 7, 12, 17, 22, 5, 9, 14, 20, 5, 9, 14, 20, 5, 9, 14, 20, 5, 9, 14, 20, 4, 11, 16, 23, 4, 11, 16, 23, 4, 11, 16, 23, 4, 11, 16, 23, 6, 10, 15, 21, 6, 10, 15, 21, 6, 10, 15, 21, 6, 10, 15, 21]
K = [3614090360, 3905402710, 606105819, 3250441966, 4118548399, 1200080426, 2821735955, 4249261313, 1770035416, 2336552879, 4294925233, 2304563134, 1804603682, 4254626195, 2792965006, 1236535329, 4129170786, 3225465664, 643717713, 3921069994, 3593408605, 38016083, 3634488961, 3889429448, 568446438, 3275163606, 4107603335, 1163531501, 2850285829, 4243563512, 1735328473, 2368359562, 4294588738, 2272392833, 1839030562, 4259657740, 2763975236, 1272893353, 4139469664, 3200236656, 681279174, 3936430074, 3572445317, 76029189, 3654602809, 3873151461, 530742520, 3299628645, 4096336452, 1126891415, 2878612391, 4237533241, 1700485571, 2399980690, 4293915773, 2240044497, 1873313359, 4264355552, 2734768916, 1309151649, 4149444226, 3174756917, 718787259, 3951481745]
blocks = [1819043144, 1919899503, 8414316, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 80, 0]
h0 = 1732584193
h1 = 4023233417
h2 = 2562383102
h3 = 271733878
length = len(blocks)
i = 0
while length > i:
a = h0
b = h1
c = h2
d = h3
j = 0
while 64 > j:
if 16 > j:
f = ctypes.c_int(c ^ d & (b ^ c)).value
g = j
tmp = d
d = c
c = b
x = a + f + K[j] + blocks[i + g]
y = R[j]
b += ctypes.c_int(x << y | ((x & 0xffffffff) >> 32 - y)).value # was >>>
a = tmp
j += 1
i += 16
print('a', a)
print('b', b)
js returns 7727443648 and python returns 4225785507 for a
Your values are outside JS limits :
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Bitwise_Operators
The numbers -2147483648 and 2147483647 are the minimum and the maximum integers representable through a 32bit signed number.
Related
Ok so I want to subtract 9 to numbers(elements in an array) over 9:
finalCredDigits = [10, 8, 18, 9, 16, 6, 16, 5, 14, 3, 14, 6, 10, 5, 8]
Thats what I tried
finalCredDigits.forEach(arr =>{
if(arr > 9){
finalCredDigits.push(arr - 9);
}
});
Output = [10, 8, 18, 9, 16, 6, 16, 5, 14, 3, 14, 6, 10, 5, 8, 1, 9, 7, 7, 5, 5, 1]
I know its cuz the result is being pushed in the array but i want to mutate it and replace the answer with numbers over 9
If you want a similar but new array, you should use Array.map():
const finalCredDigits = [10, 8, 18, 9, 16, 6, 16, 5, 14, 3, 14, 6, 10, 5, 8];
const newFinalCredDigits = finalCredDigits.map(v => {
if (v > 9) {
return v - 9;
} else {
return v;
}
});
console.log(newFinalCredDigits.join());
console.log("Is new array?", newFinalCredDigits !== finalCredDigits);
If you want to mutate the array itself with Array.forEach(), you should use the callback's additional parameters:
const finalCredDigits = [10, 8, 18, 9, 16, 6, 16, 5, 14, 3, 14, 6, 10, 5, 8];
finalCredDigits.forEach((v, i, array) => {
if (v > 9) {
array[i] = v - 9;
}
});
console.log(finalCredDigits.join());
But functional programming usually implies preferring immutable over mutable states, so if your array is shared and we'd mutate it with Array.forEach(), it would be considered a code smell. Therefore I'd use a regular for-loop instead:
const finalCredDigits = [10, 8, 18, 9, 16, 6, 16, 5, 14, 3, 14, 6, 10, 5, 8];
{
const l = finalCredDigits.length;
for (let i = 0; i < l; ++i) {
if (finalCredDigits[i] > 9) finalCredDigits[i] -= 9;
}
}
console.log(finalCredDigits.join());
You need to assign to the array index to replace the element, not push a new element.
forEach() passes a second argument to the callback function, containing the current index. You can use this for the assignment.
const finalCredDigits = [10, 8, 18, 9, 16, 6, 16, 5, 14, 3, 14, 6, 10, 5, 8];
finalCredDigits.forEach((el, i) =>{
if(el > 9){
finalCredDigits[i] = el - 9;
}
});
console.log(finalCredDigits);
Try this
let finalCredDigits = [10, 8, 18, 9, 16, 6, 16, 5, 14, 3, 14, 6, 10, 5, 8]
finalCredDigits = finalCredDigits.map(number => {
if (number > 9) {
return number - 9
}
return number
})
console.log(finalCredDigits)
I want to compare x and z and if element in x is present in z then push element of y in temp else push 0 in temp at the end length of z and temp should be equal.
below is my code ---
var x=[00,03,06,21]
var y=[79,11,18,14]
var temp=[]
var z=[00,01,02,03,04,05,06,07,08,09,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24]
for(var i=0;i<z.length;i++){
for(j=0;j<x.length;j++){
if(z[i]==x[j]){
// alert("hello")
temp.push(y[j])
}
}
if(z[i]!=x[j]){
temp.push(0)
}
}
console.log(temp)
console.log(z)
i getting the output as -
//temp (29) [79, 0, 0, 0, 11, 0, 0, 0, 18, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 14, 0, 0, 0, 0]
//z (25) [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24]
expected output --
//temp (25) [79, 0, 0, 11, 0, 0, 18, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 14, 0, 0, 0]
//z (25) [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23,
24]
Once you found a common value, you need to continue the outer loop. If not found, push after finishing the inner loop.
BTW, do not forget to declare all variables.
var x = [0, 3, 6, 21],
y = [79, 11, 18, 14],
temp = [],
z = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24];
outer: for (let i = 0; i < z.length; i++) {
for (let j = 0; j < x.length; j++) {
if (z[i] === x[j]) {
temp.push(y[j]);
continue outer;
}
}
temp.push(0);
}
console.log(temp);
console.log(z);
A version without a label.
var x = [0, 3, 6, 21],
y = [79, 11, 18, 14],
temp = [],
z = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24];
for (let i = 0; i < z.length; i++) {
let value = 0;
for (let j = 0; j < x.length; j++) {
if (z[i] === x[j]) {
value = y[j];
break;
}
}
temp.push(value);
}
console.log(temp);
console.log(z);
Finally, a shorter approach with an object for the replacement values.
var x = [0, 3, 6, 21],
y = [79, 11, 18, 14],
z = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24],
values = x.reduce((r, k, i) => (r[k] = y[i], r), {}),
temp = z.map(k => values[k] || 0);
console.log(temp);
console.log(z);
I'm trying to get my code to do this:
Original array = [1,2,3,4] swap once-> [4,2,3,1] swap again->[4,3,2,1]
Therefore result is 2
But it's not working. Here's what I have so far:
function check(arr){
var sarr = [];
var cnt = 0;
var arrL = arr.length;
// Create a second copy of the array for reference
var arrCopy = [...arr];
for(let i=0; i<arrL;i++){
var maxV = Math.max(...arr);
sarr.push(maxV);
let pos = arr.indexOf(maxV);
// Remove the found number
arr.splice(pos,1);
// Check if the index of the number in the new array is same with the copy, if not then there was a swap
let ai =arrCopy.indexOf(maxV);
let si =sarr.indexOf(maxV);
if (ai !== si && (i+1)!=arrL && pos !== 0){
cnt++;
};
}
console.log(cnt);
}
check([1, 2, 3, 4, 5, 6]);//Result should be 3
check([6,5,4,3,2,1]); //result should be 0
check([1,2,3,4]); //result should be 2
check([1,3,2,5,4,6]); //result should be 3
check([1,2,10,4,5,6,7,8,9,3,12,11]);//result should be 6
check([ 49, 37, 9, 19, 27, 3, 25, 11, 53, 42, 57, 50, 55, 56, 38, 48, 6, 33, 28, 8, 20, 31, 51, 14, 23, 4, 58, 52, 36, 22, 41, 47, 39, 2, 7, 13, 45, 1, 44, 32, 10, 15, 21, 30, 17, 60, 29, 5, 59, 12, 40, 24, 54, 46, 26, 43, 35, 34, 18, 16]);//result should be 54
Can someone please let me know what I'm doing wrong?
I would start with a copy of the array in descending order for getting the right index of the items.
For practical reasons, (or just a shorter conception of the loop with including check and decrement), I loop from the end of the array.
Then I check the value of array and reversed at the dame index and go on with the iteration.
If not the same value, the items at the wanted position i and the actual position p are swapped and the count incremented.
At the end the count is returned.
function check(array) {
var reversed = array.slice().sort((a, b) => b - a),
count = 0,
i = array.length,
p;
while (i--) {
if (array[i] === reversed[i]) continue;
p = array.indexOf(reversed[i]);
[array[i], array[p]] = [array[p], array[i]];
count++;
}
console.log(...array);
return count;
}
console.log(check([1, 2, 3, 4, 5, 6])); // 3
console.log(check([6, 5, 4, 3, 2, 1])); // 0
console.log(check([1, 2, 3, 4])); // 2
console.log(check([1, 3, 2, 5, 4, 6])); // 3
console.log(check([1, 2, 10, 4, 5, 6, 7, 8, 9, 3, 12, 11])); // 6
console.log(check([ 49, 37, 9, 19, 27, 3, 25, 11, 53, 42, 57, 50, 55, 56, 38, 48, 6, 33, 28, 8, 20, 31, 51, 14, 23, 4, 58, 52, 36, 22, 41, 47, 39, 2, 7, 13, 45, 1, 44, 32, 10, 15, 21, 30, 17, 60, 29, 5, 59, 12, 40, 24, 54, 46, 26, 43, 35, 34, 18, 16])); // 54
.as-console-wrapper { max-height: 100% !important; top: 0; }
function minimumSwaps(arr) {
var count = 0;
arr.sort((a, b) => {
if (a < b) {
count++;
}
});
return count;
}
console.log(minimumSwaps([1, 2, 3, 4, 7, 6, 5]));
I have an array that can be of any length. and need to split it into sections. The first section will be a length of 14, and there after a length of 16
var size1 = 14;
var size2 = 16;
var a = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21,
22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40];
var arrays = [];
if (a.length > 14){
for (i = 0; i < 14; i++) {
arrays.push(a.splice(0, size1));
}
for (i = 14 ; i < a.length; i++){
arrays.push(a.splice(0, size2));
}
} else {
arrays.push(a.splice(0, size1));
}
console.log(arrays);
However based on what I am doing my array keeps splitting only at 14. Can you advice on how I can do this?
Thank you
The solution using Array.prototype.slice() function:
var a = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21,
22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40],
size1 = 14,
size2 = 16,
arrays = [];
[0, size1, size2].forEach(function (v, i, arr) {
arrays.push((arr[i+1])? a.slice(v, v + arr[i+1]) : a.slice(arr[i-1] + v));
});
console.log(arrays);
You could use an array for the chunk length and a zero for the rest and map the chunks by keeping the length of the previous lengths.
It works for an arbitrary count of chunks.
var chunks = [14, 16, 0],
array = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40],
result = chunks.map((last => a => array.slice(last, a ? (last += a) : undefined))(0));
console.log(result);
.as-console-wrapper { max-height: 100% !important; top: 0; }
Edit: so, like this then?
var size1 = 14;
var size2 = 16;
var a = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21,22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40];
var head = a.slice(0, size1);
var arrays = [head];
while (size1 < a.length){
arrays.push(a.slice(size1, Math.min(size1+size2, a.length)));
size1 += size2;
}
console.log(arrays)
You can try this with all dynamic array sizes, it will get you desired output.
Hope you were looking for this solution.
var size1 = 14;
var size2 = 16;
var flag=0;
var a = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21,
22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40];
var arrays = [];
var t=a.length/14;
while(a.length>0){
if (flag==0 && a.length > 14){
arrays.push(a.splice(0, size1));
flag=1;
} else if(a.length>=16){
arrays.push(a.splice(0, size2));
}
else{
arrays.push(a.splice(0, a.length));
}
}
console.log(arrays)
So, I'm working with A* Pathfinding. I got it working however it doesn't work all the way. It works all the way until the last 4 columns to the right. Weird.
It works all the way until X is 10 or less. Which is weird because Y's max is 10. Maybe it's together? I don't know. But my map is 15 columns by 10 rows. Here is an online example: http://mystikrpg.com/html5/
An interesting error I get is Uncaught TypeError: Cannot read property '8' of undefined.
The 8 is the Y of where you clicked. If you click a the very first gray block on the right-side (since row 0 is walled off). Then that 8 would say 1.
Here's the part where it lays out the nodes.
// Creates a Graph class used in the astar search algorithm.
function Graph(grid) {
var nodes = [];
var row, rowLength, len = grid.length;
for (x = 0; x <= 10; x++) {
row = grid[x];
nodes[x] = new Array(15);
for (y = 0; y <= 15; y++) {
nodes[x][y] = new GraphNode(x, y, row[y]);
}
}
this.input = grid;
this.nodes = nodes;
}
However, you can download it offline and put it on localhost, if you'd like here http://mystikrpg.com/html5/Ethios.rar
Anyway... something else I found:
My loadMap() function returns an array of 11 elements.
And when x_block is 13 (clicking on X axis of map) for example, graph.nodes[x_block][y_block] returns undefined.
Here is my loadMap() function:
function loadMap(map) {
if (map == 1) {
return [[1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1],
[1, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 1],
[1, 13, 1, 13, 13, 13, 13, 13, 1, 1, 1, 1, 1, 13, 13, 1],
[1, 13, 1, 1, 13, 1, 1, 13, 1, 13, 13, 1, 13, 13, 13, 1],
[1, 13, 13, 1, 1, 1, 13, 13, 1, 13, 13, 1, 1, 1, 13, 1],
[1, 13, 13, 1, 13, 1, 13, 13, 13, 13, 13, 1, 13, 13, 13, 1],
[1, 13, 13, 13, 13, 1, 13, 13, 13, 13, 13, 1, 13, 13, 13, 1],
[1, 13, 1, 13, 13, 13, 13, 13, 1, 1, 1, 1, 13, 13, 13, 1],
[1, 13, 1, 1, 1, 1, 13, 13, 13, 13, 1, 13, 13, 13, 13, 1],
[1, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 1],
[1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1]];
}
}
As you can see, it's 15 columns across and 10 rows down.
What am I doing wrong?
UPDATE NEW
for (y = 0; y <= 10; y++) {
row = grid[y];
nodes[y] = new Array(15);
for (x = 0; x <= 15; x++) {
console.log("X: " + x + " Y: " + y);
//console.log("Row: " + row[x]);
nodes[x][y] = new GraphNode(x, y, row[x]);
}
}
You have your x and y nomenclature the wrong way around.
The x axis should be the second dimension in your table, e.g. nodes[y][x]:
for (y = 0; y <= 10; x++) {
row = grid[y];
nodes[y] = [];
for (x = 0; x <= 15; x++) {
nodes[y][x] = new GraphNode(x, y, row[y]);
}
}