I failed my algorithm exam in January. I'm going to an oral exam tomorrow. I was going through the ordinary exam and answers, when there was an answer I couldn't understand.
According to the answers, the answer is A. Why? 20 mod 7 is 6, but 12 mod 7 is 5 and it is empty. Hope that you would help me out here.
PS: Sorry if the formatting is wrong
h(20,0) = 5
h(12,0) = 3
h(5,0) = 3*
h(5,1) = 6
h(3,0) = 6*
h(3,1) = 2
h(1,0) = 2*
h(1,1) = 5*
h(1,2) = 0
* collision
i k
-------------------------
0 20 (2*20+3*0^2) mod 7 = (40 + 0) mod 7 = 40 mod 7 = 5 <- [e, e, e, e, e, 20, e]
0 12 (2*12+3*0^2) mod 7 = (24 + 0) mod 7 = 24 mod 7 = 3 <- [e, e, e, 12, e, 20, e]
0 5 (2*5+3*0^2) mod 7 = (10 + 0) mod 7 = 10 mod 7 = 3 <- collision
1 5 (2*5+3*1^2) mod 7 = (10 + 3) mod 7 = 13 mod 7 = 6 <- [e, e, e, 12, e, 20, 5]
0 3 (2*3+3*0^2) mod 7 = (6 + 0 ) mod 7 = 6 mod 7 = 6 <- collision
1 3 (2*3+3*1^2) mod 7 = (6 + 3) mod 7 = 9 mod 7 = 2 <- [e, e, 3, 12, e, 20, 5]
0 1 (2*1+3*0^2) mod 7 = (2 + 0) mod 7 = 2 mod 7 = 2 <- collision
1 1 (2*1+3*1^2) mod 7 = (2 + 3) mod 7 = 5 mod 7 = 5 <- collision
2 1 (2*1+3*2^2) mod 7 = (2 + 12) mod 7 = 14 mod 7 = 0 <- [1, e, 3, 12, e, 20, 5]
So
[1, empty, 3, 12, empty, 20, 5]
Here is how it works, each time collision happens, quadratic probing is going to be used (with i=1,2,..) until there is a free space available in the hash table:
Related
I need to draw an n sample from the uniform distribution on the interval [a,b] such that no two numbers are closer than d > 0. I can draw a sample and check this property and then throw it away and try again if not, but if n is large relative to b-a that could take a looong time. Is there a simple and nice algorithm to solve this problem? The numbers got to be uniformly distributed on [a,b], no deterministic setup.
This problem is equivalent to choosing n numbers greater than or equal to d and whose sum is equal to b - a.
There will be some solution provided that n * d <= b - a. We can write a recursive algorithm that looks for one:
b - a - X < (n - 1) * D
X > b - a - (n - 1) * d
FindSpacedSample(n, d, a, b)
1. if n * d > b - a then return "no solution"
2. avail = [d, b - a - (n - 1) * d]
3. guess = random(avail)
4. print(guess)
5. FindSpacedSample(n - 1, d, a + guess, b)
Example: n = 5, a = 0, b = 10, d = 1, assuming real numbers
FindSpacedSample(5, 1, 0, 10)
5 * 1 >? b - a? no
avail = [1, 10 - 0 - 4 * 1] = [1, 6]
guess = random(avail) = 2 (for the sake of argument)
print(2)
FindSpacedSample(4, 1, 2, 10)
4 * 1 >? 10 - 2? no
avail = [1, 10 - 2 - 3 * 1] = [1, 5]
guess = random(avail) = 4 (for the sake of argument)
print(4)
FindSpacedSample(3, 1, 6, 10)
3 * 1 >? 10 - 6? no
avail = [1, 10 - 6 - 2 * 1] = [1, 2]
guess = random(avail) = 1 (for the sake of argument)
print(1)
FindSpacedSample(2, 1, 7, 10)
2 * 1 >? 10 - 7? no
avail = [1, 10 - 7 - 1 * 1] = [1, 2]
guess = random(avail) = 2 (for the sake of argument)
print(2)
FindSpacedSample(1, 1, 9, 10)
1 * 1 >? 10 - 9? no
avail = [1, 10 - 9 - 0 * 1] = [1, 1]
guess = 1
print(1)
We should also have stopping condition n = 0. Then we get the sequence of spaces 2, 4, 1, 2, 1; we see these sum to ten; and we can get the values as follows:
point1 = 2 = 2
point2 = 2 + 4 = 6
point3 = 2 + 4 + 1 = 7
point4 = 2 + 4 + 1 + 2 = 9
point5 = 2 + 4 + 1 + 2 + 1 = 10
Now, there are a couple of ways in which this result is less than totally uniform:
the first number will never be less than d
earlier numbers tend to be spaced further apart
We can fix these by:
shuffling the spacings before converting to points
subtracting from each point some random value from [0, point1 - a].
So, if we shuffled 2, 4, 1, 2, 1 to 4, 1, 1, 2, 2 we'd get points 4, 5, 6, 8, 10; and if we subtracted 3 from each one (taken randomly between 0 and 4) we'd get 1, 2, 3, 5, 7.
Does this give you a uniform distribution over the set of all possible solutions? I'd be surprised if it did, but I'd also be surprised if what this does give you differs from that truly uniform distribution to an appreciable degree.
I am asking myself the following question.
Is there a smart way to solve the problem using the package data.table instead of solving it with data.frames. I got a huge dataset and want to adress this problem as efficient as possible
Random <- sample(c("A","B","C","D","E","F","G"), size = 100, replace =
TRUE)
Year <- sample(c(2000,2001,2002,2003,2004,2005), 100, TRUE)
Value <- sample(c(1,2,3,4), 100, TRUE)
data <- data.frame(Random,Year,Value)
# open dplyr library
library(dplyr)
#Group data by Random and year and count Values that are not NA
data %>% group_by(Random, Year) %>% summarise(count =
length(Value[!is.na(Value)]))
I still wish to delete all the rows that do not change. So to be precise, all the rows which have the same min and max :)
EDITED following #Hannie ´s comment.
Say you want to remove all rows where columns b, c, and d are equal. You can use Reduce and ==.
set.seed(0)
dt <- data.frame(a = sample(letters[1:3], 100, T)
, b = sample(1:2, 100, T)
, c = sample(1:2, 100, T)
, d = sample(1:2, 100, T))
df[!Reduce(`==`, df[, -1]),]
In this example though, it's probably better to remove those rows before using xtabs.
data <- data.frame(Random,Year,Value)
library(data.table)
setDT(data)
data[, .(Count = sum(!is.na(Value))), by = .(Random, Year)
][, if(!Reduce(`==`, Count)) .SD, by = Random]
If I understand correctly, it would also be the same if your variance does not equal 0. You can do that using apply and var together, and then index on your dataframe.
I named the dataframe x
x[apply(x, 1, var)!=0,]
The 1 means you're calculating the variance over rows. Output:
2000 2001 2002 2003 2004
b 1 2 3 4 5
d 6 7 8 9 5
f 1 2 3 4 5
I couldn't get your code to work so I created a data.frame like this:
dput(x)
structure(list(`2000` = c(0, 1, 2, 6, 1, 1), `2001` = c(0, 2,
2, 7, 1, 2), `2002` = c(0, 3, 2, 8, 1, 3), `2003` = c(0, 4, 2,
9, 1, 4), `2004` = c(0, 5, 2, 5, 1, 5)), class = "data.frame", row.names = c("a",
"b", "c", "d", "e", "f"))
Which has this output:
2000 2001 2002 2003 2004
a 0 0 0 0 0
b 1 2 3 4 5
c 2 2 2 2 2
d 6 7 8 9 5
e 1 1 1 1 1
f 1 2 3 4 5
The question is to find the number of 5 digits numbers possible using 1, 2, 3, 4, and 5 as digits, in which the set of first k numbers (k is natural number, and k < 5) is not equal to set of numbers from 1 to k.
Clarification - Order of elements of set does not matter. {1, 2} is same as {2, 1} ie {1, 2} = {2, 1}.
For example, in 54213 is a correct number and it will be counted - as
k = 1, we get {5}, and {5} != {1}
k = 2, {5, 4} != {1, 2}
k = 3, {5, 4, 2} != {1, 2, 3}
k = 4, {5, 4, 2, 1} != {1, 2, 3, 4}
Also, the number 13245 is not valid, as for k = 1, {1} = {1}.
Bonus question, find the number of 6 digit possible numbers with same criteria and digits 1, 2, 3, 4, 5, & 6.
Edit - I am sorry for not having followed this up with my method. I have added my solution below.
Number of 5 digit numbers possible with the given digits = 5! = 120
Let's consider the digits that are NOT to be formed.
1 _ _ _ _ = 4! = 24 (As clearly, k = 1 {1} = {1})
2 1 _ _ _ = 3! = 6 (As clearly, k = 2 {2, 1} = {1, 2}, also we will not consider 1 2 _ _ _ as it has already been included in 1)
2 3 1 _ _ = 2! = 2
3 1 2 _ _ = 2! = 2
3 2 1 _ _ = 2! = 2
2 3 4 1 _ = 1
2 4 1 3 _ = 1
2 4 3 1 _ = 1
3 1 4 2 _ = 1
3 2 4 1 _ = 1
3 4 2 1 _ = 1
3 4 1 2 _ = 1
4 - - - _ = 3! x 1 = 6 (Where dashes can be filled by 1, 2, 3)
Total number = 49
But there are the NOT cases. Now, the cases required = 120 - 49 = 71.
For 6, I used recursion, as clearly in case of 5, the series (for the numbers that are NOT to be formed) is
1 x 4! + 1 x 3! + 3 x 2! + 13 x 1! (where 1, 1, 3, and 13 is the solution for the given condition for 1 digit, 2, digit, 3 digit and 4 digit respectively)
{ie, for 1 digit number using only 1, where k < 1, k is natural, number of possible digits - 1 (1). For 2 digit number using only 1, 2, where k < 2, the number of possible digits - 1 (21). For 3, it is 321, 231, 312 and so on)
Hence, for 6, the series becomes
1 x 5! + 1 x 4! + 3 x 3! + 13 x 2! + 71 (where 71 is the solution for given condition of 5 digits)
= 259
ie. for 6, the solutions = 6! - 259 = 461
Given an unsorted permutation of [n], I want to collect the numbers by iterating from left to right in order to sort the premutation (1...n).
What is the number of iteration I have to do in order to acheieve this goal?
For example:
Given '3, 7, 4, 2, 10, 8, 9, 1, 6, 5'- the number of iterations is 6.
In the first iteration I will collect the number 1
In the second iteration I will collect the number 2
In the third iteration I will collect the numbers 3,4,5
In the forth iteration I will collect the number 6
In the fifth iteration I will collect the numbers 7,8,9
In the sixth iteration I will collect the number 10
I build a naive code, doing the task with O(n^2), but I need it to be more efficient, so I think there's a trick I'm missing here.
Any suggestions?
Invert the permutation, then count how many times two consecutive numbers are decreasing, plus one.
def iterations(perm):
invperm = [None] * len(perm)
for i in range(len(perm)): # yes, we could use enumerate
invperm[perm[i] - 1] = i
count = 1
for i in range(1, len(perm)):
count += invperm[i - 1] > invperm[i]
return count
Explaination:
Given : 3, 7, 4, 2, 10, 8, 9, 1, 6, 5
x : 1, 2, 3, 4, 5, 6, 7, 8, 9, 10
Index of x in the given array : |8, |4, |1, 3, 10, |9, |2, 6, 7, |5
If indexes are out of order then you have to start again. So if you count |s then you know number of iterations you need.
Since you already know the result, it's unclear to me in what sense you're "sorting" anything. What result are you looking for -- the information about what numbers are "collected" at each iteration, as you show in your Q? In this case here's a simple Python 2 implementation example:
target = 3, 7, 4, 2, 10, 8, 9, 1, 6, 5
def do_permut(targ):
look_for = 1
iter_num = 1
while look_for != len(targ) + 1:
print 'Iteration', iter_num, ':',
for item in targ:
if item == look_for:
print item,
look_for += 1
print
iter_num += 1
do_permut(target)
However the task is inevitably O(N squared) -- remember big-O stands for worst case! You'll have up to N iterations (worst case realized when targ is reverse sorted to start with) each over N numbers -- thus, N squared. You could slightly optimize each iteration by collecting a set of numbers previously seen during it and breaking when look_for is in that set, but that only (roughly) halves each iteration's work, so it's still O(N squared).
If you can explain better what results and outputs you expect from your work we may be able to help more!
Just for curiosity here's a version with the above "improvement" and also a sanity check to ensure it raises an exception, rather than looping forever, if passed a sequence that's NOT a permutation of [1:n)...:
target = 3, 7, 4, 2, 10, 8, 9, 1, 6, 5
def do_permut(targ):
look_for = 1
iter_num = 1
while look_for != len(targ) + 1:
print 'iteration', iter_num, ':',
seen = set()
found_in_iter = 0
for item in targ:
seen.add(item)
if item == look_for:
print item,
found_in_iter += 1
look_for += 1
if look_for in seen:
break
print
if not found_in_iter:
raise ValueError('missing: %s' % look_for)
iter_num += 1
do_permut(target)
If you know that in assumption is given an array where for sure are present all elements of the permutation of [n] then I think:
Allocate an array y[1..n]
In one loop from 1 to n search initial array x of unsorted elements colecting items in each iteration the following way: y[x[i]] := x[i]
After the loop all in y is a sorted permutation with O (n)
-- edited 20-12-2014 22:54 CET:
The solution above works only for situation, where there is n-elementh table of integers from 1 to n unordered in any given way.
I'd like to explain in details how you can achieve the goal with only one iteration through the inpput array basing on your example.
Let's take the initial array:
x[] = { 3, 7, 4, 2, 10, 8, 9, 1, 6, 5 }
As a result let's take the following array filled at start with zero's:
y[] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }
Now let each item of the following ordered list be an iteration of the sorting algorithm:
We take x[1] which equals 3 - let's write it under 3rd position in result table y:
y[3] := 3 (which in fact is: y[x[1]] := x[1])
the result table now looks like following
y[] = { 0, 0, 3, 0, 0, 0, 0, 0, 0, 0 }
In second step we take x[2] which equals 7 and we repeat the steps:
y[7] := 7 (which in fact is: y[x[2]] := x[2])
the result table now looks like following
y[] = { 0, 0, 3, 0, 0, 0, 7, 0, 0, 0 }
Third step: x[3] which equals 4:
y[4] := 4 (which in fact is: y[x[3]] := x[3])
result table:
y[] = { 0, 0, 3, 4, 0, 0, 7, 0, 0, 0 }
x[4] which equals 2:
y[2] := 2 (which in fact is: y[x[4]] := x[4])
result table:
y[] = { 0, 2, 3, 4, 0, 0, 7, 0, 0, 0 }
x[5] which equals 10:
y[10] := 10 (which in fact is: y[x[5]] := x[5])
result table:
y[] = { 0, 2, 3, 4, 0, 0, 7, 0, 0, 10 }
x[6] which equals 8:
y[8] := 8 (which in fact is: y[x[6]] := x[6])
result table:
y[] = { 0, 2, 3, 4, 0, 0, 7, 8, 0, 10 }
x[7] which equals 9:
y[9] := 9 (which in fact is: y[x[7]] := x[7])
result table:
y[] = { 0, 2, 3, 4, 0, 0, 7, 8, 9, 10 }
x[8] which equals 1:
y[1] := 1 (which in fact is: y[x[8]] := x[8])
result table:
y[] = { 1, 2, 3, 4, 0, 0, 7, 8, 9, 10 }
x[9] which equals 6:
y[6] := 6 (which in fact is: y[x[9]] := x[9])
result table:
y[] = { 1, 2, 3, 4, 0, 6, 7, 8, 9, 10 }
The last iteration:
x[10] which equals 5:
y[5] := 5 (which in fact is: y[x[10]] := x[10])
result table:
y[] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 }
As we can see table y is a fully sorted version of input table x that was generated with 10 iterations (so O(n) cost level).
No matter how big is n and how much unordered is the given input table, with those particular assumptions taken, the cost is constant and equals n;
I hope I didn't misunderstood your question.
I tried to implement your sample in PERL.
#!/usr/bin/perl
if ($#ARGV < 0) { # with no arguments
#data = (3, 7, 4, 2, 10, 8, 9, 1, 6, 5);
}
else {
#tmp = (1..$ARGV[0]);
while(#tmp) {
push(#data, splice(#tmp, rand($#tmp), 1));
}
}
$key = 1;
while (#data) {
#remove = (); #remain = ();
printf "key = $key\t(#data) --> ";
foreach $i (#data) {
if ($i == $key) { # found
push(#remove, $i);
$key++;
}
else {
push(#remain, $i);
}
}
#data = #remain;
print "(#remove) & (#data)\n";
$count++;
}
print "Iteration = $count\n";
As a result.
$ ./a.pl
key = 1 (3 7 4 2 10 8 9 1 6 5) --> (1) & (3 7 4 2 10 8 9 6 5)
key = 2 (3 7 4 2 10 8 9 6 5) --> (2) & (3 7 4 10 8 9 6 5)
key = 3 (3 7 4 10 8 9 6 5) --> (3 4 5) & (7 10 8 9 6)
key = 6 (7 10 8 9 6) --> (6) & (7 10 8 9)
key = 7 (7 10 8 9) --> (7 8 9) & (10)
key = 10 (10) --> (10) & ()
Iteration = 6
$ ./a.pl 10
key = 1 (2 1 4 8 5 9 3 6 7 10) --> (1) & (2 4 8 5 9 3 6 7 10)
key = 2 (2 4 8 5 9 3 6 7 10) --> (2 3) & (4 8 5 9 6 7 10)
key = 4 (4 8 5 9 6 7 10) --> (4 5 6 7) & (8 9 10)
key = 8 (8 9 10) --> (8 9 10) & ()
Iteration = 4
$ ./a.pl 10
key = 1 (3 1 7 8 6 2 9 5 4 10) --> (1 2) & (3 7 8 6 9 5 4 10)
key = 3 (3 7 8 6 9 5 4 10) --> (3 4) & (7 8 6 9 5 10)
key = 5 (7 8 6 9 5 10) --> (5) & (7 8 6 9 10)
key = 6 (7 8 6 9 10) --> (6) & (7 8 9 10)
key = 7 (7 8 9 10) --> (7 8 9 10) & ()
Iteration = 5
Thanks in advance for the help
Suppose I have a multi D array such that
x(:,:,1) = [1 2 ; 3 4];
x(:,:,2) = [5 6 ; 7 8];
x(:,:,3) = [9 10 ; 11 12];
I would like quickly and efficiently convert x into
y = [1 5 9 2 6 10 3 7 11 4 8 12];
I there an efficient way to go about this besides using loops (the matrix I would like to do this to is relatively large)?
You can use the colon operator : but you first have to reorder the matrix x:
x(:,:,1) = [1 2 ; 3 4];
x(:,:,2) = [5 6 ; 7 8];
x(:,:,3) = [9 10 ; 11 12];
z=permute(x,[3 2 1]);
y=z(:).'