Related
I am weak in math's hence the question I ask might be irrelevant to most here but the question is why are we dividing the Armstrong number by 10? I mean we can divide the number with any other number apart from 10.
I think the problem is that you don't understand what an Armstrong number is. From one web search:
An Armstrong number of three digits is an integer such that the sum of the cubes of its digits is equal to the number itself. For example, 371 is an Armstrong number since 33 + 73 + 13 = 371.
So, to check whether any random number is an Armstrong number: 243, say. Take the number as written and do 2×2×2 + 4×4×4 + 3×3×3 = 8 + 16 + 27, which is only 99, so 243 isn't an Armstrong number.
Now, there are two straightforward ways to get the individual digits of a number in a computer program. First, you can convert to a string.
std::string theString = to_string(243);
And then for each digit, convert back to a number. This is kind of gross.
Or you can do this:
int sumOfCubes = 0;
for (int newNumber = myNumber; newNumber > 0; newNumber = newNumber / 10) {
// This is the modulus operator, or the remainder. 243 % 10 = 3.
// 24 % 10 = 4. and 2 % 10 = 2.
int digit = newNumber % 10;
sumOfCubes += digit*digit*digit;
}
if (sumOfCubes == myNumber) {
cout << myNumber << " is an Armstrong number." << endl;
}
What happens in the loop:
newNumber is initialized to myNumber (243 in my example). digit
becomes 3 (243 divided by 10 has a remainder of 3). sumOfCubes +=
27;
Then it loops. newNumber becomes newNumber / 10 as an integer, which
is now 24. digit is 4. We add 64 to sumOfCubes.
Loops again. newNumber becomes 24 / 10 = 2. So we add 8.
Tries to loop. NewNumber becomes zero, which fails the condition, so
the loop ends.
Done.
I came across different ways of calculating CCN (according to formula CCN = E-N+2P)
One way was to count all the lines in the code separately and the other way is to count a few lines of code as one step; lets have the following example:
1 public class SumAndAverage {
2
3 public static void main (String[] args) {
4 int sum = 0;
5 double average = 0.0;
6 String message = "";
7
8 int num = Integer.parseInt(args[0]);
9
10 if ((num < 1) || (num > 100)) {
11 message = "Invalid number entered.";
12 } else {
13 for (int i = 1; i <= num; i++) {
14 sum += i;
15 }
16 average = (double) sum / num;
17 message = "The sum is " + sum + " and the average is " + average;
18 }
19 System.out.println(message);
20 }
21}
Counting every statement we'd get 12 - 11 + 2x 1 = 3
I was wondering if I "join" lines 4,5,6,8 and count them as one step and do the same with line 16 and 17, would that be correct too? The result would be the same as no of edges would also decrease: 8 - 7 + 2*1 = 3
The right way to calculate complexity is by considering blocks of code. A block of code is where there is no chance of dissecting the execution path.
McCabe's paper mentions the below:
The tool, FLOW, was written in APL to input the source code from Fortran files on disk. FLOW would then break a Fortran job into distinct subroutines and analyze the control structure of each subroutine. It does this by breaking the Fortran subroutines into blocks that are delimited by statements that affect control flow: IF, GOTO ,referenced LABELS, DO, etc.
For other information on complexity, also read through Cyclomatic complexity as a Quality measure
Time limit : 2sec / Stack limit : 256MB / Memory limit : 256MB
Problem
Dave's calculator is broken. It halts when presented with more than K different digits.
Dave wants to input an integer A, but if he inputs this number correctly the calculator might halt. Instead, he inputs the closest integer that won't halt the calculator.
Output the difference between Dave's input and the integer A.
Input
The input will be given in the following format from the Standard Input.
A K
On the first line, you will be given the integer A(1≦A≦10^15), the integer Dave wants to input, followed by a space and K(1≦K≦10), the number of different digits his calculator can recognize.
Output
Output the minimum difference between Dave's input and the integer A in one line. Make sure to insert a line break at the end of the output.
Input Example 1
1234 2
Output Example 1
12
In this case Dave can only use up to 2 different digits. He will input the closest integer 1222, so the difference is 12.
Input Example 2
7328495 10
Output Example 2
0
In this case Dave's calculator is not broken at all. He can input the given integer A as is.
Input Example 3
800000 1
Output Example 3
22223
Dave can use only one digit, so 777777 is the closest integer.
Input Example 4
262004 2
Output Example 4
218
The closest integer is 262222.
I have solved the problem by a brute force solution...
I try all possible situation where i in 1<= i < A or A < i <= 10^15.
I'll get two solutions composed from K different digits, and find the min difference between A and solutions.
It's a straightforward solution.
When A is larger, the execution will exceed the threshold of 2 sec.
Is there a smart and efficient way to solve it?
The first part is: Choose which k digits (out of the 10 possible) are used in the result
With a bit math (binomial coefficient) it´s easy to calculate the number
of different digit combinations possible for a given k.
There are up to 252 possibilities to choose (252 if k=5, else not so many).
If it is not clear what I´m saying: For k=2, there are 01,02,03,...09,12,13,...,19,23,24,...,89
No eg. 11 because it´s only 1 but k=2 allows two different digits.
And no eg. 90 because it´s the same as 09, 91=19 etc.
The count of these possible combinations is 252 for k=5, and it won´t get larger.
Finding all of the (up to) 252 possibilities for the current k
and iterating over them in a loop shouldn´t be too hard.
For each of the possibilities do the following:
{
Within the loop, we have the A, K, and the current choosen valid digits
for the solution (latter differs in each iteration of the loop, of course)
Lets take A=12899, K=3, digits 123 as example.
Now search the first digit of a (from left to right) which is not allowed.
In the example, this would be 12899, because 1 and 2 left of it are allowed.
Replace this (8) with the next-lower allowed digit (2) if there is one
and replace everything right of it with the highest possible digit (3 too).
12899=>12399=>12333
Save the result 12333 somewhere in an array etc.
If there was no next-lower possible digit, do nothing (nothing goes to the array)
(A proper addition with carry would introduce a new digit left of the changed one,
ie. invalid. A solution with this new digit will be found
when the loop comes to that digit)
Then the same thing again in the other direction:
Replace the found digit with the next-higher possible one
and everything right with the lowest. This goes in the array too,
of course only if there was a next-higher possible digit.
In case of 12899, the only higher replacement for 8 would be 9,
but 9 is not possible (only 123).
}
After the whole loop has finished (and every iteration has produced
up to two new array entries), you have up to 502 possible solutions for the problem.
The only thing left to do is to check which soltion is the best (ie. calculate the difference
to A for every entry and take the solution which minimal difference)
At each step you can use the digit you need, that digit + 1 (mod 10), that digit -1 (mod 10), or any digit you have used before. Once you run out of digits you can only use digits you have used before.
This creates a tree. At each step take the current states and calculate all possible new states in the next level down.
You can prune the tree as you go along by removing any next steps that have a delta that's more than a certain distance from the smallest delta of any of the next steps.
This is essentially a linear programming problem.
Below is the complete algorithm! Maybe someone can fine tune the decision as to which branches to prune to make it even faster.
using System.IO;
using System;
using System.Collections.Generic;
using System.Linq;
public static class Converter
{
public static int ToInt(this IEnumerable<int> values)
{
return values.Aggregate(0, (total, v) => total * 10 + v);
}
public static IEnumerable<int> ToList (this int value)
{
if (value == 0) return Enumerable.Empty<int>();
else return value.ToString().Select(x => (int)x - '0').ToList();
}
}
class Program
{
static void Main(string[] args)
{
//int desired = 262004;
//int digits = 2;
int desired = 800000;
int digits = 1;
IEnumerable<State> currentStates = new[] { new State(0, 0, desired, digits) };
foreach (var digit in desired.ToList())
{
var nextStates = currentStates.SelectMany(x => x.NextPossibleStates());
foreach (var state in nextStates.OrderBy(s => s.Delta()).Take(10))
{
Console.WriteLine(state.ToString());
}
currentStates = nextStates;
Console.WriteLine("------------");
}
Console.ReadKey();
}
public class State
{
int index;
int current;
int desired;
int digitsRemaining;
private int desiredToNow()
{
return desired.ToList().Take(index).ToInt();
}
public int Delta()
{
return Math.Abs(desiredToNow() - current);
}
public State(int index, int current, int desired, int digitsRemaining)
{
this.index = index;
this.current = current;
this.desired = desired;
this.digitsRemaining = digitsRemaining;
}
private State Next (int nextDigit, int digitsRemaining)
{
return new State(this.index + 1, this.current * 10 + nextDigit, this.desired, digitsRemaining);
}
private IEnumerable<int> NextPossibleDigitsWithDuplicates()
{
if (this.digitsRemaining > 0)
{
int nextDesiredDigit = desired.ToList().Skip(index).First();
yield return nextDesiredDigit;
yield return (nextDesiredDigit + 9) % 10;
yield return (nextDesiredDigit + 1) % 10;
}
// Any previously used digit is OK
foreach (int i in this.current.ToList())
yield return i;
}
public IEnumerable<State> NextPossibleStates()
{
var possibles = this.NextPossibleDigitsWithDuplicates().Distinct();
var possiblesUsingExistingDigits = possibles.Where(p => this.current.ToList().Contains(p));
var possiblesUsingNewDigits = possibles.Where(p => !this.current.ToList().Contains(p));
var states = possiblesUsingExistingDigits.Select(p => Next(p, this.digitsRemaining))
.Concat(possiblesUsingNewDigits.Select(p => Next(p, this.digitsRemaining - 1)))
.ToList();
var bestDelta = states.Min(s => s.Delta());
// Now reject any that can never be better
// Guessing on the '2' here ...
var validStates = states.Where(s => s.Delta() < bestDelta + 2);
return validStates;
}
public override string ToString()
{
return this.current + " d=" + this.Delta() + " remaining " + this.digitsRemaining;
}
}
}
After thinking a bit about the problem I guess an A* algorithm that assigns digits from left to right is best. For that we need an estimation of the lower bound for the error of a partial solution. A simple possibility is:
if the already set digits are exactly the same as in the problem the bound is 0
if the already set digits are lower as in the problem replace the missing digits by 9 to get the lower bound
if the already set digits are higher as in the problem replace the missing digits by 0 to get the lower bound
Taking the example problem 12899 3 the algorithm would work like this:
Start node
node best error
xxxxx 12899 0
expansion of the most promising partial solution xxxxx
node best error
0xxxx 09999 2900
1xxxx 12899 0
2xxxx 20000 7101
3xxxx 30000 17101
4xxxx 40000 27101
5xxxx 50000 37101
6xxxx 60000 47101
7xxxx 70000 57101
8xxxx 80000 67101
9xxxx 90000 77101
Expansion of the most promising partial solution 1xxxx
node best error
0xxxx 09999 2900
10xxx 10999 1900
11xxx 11999 900
12xxx 12899 0
13xxx 13000 101
14xxx 14000 1101
15xxx 15000 2101
16xxx 16000 3101
17xxx 17000 4101
18xxx 18000 5101
19xxx 19000 6101
2xxxx 20000 7101
3xxxx 30000 17101
4xxxx 40000 27101
5xxxx 50000 37101
6xxxx 60000 47101
7xxxx 70000 57101
8xxxx 80000 67101
9xxxx 90000 77101
Expansion of the most promising partial solution 12xxx
node best error
0xxxx 09999 2900
10xxx 10999 1900
11xxx 11999 900
120xx 12099 800
121xx 12199 700
122xx 12299 600
123xx 12399 500
124xx 12499 400
125xx 12599 300
126xx 12699 200
127xx 12799 100
128xx 12899 0
129xx 12900 1
13xxx 13000 101
14xxx 14000 1101
15xxx 15000 2101
16xxx 16000 3101
17xxx 17000 4101
18xxx 18000 5101
19xxx 19000 6101
2xxxx 20000 7101
3xxxx 30000 17101
4xxxx 40000 27101
5xxxx 50000 37101
6xxxx 60000 47101
7xxxx 70000 57101
8xxxx 80000 67101
9xxxx 90000 77101
Expansion of the most promising partial solution 128xx (only the digits 1, 2 and 8 are allowed now)
node best error
0xxxx 09999 2900
10xxx 10999 1900
11xxx 11999 900
120xx 12099 800
121xx 12199 700
122xx 12299 600
123xx 12399 500
124xx 12499 400
125xx 12599 300
126xx 12699 200
127xx 12799 100
1281x 12819 80
1282x 12829 70
1288x 12889 10
129xx 12900 1
13xxx 13000 101
14xxx 14000 1101
15xxx 15000 2101
16xxx 16000 3101
17xxx 17000 4101
18xxx 18000 5101
19xxx 19000 6101
2xxxx 20000 7101
3xxxx 30000 17101
4xxxx 40000 27101
5xxxx 50000 37101
6xxxx 60000 47101
7xxxx 70000 57101
8xxxx 80000 67101
9xxxx 90000 77101
Expansion of the most promising partial solution 129xx (only the digits 1, 2 and 9 are allowed now)
node best error
0xxxx 09999 2900
10xxx 10999 1900
11xxx 11999 900
120xx 12099 800
121xx 12199 700
122xx 12299 600
123xx 12399 500
124xx 12499 400
125xx 12599 300
126xx 12699 200
127xx 12799 100
1281x 12819 80
1282x 12829 70
1288x 12889 10
1291x 12910 11
1292x 12920 21
1299x 12990 91
13xxx 13000 101
14xxx 14000 1101
15xxx 15000 2101
16xxx 16000 3101
17xxx 17000 4101
18xxx 18000 5101
19xxx 19000 6101
2xxxx 20000 7101
3xxxx 30000 17101
4xxxx 40000 27101
5xxxx 50000 37101
6xxxx 60000 47101
7xxxx 70000 57101
8xxxx 80000 67101
9xxxx 90000 77101
Expansion of the most promising partial solution 1288x (only the digits 1, 2 and 8 are allowed now)
node best error
0xxxx 09999 2900
10xxx 10999 1900
11xxx 11999 900
120xx 12099 800
121xx 12199 700
122xx 12299 600
123xx 12399 500
124xx 12499 400
125xx 12599 300
126xx 12699 200
127xx 12799 100
1281x 12819 80
1282x 12829 70
12881 12881 18
12882 12882 17
12888 12888 11 <-- optimal solution found
1291x 12910 11
1292x 12920 21
1299x 12990 91
13xxx 13000 101
14xxx 14000 1101
15xxx 15000 2101
16xxx 16000 3101
17xxx 17000 4101
18xxx 18000 5101
19xxx 19000 6101
2xxxx 20000 7101
3xxxx 30000 17101
4xxxx 40000 27101
5xxxx 50000 37101
6xxxx 60000 47101
7xxxx 70000 57101
8xxxx 80000 67101
9xxxx 90000 77101
This does still not cover the case that the optimal solution may have more digits than the original number (not sure if this is even possible), but you get the idea ...
For K=10 , the solution is trivial. Difference equals to 0.
If the original number use less than or equals to K distinct digit. Difference equals to 0. For example, 987777 5 use 3 distinct digit which is less than K (= 5).
For K=1 ,
A number with length n will be bound by 999...999 (n-digit) and 999...999((n-1)-digit). Which mean 587 is bound by 999 and 99. Hence, the solution must either be a n-digit length number or 999...999((n-1)-digit).
Let leading digit of the number be a (5 in 587), denote b=a+1 and c=a-1. Compare the number with aaa...aaa, bbb...bbb, ccc...ccc (all n-digit length). Notice that this just check at most 2 of them.
If original number = aaa...aaa, difference equals to 0.
If original number > aaa...aaa, continue to compare with bbb...bbb.
If original number < aaa...aaa, continue to compare with ccc...ccc.
Regulation for K=1, if b=10, ignore bbb...bbb since aaa...aaa = 999...999 which is upper bound. if c=0, change ccc...ccc to 999...999((n-1)-digit) for lower bound checking like 10000 1 -> 9999
For K in range [2,9], observe that first K-1 distinct digit from left to right must be used. For example, 9988898988981234 3, 2 digit 9 and 8 must be used in this case.
Proof:
Fact :
Number of distinct digit in original number > K
K-1 != 0
We can always form two value z000...000 and z999...999 using K distinct digit where z is form by K-1 distinct digit (z = 998889898898 in above example) and assign K th digit as 0 or 9 (ignore the fact that 0 or 9 may be used in K-1 as not important)
With z000...000 and z999...999 (9988898988980000 and 9988898988989999), the optimal solution is bound by the two value. If z change to z+1 or z-1, the difference will increase which makes no sense. Thus, z part will always be used and first K-1 distinct digit from left to right must be used holds.
End of Proof
At the first encounter K th distinct digit (leading digit right after z part, denote as t), there are three possible cases to consider: t, t+1 and t-1.
Let's start with t first. Using t will use up all K digit, so no more digit can be assigned. Keep on to check digit on the right part until we encounter a digit that is not in those K distinct digit. This time, we have at most two choose. The closest digit in K that is larger than the encounter digit and the closest digit in K that is smaller than the encounter digit. Using larger closest digit in K will result in a number larger than original number, so the remaining digit should be minimized by choosing smallest digit in K. Similarly, the remaining digit for smaller closest digit in K case will be largest digit in K.
For case t+1, this only need to be checked when there is no larger closest digit in K for case t. Using t+1 will always larger than original number, we need to minimized the remaining digit. Notice that t+1 may be one of the digit in K-1 , we have a free digit and so include 0 (if 0 is not in K-1). Then, we can choose the smallest digit in K (or K-1 if t+1 and 0 are in K-1) for remaining digit.
For case t-1, this only need to be checked when there is no smaller closest digit in K for case t. Using t-1 will always smaller than original number, we need to maximized the remaining digit. Notice that t-1 may be one of the digit in K-1 , we have a free digit and so include 9 (if 9 is not in K-1). Then, we can choose the largest digit in K (or K-1 if t-1 and 9 are in K-1) for remaining digit.
The solution time is O(len(A)).
To find the min|A - B|, with differnt K digits number.
First , to remove the abs, we should find B1 with the condition( min(Bi| Bi>=A, with different digits number),
Let A=a1a2...an, B1 = b1b2…bn,find the longest sequence which ai=bi until the different number exceed the K. Suppose we have a1->aj = b1->bj
If j == n, then B1 = A
From the set of {a1, a2,…,aj}, find the minimal number which is bigger than b[j+1]
If find ak(1<=k<=j), then let b[j+1]= ak, and the rest of b[j+1]->bn is filled with min{a1, a2,…,aj}
If not find, we change bj from aj to a[j]+1. For the rest of b[j+1]->bn,
If a[j]+1 is in the set of {a1, a2,…,aj-1}, it means we still can have one digit to press, we choose the 0 as the padding. b[j+1]->bn is all filled with 0.
If a[j]+1 is not in the set of {a1, a2,…,aj-1}, we choose the min{a1, a2,…,aj-1, a[j]+1} as the value which is filled with b[j+1]->bn
Similarity, we can find the closest number B2 which is smaller than A,
After that ,we just compare the B1-A with A-B2, choose the minimal.
Following the C++ Code:
#include <vector>
#include <list>
#include <map>
#include <set>
#include <queue>
#include <deque>
#include <stack>
#include <bitset>
#include <algorithm>
#include <functional>
#include <numeric>
#include <utility>
#include <iostream>
#include <iomanip>
#include <cstdio>
#include <cmath>
#include <cstdlib>
#include <ctime>
#include <sstream>
using namespace std;
string target_num;
string up_num;
string down_num;
int K;
bool hash_key[10];
bool hash_copy[10];
int find_closet_k(int c, bool up) {
int i = c;
while(true) {
if (hash_key[i]) {
return i;
}
if(up) {
++i;
if (10 <= i) {
break;
}
} else {
--i;
if (i < 0) {
break;
}
}
}
return -1;
}
char min_k() {
for (int i = 0; i < 10; ++i) {
if (hash_key[i]) {
return '0' + i;
}
}
}
char max_k() {
for (int i = 9; 0 <= i; --i) {
if (hash_key[i]) {
return '0' + i;
}
}
}
bool is_head_zero(int v, string num,int end_pos) {
if (0 == v) {
for (int i = 0; i < end_pos; ++i) {
if (num[i] != '0') {
return false;
}
}
return true;
}
return false;
}
int string2int(string s) {
std::stringstream ss;
ss << s;
int is;
ss >> is;
return is;
}
void find_closest() {
int k = 0;
int i = 0;
for (i = 0; i < target_num.size(); ++i) {
int c = target_num[i] - '0';
if (!hash_key[c]) {
if (k == K) {
break;
}
hash_key[c] = true;
++k;
}
up_num.push_back(target_num[i]);
down_num.push_back(target_num[i]);
}
if (i == target_num.size()) {
printf("0\n");
return;
}
copy(hash_key, hash_key + 10, hash_copy);
int j = i - 1;
up_num.resize(target_num.size());
int c = target_num[j + 1] - '0';
int v = find_closet_k(c, true);
if (v == -1) {
int aj = target_num[j] - '0';
up_num[j] = aj + 1 + '0';
if (hash_key[aj + 1]) {
//only used K - 1, use 0 as min_k();
fill(up_num.begin() + j + 1, up_num.end(), '0');
} else {
hash_key[aj] = false;
hash_key[aj + 1] = true;
fill(up_num.begin() + j + 1, up_num.end(), min_k());
}
} else {
up_num[j + 1] = v + '0';
fill(up_num.begin() + j + 1, up_num.end(), min_k());
}
copy(hash_copy, hash_copy + 10, hash_key);
j = i - 1;
down_num.resize(target_num.size());
v = find_closet_k(c, false);
if (v == -1) {
int aj = target_num[j] - '0';
down_num[j] = aj - 1 + '0';
if (hash_key[aj - 1] || is_head_zero(aj - 1,down_num, j)) {
fill(down_num.begin() + j + 1, down_num.end(), '9');
} else {
hash_key[aj] = false;
hash_key[aj -1] = true;
fill(down_num.begin() + j + 1, down_num.end(), max_k());
}
} else {
down_num[j + 1] = v + '0';
fill(down_num.begin() + j + 1, down_num.end(), max_k());
}
unsigned __int64 upi;
unsigned __int64 targeti;
unsigned __int64 downi;
sscanf(up_num.c_str(), "%lld", &upi);
sscanf(target_num.c_str(),"%lld",&targeti);
sscanf(down_num.c_str(),"%lld",&downi);
unsigned __int64 delta = min(upi - targeti, targeti - downi);
printf("%lld\n", delta);
}
int main(){
while (true) {
cin>>target_num>>K;
fill(hash_key, hash_key + 10, false);
find_closest();
up_num.clear();
down_num.clear();
target_num.clear();
}
}
Edit N2
on every step check if:
a) putting closeset possible digit less then current, and then maximizing remaining digits is better then current answer
b) putting closest possible digit greater then current, and then minimizing remaining digits is better then current answer
then if possible put same digit and then proceed to next digit
Let's say that I have a list of prizes:
PrizeA
PrizeB
PrizeC
And, for each of them, I want to draw a winner from a list of my attendees.
Give that my attendee list is as follows:
user1, user2, user3, user4, user5
What is an unbiased way to choose a user from that list?
Clearly, I will be using a cryptographically secure pseudo-random number generator, but how do I avoid a bias towards the front of the list? I assume I will not be using modulus?
EDIT
So, here is what I came up with:
class SecureRandom
{
private RNGCryptoServiceProvider rng = new RNGCryptoServiceProvider();
private ulong NextUlong()
{
byte[] data = new byte[8];
rng.GetBytes(data);
return BitConverter.ToUInt64(data, 0);
}
public int Next()
{
return (int)(NextUlong() % (ulong)int.MaxValue);
}
public int Next(int maxValue)
{
if (maxValue < 0)
{
throw new ArgumentOutOfRangeException("maxValue");
}
if (maxValue == 0)
{
return 0;
}
ulong chop = ulong.MaxValue - (ulong.MaxValue % (ulong)maxValue);
ulong rand;
do
{
rand = NextUlong();
} while (rand >= chop);
return (int)(rand % (ulong)maxValue);
}
}
BEWARE:
Next() Returns an int in the range [0, int.MaxValue]
Next(int.MaxValue) Returns an int in the range [0, int.MaxValue)
Pseudocode for special random number generator:
rng is random number generator produces uniform integers from [0, max)
compute m = max modulo length of attendee list
do {
draw a random number r from rng
} while(r >= max - m)
return r modulo length of attendee list
This eliminates the bias to the front part of the list. Then
put the attendees in some data structure indexable by integers
for every prize in the prize list
draw a random number r using above
compute index = r modulo length of attendee list
return the attendee at index
In C#:
public NextUnbiased(Random rg, int max) {
do {
int r = rg.Next();
} while(r >= Int32.MaxValue - (Int32.MaxValue % max));
return r % max;
}
public Attendee SelectWinner(IList<Attendee> attendees, Random rg) {
int winningAttendeeIndex = NextUnbiased(rg, attendees.Length)
return attendees[winningAttendeeIndex];
}
Then:
// attendees is list of attendees
// rg is Random
foreach(Prize prize in prizes) {
Attendee winner = SelectWinner(attendees, rg);
Console.WriteLine("Prize {0} won by {1}", prize.ToString(), winner.ToString());
}
Assuming a fairly distributed random number generator...
do {
i = rand();
} while (i >= RAND_MAX / 5 * 5);
i /= 5;
This gives each of 5 slots
[ 0 .. RAND_MAX / 5 )
[ RAND_MAX / 5 .. RAND_MAX / 5 * 2 )
[ RAND_MAX / 5 * 2 .. RAND_MAX / 5 * 3 )
[ RAND_MAX / 5 * 3 .. RAND_MAX / 5 * 4 )
[ RAND_MAX / 5 * 4 .. RAND_MAX / 5 * 5 )
and discards a roll which falls out of range.
You have already seem several perfectly good answers that depend on knowing the length of the list in advance.
To fairly select a single item from a list without needing to know the length of the list in the first place do this:
if (list.empty()) error_out_somehow
r=list.first() // r is a reference or pointer
s=list.first() // so is s
i = 2
while (r.next() is not NULL)
r=r.next()
if (random(i)==0) s=r // random() returns a uniformly
// drawn integer between 0 and i
i++
return s
(Useful if you list is stored as a linked list)
To distribute prizes in this scenario, just walk down the list of prizes selecting a random winner for each one. (If you want to prevent double winning you then remove the winner from the participant list.)
Why does it work?
You start with the first item at 1/1
On the next pass, you select the second item half the time (1/2), which means that the first item has probability 1 * (2-1)/2 = 1/2
on further iteration, you select the nth item with probability 1/n, and the chance for each previous item is reduced by a factor of (n-1)/n
which means that when you come to the end, the chance of having the mth item in the list (of n items) is
1/m * m/(m+1) * (m+1)/(m+2) * ... * (n-2)/(n-1) * (n-1)/n = 1/n
and is the same for every item.
If you are paying attention, you'll note that this means walking the whole list every time you want to select an item from the list, so this is not maximally efficient for (say) reordering the whole list (though it does that fairly).
I suppose one answer would be to assign each item a random value, and take the largest or smallest, drilling down as necessary.
I'm not sure if this is the most efficient, tho...
If you're using a good number generator, even with a modulus your bias will be miniscule. If, for instance, you're using a random number generator with 64 bits of entropy and five users, your bias toward the front of the array should be on the order of 3x10^-19 (my numbers may be off, by I don't think by much). That's an extra 3-in-10-quintillion likelihood of the first user winning compared to the later users. That should be good enough to be fair in anyone's book.
You can buy truly random bits from a provider, or use a mechanical device.
Here you will find Oleg Kiselyov's discussion of purely functional random shuffling.
A description of the linked content (quoted from the beginning of that article):
This article will give two pure functional programs that perfectly,
randomly and uniformly shuffle a sequence of arbitrary elements. We
prove that the algorithms are correct. The algorithms are implemented
in Haskell and can trivially be re-written into other (functional)
languages. We also discuss why a commonly used sort-based shuffle
algorithm falls short of perfect shuffling.
You could use that to shuffle your list and then pick the first item of the shuffled result (or maybe you'd prefer not to give two prizes two the same person -- then use n initial positions of the result, for n = number of prizes); or you could simplify the algorithm to just produce the first item; or you could take a look around that site, because I could have sworn there's an article on picking one random element from an arbitrary tree-like structure with uniform distribution, in a purely functional way, proof of correctness provided, but my search-fu is failing me and I can't seem to find it.
Without truly random bits, you will always have some bias. The number of ways to assign prizes to guests is much larger than any common PRNG's period for even a fairly low number of guests and prizes. As suggested by lpthnc, buy some truly random bits, or buy some random-bit-generating hardware.
As for the algorithm, just do a random shuffle of the guest list. Be careful, as naive shuffling algorithms do have a bias: http://en.wikipedia.org/wiki/Shuffling#Shuffling_algorithms
You can 100% reliably pick a random item from any arbitrary list with a single pass and without knowing how many items are in the list ahead of time.
Psuedo Code:
count = 0.0;
item_selected = none;
foreach item in list
count = count + 1.0;
chance = 1.0 / count;
if ( random( 1.0 ) <= chance ) then item_selected = item;
Test program comparing results of a single rand() % N vs iterating as above:
#include "stdafx.h"
#include <stdio.h>
#include <stdlib.h>
#include <memory.h>
static inline float frand01()
{
return (float)rand() / (float)RAND_MAX;
}
int _tmain(int argc, _TCHAR* argv[])
{
static const int NUM_ITEMS = 50;
int resultRand[NUM_ITEMS];
int resultIterate[NUM_ITEMS];
memset( resultRand, 0, NUM_ITEMS * sizeof(int) );
memset( resultIterate, 0, NUM_ITEMS * sizeof(int) );
for ( int i = 0; i < 100000; i++ )
{
int choiceRand = rand() % NUM_ITEMS;
int choiceIterate = 0;
float count = 0.0;
for ( int item = 0; item < NUM_ITEMS; item++ )
{
count = count + 1.0f;
float chance = 1.0f / count;
if ( frand01() <= chance )
{
choiceIterate = item;
}
}
resultRand[choiceRand]++;
resultIterate[choiceIterate]++;
}
printf("Results:\n");
for ( int i = 0; i < NUM_ITEMS; i++ )
{
printf( "%02d - %5d %5d\n", i, resultRand[i], resultIterate[i] );
}
return 0;
}
Output:
Results:
00 - 2037 2050
01 - 2038 2009
02 - 2094 1986
03 - 2007 1953
04 - 1990 2142
05 - 1867 1962
06 - 1941 1997
07 - 2023 1967
08 - 1998 2070
09 - 1930 1953
10 - 1972 1900
11 - 2013 1985
12 - 1982 2001
13 - 1955 2063
14 - 1952 2022
15 - 1955 1976
16 - 2000 2044
17 - 1976 1997
18 - 2117 1887
19 - 1978 2020
20 - 1886 1934
21 - 1982 2065
22 - 1978 1948
23 - 2039 1894
24 - 1946 2010
25 - 1983 1927
26 - 1965 1927
27 - 2052 1964
28 - 2026 2021
29 - 2090 1993
30 - 2039 2016
31 - 2030 2009
32 - 1970 2094
33 - 2036 2048
34 - 2020 2046
35 - 2010 1998
36 - 2104 2041
37 - 2115 2019
38 - 1959 1986
39 - 1998 2031
40 - 2041 1977
41 - 1937 2060
42 - 1946 2048
43 - 2014 1986
44 - 1979 2072
45 - 2060 2002
46 - 2046 1913
47 - 1995 1970
48 - 1959 2020
49 - 1970 1997
I have a list of numbers and I want to add up all the different combinations.
For example:
number as 1,4,7 and 13
the output would be:
1+4=5
1+7=8
1+13=14
4+7=11
4+13=17
7+13=20
1+4+7=12
1+4+13=18
1+7+13=21
4+7+13=24
1+4+7+13=25
Is there a formula to calculate this with different numbers?
A simple way to do this is to create a bit set with as much bits as there are numbers.
In your example 4.
Then count from 0001 to 1111 and sum each number that has a 1 on the set:
Numbers 1,4,7,13:
0001 = 13=13
0010 = 7=7
0011 = 7+13 = 20
1111 = 1+4+7+13 = 25
Here's how a simple recursive solution would look like, in Java:
public static void main(String[] args)
{
f(new int[] {1,4,7,13}, 0, 0, "{");
}
static void f(int[] numbers, int index, int sum, String output)
{
if (index == numbers.length)
{
System.out.println(output + " } = " + sum);
return;
}
// include numbers[index]
f(numbers, index + 1, sum + numbers[index], output + " " + numbers[index]);
// exclude numbers[index]
f(numbers, index + 1, sum, output);
}
Output:
{ 1 4 7 13 } = 25
{ 1 4 7 } = 12
{ 1 4 13 } = 18
{ 1 4 } = 5
{ 1 7 13 } = 21
{ 1 7 } = 8
{ 1 13 } = 14
{ 1 } = 1
{ 4 7 13 } = 24
{ 4 7 } = 11
{ 4 13 } = 17
{ 4 } = 4
{ 7 13 } = 20
{ 7 } = 7
{ 13 } = 13
{ } = 0
The best-known algorithm requires exponential time. If there were a polynomial-time algorithm, then you would solve the subset sum problem, and thus the P=NP problem.
The algorithm here is to create bitvector of length that is equal to the cardinality of your set of numbers. Fix an enumeration (n_i) of your set of numbers. Then, enumerate over all possible values of the bitvector. For each enumeration (e_i) of the bitvector, compute the sum of e_i * n_i.
The intuition here is that you are representing the subsets of your set of numbers by a bitvector and generating all possible subsets of the set of numbers. When bit e_i is equal to one, n_i is in the subset, otherwise it is not.
The fourth volume of Knuth's TAOCP provides algorithms for generating all possible values of the bitvector.
C#:
I was trying to find something more elegant - but this should do the trick for now...
//Set up our array of integers
int[] items = { 1, 3, 5, 7 };
//Figure out how many bitmasks we need...
//4 bits have a maximum value of 15, so we need 15 masks.
//Calculated as:
// (2 ^ ItemCount) - 1
int len = items.Length;
int calcs = (int)Math.Pow(2, len) - 1;
//Create our array of bitmasks... each item in the array
//represents a unique combination from our items array
string[] masks = Enumerable.Range(1, calcs).Select(i => Convert.ToString(i, 2).PadLeft(len, '0')).ToArray();
//Spit out the corresponding calculation for each bitmask
foreach (string m in masks)
{
//Get the items from our array that correspond to
//the on bits in our mask
int[] incl = items.Where((c, i) => m[i] == '1').ToArray();
//Write out our mask, calculation and resulting sum
Console.WriteLine(
"[{0}] {1}={2}",
m,
String.Join("+", incl.Select(c => c.ToString()).ToArray()),
incl.Sum()
);
}
Outputs as:
[0001] 7=7
[0010] 5=5
[0011] 5+7=12
[0100] 3=3
[0101] 3+7=10
[0110] 3+5=8
[0111] 3+5+7=15
[1000] 1=1
[1001] 1+7=8
[1010] 1+5=6
[1011] 1+5+7=13
[1100] 1+3=4
[1101] 1+3+7=11
[1110] 1+3+5=9
[1111] 1+3+5+7=16
Here is a simple recursive Ruby implementation:
a = [1, 4, 7, 13]
def add(current, ary, idx, sum)
(idx...ary.length).each do |i|
add(current + [ary[i]], ary, i+1, sum + ary[i])
end
puts "#{current.join('+')} = #{sum}" if current.size > 1
end
add([], a, 0, 0)
Which prints
1+4+7+13 = 25
1+4+7 = 12
1+4+13 = 18
1+4 = 5
1+7+13 = 21
1+7 = 8
1+13 = 14
4+7+13 = 24
4+7 = 11
4+13 = 17
7+13 = 20
If you do not need to print the array at each step, the code can be made even simpler and much faster because no additional arrays are created:
def add(ary, idx, sum)
(idx...ary.length).each do |i|
add(ary, i+1, sum + ary[i])
end
puts sum
end
add(a, 0, 0)
I dont think you can have it much simpler than that.
Mathematica solution:
{#, Total##}& /# Subsets[{1, 4, 7, 13}] //MatrixForm
Output:
{} 0
{1} 1
{4} 4
{7} 7
{13} 13
{1,4} 5
{1,7} 8
{1,13} 14
{4,7} 11
{4,13} 17
{7,13} 20
{1,4,7} 12
{1,4,13} 18
{1,7,13} 21
{4,7,13} 24
{1,4,7,13} 25
This Perl program seems to do what you want. It goes through the different ways to choose n items from k items. It's easy to calculate how many combinations there are, but getting the sums of each combination means you have to add them eventually. I had a similar question on Perlmonks when I was asking How can I calculate the right combination of postage stamps?.
The Math::Combinatorics module can also handle many other cases. Even if you don't want to use it, the documentation has a lot of pointers to other information about the problem. Other people might be able to suggest the appropriate library for the language you'd like to you.
#!/usr/bin/perl
use List::Util qw(sum);
use Math::Combinatorics;
my #n = qw(1 4 7 13);
foreach my $count ( 2 .. #n ) {
my $c = Math::Combinatorics->new(
count => $count, # number to choose
data => [#n],
);
print "combinations of $count from: [" . join(" ",#n) . "]\n";
while( my #combo = $c->next_combination ){
print join( ' ', #combo ), " = ", sum( #combo ) , "\n";
}
}
You can enumerate all subsets using a bitvector.
In a for loop, go from 0 to 2 to the Nth power minus 1 (or start with 1 if you don't care about the empty set).
On each iteration, determine which bits are set. The Nth bit represents the Nth element of the set. For each set bit, dereference the appropriate element of the set and add to an accumulated value.
ETA: Because the nature of this problem involves exponential complexity, there's a practical limit to size of the set you can enumerate on. If it turns out you don't need all subsets, you can look up "n choose k" for ways of enumerating subsets of k elements.
PHP: Here's a non-recursive implementation. I'm not saying this is the most efficient way to do it (this is indeed exponential 2^N - see JasonTrue's response and comments), but it works for a small set of elements. I just wanted to write something quick to obtain results. I based the algorithm off Toon's answer.
$set = array(3, 5, 8, 13, 19);
$additions = array();
for($i = 0; $i < pow(2, count($set)); $i++){
$sum = 0;
$addends = array();
for($j = count($set)-1; $j >= 0; $j--) {
if(pow(2, $j) & $i) {
$sum += $set[$j];
$addends[] = $set[$j];
}
}
$additions[] = array($sum, $addends);
}
sort($additions);
foreach($additions as $addition){
printf("%d\t%s\n", $addition[0], implode('+', $addition[1]));
}
Which will output:
0
3 3
5 5
8 8
8 5+3
11 8+3
13 13
13 8+5
16 13+3
16 8+5+3
18 13+5
19 19
21 13+8
21 13+5+3
22 19+3
24 19+5
24 13+8+3
26 13+8+5
27 19+8
27 19+5+3
29 13+8+5+3
30 19+8+3
32 19+13
32 19+8+5
35 19+13+3
35 19+8+5+3
37 19+13+5
40 19+13+8
40 19+13+5+3
43 19+13+8+3
45 19+13+8+5
48 19+13+8+5+3
For example, a case for this could be a set of resistance bands for working out. Say you get 5 bands each having different resistances represented in pounds and you can combine bands to sum up the total resistance. The bands resistances are 3, 5, 8, 13 and 19 pounds. This set gives you 32 (2^5) possible configurations, minus the zero. In this example, the algorithm returns the data sorted by ascending total resistance favoring efficient band configurations first, and for each configuration the bands are sorted by descending resistance.
This is not the code to generate the sums, but it generates the permutations. In your case:
1; 1,4; 1,7; 4,7; 1,4,7; ...
If I have a moment over the weekend, and if it's interesting, I can modify this to come up with the sums.
It's just a fun chunk of LINQ code from Igor Ostrovsky's blog titled "7 tricks to simplify your programs with LINQ" (http://igoro.com/archive/7-tricks-to-simplify-your-programs-with-linq/).
T[] arr = …;
var subsets = from m in Enumerable.Range(0, 1 << arr.Length)
select
from i in Enumerable.Range(0, arr.Length)
where (m & (1 << i)) != 0
select arr[i];
You might be interested in checking out the GNU Scientific Library if you want to avoid maintenance costs. The actual process of summing longer sequences will become very expensive (more-so than generating a single permutation on a step basis), most architectures have SIMD/vector instructions that can provide rather impressive speed-up (I would provide examples of such implementations but I cannot post URLs yet).
Thanks Zach,
I am creating a Bank Reconciliation solution. I dropped your code into jsbin.com to do some quick testing and produced this in Javascript:
function f(numbers,ids, index, sum, output, outputid, find )
{
if (index == numbers.length){
var x ="";
if (find == sum) {
y= output + " } = " + sum + " " + outputid + " }<br/>" ;
}
return;
}
f(numbers,ids, index + 1, sum + numbers[index], output + " " + numbers[index], outputid + " " + ids[index], find);
f(numbers,ids, index + 1, sum, output, outputid,find);
}
var y;
f( [1.2,4,7,13,45,325,23,245,78,432,1,2,6],[1,2,3,4,5,6,7,8,9,10,11,12,13], 0, 0, '{','{', 24.2);
if (document.getElementById('hello')) {
document.getElementById('hello').innerHTML = y;
}
I need it to produce a list of ID's to exclude from the next matching number.
I will post back my final solution using vb.net
v=[1,2,3,4]#variables to sum
i=0
clis=[]#check list for solution excluding the variables itself
def iterate(lis,a,b):
global i
global clis
while len(b)!=0 and i<len(lis):
a=lis[i]
b=lis[i+1:]
if len(b)>1:
t=a+sum(b)
clis.append(t)
for j in b:
clis.append(a+j)
i+=1
iterate(lis,a,b)
iterate(v,0,v)
its written in python. the idea is to break the list in a single integer and a list for eg. [1,2,3,4] into 1,[2,3,4]. we append the total sum now by adding the integer and sum of remaining list.also we take each individual sum i.e 1,2;1,3;1,4. checklist shall now be [1+2+3+4,1+2,1+3,1+4] then we call the new list recursively i.e now int=2,list=[3,4]. checklist will now append [2+3+4,2+3,2+4] accordingly we append the checklist till list is empty.
set is the set of sums and list is the list of the original numbers.
Its Java.
public void subSums() {
Set<Long> resultSet = new HashSet<Long>();
for(long l: list) {
for(long s: set) {
resultSet.add(s);
resultSet.add(l + s);
}
resultSet.add(l);
set.addAll(resultSet);
resultSet.clear();
}
}
public static void main(String[] args) {
// this is an example number
long number = 245L;
int sum = 0;
if (number > 0) {
do {
int last = (int) (number % 10);
sum = (sum + last) % 9;
} while ((number /= 10) > 0);
System.err.println("s = " + (sum==0 ? 9:sum);
} else {
System.err.println("0");
}
}