Finding the row of an object - math

I'm trying to create a procedural shape made up of quads.
I want to be able to take any quad and use it's index to find the row that it is in.
Take quad 9 from the image. What sort of function can I use to find the row (in this case it is 2 from a 0-index). What about quad 20?
The rows always change in width by 2 quads, one removed from each side.
Sorry it's a bit convoluted but I'm not sure how to approach the problem.

Assume diameter d and quad number q. I claim the rows go 0 to d-1. Moreover, there are (d/2)(2+d) elements. The easier case is if 0<=q<(d/4)(2+d) in which case we are in the first half. Then the index is trunc((-1+sqrt(1+4*q))/2). This comes from using the observation that row n begins with n(n+1) which could be formally shown with the sum of an arithmetic series, then working backwards and solving the quadratic equation.
On the other hand, if we are in the second half (d/4)(2+d)<=q<(d/2)(2*d) and we solve by taking the offset from the end. Let q' be (d/2)(2+d)-1-q. Apply the above index formula to q' instead of q, and subtract the result from d-1 to get the index of q's row.
I may be off by one here or there, but I think this is the gist of it.

I was thinking since this was posted to a programming site, maybe it would be more logical to give a function one could implement without pulling out a lot of math, and instead just relying on addition. I think it would be easier to follow and harder to mess up (though maybe I underestimate my capability to mess up, and I almost did).
var quadRowIndex = function (diameter, quadNumber) {
//diameter should be a positive even number
//quadNumber should be between 0 and index of last number in last row (inclusive)
var quadIndex = 0; //holds the RowIndex, which the function will return once the row contains quadNumber
var rowStartNum = 0;
var rowLength = 2;
//iterate through first half
while (rowLength <= diameter) {
rowStartNum += rowLength;
if (rowStartNum > quadNumber) {
return quadIndex;
}
quadIndex++;
rowLength += 2;
}
rowLength -= 2;
//iterate through second half if still here
while (rowLength >= 2) {
rowStartNum += rowLength;
if (rowStartNum > quadNumber) {
return quadIndex;
}
quadIndex++;
rowLength -= 2;
}
//still here -- number was too high, return error signal
return -1;
};
console.log(quadRowIndex(6, 9));
console.log(quadRowIndex(6, 20));
console.log(quadRowIndex(6, 100));

Related

How to figure out if two linear functions are, after being rounded, equal over a given range

Title is a bit confusing and uses mathy words, so just take a look at this C function:
void myfun(uint stepcount,float step,float base,int *step_array) {
for (uint i=0;i<stepcount;i++) {
base += step;
step_array[i] = (int)floor(base);
}
}
Given stepcount and step (always between 0 and 1), how can I tell if two base values will write the same results into step_array?

Function to generate randomly incrementing number over time

I'm trying to make a fake download count. It should increment randomly over time. Some download-count-like patterns would be nice.
Is this possible without using a database, or storing a counter anywhere?
My idea is to check the number of seconds that have passed since my app was released. Then just throw that into a formula which spits out the fake download count. Users can request to see the download count at any time.
Is there a math function that increments randomly? I could just pass my secondsPassed into there and scale it how I'd like.
Something like this: getDownloadCount(secondsPassed)
Edit: here's an example solution. But it gets worse performance over time.
downloadCount = 0
loop secondsPassed/60 times // Loop one more time for every minute passed
downloadCount += seededRandom(0, 10)
Making a fake download count doesn't sound like a nice thing to do. However in designing secure communication protocols, there are legitimate use cases for monotonically growing functions with some randomness in their values.
I am assuming you have:
A growth model given as a monotonically growing function providing approximate values for the desired function.
Access to a time stamp, which never decreases.
Ability to store a constant random seed along with the function definition.
No way to store any updated data upon the function being queried.
First you decide on a window length, which will control how much randomness will be in the final output. I expect you will want this to be on the order of one hour or a few.
Figure out which window the current time is within. Evaluate the reference function at the start and end of this window. Consider the rectangle given by start and end time of the window as well as min and maximum value given by the reference function. Feed the corners of this rectangle and your constant seed into a PRNG. Use the PRNG to choose a random point within the rectangle. This point will be on the final curve.
Perform the same computation for one of the neighbor windows. Which neighbor window to use depend on whether the first computed point on the curve is to the left or the right of the current time.
Now that you have two points on the curve (which are reproducible and consistent), you will have to iterate the following procedure.
You are given two points on the final curve. Consider the rectangle given by those corners. Feed the corners and your constant seed into a PRNG. Use that PRNG to chose a random point within the rectangle. This point will be on the final curve. Discard one of the outer points, which is no longer needed.
Since the Y-values are restricted to integers, this procedure will eventually terminate once your two points on the curve have identical Y-coordinate, and you will know, that the function has to be constant between those two points.
You could implement a Morris Counter.
It works like this: start off by setting the counter to 1. Each time you want to increase the count (which could be every iteration of some loop or every time an event happens, but does not need to be determined randomly), then you do a random procedure to determine the effect it has on the counter.
It can have possibly no effect, or it can have the effect of raising the order of magnitude of the count. The probability is based on whether or not n successive fair coin flips all turn up heads, where n is the number of bits needed to encode the current counter value in binary. As a result, once the counter has gotten pretty high, it's very hard to make it go even higher (the state of the counter models a phenomenon where by you are already way overestimating the count, so now you need lots of nothing-happens events to compensate, making the count more accurate).
This is used as a cheap way to store an approximate count of a very large collection, but there's no reason why you can't use it as your randomly increasing counter device.
If you want better accuracy, or you want the count outputs to be more "normal" numbers instead of always powers of 2, then you can just create several Morris Counters, and at each step average together the set of current counts across them all.
You are after a sequence which always increases by a random amount, depending on how long you last requested the sequence.
This can be done through a random sequence that is always seeded the same.
Then we iterate through the same sequence each time to get the graph.
We need a function that increments our counter, store the new Time and Count and return the count.
Ideally we would model the increases as a poisson process, but a linear one here will do.
class Counter {
private static int counter = 0;
private static int time = 0;
private static double rate = 5.0;
private Random r;
public Counter(int seed){
counter = 0;
r = new Random(seed);
}
private int poisson(double rate, int diff){
// We're gonna cheat here and sample uniformly
return r.Next(0, (int)Math.Round(rate * diff));
}
public int getNext(int t){
var diff = t - time;
time = t;
if (diff <= 0) return counter;
counter += this.poisson(rate, diff);
return counter;
}
}
void Main()
{
var c = new Counter(1024);
for(var i = 0; i< 10; i++){
Console.WriteLine(String.Format("||{0}\t|{1}\t||",i,c.getNext(i)));
}
}
This outputs (for example):
||t |hit||
||0 |0 ||
||1 |3 ||
||2 |4 ||
||3 |6 ||
||4 |6 ||
||5 |8 ||
||6 |10 ||
||7 |13 ||
||8 |13 ||
||9 |16 ||
For some deterministic function f, (perhaps f(x) = x, or if your fake app is REALLY awesome f(x) = 2^x), and a random function r which outputs random number that's sometimes negative and sometimes positive.
Your graphing function g could be:
g(x) = f(x) + r
EDIT
How about this: https://gamedev.stackexchange.com/questions/26391/is-there-a-family-of-monotonically-non-decreasing-noise-functions
Well it's not "random" but you could use A*(X/B + SIN(X/B)) (scaled by some number) to introduce some noise. You can adjust A and B to change the scale of the result and how often the "noise" cycles.
Really, any periodic function that has a first derivative within some bounds could work.
as quick solution you can use something like this (code in java):
static long f(final int x) {
long r = 0; // initial counter
long n = 36969L; // seed
for (int i = 0; i <= x; i++) {
n = 69069L * n + 1234567L; // generate Ith random number
r += (n & 0xf); // add random number to counter
}
return r;
}
by playing with numbers 36969L and 0xf you can achieve different results
numbers 69069L and 1234567L are from standard LCG
the main idea - create simple random, with the same seed and for every passed x (number of seconds) replay random additions to counter
A good model for random events like downloads is the Poisson distribution. You need to estimate the average number of downloads in a given time period (hour, say) and then invert the Poisson distribution to get the number of downloads in a time period given a uniformly distributed random number. For extra realism you can vary the average according to time of day, time of week, etc. Sample algorithms are available at http://en.m.wikipedia.org/wiki/Poisson_distribution#Generating_Poisson-distributed_random_variables.
Here is a javascript implementation of a "fake" download-counter that appears the same to everyone. This always returns the same results for everyone each time and doesn't require database or files to do that. It also gracefully handles the case where you don't ask for new data at the same time, it will still look natural next time you request a day.
https://jsfiddle.net/Lru1tenL/1/
Counter = {
time:Date.now(),
count:0,
rate:0.45
};
Counter.seed = function(seed, startTime)
{
this.time = startTime,
this.count = 0,
this.prng = new Math.seedrandom(seed);
this.prng.getRandomInt = function(min, max) {
return Math.floor(this() * (max - min)) + min;
};
};
Counter.getNext = function(t){
var diff = t - this.time;
console.log(diff);
if(diff <= 0) return this.count;
this.time = t;
var max = Math.ceil(diff/100 * this.rate);
console.log("max: " + max);
this.count += this.prng.getRandomInt(0,max);
return this.count;
};
var results = [];
var today = Date.now();
Counter.seed("My Random Seed", today);
for (var i = 0; i < 7; i++) {
if(i === 4)
{
results.push(null);
} else {
var future = today + 86400000 * i;
results.push(Counter.getNext(future));
}
}
console.log(results);
var data = {
labels: ["Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday","Sunday"],
datasets: [
{
label: "My Second dataset",
fillColor: "rgba(151,187,205,0.2)",
strokeColor: "rgba(151,187,205,1)",
pointColor: "rgba(151,187,205,1)",
pointStrokeColor: "#fff",
pointHighlightFill: "#fff",
pointHighlightStroke: "rgba(151,187,205,1)",
data: results
}
]
};
var ctx = document.getElementById("myChart").getContext("2d");
var myLineChart = new Chart(ctx).Line(data);
Is the javascript. It creates a counter object that increments when requested based on the time of the previous value asked for. The repeatability comes through a thirdparty library "seedrandom" and the chart is drawn using chartjs.
<script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/1.0.2/Chart.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/seedrandom/2.4.0/seedrandom.min.js">
</script>
<body>
<canvas id="myChart" width="600" height="400"></canvas>
</body>
</html>
You can use Unix timestamp. Something like:
Downloads = constant + ( unix time / another constant )
You can vary both constants to get a reasonable number.
P.S: Thats if you want a linear function, otherwise you can do:
Downloads = (unix time) ^ constant
and so on.

How to suitably avoid RangeErrors when "looking around" this 2D array?

I have a 2D array structure to represent a grid of tiles that is a part of the game I am making. One aspect of the game is that the grid is filled in in a somewhat random fashion, based on analysis of a text file. Right from the outset though, I already realised that just leaving it be pretty much randomly done like this without sticking in some kind of validity checks or prevention mechanism, to stop really badly configured grid from forming, would not work out. The main problem I want to avoid is too many tiles that would be untraversable being close together, potentially severing chunks of the grid from the rest.
The idea I came up with to try avoid some really bad grids is to check when assigning a tile value to each "grid square" during generation with logic like this
if (tileBeingInserted.isTraversable()) {
//all is well
return true;
} else {
//we may have a problem, are there too many untraversables nearby?
//Proceed to check all squares "around" the current one.
}
To be clear, checking around the current square means checking the square immediately adjacent in each of the 8 cardinal directions. Now, my problem is that I am trying to reason out how to code this so that it will certainly not give a RangeErrorat any point or at least catch it and recover if it must. As an example, you could clearly take one of the corner squares to be the worst scenario in the sense that only 2 of the squares the algorithm would want to check are within the array's bounds. Naturally, if a RangeErrorhappens for this reason I just want the program to progress onward without issue so the structure
try {
//check1
//check2...8
} catch (RangeError e) {
}
is unacceptable because as soon as a single out of range square is tested the code falls out of the check block. An alternative I thought of, but do not like because of its messiness, would be to individually wrap each check in a try-catch and yes that would work I guess but that's some horrid looking code...so can anyone help me out here? Is there perhaps a different angle from which to come at this problem of avoiding the RangeErrors that I am not seeing?
So my code for testing whether another untraversable tile should be placed has shaped up like this:
bool _tileFitsWell(int tileTypeInt, int row, int col)
{
//...initialise some things, set stuff up
...
if (tile.traversable == true) {
//In this case a new traversable tile is being put in, so no problems.
return true;
} else {
//begin testing what tiles are around the current tile
//Test NW adjacent
if (row > 0 && col > 0) {
temp = tileAt(row - 1, col - 1);
if (!temp.traversable) {
strikeCount++;
}
}
//Test N adjacent
if (row > 0) {
temp = tileAt(row - 1, col - 1);
if (!temp.traversable) {
strikeCount++;
}
}
//Test NE adjacent
if (row > 0 && col < _grid[0].length - 2) {
temp = tileAt(row - 1, col 1);
if (!temp.traversable) {
strikeCount++;
}
}
//Test W adjacent
if (col > 0) {
temp = tileAt(row, col - 1);
if (!temp.traversable) {
strikeCount++;
}
}
}
return strikeCount < 2;
}
The code inside each "initial" if-statement (the ones that check row and col) is a bit pseudocode-ish for simplicity's sake. As I explained in a previous comment, the reason why I don't need to check tiles in the other 4 cardinal directions is since these checks are done while filling the map, tiles in those positions will always be either uninitialised or just out of bounds, depending on what tile the function is called to check at a given time.

Using Count To Split A Checklist Into 2 Columns in X++ Fetch Method

Here is what I have so far, this is returning two columns, but each counter is stopping and then duplicating the same value over and over...
if(lLogisticsControlTable.APMJobTypeId)
select count (RecID) from jobTypeCheck where jobTypeCheck.APMJobTypeId == lLogisticsControlTable.APMJobTypeId;
{
counter = jobTypeCheck.RecId;
}
while select jobTypeCheck where jobTypeCheck.APMJobTypeId == lLogisticsControlTable.APMJobTypeId
{
counter1 = counter / 2;
halfCount1 = counter - counter1;
if(halfcount <= counter1)
{
halfCount++;
jobListCheck1 = jobTypeCheck.Name;
}
if (halfCount1 > halfCount)
{
halfCount1++;
jobListCheck2 = jobTypeCheck.Name;
}
element.execute(2);
}
}
As Michael Brown indicated, it's difficult to understand the problem with half of the code ;)
However, I would suggest that you call the element.execute(2) method on every second pass through the loop? That way jobListCheck1 would be on the left, and jobListCheck2 would be on the right hand side. Finally you would then need to check immediately outside of your loop if you had an odd number of jobTypeCheck elements, and call the element.execute(2) method one last time remembering to set the jobListCheck2 variable as empty beforehand.
Regards

How to calculate this time?

I want to show some effect (animate) with the help of jQuery during the time that should be calculated based on how many results are found for a particular needle. The rule is that the effect should continue no longer than 5 minutes and at the very least be 5 seconds long.
So, here's what I do in particular. I search a database for a particular word the user inputs and count the results. Then I search a myself defined word in the same database and count the results. If there are more the latter results than the former results, I need to calculate how long to show the effect. The more the latter results found, the longer the time the effect should continue. Plus, I need to obey the rule: no longer than 5 minutes, no less than 5 seconds.
I need that to be accurate at best.
That may be a stupid question but I cannot figure out on my own how to calculate the time! :)
http://jsfiddle.net/rCVnv/3/
$(function(){
var firstNum = Math.random()*10000,
secondNum = Math.random()*10000,
result = parseInt(secondNum - firstNum),
milli = 0;
if(result > 0){
if(result < 300000 && result > 5000){
milli = result;
$("#test").fadeOut(result);
}else if(result > 300000){
milli = 300000;
}else if(result < 5000){
milli = 5000;
}
$("#test").fadeOut(milli);
}
$("#result").text("Result : " + result);
});
Im not really sure how you will calculate the milliseconds needed. What I do here is generate 2 random numbers, and subtract the first value from the second value. If the result is between 300000 milliseconds (5 minutes) and 5000 milliseconds, then it just fades it at that number. If it falls beyond those ranges, it sets it to either the high end or low end. Of course, if the result is negative nothing happens because value 1 was larger than value 2.
Also I used fadeOut, which can easily be replaced with animate.
var intSecondsPerResult = 2;
var intAnimationDuration = intSecondsPerResult*{$intResultsCount};
if(intAnimationDuration < 5) {
intAnimationDuration = 5;
} else if(intAnimationDuration > 300) {
intAnimationDuration = 300;
}
PS: $intResultsCount contains the size of your resultset
That is what you want?

Resources