How can summarize all numbers in NSArray? - nsdate

I have NSArray with strings - 00:02:34, 02:05:17 so i need to calculate all strings in my array and get result: 2 hours:7 minutes and 51 seconds.
I tried this:
// Get strings from array for the first and separate for three objects by:
for (NSDictionary *dic in dicts) {
NSString *string = dic[#"duration"]; (my type of string 00:00:00)
NSArray *components = [string componentsSeparatedByString:#":"];
NSInteger minutes = [components[1] integerValue];
NSInteger seconds = [components[2] integerValue];
NSInteger hour = [components[0] integerValue];
}
But how can i summ this date to get results? Thanks for help.

There are a few different ways you could approach this.
Personally, I'd iterate through dicts and convert each duration string to seconds and keep count of the total seconds in an integer outside of the loop.
Then, you can easily convert the cumulative seconds total back into hours, minutes and seconds and compose a string from them, after the loop is complete:
int totalSeconds = 0;
for (NSDictionary * dic in dicts) {
NSString *string = dic[#"duration"];
NSArray *components = [string componentsSeparatedByString:#":"];
totalSeconds += (int) [components[0] integerValue] * 60 * 60;
totalSeconds += (int) [components[1] integerValue] * 60;
totalSeconds += (int) [components[2] integerValue];
}
int hour = totalSeconds / 3600;
int mins = (totalSeconds % 3600) / 60;
int secs = totalSeconds % 60;
NSString * totalString = [NSString stringWithFormat:#"%d:%d:%d", hour, mins, secs];
Note: you'll have to write a bit of code to compose the string and include zeros as appropriate, where any of the values are less than 10.

Related

How to rewrite this using Object Oriented Programming? remove statics, create object, prefix methods with object name...? what else?

Can someone help me understand how to make the following using object-oriented programming?
It is a short program that compares how quickly two different sort algorithms run on arrays of various sizes. When trying to rewrite it using object orientation, I start by making an object called "OO" at the top of Main, then prefixing all the method calls with "OO.", then remvoing all the static modifiers, but it still throws errors. I'm sure there is an easy fix, I'm just very new to this. Thanks. (below is the version that runs, with no attempt yet at OOP)
import java.util.Arrays;
public class SortingExercise {
//Create constants to give array size
final static int CONST100 = 100000; // The length of arrays that will be sorted.
final static int CONST10 = 10000; // The length of arrays that will be sorted.
final static int CONST1 = 1000; // The length of arrays that will be sorted.
final static int CONSTMIL = 1000000; //Constant for use in making/sorting a million-element array
/*
* Creates an array populated with random integers varying widely in size
* #param count : the length of the array that is created.
*/
private static int[] randomInts(int count) {
int[] numbers = new int[count];
for (int i = 0; i < count; i++)
numbers[i] = (int)(Integer.MAX_VALUE * Math.random());
return numbers;
}
/*
* Sorts an array of integers using the selection sort algorithm.
*/
private static void selectionSort(int[] numbers) {
for (int end = numbers.length-1; end > 0; end-- ) {
int maxloc = 0;
for (int i = 1; i <= end; i++) {
if (numbers[i] > numbers[maxloc])
maxloc = i;
}
int temp = numbers[end];
numbers[end] = numbers[maxloc];
numbers[maxloc] = temp;
}
}
public static void main(String[] args) {
double startTime;
double runTime;
int[] Array1;
int[] Array2;
//FIRST RUN - 1,000 ELEMENTS
//Create Arrays
Array1 = randomInts(CONST1);
Array2 = Arrays.copyOf(Array1, CONST1);
//Sort and print comparative run times of selectionSort and the Array.sort method on identical 1,000-element arrays
startTime = System.currentTimeMillis();
selectionSort(Array1);
runTime = System.currentTimeMillis() - startTime;
System.out.println(runTime + " milliseconds for Array1 with 1,000 elements using selectionSort");
startTime = System.nanoTime();
Arrays.sort(Array2);
runTime = System.nanoTime() - startTime;
System.out.println(runTime/1000000 + " milliseconds for Array2 with 1,000 elements using built-in Array.sort method");
System.out.println();
//SECOND RUN - 10,000 ELEMENTS
//Create Arrays
Array1 = randomInts(CONST10);
Array2 = Arrays.copyOf(Array1, CONST10);
//Sort and print comparative run times of selectionSort and the Array.sort method on identical 10,000-element arrays
startTime = System.currentTimeMillis();
selectionSort(Array1);
runTime = System.currentTimeMillis() - startTime;
System.out.println(runTime + " milliseconds for Array1 with 10,000 elements using selectionSort");
startTime = System.currentTimeMillis();
Arrays.sort(Array2);
runTime = System.currentTimeMillis() - startTime;
System.out.println(runTime + " milliseconds for Array2 with 10,000 elements using built-in Array.sort method");
System.out.println();
//THIRD RUN - 100,000 ELEMENTS
//Create Arrays
Array1 = randomInts(CONST100);
Array2 = Arrays.copyOf(Array1, CONST100);
//Sort and print comparative run times of selectionSort and the Array.sort method on identical 100,000-element arrays
startTime = System.currentTimeMillis();
selectionSort(Array1);
runTime = System.currentTimeMillis() - startTime;
System.out.println(runTime + " milliseconds for Array1 with 100,000 elements using selectionSort");
startTime = System.currentTimeMillis();
Arrays.sort(Array2);
runTime = System.currentTimeMillis() - startTime;
System.out.println(runTime + " milliseconds for Array2 with 100,000 elements using built-in Array.sort method");
System.out.println();
//OPTIONAL FINAL RUN ONLY USING .sort() -> 1 MILLION ELEMENTS
//Create Array
Array1 = randomInts(CONSTMIL);
//Sort and print runtime for a million-element array
startTime = System.currentTimeMillis();
Arrays.sort(Array1);
runTime = System.currentTimeMillis() - startTime;
System.out.println(runTime + " milliseconds for Array1 with 1 million elements using built-in Array.sort method");
//END PROGRAM
}
}

math.ceil groovy script return value

I am trying to generate a random date between two dates, could you check the below code?
What i notice is the output as : 02.0/01.0/1918.0
How can i save it as 02/02/1918 instead of 02.0/01.0/1918.0
var dob;
//set a range of years
var min = 1900;
var max = 2004;
// Math.ceil prevents the value from being 0;
var month = Math.ceil(Math.random() * 12);
var day = Math.ceil(Math.random() * 28);
var year = Math.floor(Math.random() * (max - min) + min);
//this ensures that the format will stay mm/dd/yyyy;
if(month < 10) {
month = "0" + month;
}
if(day < 10) {
day = "0" + day;
}
//concatenates random dob in mm/dd/yyyy format;
dob = month + "/" + day + "/" + year;
return dob;
Math.floor returns double. You have to convert it to int.
var year = Math.floor(...) as int

Number of substrings with count of each character as k

Source: https://www.geeksforgeeks.org/number-substrings-count-character-k/
Given a string and an integer k, find number of substrings in which all the different characters occurs exactly k times.
Looking for a solution in O(n), using two pointers/sliding window approach. I'm able to find only longest substrings satisfying this criteria but not substrings within that long substring.
For ex: ababbaba, k = 2
My solution finds abab, ababba etc, but not bb within ababba.
Can someone help me with the logic?
If you could edit your question to include your solution code, I'd be happy to help you with that.
For now I'm sharing my solution code (in java) which runs in O(n2). I've added enough comments to make the code self explanatory. Nonetheless the logic for the solution is as follows:
As you correctly pointed out, the problem can be solved using sliding window approach (with variable window size). The solution below considers all possible sub-strings, using nested for loops for setting start and end indices. For each sub-string, we check if every element in the sub-string occurs exactly k times.
To avoid recalculating the count for every sub-string, we maintain the count in a map, and keep putting new elements in the map as we increment the end index (slide the window). This ensures that our solution runs in O(n2) and not O(n3).
To further improve efficiency, we only check the count of individual elements if the sub-string's size matches our requirement. e.g. for n unique elements (keys in the map), the size of required sub-string would be n*k. If the sub-string's size doesn't match this value, there's no need to check how many times the individual characters occur.
import java.util.*;
/**
* Java program to count the number of perfect substrings in a given string. A
* substring is considered perfect if all the elements within the substring
* occur exactly k number of times.
*
* #author Codextor
*/
public class PerfectSubstring {
public static void main(String[] args) {
String s = "aabbcc";
int k = 2;
System.out.println(perfectSubstring(s, k));
s = "aabccc";
k = 2;
System.out.println(perfectSubstring(s, k));
}
/**
* Returns the number of perfect substrings in the given string for the
* specified value of k
*
* #param s The string to check for perfect substrings
* #param k The number of times every element should occur within the substring
* #return int The number of perfect substrings
*/
public static int perfectSubstring(String s, int k) {
int finalCount = 0;
/*
* Set the initial starting index for the subarray as 0, and increment it with
* every iteration, till the last index of the string is reached.
*/
for (int start = 0; start < s.length(); start++) {
/*
* Use a HashMap to store the count of every character in the subarray. We'll
* start with an empty map everytime we update the starting index
*/
Map<Character, Integer> frequencyMap = new HashMap<>();
/*
* Set the initial ending index for the subarray equal to the starting index and
* increment it with every iteration, till the last index of the string is
* reached.
*/
for (int end = start; end < s.length(); end++) {
/*
* Get the count of the character at end index and increase it by 1. If the
* character is not present in the map, use 0 as the default count
*/
char c = s.charAt(end);
int count = frequencyMap.getOrDefault(c, 0);
frequencyMap.put(c, count + 1);
/*
* Check if the length of the subarray equals the desired length. The desired
* length is the number of unique characters we've seen so far (size of the map)
* multilied by k (the number of times each character should occur). If the
* length is as per requiremets, check if each element occurs exactly k times
*/
if (frequencyMap.size() * k == (end - start + 1)) {
if (check(frequencyMap, k)) {
finalCount++;
}
}
}
}
return finalCount;
}
/**
* Returns true if every value in the map is equal to k
*
* #param map The map whose values are to be checked
* #param k The required value for keys in the map
* #return true if every value in the map is equal to k
*/
public static boolean check(Map<Character, Integer> map, int k) {
/*
* Iterate through all the values (frequency of each character), comparing them
* with k
*/
for (Integer i : map.values()) {
if (i != k) {
return false;
}
}
return true;
}
}
For a given value k and a string s of length n with alphabet size D, we can solve the problem in O(n*D).
We need to find sub-strings with each character having exactly k-occurences
Minimum size of such sub-string = k (when only one character is there)
Maximum size of such sub-string = k*D (when all characters are there)
So we will check for all sub-strings of sizes in range [k, k*D]
from collections import defaultdict
ALPHABET_SIZE = 26
def check(count, k):
for v in count.values():
if v != k and v != 0:
return False
return True
def countSubstrings(s, k):
total = 0
for d in range(1, ALPHABET_SIZE + 1):
size = d * k
count = defaultdict(int)
l = r = 0
while r < len(s):
count[s[r]] += 1
# if window size exceed `size`, then fix left pointer and count
if r - l + 1 > size:
count[s[l]] -= 1
l += 1
# if window size is adequate then check and update count
if r - l + 1 == size:
total += check(count, k)
r += 1
return total
def main():
string1 = "aabbcc"
k1 = 2
print(countSubstrings(string1, k1)) # output: 6
string2 = "bacabcc"
k2 = 2
print(countSubstrings(string2, k2)) # output: 2
main()
I can't give you a O(n) solution but I can give you a O(k*n) solution (better than O(n^2) mentioned in the geeksforgeeks page).
The idea is that max no. elements are 26. So, we don't have to check all the substrings, we just have to check substrings with length<=26*k (26*k length is the case when all elements will occur k times. If length is more than that then at least one element will have to occur at least k+1 times). Also, we need to check only those substrings whose lengths are a factor of k.
So, check all 26*k*l possible substrings! (assuming k<<l). Thus, solution is O(k*n) but with a bit high constant (26).
There are few observation which will help optimize the solution
Notice that, you don't need to check every possible size substrings, you just need to check substrings of size k, 2k, 3k so on up to ALPHABET_SIZE * k (remember Pigeonhole principle)
You can pre-calculate frequency of alphabets till certain index from any end and later you can use it to find the frequency of alphabets between any two indexes in O(26)
C++ Implementation of your problem in O(n * ALPHABET_SIZE^2)
I have added comments and diagrams to help you out in understanding code quickly
diagram 1
diagram 2
#include <bits/stdc++.h>
#define ll long long
#define ALPHABET_SIZE 26
using namespace std;
int main()
{
ios_base::sync_with_stdio(false);
cin.tie(NULL);
cout.tie(NULL);
int n, k;
string s;
cin >> n >> k;
cin >> s;
ll cnt = 0;
/**
* It will be storing frequency of each alphabets
**/
vector<int> f(ALPHABET_SIZE, 0);
/**
* It will store alphabets frequency till that index
**/
vector<vector<int>> v;
v.push_back(f);
/**
* Scan array from left to right and calculate the frequency of each alphabets till that index
* Now push that frequency array in v
* This loop will run for n times
**/
for (int i = 1; i <= n; i++)
{
f[s[i - 1] - 'a']++;
v.push_back(f);
}
/**
* This loop will run for k times
**/
for (int i = 0; i < k; i++)
{
/**
* start is the lower bound (left end from where window will start sliding)
**/
int start = i;
/**
* end is the upper bound (right end till where window will be sliding)
**/
int end = (n / k) * k + i;
if (end > n)
{
end -= k;
}
/**
* This loop will run for n/k times
**/
for (int j = start; j <= end; j += k)
{
/**
* This is a ALPHABET_SIZE * k size window
* It will be sliding between start and end (inclusive)
* This loop will run for at most ALPHABET_SIZE times
**/
for (int d = j + k; d <= min(ALPHABET_SIZE * k + j, end); d += k)
{
/**
* A flag to check weather substring is valid or not
**/
bool flag = true;
/**
* Check if frequencies at two different indexes differ only by zero or k (element wise)
* Note that frequencies at two different index can't be same
* This loop will run for ALPHABET_SIZE times
**/
for (int idx = 0; idx < ALPHABET_SIZE; idx++)
{
if (abs(v[j][idx] - v[d][idx]) != k && abs(v[j][idx] - v[d][idx]) != 0)
{
flag = false;
}
}
/**
* Increase the total count if flag is true
**/
if (flag)
{
cnt++;
}
}
}
}
/**
* Print the total count
**/
cout << cnt;
return 0;
}
if you want solution in simple way and not worried about time complexity. Here is the solution.
public class PerfecSubstring {
public static void main(String[] args) {
String st = "aabbcc";
int k = 2;
System.out.println(perfect(st, k));
}
public static int perfect(String st, int k) {
int count = 0;
for (int i = 0; i < st.length(); i++) {
for (int j = st.length(); j > i; j--) {
String sub = st.substring(i, j);
if (sub.length() > k && check(sub, k)) {
System.out.println(sub);
count++;
}
}
}
return count;
}
public static boolean check(String st, int k) {
Map<Character, Integer> map = new HashMap<>();
for (int i = 0; i < st.length(); i++) {
Character c = st.charAt(i);
map.put(c, map.getOrDefault(c, 0) + 1);
}
return map.values().iterator().next() == k && new HashSet<>(map.values()).size() == 1;
}
}
Here is an answer I did in C#, with O(n^2) complexity. I probably should have used a helper method to avoid having a large chunk of code, but it does the job. :)
namespace CodingChallenges
{
using System;
using System.Collections.Generic;
class Solution
{
// Returns the number of perfect substrings of repeating character value 'num'.
public static int PerfectSubstring(string str, int num)
{
int count = 0;
for (int startOfSliceIndex = 0; startOfSliceIndex < str.Length - 1; startOfSliceIndex++)
{
for (int endofSliceIndex = startOfSliceIndex + 1; endofSliceIndex < str.Length; endofSliceIndex++)
{
Dictionary<char, int> dict = new Dictionary<char, int>();
string slice = str.Substring(startOfSliceIndex, (endofSliceIndex - startOfSliceIndex) + 1);
for (int i = 0; i < slice.Length; i++)
{
if (dict.ContainsKey(slice[i]))
{
dict[slice[i]]++;
}
else
{
dict[slice[i]] = 1;
}
}
bool isPerfect = true;
foreach (var entry in dict)
{
if (entry.Value != num)
{
isPerfect = false;
}
}
if (isPerfect)
{
Console.WriteLine(slice);
count++;
}
}
}
if (count == 1)
{
Console.WriteLine(count + " perfect substring.");
}
else
{
Console.WriteLine(count + " perfect substrings.");
}
return count;
}
public static void Main(string[] args)
{
string test = "1102021222";
PerfectSubstring(test, 2);
}
}
}
This solution works in O(n*D)
I think it can be upgraded to be O(n) by replacing the hash_map(frozenset(head_sum_mod_k.items())) with a map implementation that updates its hash rather than recalculating it -
this can be done because only one entry of head_sum_mod_k is changed per iteration.
from copy import deepcopy
def countKPerfectSequences(string:str, k):
print(f'Processing \'{string}\', k={k}')
# init running sum
head_sum = {char: 0 for char in string}
tail_sum = deepcopy(head_sum)
tail_position = 0
# to match both 0 & k sequence lengths, test for mod k == 0
head_sum_mod_k = deepcopy(head_sum)
occurrence_positions = {frozenset(head_sum_mod_k.items()): [0]}
# iterate over string
perfect_counter = 0
for i, val in enumerate(string):
head_sum[val] += 1
head_sum_mod_k[val] = head_sum[val] % k
while head_sum[val] - tail_sum[val] > k:
# update tail to avoid longer than k sequnces
tail_sum[string[tail_position]] += 1
tail_position += 1
# print(f'str[{tail_position}..{i}]=\'{string[tail_position:i+1]}\', head_sum_mod_k={head_sum_mod_k} occurrence_positions={occurrence_positions}')
# get matching sequences between head and tail
indices = list(filter(lambda i: i >= tail_position, occurrence_positions.get(frozenset(head_sum_mod_k.items()), [])))
# for start in indices:
# print(f'{string[start:i+1]}')
perfect_counter += len(indices)
# add head
indices.append(i+1)
occurrence_positions[frozenset(head_sum_mod_k.items())] = indices
return perfect_counter

What is the format of the timestamp in InstallShield's ISString table?

I was recently trying to determine the answer to this question. The only post I was able to find on the topic was this old unanswered post on Flexera's website.
I wanted to know the answer to this question to incorporate in a tool for managing string translations. I already discovered the answer (my coworker and I spent the better half of our day trying to figure it out) but I thought I'd post the question/answer on Stack Overflow just in case someone else searches for it.
The answer is that the timestamp is a 32-bit integer with different bits representing different parts of the date.
Here's how it breaks down
Bits 1-5 : The Day of the Month [1-31] (end range could be 28-31 depending on month)
Bits 6-9 : The Month [1-12]
Bits 10-16: The Year after 1980 (only goes to year 2107) [0-127]
Bits 17-21: (?) Seconds rounded to even (only 5 bits so can only contain 31 values) [0-30]
Bits 22-27: Minutes [0-59]
Bits 28-32: Hours from 12 AM [0-23]
If the 32-bit integer is an invalid date it's evaluated to a default date Dec/30/1899 12:00 AM
Here is an example:
-------BINARY-32-bit-Integer----- | Decimal | Date String
DOM Month Year Seconds*2 Min Hour | |
00111 0111 0010000 00001 010000 00000 | 999295488 | Jul/07/1996 12:16 AM
7 7 16 1 16 0
Here is some C# code written to convert between DateTime and the string representation of the ISString timestamp (Small Disclaimer: this code doesn't currently handle invalid timestamp input):
private static int bitsPerDOM = 5;
private static int bitsPerMonth = 4;
private static int bitsPerYear = 7;
private static int bitsPerEvenSecond = 5;
private static int bitsPerMinute = 6;
private static int bitsPerHour = 5;
private static int startYear = 1980;
public static string getISTimestamp(DateTime date)
{
int[] shiftValues = { bitsPerDOM, bitsPerMonth, bitsPerYear, bitsPerEvenSecond, bitsPerMinute, bitsPerHour };
int[] dateValues = { date.Day, date.Month, date.Year -startYear, date.Second/2, date.Minute, date.Hour };
int shift = 32;
int dateInt = 0;
for (int i = 0; i < dateValues.Length; i++)
{
shift -= shiftValues[i];
dateInt |= (dateValues[i] << shift);
}
return dateInt.ToString();
}
public static DateTime getTimeFromISTimestampStr(string ISTimestampStr)
{
int timestampInt = Int32.Parse(ISTimestampStr);
int dom = getBits(timestampInt, 0, 4);
int month = getBits(timestampInt, 5, 8);
int year = startYear + getBits(timestampInt, 9, 15);
int seconds = getBits(timestampInt, 16, 20) * 2;
int minutes = getBits(timestampInt, 21, 26);
int hours = getBits(timestampInt, 27, 31);
return new DateTime(year, month, dom, hours, minutes, seconds);
}
private static int getBits(int n, int start, int end)
{
//Clear left bits by shifting
n <<= start;
n >>= 31 + start - end; //Shift to the right
return n;
}

Random number in long range, is this the way?

Can somebody verify this method. I need a long type number inside a range of two longs. I use the .NET Random.Next(min, max) function which return int's. Is my reasoning correct if I simply divide the long by 2, generate the random number and finally multiply it by 2 again? Or am I too enthusiastic...
I understand that my random resolution will decrease but are there any other mistakes which will lead to no such a random number.
long min = st.MinimumTime.Ticks; //long is Signed 64-bit integer
long max = st.MaximumTime.Ticks;
int minInt = (int) (min / 2); //int is Signed 64-bit integer
int maxInt = (int) (max / 2); //int is Signed 64-bit integer
Random random = new Random();
int randomInt = random.Next(minInt, maxInt);
long randomLong = (randomInt * 2);
Why don't you just generate two random Int32 values and make one Int64 out of them?
long LongRandom(long min, long max, Random rand) {
long result = rand.Next((Int32)(min >> 32), (Int32)(max >> 32));
result = (result << 32);
result = result | (long)rand.Next((Int32)min, (Int32)max);
return result;
}
Sorry, I forgot to add boundaries the first time. Added min and max params. You can test it like that:
long r = LongRandom(100000000000000000, 100000000000000050, new Random());
Values of r will lie in the desired range.
EDIT: the implementation above is flawed. It's probably worth it to generate 4 16-bit integers rather than 2 32-bit ones to avoid signed-unsigned problems. But at this point the solution loses its elegancy, so I think it's best to stick with Random.NextBytes version:
long LongRandom(long min, long max, Random rand) {
byte[] buf = new byte[8];
rand.NextBytes(buf);
long longRand = BitConverter.ToInt64(buf, 0);
return (Math.Abs(longRand % (max - min)) + min);
}
It looks pretty well in terms of value distribution (judging by very simple tests I ran).
Some other answers here have two issues: having a modulo bias, and failing to correctly handle values of max = long.MaxValue. (Martin's answer has neither problem, but his code is unreasonably slow with large ranges.)
The following code will fix all of those issues:
//Working with ulong so that modulo works correctly with values > long.MaxValue
ulong uRange = (ulong)(max - min);
//Prevent a modolo bias; see https://stackoverflow.com/a/10984975/238419
//for more information.
//In the worst case, the expected number of calls is 2 (though usually it's
//much closer to 1) so this loop doesn't really hurt performance at all.
ulong ulongRand;
do
{
byte[] buf = new byte[8];
random.NextBytes(buf);
ulongRand = (ulong)BitConverter.ToInt64(buf, 0);
} while (ulongRand > ulong.MaxValue - ((ulong.MaxValue % uRange) + 1) % uRange);
return (long)(ulongRand % uRange) + min;
The following fully-documented class can be dropped into your codebase to implement the above solution easily and brain-free. Like all code on Stackoverflow, it's licensed under CC-attribution, so you can feel free to use to use it for basically whatever you want.
using System;
namespace MyNamespace
{
public static class RandomExtensionMethods
{
/// <summary>
/// Returns a random long from min (inclusive) to max (exclusive)
/// </summary>
/// <param name="random">The given random instance</param>
/// <param name="min">The inclusive minimum bound</param>
/// <param name="max">The exclusive maximum bound. Must be greater than min</param>
public static long NextLong(this Random random, long min, long max)
{
if (max <= min)
throw new ArgumentOutOfRangeException("max", "max must be > min!");
//Working with ulong so that modulo works correctly with values > long.MaxValue
ulong uRange = (ulong)(max - min);
//Prevent a modolo bias; see https://stackoverflow.com/a/10984975/238419
//for more information.
//In the worst case, the expected number of calls is 2 (though usually it's
//much closer to 1) so this loop doesn't really hurt performance at all.
ulong ulongRand;
do
{
byte[] buf = new byte[8];
random.NextBytes(buf);
ulongRand = (ulong)BitConverter.ToInt64(buf, 0);
} while (ulongRand > ulong.MaxValue - ((ulong.MaxValue % uRange) + 1) % uRange);
return (long)(ulongRand % uRange) + min;
}
/// <summary>
/// Returns a random long from 0 (inclusive) to max (exclusive)
/// </summary>
/// <param name="random">The given random instance</param>
/// <param name="max">The exclusive maximum bound. Must be greater than 0</param>
public static long NextLong(this Random random, long max)
{
return random.NextLong(0, max);
}
/// <summary>
/// Returns a random long over all possible values of long (except long.MaxValue, similar to
/// random.Next())
/// </summary>
/// <param name="random">The given random instance</param>
public static long NextLong(this Random random)
{
return random.NextLong(long.MinValue, long.MaxValue);
}
}
}
Usage:
Random random = new Random();
long foobar = random.NextLong(0, 1234567890L);
This creates a random Int64 by using random bytes, avoiding modulo bias by retrying if the number is outside the safe range.
static class RandomExtensions
{
public static long RandomLong(this Random rnd)
{
byte[] buffer = new byte[8];
rnd.NextBytes (buffer);
return BitConverter.ToInt64(buffer, 0);
}
public static long RandomLong(this Random rnd, long min, long max)
{
EnsureMinLEQMax(ref min, ref max);
long numbersInRange = unchecked(max - min + 1);
if (numbersInRange < 0)
throw new ArgumentException("Size of range between min and max must be less than or equal to Int64.MaxValue");
long randomOffset = RandomLong(rnd);
if (IsModuloBiased(randomOffset, numbersInRange))
return RandomLong(rnd, min, max); // Try again
else
return min + PositiveModuloOrZero(randomOffset, numbersInRange);
}
static bool IsModuloBiased(long randomOffset, long numbersInRange)
{
long greatestCompleteRange = numbersInRange * (long.MaxValue / numbersInRange);
return randomOffset > greatestCompleteRange;
}
static long PositiveModuloOrZero(long dividend, long divisor)
{
long mod;
Math.DivRem(dividend, divisor, out mod);
if(mod < 0)
mod += divisor;
return mod;
}
static void EnsureMinLEQMax(ref long min, ref long max)
{
if(min <= max)
return;
long temp = min;
min = max;
max = temp;
}
}
Here is a solution that leverages from the other answers using Random.NextBytes, but also pays careful attention to boundary cases. I've structured it as a set of extension methods. Also, I've accounted for modulo bias, by sampling another random number it falls out of range.
One of my gripes (at least for the situation I was trying to use it) is that the maximum is usually exclusive so if you want to roll a die, you do something like Random.Next(0,7). However, this means you can never get this overload to return the .MaxValue for the datatype (int, long, ulong, what-have-you). Therefore, I've added an inclusiveUpperBound flag to toggle this behavior.
public static class Extensions
{
//returns a uniformly random ulong between ulong.Min inclusive and ulong.Max inclusive
public static ulong NextULong(this Random rng)
{
byte[] buf = new byte[8];
rng.NextBytes(buf);
return BitConverter.ToUInt64(buf, 0);
}
//returns a uniformly random ulong between ulong.Min and Max without modulo bias
public static ulong NextULong(this Random rng, ulong max, bool inclusiveUpperBound = false)
{
return rng.NextULong(ulong.MinValue, max, inclusiveUpperBound);
}
//returns a uniformly random ulong between Min and Max without modulo bias
public static ulong NextULong(this Random rng, ulong min, ulong max, bool inclusiveUpperBound = false)
{
ulong range = max - min;
if (inclusiveUpperBound)
{
if (range == ulong.MaxValue)
{
return rng.NextULong();
}
range++;
}
if (range <= 0)
{
throw new ArgumentOutOfRangeException("Max must be greater than min when inclusiveUpperBound is false, and greater than or equal to when true", "max");
}
ulong limit = ulong.MaxValue - ulong.MaxValue % range;
ulong r;
do
{
r = rng.NextULong();
} while(r > limit);
return r % range + min;
}
//returns a uniformly random long between long.Min inclusive and long.Max inclusive
public static long NextLong(this Random rng)
{
byte[] buf = new byte[8];
rng.NextBytes(buf);
return BitConverter.ToInt64(buf, 0);
}
//returns a uniformly random long between long.Min and Max without modulo bias
public static long NextLong(this Random rng, long max, bool inclusiveUpperBound = false)
{
return rng.NextLong(long.MinValue, max, inclusiveUpperBound);
}
//returns a uniformly random long between Min and Max without modulo bias
public static long NextLong(this Random rng, long min, long max, bool inclusiveUpperBound = false)
{
ulong range = (ulong)(max - min);
if (inclusiveUpperBound)
{
if (range == ulong.MaxValue)
{
return rng.NextLong();
}
range++;
}
if (range <= 0)
{
throw new ArgumentOutOfRangeException("Max must be greater than min when inclusiveUpperBound is false, and greater than or equal to when true", "max");
}
ulong limit = ulong.MaxValue - ulong.MaxValue % range;
ulong r;
do
{
r = rng.NextULong();
} while(r > limit);
return (long)(r % range + (ulong)min);
}
}
private long randomLong()
{
Random random = new Random();
byte[] bytes = new byte[8];
random.NextBytes(bytes);
return BitConverter.ToInt64(bytes, 0);
}
This will get you a secure random long:
using (RNGCryptoServiceProvider rg = new RNGCryptoServiceProvider())
{
byte[] rno = new byte[9];
rg.GetBytes(rno);
long randomvalue = BitConverter.ToInt64(rno, 0);
}
Start at the minimum, add a random percentage of the difference between the min and the max. Problem with this is that NextDouble returns a number x such that 0 <= x < 1, so there's a chance you'll never hit the max number.
long randomLong = min + (long)(random.NextDouble() * (max - min));
Your randomLong will always be even and you will have eliminated even more values because you are very far away from the maximum for long, The maximum for long is 2^32 * max for int. You should use Random.NextBytes.
You can try CryptoRandom of the Inferno library:
public class CryptoRandom : Random
// implements all Random methods, as well as:
public byte[] NextBytes(int count)
public long NextLong()
public long NextLong(long maxValue)
public long NextLong(long minValue, long maxValue)
I wrote some Test Methods and check my own method and many of the answers from this and the same questions. Generation of redundant values is a big problem. I found #BlueRaja - Danny Pflughoeft answer at this address Is good enough and did not generate redundant values at least for first 10,000,000s. This is a Test Method:
[TestMethod]
public void TestRand64WithExtensions()
{
Int64 rnum = 0;
HashSet<Int64> hs = new HashSet<long>();
Random randAgent = new Random((int)DateTime.Now.Ticks);
for (int i = 0; i < 10000000; i++)
{
rnum = randAgent.NextLong(100000000000000, 999999999999999);
//Test returned value is greater than zero
Assert.AreNotEqual(0, rnum);
//Test Length of returned value
Assert.AreEqual(15, rnum.ToString().Length);
//Test redundancy
if (!hs.Contains(rnum)) { hs.Add(rnum); }
else
{
//log redundant value and current length we received
Console.Write(rnum + " | " + hs.Count.ToString());
Assert.Fail();
}
}
}
I didn't want to post this as an answer but I can't stuff this in the comment section and I didn't want to add as an edit to answer without author consent. So pardon me as this is not an independent answer and maybe just a prove to one of the answers.
I wrote a benchmarking C# console app that tests 5 different methods for generating unsigned 64-bit integers. Some of those methods are mentioned above. Method #5 appeared to consistently be the quickest. I claim to be no coding genius, but if this helps you, you're welcome to it. If you have better ideas, please submit. - Dave (sbda26#gmail.com)
enter code here
static private Random _clsRandom = new Random();
private const int _ciIterations = 100000;
static void Main(string[] args)
{
RunMethod(Method1);
RunMethod(Method2);
RunMethod(Method3);
RunMethod(Method4);
RunMethod(Method5);
Console.ReadLine();
}
static void RunMethod(Func<ulong> MethodX)
{
ulong ulResult;
DateTime dtStart;
TimeSpan ts;
Console.WriteLine("--------------------------------------------");
Console.WriteLine(MethodX.Method.Name);
dtStart = DateTime.Now;
for (int x = 1; x <= _ciIterations; x++)
ulResult = MethodX.Invoke();
ts = DateTime.Now - dtStart;
Console.WriteLine(string.Format("Elapsed time: {0} milliseconds", ts.TotalMilliseconds));
}
static ulong Method1()
{
int x1 = _clsRandom.Next(int.MinValue, int.MaxValue);
int x2 = _clsRandom.Next(int.MinValue, int.MaxValue);
ulong y;
// lines must be separated or result won't go past 2^32
y = (uint)x1;
y = y << 32;
y = y | (uint)x2;
return y;
}
static ulong Method2()
{
ulong ulResult = 0;
for(int iPower = 0; iPower < 64; iPower++)
{
double dRandom = _clsRandom.NextDouble();
if(dRandom > 0.5)
{
double dValue = Math.Pow(2, iPower);
ulong ulValue = Convert.ToUInt64(dValue);
ulResult = ulResult | ulValue;
}
}
return ulResult;
}
static ulong Method3() // only difference between #3 and #2 is that this one (#3) uses .Next() instead of .NextDouble()
{
ulong ulResult = 0;
for (int iPower = 0; iPower < 64; iPower++)
if (_clsRandom.Next(0, 1) == 1)
ulResult = ulResult | Convert.ToUInt64(Math.Pow(2, iPower));
return ulResult;
}
static ulong Method4()
{
byte[] arr_bt = new byte[8];
ulong ulResult;
_clsRandom.NextBytes(arr_bt);
ulResult = BitConverter.ToUInt64(arr_bt, 0);
return ulResult;
}
// Next method courtesy of https://stackoverflow.com/questions/14708778/how-to-convert-unsigned-integer-to-signed-integer-without-overflowexception/39107847
[System.Runtime.InteropServices.StructLayout(System.Runtime.InteropServices.LayoutKind.Explicit)]
struct EvilUnion
{
[System.Runtime.InteropServices.FieldOffset(0)] public int Int32;
[System.Runtime.InteropServices.FieldOffset(0)] public uint UInt32;
}
static ulong Method5()
{
var evil = new EvilUnion();
ulong ulResult = 0;
evil.Int32 = _clsRandom.Next(int.MinValue, int.MaxValue);
ulResult = evil.UInt32;
ulResult = ulResult << 32;
evil.Int32 = _clsRandom.Next(int.MinValue, int.MaxValue);
ulResult = ulResult | evil.UInt32;
return ulResult;
}
}
I'll add my solution for generating random unsigned long integer (random ulong) below max value.
public static ulong GetRandomUlong(ulong maxValue)
{
Random rnd = new Random();
//This algorithm works with inclusive upper bound, but random generators traditionally have exclusive upper bound, so we adjust.
//Zero is allowed, function will return zero, as well as for 1. Same behavior as System.Random.Next().
if (maxValue > 0) maxValue--;
byte[] maxValueBytes = BitConverter.GetBytes(maxValue);
byte[] result = new byte[8];
int i;
for(i = 7; i >= 0; i--)
{
//senior bytes are either zero (then Random will write in zero without our help), or equal or below that of maxValue
result[i] = (byte)rnd.Next( maxValueBytes[i] + 1 );
//If, going high bytes to low bytes, we got ourselves a byte, that is lower than that of MaxValue, then lower bytes may be of any value.
if ((uint)result[i] < maxValueBytes[i]) break;
}
for(i--; i >= 0; i--) // I like this row
{
result[i] = (byte)rnd.Next(256);
}
return BitConverter.ToUInt64(result, 0);
}
C#10 now has long randoms built in.
Use NextInt64 if you can.
You're better off taking the difference between minimum and maximum (if it fits in an int), getting a random between 0 and that, and adding it to the minimum.
Is there anything wrong with using this simple approach?
long min = 10000000000001;
long max = 99999999999999;
Random random = new Random();
long randomNumber = min + random.Next() % (max - min);
d
My worked solution. Tested for 1000+ times:
public static long RandomLong(long min, long max)
{
return min + (long)RandomULong(0, (ulong)Math.Abs(max - min));
}
public static ulong RandomULong(ulong min, ulong max)
{
var hight = Rand.Next((int)(min >> 32), (int)(max >> 32));
var minLow = Math.Min((int)min, (int)max);
var maxLow = Math.Max((int)min, (int)max);
var low = (uint)Rand.Next(minLow, maxLow);
ulong result = (ulong)hight;
result <<= 32;
result |= (ulong)low;
return result;
}
How about generating bytes and converting to int64?
/* generate a byte array, then convert to unint64 */
var r = new Random(); // DONT do this for each call - use a static Random somewhere
var barray = new byte[64/8];
r.NextBytes(barray);
var rint64 = BitConverter.ToUInt64(barray, 0);
Sees to work for me (:
What's wrong with generating a double to be intended as a factor to be used to calculate the actual long value starting from the max value a long can be?!
long result = (long)Math.Round( random.NextDouble() * maxLongValue );
NextDouble generates a random number between [0.0, 0.99999999999999978] (msdn doc)
You multiply this random number by your maxLongValue.
You Math.Round that result so you can get the chance to get maxLongValue anyway (eg: simulate you got 1.0 from the NextDouble).
You cast back to long.

Resources