Related
An array(10^5 size) of 32-bit binary numbers is given, we're required to count the no. of ones for every bit of those numbers.
For example:
Array : {10101,1011,1010,1}
Counts : {1's place: 3, 2's place: 2, 3's place: 1, 4's place: 2, 5's place: 1}
No bit manipulation technique seems to satisfy the constraints to me.
Well, this should be solveable with two loops: one going over the array the other one masking the right bits. Running time should be not too bad for your constraints.
Here is a rust implementation (out of my head, not throughtfully tested):
fn main() {
let mut v = vec!();
for i in 1..50*1000 {
v.push(i);
}
let r = bitcount_arr(v);
r.iter().enumerate().for_each( |(i,x)| print!("index {}:{} ",i+1,x));
}
fn bitcount_arr(input:Vec<u32>) -> [u32;32] {
let mut res = [0;32];
for num in input {
for i in 0..31 {
let mask = 1 << i;
if num & mask != 0 {
res[i] += 1;
}
}
}
res
}
This can be done with transposed addition, though the array is a bit long for it.
To transpose addition, use an array of counters, but instead of using one counter for every position we'll use one counter for every bit of the count. So a counter that tracks for each position whether the count is even/odd, a counter that tracks for each position whether the count has a 2 in it, etc.
To add an element of the array into this, only half-add operations (& to find the new carry, ^ to update) are needed, since it's only a conditional increment: (not tested)
uint32_t counters[17];
for (uint32_t elem : array) {
uint32_t c = elem;
for (int i = 0; i < 17; i++) {
uint32_t nextcarry = counters[i] & c;
counters[i] ^= c;
c = nextcarry;
}
}
I chose 17 counters because log2(10^5) is just less than 17. So even if all bits are 1, the counters won't wrap.
To read off the result for bit k, take the k'th bit of every counter.
There are slightly more efficient ways that can add several elements of the array into the counters at once using some full-adds and duplicated counters.
I got a numberArray.
It contains intergers - randomised, within a specific range.
I want to get a specific sum, but not for everything inside the numberArray,
more of trying to sum up different amount of numbers (total of 5 only) inside the numberArray and see if it'll get the specific total required. and if not, it'll randomise another number to take over one of the numbers inside the numberArray.
What's the easiest way to do this ?
doing lots of
if (numberArray[1] + numberArray[2] == specificNumber)
{
}
if (numberArray[1] + numberArray[3] == specificNumber)
{
}
etc. etc. etc.
have too many lines of codes, and it seems like there are easier codes. right now i only have 5 different numbers in the array, so it's still bearable, but if the amount of numbers are higher.... ....
Reading your question like this: For your array of random integers, find a (or all) set(s) of integers that have a given sum.
This is an NP-Complete problem - i.e. there's no known algorithm that solves it efficiently.
The fastest known way is rather complex, so we'll go with a naive solution - should be good enough if you're not doing this on every frame or the input set is huge.
This should also work with 0 or negative values in the input set.
// The sum we're looking for:
var requiredSum:int = 8;
// Our input set:
var numberArray:Array = [1, 2, 3, 4, 5, 2, 3];
// Results will be stored here:
var resultSets:Array = [];
// Go through all possible subset sizes.
// This allows subset sizes all the way up to the size of
// the input set (numberArray.length).
// You can modify it to a fixed value (say, 5), of course:
for (var subsetSize:int = 1; subsetSize <= numberArray.length; subsetSize++)
{
// We'll use the same array for all our attempts of this size:
var subset:Array = new Array(subsetSize);
findSum(numberArray, subset, 0, 0);
}
// Output results:
for (var i:int = 0; i < resultSets.length; i++)
{
trace(resultSets[i].join("+"));
}
// numberArray : Our input set
// subset : The set we're currently filling
// setIndex : The position we're at in numberArray
// subsetIndex : The position we're at in the set we're filling
function findSum(numberArray:Array, subset:Array, setIndex:int,
subsetIndex:int):void
{
// Try every value from the input set starting from our current position,
// and insert the value at the current subset index:
for (var index:int = setIndex ; index < numberArray.length; index++)
{
subset[subsetIndex] = numberArray[index];
// Have we filled the subset?
if (subsetIndex == subset.length - 1)
{
var sum:int = 0;
for (var i:int = 0; i < subset.length; i++)
{
sum += subset[i];
}
if (sum == requiredSum)
{
// Clone the array before adding it to our results,
// since we'll be modifying it if we find more:
resultSets.push(subset.concat());
}
}
else
{
// Recursion takes care of combining our subset so far
// with every possible value for the remaining subset indices:
findSum(numberArray, subset, index + 1, subsetIndex + 1);
}
}
}
Output for the values used in the above code:
3+5
5+3
1+2+5
1+3+4
1+4+3
1+5+2
2+3+3
2+4+2
3+2+3
1+2+3+2
1+2+2+3
If we only need to know IF a sum exists, there's no need for the result set - we just return true/false, and break out of the recursive algorithm completely when a sum has been found:
var requiredSum:int = 8;
var numberArray:Array = [1, 2, 3, 4, 5, 2, 3];
// Go through all possible subset sizes:
for (var subsetSize:int = 1; subsetSize <= numberArray.length; subsetSize++)
{
// We'll use the same array for all our attempts of this size:
var subset:Array = new Array(subsetSize);
if (findSum(numberArray, subset, 0, 0))
{
trace("Found our sum!");
// If we found our sum, no need to look for more sets:
break;
}
}
// numberArray : Our input set
// subset : The set we're currently filling
// setIndex : The position we're at in numberArray
// subsetIndex : The position we're at in the set we're filling
// RETURNS : True if the required sum was found, otherwise false.
function findSum(numberArray:Array, subset:Array, setIndex:int,
subsetIndex:int):Boolean
{
// Try every value from the input set starting from our current position,
// and insert the value at the current subset index:
for (var index:int = setIndex ; index < numberArray.length; index++)
{
subset[subsetIndex] = numberArray[index];
// Have we filled the subset?
if (subsetIndex == subset.length - 1)
{
var sum:int = 0;
for (var i:int = 0; i < subset.length; i++)
{
sum += subset[i];
}
// Return true if we found our sum, false if not:
return sum == requiredSum;
}
else
{
if (findSum(numberArray, subset, index + 1, subsetIndex + 1))
{
// If the "inner" findSum found a sum, we're done, so return
// - otherwise stay in the loop and keep looking:
return true;
}
}
}
// We found no subset with our required sum this time around:
return false;
}
ETA: How this works... As mentioned, it's the naive solution - in other words, we're simply checking every single permutation of numberArray, summing each permutation, and checking if it's the sum we want.
The most complicated part is making all the permutations. The way this code does it is through recursion - i.e., the findSum() function filling a slot then calling itself to fill the next one, until all slots are filled and it can check the sum. We'll use the numberArray [1, 5, 4, 2] as an example here:
Go through all subset sizes in a loop - i.e., start by making all [a], then all [a,b], [a,b,c], [a,b,c,d]... etc.
For each subset size:
Fill slot 1 of the subset...
... with each value of numberArray - [1, ?, ?], [5, ?, ?], [4, ?, ?]...
If all slots in subset have been filled, check if the sum matches and skip step 4.
(Recursively) call findSum to:
Fill slot 2 of the subset...
... with each remaining value of numberArray - [1, 5, ?], [1, 4, ?], [1, 2, ?]
If all slots in subset have been filled, check if the sum matches and skip step 4.
(Recursively) call findSum to:
Fill slot 3 of the subset
... with each remaining value of numberArray - [1, 5, 4], [1, 5, 2]
If all slots in subset have been filled, check if the sum matches and skip step 4.
(Recursively) call findSum (this goes on "forever", or until all slots are filled and we "skip step 4")
Go to 2.4.4.1. to try next value for slot 3.
Go to 2.4.1 to try next value for slot 2.
Go to 2.1 to try next value for slot 1.
This way, we go through every permutation of size 1, 2, 3, 4...
There's more optimization that could be done here, since the code never checks that it actually has enough values left in the input set to fill the remaining slots - i.e. it does some loops and calls to findSum() that are unneeded. This is only a matter of efficiency, however - the result is still correct.
I would do something like the following:
shuffle array
take random amount of numbers from the array
sum them up
if the sum is not the total sum you want, repeat
hm, not sure what you want to do at the end when a "conclusion" or "no conclusion" is reached, but you could generate a Power set from your set of numbers then for each subset add up all the numbers in it to see if you get your desired sum.
(This would be a 'brute force' approach and could be slow if you have many numbers.)
Possibly useful for how to create a Power set:
Calculating all of the subsets of a set of numbers
I'm moving to MYSQL from files and I want to use md5 instead of Encryption
public Encrypt(string[])
{
for(new x=0; x < strlen(string); x++)
{
string[x] += (3^x) * (x % 15);
if(string[x] > (0xff))
{
string[x] -= 256;
}
}
return 1;
}
But I need to decrypt it. I don't know how to make a decrypting function. Can anybody help me?
My understanding of PAWN is that it uses null-terminated strings. If that is the case, then this encryption is not a reversable process in general.
Consider a string where the thirteenth character (string[12]) is 'L'. The offset that will be added to that is (3^12) * (12 % 15), i.e. 180. In ASCII, the character 'L' has a value of 76, which when added to 180 is 256. After wrapping to fit in the 0-255 character range that becomes a zero, potentially terminating your encrypted string somewhere in the middle.
If you are storing the length of the original string separately or it's always a fixed length, then maybe this isn't a problem. But if you are relying on a null terminator to determine the length of the string, it isn't going to work.
It looks like the "encryption" adds to each character a number derived from its position. The encryption can be undone by subtracting by the same number.
public Decrypt(string[])
{
for(new x=0; x < strlen(string); x++)
{
string[x] -= (3^x) * (x % 15);
if(string[x] < (0x00))
{
string[x] += 256;
}
}
return 1;
}
I'm cutting my teeth on randomization in games and trying to figure out the trick that games like Binding Of Isacc & Sperlunky use of pre-fab level fragments arranged randomly to create a functional floor/level, something along the lines of this:
A floor will always contain the player, exit and a bonus room (yellow dot). Rooms that are connected are directly connected to each other.
I have a faint idea of how to go about it: Start by creating an multi-dimensional array that holds the tilemap & grid data:
public static var levelLayout:Array =
[[tile,grid],[tile,grid],[tile,grid],[tile,grid]
[tile, grid],[tile,grid],[tile,grid],[tile,grid] etc]
And from there, go through each grid space, roll to see if that spot is nothing, also making rooms nothing if they are isolated and then begin to assign rooms from an shuffled array that contains all the tilemaps/grids.
Am I on the right track? How should I handle the exits? Any help would be appreciated. Cheers
Start by making a perfect maze (a maze where you can get to any point in the maze from anywhere else in the maze). This helps create a network of rooms that are connected in a winnable/solvable way.
There are plenty of tutorials out there for doing this. This one is a little dirty and has a bunch of code you may not need, but it's good to look through some relevant examples of this to understand different approaches:
http://www.emanueleferonato.com/2008/11/28/perfect-maze-generation-with-as3/
I've had good luck with a recursive backtracking algorithm:
http://en.wikipedia.org/wiki/Maze_generation_algorithm#Recursive_backtracker
Consider each cell in the maze to be a room. Once the maze is built, you know which rooms are connected to other rooms, so make each room have a means for either having a door to connect to the next room, or a wall. You probably would want to make like a 4x4 perfect maze.
Ways to spice it up-
You can safely remove deadends from your maze and it will still be perfect. Once the maze is generated, loop through all cells in the maze. Any cell that has 3 walls is a dead end, and you can wall it off completely. Or make it a secret room or whatever.
Add loops to the maze. Randomly connect 2 rooms in the maze that weren't previously connected. This still keeps the maze perfect, it just makes it a little more open.
This is fun territory, enjoy it :)
I've actually been looking into information like this myself recently, having been inspired by Spelunky and Rogue Legacy. While reading around, I found there is a lot of information on how the level layout in Spelunky is generated at http://tinysubversions.com/spelunkyGen/
Inspired(stolen?) by this, I've rigged up a simple version of this to generate a multidimensional Array with a single solution path, using the numbers 0-5 to identify what type of room each cell represents (based off the site listed above). Note that you could easily have it return a different type of result based on your needs. Also I've used Math.random() throughout but you could substitute FP.rand() if you wanted. Supports level layouts of whatever size Room x Room, default is 4 x 4. Some random results I've had [EDITED TO MAKE MORE READABLE]:
4 x 4 6 x 5 7 x 12
[S][ ][ ][ ] [ ][ ][ ][ ][ ][S] [v][-][-][-][-][-][S]
[v][ ][ ][ ] [ ][ ][v][-][-][^] [^][-][-][-][-][-][v]
[^][-][-][v] [ ][v][^][ ][ ][ ] [ ][ ][v][-][-][-][^]
[E][-][-][^] [v][^][ ][ ][ ][ ] [v][-][^][ ][ ][ ][ ]
[^][-][-][-][-][E] [v][ ][ ][ ][ ][ ][ ]
[^][-][-][-][-][-][v]
[ ][ ][v][-][-][-][^]
[v][-][^][ ][ ][ ][ ]
[v][ ][ ][ ][ ][ ][ ]
[^][-][-][-][-][-][v]
[ ][ ][ ][ ][ ][ ][v]
[E][-][-][-][-][-][^]
In any case, I think it's better suited for the 4x4 layout of Spelunky (gee, I wonder why) and I'm pretty sure that I'm going about it slightly off, but here's my code:
/**Generates a pseudo-random single solution path layout to be used for tile painting
* #param dimenR Number of rows (Y-Axis) Should correspond with height of level, in rooms
* #param dimenC Number of columns (X-Axis) Should correspond with width of level, in rooms
* #return The resulting multi-dimensional array*/
private function generateNewRoomLayout(dimenC:int = 4, dimenR:int = 4):Array {
// NOTE: 0= non solution, 1= left/right, 2= left/right/down, 3= left/right/up, 4= start, 5= end
// Initialize array as all non-solution path rooms
var generatedLayout:Array = new Array(dimenR);
for (var i:int = 0; i < dimenR; i++) {
generatedLayout[i] = new Array(dimenC);
for (var j:int = 0; j < dimenC; j++) { generatedLayout[i][j] = 0; }
}
// Initialize our Start Room location
/**Position along X-Axis in the grid*/
var column:int = Math.random() * dimenC;
/**Position along Y-Axis in the grid*/
var row:int = 0;
generatedLayout[row][column] = 4;
/**Chooses the next direction. 0-1= left, 2-3= right, 5= down*/
var chooseDirection:int = Math.random() * 6;
/**Direction solution path is currently taking. -1= left, 1= right*/
var currentDirection:int = 0;
// Keep running until our position goes beyond the dimension of the grid
while (row < dimenR) {
// Chosen to go downards
if (chooseDirection == 5) {
// Reset which way we're going so we can make a random choice later
currentDirection = 0;
if (generatedLayout[row][column] != 4) { generatedLayout[row][column] = 2; }
// Bottom row
if (row == dimenR - 1) {
generatedLayout[row][column] = 5; // Found our ending point
break;
}
else {
row++;
generatedLayout[row][column] = 3;
}
}
else {
// If we don't have a direction to go left/right
if (currentDirection == 0) {
if (chooseDirection < 3) { currentDirection = -1; }
else { currentDirection = 1; }
}
// If we're at the edge of the grid and trying to move past it, we move down and flip our direction instead
if ((currentDirection < 0 && column == 0) || (currentDirection > 0 && column == dimenC - 1)) {
currentDirection = -currentDirection;
generatedLayout[row][column] = 2;
if (row == dimenR - 1) {
generatedLayout[row][column] = 5;
break;
}
else {
row++;
generatedLayout[row][column] = 3;
}
}
else {
column += currentDirection;
generatedLayout[row][column] = 1;
}
}
chooseDirection = Math.random() * 6;
}
return generatedLayout;
}
I'm trying to create an optical character recognition system with the dictionary.
In fact I don't have an implemented dictionary yet=)
I've heard that there are simple metrics based on Levenstein distance which take in account different distance between different symbols. E.g. 'N' and 'H' are very close to each other and d("THEATRE", "TNEATRE") should be less than d("THEATRE", "TOEATRE") which is impossible using basic Levenstein distance.
Could you help me locating such metric, please.
This might be what you are looking for: http://en.wikipedia.org/wiki/Damerau%E2%80%93Levenshtein_distance (and kindly some working code is included in the link)
Update:
http://nlp.stanford.edu/IR-book/html/htmledition/edit-distance-1.html
Here is an example (C#) where weight of "replace character" operation depends on distance between character codes:
static double WeightedLevenshtein(string b1, string b2) {
b1 = b1.ToUpper();
b2 = b2.ToUpper();
double[,] matrix = new double[b1.Length + 1, b2.Length + 1];
for (int i = 1; i <= b1.Length; i++) {
matrix[i, 0] = i;
}
for (int i = 1; i <= b2.Length; i++) {
matrix[0, i] = i;
}
for (int i = 1; i <= b1.Length; i++) {
for (int j = 1; j <= b2.Length; j++) {
double distance_replace = matrix[(i - 1), (j - 1)];
if (b1[i - 1] != b2[j - 1]) {
// Cost of replace
distance_replace += Math.Abs((float)(b1[i - 1]) - b2[j - 1]) / ('Z'-'A');
}
// Cost of remove = 1
double distance_remove = matrix[(i - 1), j] + 1;
// Cost of add = 1
double distance_add = matrix[i, (j - 1)] + 1;
matrix[i, j] = Math.Min(distance_replace,
Math.Min(distance_add, distance_remove));
}
}
return matrix[b1.Length, b2.Length] ;
}
You see how it works here: http://ideone.com/RblFK
A few years too late but the following python package (with which I am NOT affiliated) allows for arbitrary weighting of all the Levenshtein edit operations and ASCII character mappings etc.
https://github.com/infoscout/weighted-levenshtein
pip install weighted-levenshtein
Also this one (also not affiliated):
https://github.com/luozhouyang/python-string-similarity
I've recently created a python package that does exactly that https://github.com/zas97/ocr_weighted_levenshtein.
In my Weigthed-Levenshtein implementation the distance between "THEATRE" and "TNEATRE" is 1.3 while the distance between "THEATRE" and "TOEATRE" is 1.42.
Other exemples are the d("O", "0") is 0.06 and d("e","c") is 0.57.
This distances have been calculated by running multiple ocrs in a synthetic dataset and doing statistics on the most common ocr errors. I hope it helps someone =)