First, I give thanks to ksav and his help thus far.
I'm a foreman for a landscaping company and it's my responsibility to fill out forms for each site and keep track of our man hours so we don't go over the allotted time. I'm trying to digitize the documents in Adobe so I can enter the times in the field on my phone without pen and paper and have a JavaScript code automatically calculate the hours on site in decimal format.
Note: I will be using 24-hour time aka military time (13:00/1PM 16:40/4:40PM)
The JS code currently used within Adobe isn't calculating/converting the time difference correctly:
This gives incorrect decimal calculations on the time difference:
var start = this.getField("Monday Site #1 Start Time").value;
var startArr = start.split(":");
// finish
var finish = this.getField("Monday Site #1 Depart Time").value;
var finishArr = finish.split(":");
// difference
var hourDiff = Math.abs(finishArr[0] - startArr[0]);
var minDiff = Math.floor((Math.abs(finishArr[1] - startArr[1]) / 59)*100);
if (minDiff.toString().length == 1)
minDiff = '0' + minDiff;
var output = hourDiff + "." + minDiff;
event.value = output;
if ((event.value == "") || (event.value == Infinity) || isNaN(event.value))
{event.value = "";}
Examples of the hour-decimal calculation errors:
I should mention these fields are all uniquely named Form Fill fields within Adobe, hence the variable field names "Monday Site #1 Start Time, Monday Site #1 Depart Time, MS1 Total Hours etc etc:
See my original question where I tried other JS code to no avail. Some of those snippets didn't give me any value whatsoever
I have limited knowledge on JavaScript code so any assistance with this would be greatly appreciated!
I started programming a few months ago. I'm making a complete client side game in Animate CC, so I'm trying a simple measure against memory scan software.
I'm trying to avoid people to change my money variable.
var canMoneyChange = false;
var money = 0;
var previousMoney = 0;
function everyFrame() { //Let's admit that this function is called every frame
if (moneyChange == true) {
lastMoney = money;
canMoneyChange = false;
} else {
if (lastMoney != money) { //If money is "magically" changed it should drop here
resetGame();
}
}
Now evertime I update the money visual display I also have to include the boolean variable:
//...
canMoneyChange = true;
money += 100; //For example
updateMoney(); //This is only for visual effects
//...
Wondering if this works at all, thanks.
EDIT: Oh damn, I was not realising that CE would find both lastMoney and money at the same time. I could do something like multiplying by a number to hide lastMoney:
function everyFrame() { //Let's admit that this function is called every frame
if (moneyChange == true) {
lastMoney = money * 8;
canMoneyChange = false;
} else {
if (lastMoney != money * 8) {
resetGame();
}
}
This will stop 50% of Cheat Engine users because most users are inexperienced and are only capable of doing simple scans and memory modifications. They will just give up because you've raised the adversarial costs above their threshold.
As others have commented, it's a cat and mouse game.
Users can still scan for "unknown initial value" and scan for decreased and increased values. This will yield the obfuscated money value and the regular value, doesn't take too much to figure it out from there.
Also users can do "Find what Writes to this address" that will put a write breakpoint on the money address, it will then give them the instruction that changes the money back to the original value. At this point they will see the:
lastMoney = money * 8;
in assembly and be able to figure it out from there.
In all anti-cheat situations, each deterrent you put in place will raise adversarial costs and filter out another tier of cheaters. Your goal should never be to stop all cheaters 'cuz that's never happening. But in a few hours you can roll up a bit of obfuscation and a couple anti-debug measures to deter 75% of the cheaters. Problem is when the other 25% representing the experienced cheaters release the cheats. At that point the 75% inexperienced group's adversarial costs represent a search on a search engine.
I would say add some IsDebuggerPresent() type checks but I imagine on your platform that's not possible.
I'm not familiar with Animate CC or Flash, but combining 1 custom obfuscation technique like you're working on right now, with a public free obfuscator will annoy a substantial number of people enough to give up.
So I was solving a problem for class involving binary search and the algorithm I implemented to solve it worked fine but my hunch is that a slight gamble would be more effective given the parameters of the problem
The fictional town of HollyBroke, Fl is made up of a 30 x 30 block grid. The streets are named after the presidents of the United States and the avenues are numbered numerically. The infamous two-word arsonist is holding the town hostage. He selects a house every Saturday for destruction by fire and taunts the police department by challenging them to guess the location for each week’s crime. He will answer up 10 guesses with either a “yes”or a “no” answer during his very brief phone call right before he strikes the match. (He won’t stay on the line so the call can’t be trace.)
The city wants you to develop a program to provide a quick response when this notorious criminal calls.
The answer to that was easy enough to create an algorithm for but I thought a median-1/median+1 gamble would be more effective. My hunch is that more often than not I will arrive at the conclusion with one extra question to go allowing me to either ask a binary search question about the arsonist or if the game allowed it I would show up with police before the end of the call. If I don't outright solve it beforehand I would have a very small space to search after it was completed, like three or four blocks right next to each other,
This is my code for the "gambling" binary search.
`var array = [{"a":30,"b":30,"c":0}]
function findLower(input) {
var half = Math.floor(input/2);
if(0 == input%2)
return (half-1);
else
return (half);
};
function findUpper(input) {
var half = Math.floor(input/2);
if(input%2 == 0)
return (half+1);
else
return (half+1);
}
for (var i = 0; i <= 9; i++){
for (var z = array.length - 1; z >= 0; z--) {
if (array[z].c = i){
if (array[z].a>array[z].b)
array.push({"a":findLower(array[z].a),"b":array[z].b,"c":array[z].c + 1},{"a":findUpper(array[z].a),"b":array[z].b,"c":array[z].c + 1})
else
array.push({"a":array[z].a,"b":findLower(array[z].b),"c":array[z].c + 1},{"a":array[z].a,"b":findUpper(array[z].b),"c":array[z].c + 1})
}
};
}
console.log(array.length);`
Its coming up with an absurd array length given that it should be 2^10 +2^9 + 2^8 ..... = 2047
The program is coming up with an array length of 19683
And some of the arrays should most certainly not be 30*14 at node level 10 I'm sure the algorithm was set up properly. I've walked it through two levels by pen and paper and it seems like it should work properly.
Found it.
if (array[z].c = i){
should be
if (array[z].c == i){
its a conditional statement not declaring them equal
Also I was wrong. You only have about a 40% chance of successfully locating the house in 10 guesses.
I was wondering if it were possible to implement some kind of crude JavaScript anti-flood protection.
My code receives events from a server through AJAX, but sometimes these events can be quite frequent (they're not governed by me).
I have attempted to come up with a method of combating this, and I've written a small script: http://jsfiddle.net/Ry5k9/
var puts = {};
function receiverFunction(id, text) {
if ( !puts[id] ) {
puts = {};
puts[id] = {};
}
puts[id].start = puts[id].start || new Date();
var count = puts[id].count = puts[id].count + 1 || 0;
var time = (new Date() - puts[id].start) * 0.001;
$("text").set("text", (count / time.toFixed()).toString() + " lines/second");
doSomethingWithTextIfNotSpam(text);
}
};
which I think could prove effective against these kinds of attacks, but I'm wondering if it can be improved or perhaps rewritten?
So far, I think everything more than 3 or 2.5 lines per second seems like spam, but as time progresses forward (because start mark was set... well... at the start), an offender could simply idle for a while and then commence the flood, effectively never passing 1 line per minute.
Also, I would like to add that I use Mootools and Lo-Dash libraries (maybe they provide some interesting methods), but it would be preferable if this can be done using native JS.
Any insight is greatly appreciated!
If you are concerned about the frequency a particular javascript function fires, you could debounce the function.
In your example, I guess it would be something like:
onSuccess: function(){ _.debounce(someOtherFunction, timeOut)};
where timeout is the maximum frequency you want someOtherFunction to be called.
I know you asked about native JavaScript, but maybe take a look at RxJS.
RxJS or Reactive Extensions for JavaScript is a library for
transforming, composing, and querying streams of data. We mean all
kinds of data too, from simple arrays of values, to series of events
(unfortunate or otherwise), to complex flows of data.
There is an example on that page which uses the throttle method to "Ignores values from an observable sequence which are followed by another value before dueTime" (see source).
keyup = Rx.Observable.fromEvent(input, 'keyup').select(function(ev) {
return ev.target.value;
}).where(function(text) {
return text.length > 2;
}).throttle(500)
.distinctUntilChanged()
There might be a similar way to get your 2.5-3 per second and ignore the rest of the events until the next second.
I've spent many days pondering on effective measures to forbid message-flooding, until I came across the solution implemented somewhere else.
First, we need three things, penalty and score variables, and a point in time where last action occured:
var score = 0;
var penalty = 200; // Penalty can be fine-tuned.
var lastact = new Date();
Next, we decrease score by the distance between the previous message and current in time.
/* The smaller the distance, more time has to pass in order
* to negate the score penalty cause{d,s}.
*/
score -= (new Date() - lastact) * 0.05;
// Score shouldn't be less than zero.
score = (score < 0) ? 0 : score;
Then we add the message penalty and check if it crosses the threshold:
if ( (score += penalty) > 1000 ) {
// Do things.
}
Shouldn't forget to update last action afterwards:
lastact = new Date();
Background
This picture illustrates the problem:
I can control the red circle. The targets are the blue triangles. The black arrows indicate the direction that the targets will move.
I want to collect all targets in the minimum number of steps.
Each turn I must move 1 step either left/right/up or down.
Each turn the targets will also move 1 step according to the directions shown on the board.
Demo
I've put up a playable demo of the problem here on Google appengine.
I would be very interested if anyone can beat the target score as this would show that my current algorithm is suboptimal. (A congratulations message should be printed if you manage this!)
Problem
My current algorithm scales really badly with the number of targets. The time goes up exponentially and for 16 fish it is already several seconds.
I would like to compute the answer for board sizes of 32*32 and with 100 moving targets.
Question
What is an efficient algorithm (ideally in Javascript) for computing the minimum number of steps to collect all targets?
What I've tried
My current approach is based on memoisation but it is very slow and I don't know whether it will always generate the best solution.
I solve the subproblem of "what is the minimum number of steps to collect a given set of targets and end up at a particular target?".
The subproblem is solved recursively by examining each choice for the previous target to have visited.
I assume that it is always optimal to collect the previous subset of targets as quickly as possible and then move from the position you ended up to the current target as quickly as possible (although I don't know whether this is a valid assumption).
This results in n*2^n states to be computed which grows very rapidly.
The current code is shown below:
var DX=[1,0,-1,0];
var DY=[0,1,0,-1];
// Return the location of the given fish at time t
function getPt(fish,t) {
var i;
var x=pts[fish][0];
var y=pts[fish][1];
for(i=0;i<t;i++) {
var b=board[x][y];
x+=DX[b];
y+=DY[b];
}
return [x,y];
}
// Return the number of steps to track down the given fish
// Work by iterating and selecting first time when Manhattan distance matches time
function fastest_route(peng,dest) {
var myx=peng[0];
var myy=peng[1];
var x=dest[0];
var y=dest[1];
var t=0;
while ((Math.abs(x-myx)+Math.abs(y-myy))!=t) {
var b=board[x][y];
x+=DX[b];
y+=DY[b];
t+=1;
}
return t;
}
// Try to compute the shortest path to reach each fish and a certain subset of the others
// key is current fish followed by N bits of bitmask
// value is shortest time
function computeTarget(start_x,start_y) {
cache={};
// Compute the shortest steps to have visited all fish in bitmask
// and with the last visit being to the fish with index equal to last
function go(bitmask,last) {
var i;
var best=100000000;
var key=(last<<num_fish)+bitmask;
if (key in cache) {
return cache[key];
}
// Consider all previous positions
bitmask -= 1<<last;
if (bitmask==0) {
best = fastest_route([start_x,start_y],pts[last]);
} else {
for(i=0;i<pts.length;i++) {
var bit = 1<<i;
if (bitmask&bit) {
var s = go(bitmask,i); // least cost if our previous fish was i
s+=fastest_route(getPt(i,s),getPt(last,s));
if (s<best) best=s;
}
}
}
cache[key]=best;
return best;
}
var t = 100000000;
for(var i=0;i<pts.length;i++) {
t = Math.min(t,go((1<<pts.length)-1,i));
}
return t;
}
What I've considered
Some options that I've wondered about are:
Caching of intermediate results. The distance calculation repeats a lot of simulation and intermediate results could be cached.
However, I don't think this would stop it having exponential complexity.
An A* search algorithm although it is not clear to me what an appropriate admissible heuristic would be and how effective this would be in practice.
Investigating good algorithms for the travelling salesman problem and see if they apply to this problem.
Trying to prove that the problem is NP-hard and hence unreasonable to be seeking an optimal answer for it.
Have you searched the literature? I found these papers which seems to analyse your problem:
"Tracking moving targets and the non- stationary traveling salesman
problem": http://citeseerx.ist.psu.edu/viewdoc/summary?doi=10.1.1.85.9940
"The moving-target traveling salesman problem": http://citeseerx.ist.psu.edu/viewdoc/summary?doi=10.1.1.57.6403
UPDATE 1:
The above two papers seems to concentrate on linear movement for the euclidian metric.
Greedy method
One approach suggested in the comments is to go to the closest target first.
I've put up a version of the demo which includes the cost calculated via this greedy method here.
The code is:
function greedyMethod(start_x,start_y) {
var still_to_visit = (1<<pts.length)-1;
var pt=[start_x,start_y];
var s=0;
while (still_to_visit) {
var besti=-1;
var bestc=0;
for(i=0;i<pts.length;i++) {
var bit = 1<<i;
if (still_to_visit&bit) {
c = fastest_route(pt,getPt(i,s));
if (besti<0 || c<bestc) {
besti = i;
bestc = c;
}
}
}
s+=c;
still_to_visit -= 1<<besti;
pt=getPt(besti,s);
}
return s;
}
For 10 targets it is around twice the optimal distance, but sometimes much more (e.g. *4) and occasionally even hits the optimum.
This approach is very efficient so I can afford some cycles to improve the answer.
Next I'm considering using ant colony methods to see if they can explore the solution space effectively.
Ant colony method
An Ant colony method seems to work remarkable well for this problem. The link in this answer now compares the results when using both greedy and ant colony method.
The idea is that ants choose their route probabilistically based on the current level of pheromone. After every 10 trials, we deposit additional pheromone along the shortest trail they found.
function antMethod(start_x,start_y) {
// First establish a baseline based on greedy
var L = greedyMethod(start_x,start_y);
var n = pts.length;
var m = 10; // number of ants
var numrepeats = 100;
var alpha = 0.1;
var q = 0.9;
var t0 = 1/(n*L);
pheromone=new Array(n+1); // entry n used for starting position
for(i=0;i<=n;i++) {
pheromone[i] = new Array(n);
for(j=0;j<n;j++)
pheromone[i][j] = t0;
}
h = new Array(n);
overallBest=10000000;
for(repeat=0;repeat<numrepeats;repeat++) {
for(ant=0;ant<m;ant++) {
route = new Array(n);
var still_to_visit = (1<<n)-1;
var pt=[start_x,start_y];
var s=0;
var last=n;
var step=0;
while (still_to_visit) {
var besti=-1;
var bestc=0;
var totalh=0;
for(i=0;i<pts.length;i++) {
var bit = 1<<i;
if (still_to_visit&bit) {
c = pheromone[last][i]/(1+fastest_route(pt,getPt(i,s)));
h[i] = c;
totalh += h[i];
if (besti<0 || c>bestc) {
besti = i;
bestc = c;
}
}
}
if (Math.random()>0.9) {
thresh = totalh*Math.random();
for(i=0;i<pts.length;i++) {
var bit = 1<<i;
if (still_to_visit&bit) {
thresh -= h[i];
if (thresh<0) {
besti=i;
break;
}
}
}
}
s += fastest_route(pt,getPt(besti,s));
still_to_visit -= 1<<besti;
pt=getPt(besti,s);
route[step]=besti;
step++;
pheromone[last][besti] = (1-alpha) * pheromone[last][besti] + alpha*t0;
last = besti;
}
if (ant==0 || s<bestantscore) {
bestroute=route;
bestantscore = s;
}
}
last = n;
var d = 1/(1+bestantscore);
for(i=0;i<n;i++) {
var besti = bestroute[i];
pheromone[last][besti] = (1-alpha) * pheromone[last][besti] + alpha*d;
last = besti;
}
overallBest = Math.min(overallBest,bestantscore);
}
return overallBest;
}
Results
This ant colony method using 100 repeats of 10 ants is still very fast (37ms for 16 targets compared to 3700ms for the exhaustive search) and seems very accurate.
The table below shows the results for 10 trials using 16 targets:
Greedy Ant Optimal
46 29 29
91 38 37
103 30 30
86 29 29
75 26 22
182 38 36
120 31 28
106 38 30
93 30 30
129 39 38
The ant method seems significantly better than greedy and often very close to optimal.
The problem may be represented in terms of the Generalized Traveling Salesman Problem, and then converted to a conventional Traveling Salesman Problem. This is a well-studied problem. It is possible that the most efficient solutions to the OP's problem are no more efficient than solutions to the TSP, but by no means certain (I am probably failing to take advantage of some aspects of the OP's problem structure that would allow for a quicker solution, such as its cyclical nature). Either way, it is a good starting point.
From C. Noon & J.Bean, An Efficient Transformation of the Generalized Traveling Salesman Problem:
The Generalized Traveling Salesman Problem (GTSP) is a useful model for problems involving decisions of selection and sequence. The asymmetric version of the problem is defined on a directed graph with nodes N, connecting arcs A and a vector of corresponding arc costs c. The nodes are pregrouped into m mutually exclusive and exhaustive nodesets. Connecting arcs are defined only between nodes belonging to different sets, that is, there are no intraset arcs. Each defined arc has a corresponding non-negative cost. The GTSP can be stated as the problem of finding a minimum cost m-arc cycle which includes exactly one node from each nodeset.
For the OP's problem:
Each member of N is a particular fish's location at a particular time. Represent this as (x, y, t), where (x, y) is a grid coordinate, and t is the time at which the fish will be at this coordinate. For the leftmost fish in the OP's example, the first few of these (1-based) are: (3, 9, 1), (4, 9, 2), (5, 9, 3) as the fish moves right.
For any member of N let fish(n_i) return the ID of the fish represented by the node. For any two members of N we can calculate manhattan(n_i, n_j) for the manhattan distance between the two nodes, and time(n_i, n_j) for the time offset between the nodes.
The number of disjoint subsets m is equal to the number of fish. The disjoint subset S_i will consist only of the nodes for which fish(n) == i.
If for two nodes i and j fish(n_i) != fish(n_j) then there is an arc between i and j.
The cost between node i and node j is time(n_i, n_j), or undefined if time(n_i, n_j) < distance(n_i, n_j) (i.e. the location can't be reached before the fish gets there, perhaps because it is backwards in time). Arcs of this latter type can be removed.
An extra node will need to be added representing the location of the player with arcs and costs to all other nodes.
Solving this problem would then result in a single visit to each node subset (i.e. each fish is obtained once) for a path with minimal cost (i.e. minimal time for all fish to be obtained).
The paper goes on to describe how the above formulation may be transformed into a traditional Traveling Salesman Problem and subsequently solved or approximated with existing techniques. I have not read through the details but another paper that does this in a way it proclaims to be efficient is this one.
There are obvious issues with complexity. In particular, the node space is infinite! This can be alleviated by only generating nodes up to a certain time horizon. If t is the number of timesteps to generate nodes for and f is the number of fish then the size of the node space will be t * f. A node at time j will have at most (f - 1) * (t - j) outgoing arcs (as it can't move back in time or to its own subset). The total number of arcs will be in the order of t^2 * f^2 arcs. The arc structure can probably be tidied up, to take advantage of the fact the fish paths are eventually cyclical. The fish will repeat their configuration once every lowest common denominator of their cycle lengths so perhaps this fact can be used.
I don't know enough about the TSP to say whether this is feasible or not, and I don't think it means that the problem posted is necessarily NP-hard... but it is one approach towards finding an optimal or bounded solution.
I think another approch would be:
calculate the path of the targets - predictive.
than use Voronoi diagrams
Quote wikipedia:
In mathematics, a Voronoi diagram is a way of dividing space into a number of regions. A set of points (called seeds, sites, or generators) is specified beforehand and for each seed there will be a corresponding region consisting of all points closer to that seed than to any other.
So, you choose a target, follow it's path for some steps and set a seed point there. Do this with all other targets as well and you get a voroni diagram. Depending in which area you are, you move to the seedpoint of it. Viola, you got the first fish. Now repeat this step until you cought them all.