array - efficiency & general approach towards the question - eclipse

Edit
**After quite a bit of playing around with my code I have written few versions, one of them is what I sought for.

I'd do the following:
Create a helper Set with all the numbers from 1 to 100 - O(n) in time and space
Create an (initially) empty Set to record the indexes with 0s - O(1)
Go over the array - O(n):
If the value is 0, add the index to the index set
If the value isn't 0, remove it from the helper Set
Go over the helper set, and assign the remaining values to the indexes saved to the index set - O(m), where m<=n
All in all - an O(n) solution in time and space.
In java:
int[] numbers = /* the array with missing numbers */
Set<Integer> allNumbers = IntStream.rangeClosed(1, 100).boxed().Collect(Collectors.toSet());
Set<Ineteger> missingIndexes = new HashSet<>();
for (int i = 0; i < numbers.length; ++i) {
if (numbers[i] == 0) {
missingIndexes.add(i);
} else {
allNumbers.remove(i);
}
}
Iterator<Integer> numberIter = allNumbers.iterator();
Iterator<Integer> indexIter = missingIndexes.iterator();
while (numberIter.hasNext() && indexIter.hasNext()) {
numbers[indexIter.next()] = numberIter.next();
}

If you can sacrifice a little more space to optimize for time.
Basically just create another missing array and fill it with what's missing by traversing your helper array.
Modified your original solution.
int input [] = {5,6,0,3,0,2,1};
int output [] = new int[input.length];
boolean [] helper = new boolean[input.length];
for(int i = 0; i <input.length; i++)
{
if(input[i] != 0)
helper[i] = true;
}
int missing [] = new int[input.length];
int missingCount = 0;
for(int j = 0; j < helper.length; j++)
{
if(!helper[j]){
missing[missingCount++] = j;
}
}
missingCount = 0;
for(int j = 0; j < input.length; j++){
if(input[j]==0){
input[j]=missing[missingCount++];
}
}

Below code can find the missing element and add them back in O(n) complexity:
notFound - Will store index or location of input array having number
with zero
numberDetails - Contains details of numbers whether its present in
input array or not(true or false)
Example: input[3] = false means 4 (3+1) is not present in input array
, input[4] = true means 5 (4+1) is present in input array
int input[] = { 5, 6, 0, 3, 0, 2, 1 };
int notFound[] = new int[input.length];
boolean[] numberDetails = new boolean[input.length];
int notFoundIndex=0;
for(int i=0;i<input.length;i++) {
if(input[i]==0) {
notFound[notFoundIndex++]=i;
}
else {
numberDetails[input[i]-1]=true;
}
}
notFoundIndex=0;
for(int j=0;j<numberDetails.length;j++) {
if(!numberDetails[j]) {
input[notFound[notFoundIndex++]] = j+1;
}
}
System.out.println(Arrays.toString(input));

Related

Sending strings to BPF Map Space and printing them out

I have a small txt file that I would like to write to BPF here. Here is what my python code looks like for BPF but I am unable to print out anything as of now. I keep ending up with a Failed to load program: Invalid argument with a bunch of register errors. As of now my string basically says hello, world, hi
BPF_ARRAY(lookupTable, char, 512);
int helloworld2(void *ctx)
{
//print the values in the lookup table
#pragma clang loop unroll(full)
for (int i = 0; i < 512; i++) {
char *key = lookupTable.lookup(&i);
if (key) {
bpf_trace_printk("%s\n", key);
}
}
return 0;
}
Here is the Python code:
b = BPF(src_file="hello.c")
lookupTable = b["lookupTable"]
#add hello.csv to the lookupTable array
f = open("hello.csv","r")
file_contents = f.read()
#append file contents to the lookupTable array
b_string1 = file_contents.encode('utf-8')
b_string1 = ctypes.create_string_buffer(b_string1)
lookupTable[0] = b_string1
f.close()
b.attach_kprobe(event=b.get_syscall_fnname("clone"), fn_name="helloworld2")
b.trace_print()
I have the error linked in this pastebin since it's so long:
BPF Error
One notable error is the mention of infinite loop detected which is something I would need to check out.
The issue is that i is passed by pointer in bpf_map_lookup_elem, so the compiler can't actually unroll the loop (from its point of view, i may not linearly increase).
Using an intermediate variable is enough to fix this:
BPF_ARRAY(lookupTable, char, 512);
#define MAX_LENGTH 1
int helloworld2(void *ctx)
{
//print the values in the lookup table
#pragma clang loop unroll(full)
for (int i = 0; i < 1; i++) {
int k = i;
char *key = lookupTable.lookup(&k);
if (key) {
bpf_trace_printk("%s\n", key);
}
}
return 0;
}

Dart remove first comma from string if exists

I have a string of numbers separated by commas. I would like to remove the first and last comma if it exists.
//qlist = ',6063,6077,6051,5925,6069,6054,6071,6049,5903,5858,5760,';
if (qlist.substring(qlist.length - 1) == ','){
qlist= qlist.substring(0,qlist.length - 1);
}
if (qlist.substring(0) == ','){
qlist= qlist.substring(1,qlist.length);
}
Please suggest the right approach.
You could do the following:
int startSlice = 0;
int endSlice = myString.length;
if (myString.startsWith(‘,’))
startSlice = 1;
if (myString.endsWith(‘,’))
endSlice -= 1;
myString = myString.subString(startSlice, endSlice);

Unable to Get Bitwise XOR to work in GameMaker 2

I'm trying to implement Zobrist hashing for a chess game and thought I was doing things correctly. However, when I try to apply XOR to a Hash value, it simply changes between 0 (the starting value for the hash) and -2147483648, in spite of conducting a bitwise XOR against a random number between 0 and 18446744073709551616.
Here's some code. I thought it was relatively simple with a struct for each entry in the Grid, a constructor function to make an entry, a function to create the Hash Table, and finally one for the Hash itself.
//Hash Table struct. This can be expanded for each new piece type
HashTableEntry = {
QueenHash:-1,
BishopHash:-1,
KnightHash:-1,
RookHash:-1,
PawnHash:-1,
KingHash:-1
};
//A function for creating a Hash Table Entry
function toHashTableEntryStruct() constructor {
var HashUpperBound = 18446744073709551616;
QueenHash = random(HashUpperBound);
BishopHash = random(HashUpperBound);
KnightHash = random(HashUpperBound);
RookHash = random(HashUpperBound);
PawnHash = random(HashUpperBound);
KingHash = random(HashUpperBound);
}
//A function to create a ds_grid Hash Table of the size passed to it, which it then returns
function CreateHashTable(_width, _height){
//Copy the local variables
var width = _width;
var height = _height;
//Create the grid for the Hash Table
var NewHashTable = ds_grid_create(width, height);
//Copy the original seed and set the game's seed to create the same table each time
var OriginalSeed = random_get_seed;
random_set_seed(280804);
//Loop through the Grid and fill each value with a HashTableEntry struct
for(var i = 0; i < width; i++;){
for(var j = 0; j < height; j++;){
var NewHash = new toHashTableEntryStruct();
ds_grid_set(NewHashTable, i, j, NewHash);
}
}
//Reset the seed
random_set_seed(OriginalSeed);
//Return the shiny new Hash Table
return NewHashTable;
}
//A function for creating the original Hash of a board. This should only be called on
initialising a Board as it sets the Original Hash
function CreateBoardHash(_board){
var Board = _board;
var width = ds_grid_width(Board);
var height = ds_grid_height(Board);
HashTable = CreateHashTable(width, height);
var FinalHash = 0;
for(var i = 0; i < width; i++;){
for(var j = 0; j < height; j++;){
var PieceToCheck = ds_grid_get(Board, i, j);
if(PieceToCheck == Pieces.BLANK){ continue; }
var HashEntry = ds_grid_get(HashTable, i, j);
var XorValue = MatchPieceToHashTableEntry(PieceToCheck, HashEntry);
FinalHash ^= XorValue;
}
}
if(FinalHash == 0){
//Error here
return;
}
//Set the instance variable for this original Hash
OriginalHash = FinalHash;
//Add it to the Current Hash stack
CurrentHash = FinalHash;
//Return said hash for the calling function
return FinalHash;
}
The problem comes in the FinalHash ^= XorValue; line, where XorValue each time is a random number, but FinalHash only ever comes out as 0 or -2147483648.
Can someone help with why this is the case and what I may be doing wrong with my XOR function?
Thanks to Reddit, I have fixed this. GameMaker must be doing something weird with the ^= operator, as the solution was as follows:
FinalHash = FinalHash ^ XorValue;

Recursive Pathfinding in Swift - find longest path

(Sorry for the cross-post, but I put this up on GameDev.Stackexchange and it's not getting much traffic, so I thought I'd try here as well.)
I'm programming a simple tile-based puzzle game, and I've gotten stuck trying to work out a pathfinding algorithm.
Here's how the game is set out:
The game board is (arbitrarily) 8 tiles wide by 8 tiles tall.
Each tile can be one of four types (shown below as red, green, blue and yellow)
Additionally, a tile could be a reactor (the starting point of a path - this will become clear later on)
The board would look something like this:
(The reactors are the circles; the other tiles have no special properties.)
What I need to do is: starting from a reactor, trace the longest path along adjoining tiles of the same color as the reactor. Something like this:
The blue reactor is simple(ish) as its path doesn't branch. However, as you can see from the green reactor's start position, its path can branch two ways at the start (up or down), and take a detour midway through.
The path I'm looking for is the longest one, so that's the one that's highlighted in the screengrab (the first path only crosses two tiles, and the detour midway results in a sorter path).
When certain conditions have been fulfilled, the reactor will cause all the tiles in the longest path (where the arrows cross in the diagram) to disappear and be replaced with new ones. All other tiles will remain in place, including the extraneous green tiles adjacent to the green reactor's path.
The tiles are stored in an approximation of a 2D array (Swift doesn't have a robust native implementation of that yet, so I'm using the one described in this tutorial). They're retrieved using tile[column, row].
With some help from a friend, I've written a recursive function that should return the longest path. It's looping through correctly, but it's not pruning shorter branches from the longestPath array (for example, the longest path would include the 2-tile branch below the reactor, as well as the single-tile detour at the top of the arch).
Can anyone see where I'm going wrong in this code?
Here's the recursive function:
func pathfinder(startingTile: Tile, pathToThisPoint: Chain, var iteration: Int? = 1) -> Chain
{
var longestPath: Chain? = nil
var availableTiles = getNeighbouringTiles(startingTile)
for var nextTile = 0; nextTile < availableTiles.count; nextTile++
{
let column = availableTiles[nextTile].column
let row = availableTiles[nextTile].row
if tiles[column, row]!.tileType == startingTile.tileType && (tiles[column, row]!.isReactor == false || startingTile.isReactor)
{
// if we haven't been here before
if !pathToThisPoint.tiles.contains(tiles[column, row]!)
{
print(iteration)
iteration = iteration! + 1
// add this tile to the pathtothispoint
// go to the next unexplored tile (recurse this function)
pathToThisPointaddTile(tiles[column, row]!)
let tempPath = pathfinder(tiles[column, row]!, pathToThisPoint: pathToThisPoint)
// if the resulting path is longer...
if tempPath.length > longestPath.length
{
// then tempPath is now the longest path
for var i:Int = 0; i < tempPath.length; i++
{
let tile = Tile(column: pathToThisPoint.tiles[i].column, row: pathToThisPoint.tiles[i].row, tileType: pathToThisPoint.tiles[i].tileType)
longestPath?.addTile(tile)
}
}
}
}
if longestPath != nil
{
return longestPath!
}
else
{
return pathToThisPoint
}
}
It's dependent on the getNeighboringTiles function (shown below) that returns an array of valid tiles of the same type, excluding reactors:
func getNeighbouringTiles(tile: Tile, previousTile: Tile? = nil) -> Array<Tile>
{
var validNeighbouringTiles = Array<Tile>()
var neighbourTile: Tile
// check top, right, bottom, left
if tile.row < NumRows - 1
{
neighbourTile = tiles[tile.column, tile.row + 1]!
if neighbourTile.tileType == tile.tileType && !neighbourTile.isReactor && (previousTile == nil || previousTile != neighbourTile)
{
validNeighbouringTiles.append(neighbourTile)
}
}
if tile.column < NumColumns - 1
{
neighbourTile = tiles[tile.column + 1, tile.row]!
if neighbourTile.tileType == tile.tileType && !neighbourTile.isReactor && (previousTile == nil || previousTile != neighbourTile)
{
validNeighbouringTiles.append(neighbourTile)
}
}
if tile.row > 0
{
neighbourTile = tiles[tile.column, tile.row - 1]!
if neighbourTile.tileType == tile.tileType && !neighbourTile.isReactor && (previousTile == nil || previousTile != neighbourTile)
{
validNeighbouringTiles.append(neighbourTile)
}
}
if tile.column > 0
{
neighbourTile = tiles[tile.column - 1, tile.row]!
if neighbourTile.tileType == tile.tileType && !neighbourTile.isReactor && (previousTile == nil || previousTile != neighbourTile)
{
validNeighbouringTiles.append(neighbourTile)
}
}
// if we get this far, they have no neighbour
return validNeighbouringTiles
}
The Tile class looks like this (methods omitted for brevity):
class Tile: CustomStringConvertible, Hashable
{
var column:Int
var row:Int
var tileType: TileType // enum, 1 - 4, mapping to colors
var isReactor: Bool = false
// if the tile is a reactor, we can store is longest available path here
var reactorPath: Chain! = Chain()
}
And finally, the chain class looks like this (again, methods omitted for brevity):
class Chain {
// The tiles that are part of this chain.
var tiles = [Tile]()
func addTile(tile: Tile) {
tiles.append(tile)
}
func firstTile() -> Tile {
return tiles[0]
}
func lastTile() -> Tile {
return tiles[tiles.count - 1]
}
var length: Int {
return tiles.count
}
}
----------------------- EDIT : REPLACEMENT PATHFINDER ------------------------
I've attempted to convert User2464424's code to Swift. Here's what I've got:
func calculatePathsFromReactor(reactor: Tile) -> Chain?
{
func countDirections(neighbours: [Bool]) -> Int
{
var count: Int = 0
for var i:Int = 0; i < neighbours.count; i++
{
if neighbours[i] == true
{
count++
}
}
return count
}
var longestChain: Chain? = nil
longestChain = Chain()
var temp: Chain = Chain()
var lastBranch: Tile = reactor
var lastMove: Int? = reactor.neighbours.indexOf(true)
func looper(var currentTile: Tile)
{
if currentTile != reactor
{
if countDirections(currentTile.neighbours) > 2 //is branch
{
lastBranch = currentTile
}
if countDirections(currentTile.neighbours) == 1 //is endpoint
{
lastBranch.neighbours[lastMove!] = false // block move out of the last branch found
if longestChain.length < temp.length
{
longestChain = temp
}
currentTile = reactor // return to reactor and redo
lastVisitedTile = reactor
temp = Chain() //reset to empty array
lastBranch = reactor
lastMove = reactor.neighbours.indexOf(true)
looper(currentTile)
}
}
//let tempTile: Tile = Tile(column: currentTile.column, row: currentTile.row, tileType: currentTile.tileType, isReactor: currentTile.isReactor, movesRemaining: currentTile.movesRemaining)
//tempTile.neighbours = currentTile.neighbours
if currentTile.neighbours[0] == true
{
if !temp.tiles.contains(currentTile)
{
temp.addTile(currentTile)
}
if countDirections(currentTile.neighbours) > 2
{
lastMove = 0
}
lastVisitedTile = currentTile
currentTile = tiles[currentTile.column, currentTile.row + 1]! //must avoid going backwards
if !temp.tiles.contains(currentTile)
{
looper(currentTile)
}
}
if currentTile.neighbours[1] == true
{
if !temp.tiles.contains(currentTile)
{
temp.addTile(currentTile)
}
if countDirections(currentTile.neighbours) > 2
{
lastMove = 1
}
lastVisitedTile = currentTile
currentTile = tiles[currentTile.column + 1, currentTile.row]! //must avoid going backwards
if !temp.tiles.contains(currentTile)
{
looper(currentTile)
}
}
if currentTile.neighbours[2] == true
{
if !temp.tiles.contains(currentTile)
{
temp.addTile(currentTile)
}
if countDirections(currentTile.neighbours) > 2
{
lastMove = 2
}
lastVisitedTile = currentTile
currentTile = tiles[currentTile.column, currentTile.row - 1]! //must avoid going backwards
if !temp.tiles.contains(currentTile)
{
looper(currentTile)
}
}
if currentTile.neighbours[3] == true
{
if !temp.tiles.contains(currentTile)
{
temp.addTile(currentTile)
}
if countDirections(currentTile.neighbours) > 2
{
lastMove = 3
}
lastVisitedTile = currentTile
currentTile = tiles[currentTile.column - 1, currentTile.row]! //must avoid going backwards
if !temp.tiles.contains(currentTile)
{
looper(currentTile)
}
}
}
// trigger the function for the reactor tile
looper(reactor)
return longestChain
}
(The neighbours property is a struct containing four named variables: above, right, below and left, each initialised to false and then set to true by a function that runs immediately before the pathfinder.)
I'm finding a couple of issues now. The code loops as it should, but stops at the top of the arch, under the single-tile detour - the path that's returned is only 4 tiles long (including the reactor).
The other problem I'm having - which I'll worry about when the correct paths are being returned - is that I'm getting a memory access error when shifting the tiles in the third column down by one. I think it's getting confused when there's a block of tiles (2x2 or higher) rather than a path that's only ever a single tile wide.
I can't fix your code, but i have an idea for a system that doesn't require recursion.
You can try doing all possible paths from a reactor and block paths that you already traversed by being aware of the moves you have done when encountering a branch.
In the tile class, add another array of 4 integers initialized to 0 (called "dir" for example).
Pseudocode.
Do a preprocess loop first:
foreach tiles:
if tileHasNORTHNeighbor: tile.dir[0] = 1;
if tileHasEASTNeighbor: tile.dir[1] = 1;
if tileHasSOUTHNeighbor: tile.dir[2] = 1;
if tileHasWESTNeighbor: tile.dir[3] = 1;
Then do:
tile currentTile = reactor;
array longest;
array temp;
tile lastBranch = reactor;
int lastMove = any key of "reactor.dir" with "1" as value;
function int countOnes(array dir):
int count = 0;
int t;
for (t=0;t<4;t++):
if dir[t]==1:
count++;
return count;
:start
if currentTile != reactor:
if countOnes(currentTile.dir) > 2: //is branch
lastBranch = currentTile;
if countOnes(currentTile.dir) == 1: //is endpoint
lastBranch.dir[lastMove] = 0; // block move out of the last branch found
if longest.length < temp.length:
longest = temp;
currentTile = reactor; // return to reactor and redo
array temp = []; //reset to empty array
lastBranch = reactor;
lastMove = next "reactor.dir" key with "1" as value;
goto start;
if currentTile.dir[0] == 1:
temp.append(currentTile);
if countOnes(currentTile.dir) > 2:
lastMove = 0;
currentTile = getTileAtNORTH; //must avoid going backwards
goto start;
if currentTile.dir[1] == 1:
temp.append(currentTile);
if countOnes(currentTile.dir) > 2:
lastMove = 1;
currentTile = getTileAtEAST; //must avoid going backwards
goto start;
if currentTile.dir[2] == 1:
temp.append(currentTile);
if countOnes(currentTile.dir) > 2:
lastMove = 2;
currentTile = getTileAtSOUTH; //must avoid going backwards
goto start;
if currentTile.dir[3] == 1:
temp.append(currentTile);
if countOnes(currentTile.dir) > 2:
lastMove = 3;
currentTile = getTileAtWEST; //must avoid going backwards
goto start;
You could use the BFS Algorithm and easily modify it to give you the longest path.
You've got a implementation example here. Or you've got at least SwiftStructures and SwiftGraph github repositories with graph and search algorithms already implemented in swift.

Loop in coffee script?

I'm translating a piece of code from javascript to coffeescript.
for (var i = 0, len = keys.length; i < len; i++) {
k = keys[i];
if (!mailOptions.hasOwnProperty(k))
mailOptions[k] = app.set('mailOptions')[k]
}
I have no idea how to approach to it and on the doc website is not clear, can someone give me a clear explanation? thank you very much!
for key in keys
if not mailOptions.hasOwnProperty key
mailOptions[key] = (app.set 'mailOptions')[key]
Or guard-style:
for key in keys when not mailOptions.hasOwnProperty key
mailOptions[key] = (app.set 'mailOptions')[key]
Compiles to:
var key, _i, _len;
for (_i = 0, _len = keys.length; _i < _len; _i++) {
key = keys[_i];
if (!mailOptions.hasOwnProperty(key)) {
mailOptions[key] = (app.set('mailOptions'))[key];
}
}
Here's one way (from here: http://js2coffee.org/):
i = 0
len = keys.length
while i < len
k = keys[i]
mailOptions[k] = app.set("mailOptions")[k] unless mailOptions.hasOwnProperty(k)
i++
But I wouldn't do it this way. I would just do:
for k in keys
mailOptions[k] = app.set("mailOptions")[k] unless mailOptions.hasOwnProperty k
This outputs the following (excluding var, which it also outputs):
for (_i = 0, _len = keys.length; _i < _len; _i++) {
k = keys[_i];
if (!mailOptions.hasOwnProperty(k)) {
mailOptions[k] = app.set("mailOptions")[k];
}
}
Or, if you wanted to be fancier, which I don't advise in this situation, since it sacrifices some readability:
(mailOptions[k] = app.set("mailOptions")[k] unless mailOptions.hasOwnProperty k) for k in keys