I am complete novice who is trying to supplement online course learning, by building some rudimentary programs. I am currently trying to build a program to calculate one's golf index. In order to do this, I must first calculate the average of the lowest 8 rounds, of the golfer's last 20. Calculating the average of the last 20 rounds was easy enough. It is isolating the lowest 8 rounds from the last twenty that I cannot figure out.
Generalized, how does one calculate the sum of the lowest N values in an array?
A note for the golfers out there: for the purposes of this exercise I am imagining that the individual only plays at one course, with a par of 72. I realize that the program will not work as currently constructed if par changes.
var scores: Array = [98, 99, 87, 86, 88, 92, 88, 87, 84, 98, 85, 84, 80, 99, 100, 101, 94, 96, 79, 99, 92, 94, 87, 99, 80]
var lastTwentyScores = scores.suffix(20)
var total = lastTwentyScores.reduce(0, +)
var avg = Double(total) / Double(lastTwentyScores.count)
var index = avg - 72
Right now, it is giving me the average of the last twenty - 72.
I know I will need to create a new variable, and change the final divisor to 8, instead of 20. I just don't know how to call the 8 lowest values from the array.
You just need to sort the last 20 and take the first 8 of that sorted result. That will give you the lowest 8 of the last 20.
var scores: Array = [98, 99, 87, 86, 88, 92, 88, 87, 84, 98, 85, 84, 80, 99, 100, 101, 94, 96, 79, 99, 92, 94, 87, 99, 80]
var lastTwentyScores = scores.suffix(20)
var lowestEightScores = lastTwentyScores.sorted().prefix(8)
var total = lowestEightScores.reduce(0, +)
var avg = Double(total) / Double(lowestEightScores.count)
This gives a total of 666 and an average of 63.25.
You can simplify most of the code to just:
var total = scores.suffix(20).sorted().prefix(8).reduce(0, +)
This makes it nice and neat but having the intermediate steps can make it easier to read and certainly easier to debug.
Like #HangarRash said, it's a lot easier to do this if you sort the scores first. Simply sort the array in ascending order, and fetch the first 8 elements.
var scores: Array = [98, 99, 87, 86, 88, 92, 88, 87, 84, 98, 85, 84, 80, 99, 100, 101, 94, 96, 79, 99, 92, 94, 87, 99, 80]
scores = scores.sorted() //Sorts the scores (from least to greatest)
var eightLowestScores: Array = scores[...8] // Gets the first 8 elements based on their index.
I think you are looking for this:
scores
.suffix(20) // last 20
.sorted() // sort to get the ordered slice
.prefix(8) // 8 lowest
.reduce(0, +) / 8 // average
Swift Algorithms provide an optimised way: min(count:sortedBy:)
import Algorithms
let scores = [98, 99, 87, 86, 88, 92, 88, 87, 84, 98, 85, 84, 80, 99, 100, 101, 94, 96, 79, 99, 92, 94, 87, 99, 80]
let lowestEight = scores.suffix(20).min(count: 8, sortedBy: <)
let average = lowestEight.reduce(0.0) { $0 + Double($1) / Double(lowestEight.count) }
print(average - 72)
With the following simple code snippet:
struct timespec ts;
for (int i = 0; i < 100; i++) {
timespec_get(&ts, TIME_UTC);
printf("%ld, ", ts.tv_nsec % 100);
}
I get output like this:
58, 1, 74, 49, 5, 59, 89, 20, 52, 86, 17, 48, 79, 10, 41, 73, 3, 40, 72, 3, 36, 67, 98, 30, 61, 92, 24, 55, 86, 17, 49, 82, 14, 45, 76, 7, 40, 72, 3, 36, 71, 2, 35, 66, 97, 28, 66, 97, 28, 60, 90, 22, 52, 83, 15, 46, 77, 7, 41, 72, 3, 36, 67, 0, 44, 17, 82, 13, 45, 77, 8, 59, 90, 22, 54, 85, 17, 48, 80, 12, 43, 75, 6, 57, 89, 20, 52, 84, 15, 47, 79, 14, 50, 82, 16, 47, 79, 11, 43, 74,
I haven't studied the statistical distribution of the numbers and my searches have turned up blank, but the output does at first glance look similar to output of rand() or random(). Has anyone studied this or is able to express an opinion - could timespec_get() be used as random number generator? Would it be pseudo random or not? Why?
could timespec_get() be used as random number generator?
Of course. But that doesn't mean the output of such a RNG would have desirable or even acceptable statistical properties.
In particular, successive outputs are strongly correlated with each other. Your example hides that, somewhat, by discarding all the most-significant decimal digits. Additionally, the system clock is not required to have single-nanosecond resolution, though yours seems to have. In a system that didn`t have such resolution, the least-significant digits of all results would likely be correlated, and their distribution non-uniform.
Would it be pseudo random or not? Why?
No, actually. The output of a PRNG is deterministic with respect to the runtime state of the calling program at the time of the call. timespec_get(), on the other hand, depends on the program's execution context, not its own state.
The code you have provided is almost certainly guaranteed not to provide (pseudo-)random numbers!
Why?
Consider running this on an efficient CPU that can dedicate 100% of its time to your code (and with nothing else of 'significant impact') going on in the OS background: each run of the for loop executes an identical instruction sequence, so the intervals between successive calls to timespec_get will all be very similar - and a list of numbers with continuously similar intervals is certainly not random.
Even a fairly cursory glance through your generated number list shows that the only time a number is less than its precursor is when the value "rolls over" the 100 mark (this effect will be more noticeable if you increase your modulus from 100 to, say, 500 and run the test again).
could timespec_get() be used as random number generator?
I tried calling timespec_get(&ts, TIME_UTC); multiple times and received delta values of about 14 +/- 1 ns. To me this implies at best a non-predictable-ness (random-ness) of 1 bit per call (given the variability in the delta), not the 7 to 8 bits hoped for with timespec_get(&ts, TIME_UTC); ts.tv_nsec % 100. At worst, there is nearly zero bits of randomness.
.tv_nsec and .tv_sec could be used to initialize a random engine, but as as a source, it is very weak.
Would it be pseudo random or not? Why?
No. A PRNG is deterministic. Reading time is not deterministic enough.
I am trying to optimizing the Kasumi crypto algorithm written in C.
There are S-box which uses to encrypt the data. which I am representing as an array in which is huge:
int S7[128] = {
54, 50, 62, 56, 22, 34, 94, 96, 38, 6, 63, 93, 2, 18,123, 33,
55,113, 39,114, 21, 67, 65, 12, 47, 73, 46, 27, 25,111,124, 81,
53, 9,121, 79, 52, 60, 58, 48,101,127, 40,120,104, 70, 71, 43,
20,122, 72, 61, 23,109, 13,100, 77, 1, 16, 7, 82, 10,105, 98,
117,116, 76, 11, 89,106, 0,125,118, 99, 86, 69, 30, 57,126, 87,
112, 51, 17, 5, 95, 14, 90, 84, 91, 8, 35,103, 32, 97, 28, 66,
102, 31, 26, 45, 75, 4, 85, 92, 37, 74, 80, 49, 68, 29,115, 44,
64,107,108, 24,110, 83, 36, 78, 42, 19, 15, 41, 88,119, 59, 3
};
int S9[512] = {
167,239,161,379,391,334, 9,338, 38,226, 48,358,452,385, 90,397,
183,253,147,331,415,340, 51,362,306,500,262, 82,216,159,356,177,
175,241,489, 37,206, 17, 0,333, 44,254,378, 58,143,220, 81,400,
95, 3,315,245, 54,235,218,405,472,264,172,494,371,290,399, 76,
165,197,395,121,257,480,423,212,240, 28,462,176,406,507,288,223,
501,407,249,265, 89,186,221,428,164, 74,440,196,458,421,350,163,
232,158,134,354, 13,250,491,142,191, 69,193,425,152,227,366,135,
344,300,276,242,437,320,113,278, 11,243, 87,317, 36, 93,496, 27,
487,446,482, 41, 68,156,457,131,326,403,339, 20, 39,115,442,124,
475,384,508, 53,112,170,479,151,126,169, 73,268,279,321,168,364,
363,292, 46,499,393,327,324, 24,456,267,157,460,488,426,309,229,
439,506,208,271,349,401,434,236, 16,209,359, 52, 56,120,199,277,
465,416,252,287,246, 6, 83,305,420,345,153,502, 65, 61,244,282,
173,222,418, 67,386,368,261,101,476,291,195,430, 49, 79,166,330,
280,383,373,128,382,408,155,495,367,388,274,107,459,417, 62,454,
132,225,203,316,234, 14,301, 91,503,286,424,211,347,307,140,374,
35,103,125,427, 19,214,453,146,498,314,444,230,256,329,198,285,
50,116, 78,410, 10,205,510,171,231, 45,139,467, 29, 86,505, 32,
72, 26,342,150,313,490,431,238,411,325,149,473, 40,119,174,355,
185,233,389, 71,448,273,372, 55,110,178,322, 12,469,392,369,190,
1,109,375,137,181, 88, 75,308,260,484, 98,272,370,275,412,111,
336,318, 4,504,492,259,304, 77,337,435, 21,357,303,332,483, 18,
47, 85, 25,497,474,289,100,269,296,478,270,106, 31,104,433, 84,
414,486,394, 96, 99,154,511,148,413,361,409,255,162,215,302,201,
266,351,343,144,441,365,108,298,251, 34,182,509,138,210,335,133,
311,352,328,141,396,346,123,319,450,281,429,228,443,481, 92,404,
485,422,248,297, 23,213,130,466, 22,217,283, 70,294,360,419,127,
312,377, 7,468,194, 2,117,295,463,258,224,447,247,187, 80,398,
284,353,105,390,299,471,470,184, 57,200,348, 63,204,188, 33,451,
97, 30,310,219, 94,160,129,493, 64,179,263,102,189,207,114,402,
438,477,387,122,192, 42,381, 5,145,118,180,449,293,323,136,380,
43, 66, 60,455,341,445,202,432, 8,237, 15,376,436,464, 59,461
};
During the encryption we are accessing this array very frequently.
One optimization which I had done moving this array from header file to local function so that some cache miss will not happened.
Any suggestion to more optimize this either by changing this array to any other data structure?
that array is not huge. a typical L1 cache is at least 10s of kB (that's the total memory on, say, an apple ii). and moving the array from a header to a function is not going to change cache locality.
storing it in the appropriate form (as in comments) may make sense (it's going to fit in l1 cache, but if you have other data, perhaps used by another thread, there's more chance of it staying there) - there's no need for more than 2 bytes per value (but i have no idea if that introduces extra cost compared to using native size ints).
if this is really critical, you should look at the code generated and optimize that.
First of all, make sure you declare those arrays as const, so that the compiler knows they'll never change.
Second, as Oli Charlesworth suggests in the comments, you don't really need a full int to store each value. The elements of the S7 and S9 arrays are 7-bit and 9-bit unsigned integers, so either of int8_t or uint8_t should be enough for S7, and either of int16_t or uint16_t for S9. (You may want to benchmark whether there's any difference between using signed or unsigned types, although I wouldn't really expect any.)
Finally, if you really want to get rid of the arrays entirely, it's also possible to implement the KASUMI S-boxes directly without any lookup tables, using bit operations (specifically, AND and XOR). For details, see pages 13–16 of the KASUMI specification. However, I strongly suspect that this will not be useful for a software implementation, unless you're using bit-slicing to encrypt many blocks in parallel.
This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
Why do I always get the same sequence of random numbers with rand()?
I've been experimenting with generating random numbers in C, and I've come across something weird. I don't know if it's only on my compiler but whenever I try to generate a pseudo-random number with the rand() function, it returns a very predictable number — the number generated with the parameter before plus 3.125 to be exact. It's hard to explain but here's an example.
srand(71);
int number = rand();
printf("%d", number);
This returns 270.
srand(72);
int number = rand();
printf("%d", number);
This returns 273.
srand(73);
int number = rand();
printf("%d", number);
This returns 277.
srand(74);
int number = rand();
printf("%d", number);
This returns 280.
Every eighth number is 4 higher. Otherwise it's 3.
This can't possibly be right. Is there something wrong with my compiler?
Edit: I figured it out — I created a function where I seed only once, then I loop the rand() and it generates random numbers. Thank you all!
The confusion here is about how pseudorandom number generators work.
Pseudorandom number generators like C's rand work by having a number representing the current 'state'. Every time the rand function is called, some deterministic computations are done on the 'state' number to produce the next 'state' number. Thus, if the generator is given the same input (the same 'state'), it will produce the same output.
So, when you seed the generator with srand(74), it will always generate the same string of numbers, every time. When you seed the generator with srand(75), it will generate a different string of numbers, etc.
The common way to ensure different output each time is to always provide a different seed, usually done by seeding the generator with the current time in seconds/milliseconds, e.g. srand(time(NULL)).
EDIT: Here is a Python session demonstrating this behavior. It is entirely expected.
>>> import random
If we seed the generator with the same number, it will always output the same sequence:
>>> random.seed(500)
>>> [random.randint(0, 100) for _ in xrange(20)]
[80, 95, 58, 25, 76, 37, 80, 34, 57, 79, 1, 33, 40, 29, 92, 6, 45, 31, 13, 11]
>>> random.seed(500)
>>> [random.randint(0, 100) for _ in xrange(20)]
[80, 95, 58, 25, 76, 37, 80, 34, 57, 79, 1, 33, 40, 29, 92, 6, 45, 31, 13, 11]
>>> random.seed(500)
>>> [random.randint(0, 100) for _ in xrange(20)]
[80, 95, 58, 25, 76, 37, 80, 34, 57, 79, 1, 33, 40, 29, 92, 6, 45, 31, 13, 11]
If we give it a different seed, even a slightly different one, the numbers will be totally different from the old seed, yet still the same if the same (new) seed is used:
>>> random.seed(501)
>>> [random.randint(0, 100) for _ in xrange(20)]
[64, 63, 24, 81, 33, 36, 72, 35, 95, 46, 37, 2, 76, 21, 46, 68, 47, 96, 39, 36]
>>> random.seed(501)
>>> [random.randint(0, 100) for _ in xrange(20)]
[64, 63, 24, 81, 33, 36, 72, 35, 95, 46, 37, 2, 76, 21, 46, 68, 47, 96, 39, 36]
>>> random.seed(501)
>>> [random.randint(0, 100) for _ in xrange(20)]
[64, 63, 24, 81, 33, 36, 72, 35, 95, 46, 37, 2, 76, 21, 46, 68, 47, 96, 39, 36]
How do we make our program have different behavior each time? If we supply the same seed, it will always behave the same. We can use the time.time() function, which will yield a different number each time we call it:
>>> import time
>>> time.time()
1347917648.783
>>> time.time()
1347917649.734
>>> time.time()
1347917650.835
So if we keep re-seeding it with a call to time.time(), we will get a different sequence of numbers each time, because the seed is different each time:
>>> random.seed(time.time())
>>> [random.randint(0, 100) for _ in xrange(20)]
[60, 75, 60, 26, 19, 70, 12, 87, 58, 2, 79, 74, 1, 79, 4, 39, 62, 20, 28, 19]
>>> random.seed(time.time())
>>> [random.randint(0, 100) for _ in xrange(20)]
[98, 45, 85, 1, 67, 25, 30, 88, 17, 93, 44, 17, 94, 23, 98, 32, 35, 90, 56, 35]
>>> random.seed(time.time())
>>> [random.randint(0, 100) for _ in xrange(20)]
[44, 17, 10, 98, 18, 6, 17, 15, 60, 83, 73, 67, 18, 2, 40, 76, 71, 63, 92, 5]
Of course, even better than constantly re-seeding it is to seed it once and keep going from there:
>>> random.seed(time.time())
>>> [random.randint(0, 100) for _ in xrange(20)]
[94, 80, 63, 66, 31, 94, 74, 15, 20, 29, 76, 90, 50, 84, 43, 79, 50, 18, 58, 15]
>>> [random.randint(0, 100) for _ in xrange(20)]
[30, 53, 75, 19, 35, 11, 73, 88, 3, 67, 55, 43, 37, 91, 66, 0, 9, 4, 41, 49]
>>> [random.randint(0, 100) for _ in xrange(20)]
[69, 7, 25, 68, 39, 57, 72, 51, 33, 93, 81, 89, 44, 61, 78, 77, 43, 10, 33, 8]
Every invocation of rand() returns the next number in a predefined sequence where the starting number is the seed supplied to srand(). That' why it's called a pseudo-random number generator, and not a random number generator.
rand() is implemented by a pseudo random number generator.
The distribution of numbers generated by consecutive calls to rand() have the properties of being random numbers, but the order is pre-determined.
The 'start' number is determined by the seed that you provide.
You should give a PRNG a single seed only. Providing it with multiple seeds can radically alter the randomness of the generator. In addition, providing it the same seed over and over removes all randomness.
Generating a "random" number regardless of the implementation is dependent on a divergent infinite sequence. The infinite sequence is generated using the seed of the random function and it is actually pseudo random because of its nature. This would explain to you why your number is actually very dependent on the seed that you give the function.
In some implementations the sequence is only one and the seed is the starting member of the sequence. In others there are difference sequences depending on the seed. If a seed is not provided then the seed is determined by the internal "clock".
The number is truncated when using an upper and lower bounds for your random number by respectively doing randValue % upperBound and randValue + lowerBound. Random implementation is very similar to Hash Functions. Depending on architecture the upper bound of the random value is set depending on what it the largest integer/double that it can carry out if not set lower by the user.