I'm trying to create a code that generates random numbers within the range 10-30 but making sure that no number is repeated. It shows "subscript out of range" on NumArray(Count) = Count when I run the code.
'Make an array of completely sorted numbers
FOR Count = 10 TO 30
NumArray(Count) = Count
NEXT Count
RANDOMIZE TIMER
FOR Count = 10 TO 30
Number = (RND * (31 - Count)) + 10
PRINT #1, NumArray(Number)
FOR Counter = Number TO 30 - Count
NumArray(Counter) = NumArray(Counter + 1)
NEXT Counter
NEXT Count
This isn't actually my code. Copied and pasted for my assignment.
It looks like you're missing some DIM statements.
Variables containing numbers have type SINGLE by default, so you might see something like FOR Counter = 18.726493 TO 20 because the RND function returns a number between 0 and 1, excluding 1, meaning you will be trying to use NumArray(18.726493) which will not work.
Arrays that are not explicitly declared can only have 11 items with an index from 0 to 10, but the range 10-30 requires you to store 21 items (30 - 10 + 1 = 21). You can also specify a custom upper and lower bound if it will make your code easier for you to understand. Add these lines before the first line in your code shown above:
DIM Number AS INTEGER
DIM NumArray(10 TO 30) AS INTEGER
This will ensure Number only contains integers (any fractional values are rounded to the nearest integer), and NumArray will work from NumArray(10) to NumArray(30), but you can't use NumArray(9), NumArray(8), NumArray(31), etc. The index must be in the range 10-30.
I think that should fix your code, but I don't know for certain since I don't fully understand how it is supposed to work. At the very least, it will fix the type and subscript problems in your code.
You need to declare the array:
'Make an array of completely sorted numbers
DIM NumArray(30) AS INTEGER
FOR Count = 10 TO 30
NumArray(Count) = Count
NEXT Count
RANDOMIZE TIMER
FOR Count = 10 TO 30
Number = (RND * (31 - Count)) + 10
PRINT #1, NumArray(Number)
FOR Counter = Number TO 30 - Count
NumArray(Counter) = NumArray(Counter + 1)
NEXT Counter
NEXT Count
Say you have 3 integers:
13105
705016
13
I'm wondering if you could combine these into one integer in any way, so that you can still get back to the original 3 integers.
var startingSet = [ 13105, 705016, 13 ]
var combined = combineIntoOneInteger(startingSet)
// 15158958589285958925895292589 perhaps, I have no idea.
var originalIntegers = deconstructInteger(combined, 3)
// [ 13105, 705016, 13 ]
function combineIntoOneInteger(integers) {
// some sort of hashing-like function...
}
function deconstructInteger(integer, arraySize) {
// perhaps pass it some other parameters
// like how many to deconstruct to, or other params.
}
It doesn't need to technically be an "integer". It is just a string using only the integer characters, though perhaps I might want to use the hex characters instead. But I ask in terms of integers because underneath I do have integers of a bounded size that will be used to construct the combined object.
Some other notes....
The combined value should be unique, so no matter what values you combine, you will always get a different result. That is, there are absolutely no conflicts. Or if that's not possible, perhaps an explanation why and a potential workaround.
The mathematical "set" containing all possible outputs can be composed of different amounts of components. That is to say, you might have the output/combined set containing [ 100, 200, 300, 400 ] but the input set is these 4 arrays: [ [ 1, 2, 3 ], [ 5 ], [ 91010, 132 ], [ 500, 600, 700 ] ]. That is, the input arrays can be of wildly different lengths and wildly different sized integers.
One way to accomplish this more generically is to just use a "separator" character, which makes it super easy. So it would be like 13105:705016:13. But this is cheating, I want it to only use the characters in the integer set (or perhaps the hex set, or some other arbitrary set, but for this case just the integer set or hex).
Another idea for a potential way to accomplish this is to somehow hide a separator in there by doing some hashing or permutation jiu jitsu so that [ 13105, 705016, 13 ] becomes some integer-looking thing like 95918155193915183, where 155 and 5 are some separator like interpolator values based on the preceding input or some other tricks. A simpler approach to this would be like saying "anything following three zeroes 000 like 410001414 means it's a new integer. So basically 000 is a separator. But this specifically is ugly and brittle. Maybe it could get more tricky and work though, like "if the value is odd and followed by a multiple of 3 of itself, then it's a separator" sort of thing. But I can see that also having brittle edge cases.
But basically, given a set of integers n (of strings of integer characters), how to convert that into a single integer (or single integer-charactered string), and then convert it back into the original set of integers n.
Sure, there are lots of ways to do this.
To start with, it's only necessary to have a reversible function which combines two values into one. (For it to be reversible, there must be another function which takes the output value and recreates the two input values.)
Let's call the function which combines two values combine and the reverse function separate. Then we have:
separate(combine(a, b)) == [a, b]
for any values a and b. That means that combine(a, b) == combine(c, d)
can only be true if both a == c and b == d; in other words, every pair of inputs produces a different output.
Encoding arbitrary vectors
Once we have that function, we can encode arbitrary-length input vectors. The simplest case is when we know in advance what the length of the vector is. For example, we could define:
combine3 = (a, b, c) => combine(combine(a, b), c)
combine4 = (a, b, c, d) => combine(combine(combine(a, b), c), d)
and so on. To reverse that computation, we only have to repeatedly call separate the correct number of times, each time keeping the second returned value. For example, if we previously had computed:
m = combine4(a, b, c, d)
we could get the four input values back as follows:
c3, d = separate(m)
c2, c = separate(c3)
a, b = separate(c2)
But your question asks for a way to combine an arbitrary number of values. To do that, we just need to do one final combine, which mixes in the number of values. That lets us get the original vector back out: first, we call separate to get the value count back out, and then we call separate enough times to extract each successive input value.
combine_n = v => combine(v.reduce(combine), v.length)
function separate_n(m) {
let [r, n] = separate(m)
let a = Array(n)
for (let i = n - 1; i > 0; --i) [r, a[i]] = separate(r);
a[0] = r;
return a;
}
Note that the above two functions do not work on the empty vector, which should code to 0. Adding the correct checks for this case is left as an exercise. Also note the warning towards the bottom of this answer, about integer overflow.
A simple combine function: diagonalization
With that done, let's look at how to implement combine. There are actually many solutions, but one pretty simple one is to use the diagonalization function:
diag(a, b) = (a + b)(a + b + 1)
------------------ + a
2
This basically assigns positions in the infinite square by tracing successive diagonals:
<-- b -->
0 1 3 6 10 15 21 ...
^ 2 4 7 11 16 22 ...
| 5 8 12 17 23 ...
a 9 13 18 24 ...
| 14 19 25 ...
v 20 26 ...
27 ...
(In an earlier version of this answer, I had reversed a and b, but this version seems to have slightly more intuitive output values.)
Note that the top row, where a == 0, is exactly the triangular numbers, which is not surprising because the already enumerated positions are the top left triangle of the square.
To reverse the transformation, we start by solving the equation which defines the triangular numbers, m = s(s + 1)/2, which is the same as
0 = s² + s - 2m
whose solution can be found using the standard quadratic formula, resulting in:
s = floor((-1 + sqrt(1 + 8 * m)) / 2)
(s here is the original a+b; that is, the index of the diagonal.)
I should explain the call to floor which snuck in there. s will only be precisely an integer on the top row of the square, where a is 0. But, of course, a will usually not be 0, and m will usually be a little more than the triangular number we're looking for, so when we solve for s, we'll get some fractional value. Floor just discards the fractional part, so the result is the diagonal index.
Now we just have to recover a and b, which is straight-forward:
a = m - combine(0, s)
b = s - a
So we now have the definitions of combine and separate:
let combine = (a, b) => (a + b) * (a + b + 1) / 2 + a
function separate(m) {
let s = Math.floor((-1 + Math.sqrt(1 + 8 * m)) / 2);
let a = m - combine(0, s);
let b = s - a;
return [a, b];
}
One cool feature of this particular encoding is that every non-negative integer corresponds to a distinct vector. Many other encoding schemes do not have this property; the possible return values of combine_n are a subset of the set of non-negative integers.
Example encodings
For reference, here are the first 30 encoded values, and the vectors they represent:
> for (let i = 1; i <= 30; ++i) console.log(i, separate_n(i));
1 [ 0 ]
2 [ 1 ]
3 [ 0, 0 ]
4 [ 1 ]
5 [ 2 ]
6 [ 0, 0, 0 ]
7 [ 0, 1 ]
8 [ 2 ]
9 [ 3 ]
10 [ 0, 0, 0, 0 ]
11 [ 0, 0, 1 ]
12 [ 1, 0 ]
13 [ 3 ]
14 [ 4 ]
15 [ 0, 0, 0, 0, 0 ]
16 [ 0, 0, 0, 1 ]
17 [ 0, 1, 0 ]
18 [ 0, 2 ]
19 [ 4 ]
20 [ 5 ]
21 [ 0, 0, 0, 0, 0, 0 ]
22 [ 0, 0, 0, 0, 1 ]
23 [ 0, 0, 1, 0 ]
24 [ 0, 0, 2 ]
25 [ 1, 1 ]
26 [ 5 ]
27 [ 6 ]
28 [ 0, 0, 0, 0, 0, 0, 0 ]
29 [ 0, 0, 0, 0, 0, 1 ]
30 [ 0, 0, 0, 1, 0 ]
Warning!
Observe that all of the unencoded values are pretty small. The encoded values is similar in size to the concatenation of all the input values, and so it does grow pretty rapidly; you have to be careful to not exceed Javascript's limit on exact integer computation. Once the encoded value exceeds this limit (253) it will no longer be possible to reverse the encoding. If your input vectors are long and/or the encoded values are large, you'll need to find some kind of bignum support in order to do precise integer computations.
Alternative combine functions
Another possible implementation of combine is:
let combine = (a, b) => 2**a * 3**b
In fact, using powers of primes, we could dispense with the combine_n sequence, and just produce the combination directly:
combine(a, b, c, d, e,...) = 2a 3b 5c 7d 11e...
(That assumes that the encoded values are strictly positive; if they could be 0, we'd have no way of knowing how long the sequence was because the encoded value does not distinguish between a vector and the same vector with a 0 appended. But that's not a big issue, because if we needed to deal with 0s, we would just add one to all used exponents:
combine(a, b, c, d, e,...) = 2a+1 3b+1 5c+1 7d+1 11e+1...
That is certainly correct and its very elegant in a theoretical sense. It's the solution which you will find in theoretical CS textbooks because it is much easier to prove uniqueness and reversibility. However, in the real world it is really not practical. Reversing the combination depends on finding the prime factors of the encoded value, and the encoded values are truly enormous, well out of the range of easily representable numbers.
Another possibility is precisely the one you mention in the question: simply put a separator between successive values. One simple way to do this is to rewrite the values to encode in base 9 (or base 15) and then increment all the digit values, so that the digit 0 is not present in any encoded value. Then we can put 0s between the encoded values and read the result in base 10 (or base 16).
Neither of these solutions has the property that every non-negative integer is the encoding of some vector. (The second one almost has that property, and it's a useful exercise to figure out which integers are not possible encodings, and then fix the encoding algorithm to avoid that problem.)
I'm making a game and I've been trying to produce random movement. This is my code.
let actualDuration = NSTimeInterval(random(min(): CGFloat(3.0), max: CGFloat(4.0)))
The min and max aren't working please help.
Unlike the .NET Framework or the JDK, there isn't a function that takes min and max parameters to generate a random number. :(
If you want to generate a random number between 3 and 4, you should use the arc4random_uniform function to generate a number between 0 and 999 first and then divide that number by 1000 and plus 3:
let randomNumber = Double(arc4random_uniform(1000))
let actualDuration = CGFloat(randomNumber / 1000 + 3)
Let me explain how this works.
randomNumber is between 0 and 999 right? Now when you divide it by 1000, it becomes a number less than 1. i.e. 0 ~ 0.999. And you add this number to 3, the result becomes a random number between 3 and 4, which is what you wanted.
If you want a more precise double, you can generate a number between 0 and 9999 and divide it by 10000. You know what I mean!
#Ethan Marcus
try like this
let minValue = 3
let maxValue = 4
let actualDuration = NSTimeInterval(minValue + (random() % (maxValue - minValue)))
i have this code in if statement , and i think it is very big , how can i change this by short code and for infinity i.e that i want the if statement to work on two and after two by sixteen i.e 2 += 16 , forever , i know that my question might be not understandable
but please help me
Take the current count and subtract 2. If the number is divisible by 16 (the remainder when you do modulo division is zero), then your statement is true.
if ((count - 2) % 16 == 0)
{
_secondBall.hidden = YES;
}
This can be reduced to a mathematical problem. What you want is to divide by 16 and see if there is no 'remainder'. The 'modulo' operator gives you this remainder. You can Google it if you want to understand. So, as others have quickly posted before me, modulo in Objective-C is done via %. So x % 16 means: divide x by 16 and return the remainder (or: subtract 16 from x until x is smaller than 16). x % 16 will be a number between 0 and 15. Always. When x % 16 is 0, it means x is dividable by 16.
Since you want to take action when count is 2 + 16 * n, you want to subtract 2 from count first. Like so if ( ( count - 2 ) % 16 == 0). Or you can do this, which is shorter but perhaps less easy to understand: if ( count % 16 == 2 ).
Try this:
if ((count - 2) % 16 == 0)
Use this syntax
if ((count-2) % 16 == 0)
I have created an application in which the user continually rotates the phone about the z-axis (yaw) with the screen of the phone facing upwards. I would like to generate the angle between the two extremes each time the rotation changes direction.
Imagine an array of the following values: [-5,-3,-2, 0, 1, 2, 6, 5, 3, 2,-1,-3,-4,-7,-4,-3,...]. What I would like to do is find the relative maximums and minimums of the array in order to find the differences from one relative minimum to the next relative maximum. In the given array, -5 would be the first relative minimum and then 6 would be the next relative maximum. The difference here would be 11 units. From that relative maximum of 6, the next relative minimum is -7. The difference here would be 13 units. The process would continue on until the end of the array. I would like these difference values to be entered into an array of their own, i.e. [11,13,...]. Would greatly appreciate any assistance!
The way I see this your first value in the array is always your initial relative minimum AND maximum since you have absolutely no basis of comparison from the get-go (unless you prime both relMin and relMax to 0 OR define a range to find your relMin and relMax). With that in mind the logic behind your example itself is flawed given your assumption of using -5 & 6 as the first comparison pair.
Let's use your array and iterate through the array with a For Loop...
[-5,-3,-2, 0, 1, 2, 6, 5, 3, 2,-1,-3,-4,-7,-4,-3,...]
0: relMin = -5, relMax = -5, delta = 0
1: relMin = -5, relMax = -3, delta = 2
2: relMin = -5, relMax = -2, delta = 3
3: relMin = -5, relMax = 0, delta = 5
4: relMin = -5, relMax = 1, delta = 6
5: relMin = -5, relMax = 2, delta = 2
6: relMin = -5, relMax = 6, delta = 11
7:
....
13: relMin = -7, relMax = 6, delta = 13
....
Essentially what you're doing is writing to your output array any time your current delta is not equal to your previous delta. Since a change between relMin and relMax is mutually exclusive (only one of those values can change as you traverse the array) all you have to check for is inequality...
//prime your values
//if it make sense for your purposes prime them both with 0
//this also assumes you have at least 1 value in valueArray
relMin = valueArray[0];
relMax = valueArray[0];
//the following line will always be true if you use valueArray[0] as your relMin and relMax baseline
deltaArray[0] = 0;
for (i = 0; i < [valueArray count]; i++)
{
if (valueArray[i] < relMin)
{
relMin = valueArray[i];
}
if (valueArray[i] > relMax)
{
relMax = valueArray[i];
}
deltaPrevious = deltaArray[[deltaArray count] - 1];
deltaCurrent = relMax - relMin;
if (deltaCurrent != deltaPrevious)
{
deltaArray[deltaArray count] = deltaCurrent;
}
}
My approach to this problem would be to first write an algorithm that detects the indices of the maximums and minimums, and then finds differences from there.
To get the maxes and mins, I would recommend iterating through the array and looking at the difference between the current and the previous and next value. You need to looking at changes in sign of the differences:
A minimum will occur when the differences change from negative to positive, and a maximum will occur when the differences change from positive to negative.
For example, look at this part of your array: [1,2,6,5,3]. The difference from 1 to 2 is positive, from 2 to 6 is positive, but from 6 to 5 is negative. The sign of the differences changed from positive to negative at the 6, so we know it is a maximum.
Note that you also need to include the first and last elements as possible maxes or mins.
Once you get the indices of maximums and minimums, you should be able to get their differences fairly easily.
In a most basic sense, you could iterate through the array, checking to see if the next value is greater than or less than the previous value. Whenever you reach a change (was increasing, now decreasing, or vice versa) you have found a relative max/min (respectively). A for loop to iterate, a boolean flag to check against (whether you were increasing or decreasing) and the obvious knowledge of both your current and previous index in the array to check/store.
I don't quite feel comfortable giving exact code for this since it's very basic and seems very much like a homework question...