R: rgeom(n,p) when n and p is not fixed - r

Situation: Assume a bag contains 1 blue ball and 1 red ball. At each turn, a ball is chosen randomly, then returned back along with another (new) ball of the same colour (So after n turns, there will always be n+2 balls in the bag).
The probability of drawing the first red on the nth turn is
I want to write a loop that simulates the number of turns taken until the first red ball is drawn from the bag using the rgeom(n,p) code. But since n is unknown and p changes every turn, I am confused how to modify it. I tried the following code, but it won't print anything:
k=0
success = 0
while(success <= 1){
k = k + 1
if (rgeom(n, 1/(n+1) == 1)
success = success + 1
}
k
How can I write the loop?

If I run with a couple of small changes I got some value for k:
set.seed(123)
k=0
success = 0
while(success < 1){ # rather than <=1, which includes 0
k = k + 1
if (rgeom(n, 1/(n+1)) == 1) # missed closing parenthesis
success = success + 1
}
k
I got k=8
but there are lots of warnings!!

Related

Google Foobar Fuel Injection Perfection

Problem:
Fuel Injection Perfection
Commander Lambda has asked for your help to refine the automatic quantum antimatter fuel injection system for her LAMBCHOP doomsday device. It's a great chance for you to get a closer look at the LAMBCHOP - and maybe sneak in a bit of sabotage while you're at it - so you took the job gladly.
Quantum antimatter fuel comes in small pellets, which is convenient since the many moving parts of the LAMBCHOP each need to be fed fuel one pellet at a time. However, minions dump pellets in bulk into the fuel intake. You need to figure out the most efficient way to sort and shift the pellets down to a single pellet at a time.
The fuel control mechanisms have three operations:
Add one fuel pellet Remove one fuel pellet Divide the entire group of fuel pellets by 2 (due to the destructive energy released when a quantum antimatter pellet is cut in half, the safety controls will only allow this to happen if there is an even number of pellets) Write a function called solution(n) which takes a positive integer as a string and returns the minimum number of operations needed to transform the number of pellets to 1. The fuel intake control panel can only display a number up to 309 digits long, so there won't ever be more pellets than you can express in that many digits.
For example: solution(4) returns 2: 4 -> 2 -> 1 solution(15) returns 5: 15 -> 16 -> 8 -> 4 -> 2 -> 1
Test cases
Inputs: (string) n = "4" Output: (int) 2
Inputs: (string) n = "15" Output: (int) 5
my code:
def solution(n):
n = int(n)
if n == 2:
return 1
if n % 2 != 0:
return min(solution(n + 1), solution(n - 1)) + 1
else:
return solution(int(n / 2)) + 1
This is the solution that I came up with with passes 4 out of 10 of the test cases. It seems to be working fine so im wondering if it is because of the extensive runtime. I thought of applying memoization but im not sure how to do it(or if it is even possible). Any help would be greatly appreciated :)
There are several issues to consider:
First, you don't handle the n == "1" case properly (operations = 0).
Next, by default, Python has a limit of 1000 recursions. If we compute the log2 of a 309 digit number, we expect to make a minimum of 1025 divisions to reach 1. And if each of those returns an odd result, we'd need to triple that to 3075 recursive operations. So, we need to bump up Python's recursion limit.
Finally, for each of those divisions that does return an odd value, we'll be spawning two recursive division trees (+1 and -1). These trees will not only increase the number of recursions, but can also be highly redundant. Which is where memoization comes in:
import sys
from functools import lru_cache
sys.setrecursionlimit(3333) # estimated by trial and error
#lru_cache()
def solution(n):
n = int(n)
if n <= 2:
return n - 1
if n % 2 == 0:
return solution(n // 2) + 1
return min(solution(n + 1), solution(n - 1)) + 1
print(solution("4"))
print(solution("15"))
print(solution(str(10**309 - 1)))
OUTPUT
> time python3 test.py
2
5
1278
0.043u 0.010s 0:00.05 100.0% 0+0k 0+0io 0pf+0w
>
So, bottom line is handle "1", increase your recursion limit, and add memoization. Then you should be able to solve this problem easily.
There are more memory- and runtime-efficient ways to solve the problem, which is what Google is testing for with their constraints. Every time you recurse a function, you put another call on the stack, or 2 calls when you recurse twice on each function call. While they seem basic, a while loop was a lot faster for me.
Think of the number in binary - when ever you have a streak of 1s >1 in length at LSB side of the number, it makes sense to add 1 (which will flip that streak to all 0s but add another bit to the overall length), then shift right until you find another 1 in the LSB position. You can solve it in a fixed memory block in O(n) using just a while loop.
If you don't want or can't use functools, you can build your own cache this way :
cache = {}
def solution_rec(n):
n = int(n)
if n in cache:
return cache[n]
else:
if n <= 1:
return 0
if n == 2:
return 1
if n % 2 == 0:
div = n / 2
cache[div] = solution(div)
return cache[div] + 1
else:
plus = n + 1
minus = n - 1
cache[plus] = solution(n + 1)
cache[minus] = solution(n - 1)
return min(cache[plus], cache[minus]) + 1
However, even if it runs much faster and has less recursive calls, it's still too much recursive calls for Python default configuration if you test the 309 digits limit.
it works if you set sys.setrecursionlimit to 1562.
An implementation of #rreagan3's solution, with the exception that an input of 3 should lead to a subtraction rather than an addition even through 3 has a streak of 1's on the LSB side:
def solution(n):
n = int(n)
count = 0
while n > 1:
if n & 1 == 0:
n >>= 1
elif n & 2 and n != 3:
n += 1
else:
n -= 1 # can also be: n &= -2
count += 1
return count
Demo: https://replit.com/#blhsing/SlateblueVeneratedFactor

The game with the marbles

Problem: There are R red marbles, G green marbles and B blue marbles (R≤G≤B) Count the number of ways to arrange them in a straight line so that the two marbles next to each other are of different colors.
For example, R=G=B=2, the answer is 30.
I have tried using recursion and of course TLE:
Define r(R,B,G) to be the number of ways of arranging them where the first marble is red. Define b(R,B,G),g(R,B,G) respectively.
Then r(R, B, G) = b(R-1,B,G) + g(R-1,B,G)
And the answer is r(R,B,G) + b(R,B,G) + g(R,B,G)
But we can see that r(R, B, G) = b(B, R, G) ...
So, we just need a function f(x,y,z)=f(y,x−1,z)+f(z,x−1,y)
And the answer is f(x,y,z) + f(y,z,x) + f(z,x,y).
The time limit is 2 seconds.
I don't think dynamic is not TLE because R, G, B <= 2e5
Some things to limit the recursion:
If R>G+B+1, then there is no way to avoid having 2 adjacent reds. (Similar argument for G>R+B+1 & B>R+G+1.)
If R=G+B+1, then you alternate reds with non-reds, and your problem is reduced to how many ways you can arrange G greens and B blacks w/o worrying about adjacency (and should thus have a closed-form solution). (Again, similar argument for G=R+B+1 and B=R+G+1.)
You can use symmetry to cut down the number of recursions.
For example, if (R, G, B) = (30, 20, 10) and the last marble was red, the number of permutations from this position is exactly the same as if the last marble was blue and (R, G, B) = (10, 20, 30).
Given that R ≤ G ≤ B is set as a starting condition, I would suggest keeping this relationship true by swapping the three values when necessary.
Here's some Python code I came up with:
memo = {}
def marble_seq(r, g, b, last):
# last = colour of last marble placed (-1:nothing, 0:red, 1:green, 2:blue)
if r == g == b == 0:
# All the marbles have been placed, so we found a solution
return 1
# Enforce r <= g <= b
if r > g:
r, g = g, r
last = (0x201 >> last * 4) & 0x0f # [1, 0, 2][last]
if r > b:
r, b = b, r
last = (0x012 >> last * 4) & 0x0f # [2, 1, 0][last]
if g > b:
g, b = b, g
last = (0x120 >> last * 4) & 0x0f # [0, 2, 1][last]
# Abort if there are too many marbles of one colour
if b>r+g+1:
return 0
# Fetch value from memo if available
if (r,g,b,last) in memo:
return memo[(r,g,b,last)]
# Otherwise check remaining permutations by recursion
result = 0
if last != 0 and r > 0:
result += marble_seq(r-1,g,b,0)
if last != 1 and g > 0:
result += marble_seq(r,g-1,b,1)
if last != 2 and b > 0:
result += marble_seq(r,g,b-1,2)
memo[(r,g,b,last)] = result
return result
marble_seq(50,60,70,-1) # Call with `last` set to -1 initially
(Result: 205435997562313431685415150793926465693838980981664)
This probably still won't work fast enough for values up to 2×105, but even with values in the hundreds, the results are quite enormous. Are you sure you stated the problem correctly? Perhaps you're supposed to give the results modulo some prime number?

Python Programming While Loop

Hi I'm new to python and programming in general. I am trying write a program that uses a while loop to add integers from 1 to the number entered. the program also has to give an error statement if the user enters a 0 or negative number. So far the integers add up and the error statement works but the program is not looping, it only asks the user to input a number one time. Please help. This is my source code so far. Thanks
x = int(input("Enter a positive number not including zero:" ))
total = 0
n = 1
while n <= x:
total = total + n
n = n + 1
# prints the total of integers up to number entered
print("Sum of integers from 1 to number entered= ",total)
if x <= 0 or x == -x:
print ("invalid entry")
Try this code...
op='y'
while op=='y':
x = int(input("Enter a positive number not including zero:" ))
total = 0
n = 1
if x > 0:
while n <= x:
total = total + n
n = n + 1
# prints the total of integers up to number entered
print("Sum of integers from 1 to number entered= ",total)
else:
print ("invalid entry")
op = raw_input("Are you want to continue this operation (y/n):" )
Put your whole code this way
done = False
while not done:
//your entire code here except the last 2 lines
if x > 0:
done = True

Determining the big Oh for (n-1)+(n-1)

I have been trying to get my head around this perticular complexity computation but everything i read about this type of complexity says to me that it is of type big O(2^n) but if i add a counter to the code and check how many times it iterates per given n it seems to follow the curve of 4^n instead. Maybe i just misunderstood as i placed an count++; inside the scope.
Is this not of type big O(2^n)?
public int test(int n)
{
if (n == 0)
return 0;
else
return test(n-1) + test(n-1);
}
I would appreciate any hints or explanation on this! I completely new to this complexity calculation and this one has thrown me off the track.
//Regards
int test(int n)
{
printf("%d\n", n);
if (n == 0) {
return 0;
}
else {
return test(n - 1) + test(n - 1);
}
}
With a printout at the top of the function, running test(8) and counting the number of times each n is printed yields this output, which clearly shows 2n growth.
$ ./test | sort | uniq -c
256 0
128 1
64 2
32 3
16 4
8 5
4 6
2 7
1 8
(uniq -c counts the number of times each line occurs. 0 is printed 256 times, 1 128 times, etc.)
Perhaps you mean you got a result of O(2n+1), rather than O(4n)? If you add up all of these numbers you'll get 511, which for n=8 is 2n+1-1.
If that's what you meant, then that's fine. O(2n+1) = O(2⋅2n) = O(2n)
First off: the 'else' statement is obsolete since the if already returns if it evaluates to true.
On topic: every iteration forks 2 different iterations, which fork 2 iterations themselves, etc. etc. As such, for n=1 the function is called 2 times, plus the originating call. For n=2 it is called 4+1 times, then 8+1, then 16+1 etc. The complexity is therefore clearly 2^n, since the constant is cancelled out by the exponential.
I suspect your counter wasn't properly reset between calls.
Let x(n) be a number of total calls of test.
x(0) = 1
x(n) = 2 * x(n - 1) = 2 * 2 * x(n-2) = 2 * 2 * ... * 2
There is total of n twos - hence 2^n calls.
The complexity T(n) of this function can be easily shown to equal c + 2*T(n-1). The recurrence given by
T(0) = 0
T(n) = c + 2*T(n-1)
Has as its solution c*(2^n - 1), or something like that. It's O(2^n).
Now, if you take the input size of your function to be m = lg n, as might be acceptable in this scenario (the number of bits to represent n, the true input size) then this is, in fact, an O(m^4) algorithm... since O(n^2) = O(m^4).

Minimum Weight Triangulation Taking Forever

so I've been working on a program in Python that finds the minimum weight triangulation of a convex polygon. This means that it finds the weight(The sum of all the triangle perimeters), as well as the list of chords(lines going through the polygon that break it up into triangles, not the boundaries).
I was under the impression that I'm using the dynamic programming algorithm, however when I tried using a somewhat more complex polygon it takes forever(I'm not sure how long it takes because I haven't gotten it to finish).
It works fine with a 10 sided polygon, however I'm trying 25 and that's what is making it stall. My teacher gave me the polygons so I assume that the 25 one is supposed to work as well.
Since this algorithm is supposed to be O(n^3), the 25 sided polygon should take roughly 15.625 times longer to calculate, however it's taking way longer seeing that the 10 sided seems instantaneous.
Am I doing some sort of n operation in there that I'm not realizing? I can't see anything I'm doing, except maybe the last part where I get rid of the duplicates by turning the list into a set, however in my program I put a trace after the decomp before the conversion happens, and it's not even reaching that point.
Here's my code, if you guys need anymore info just please ask. Something in there is making it take longer than O(n^3) and I need to find it so I can trim it out.
#!/usr/bin/python
import math
def cost(v):
ab = math.sqrt(((v[0][0] - v[1][0])**2) + ((v[0][1] - v[1][1])**2))
bc = math.sqrt(((v[1][0] - v[2][0])**2) + ((v[1][1] - v[2][1])**2))
ac = math.sqrt(((v[0][0] - v[2][0])**2) + ((v[0][1] - v[2][1])**2))
return ab + bc + ac
def triang_to_chord(t, n):
if t[1] == t[0] + 1:
# a and b
if t[2] == t[1] + 1:
# single
# b and c
return ((t[0], t[2]), )
elif t[2] == n-1 and t[0] == 0:
# single
# c and a
return ((t[1], t[2]), )
else:
# double
return ((t[0], t[2]), (t[1], t[2]))
elif t[2] == t[1] + 1:
# b and c
if t[0] == 0 and t[2] == n-1:
#single
# c and a
return ((t[0], t[1]), )
else:
#double
return ((t[0], t[1]), (t[0], t[2]))
elif t[0] == 0 and t[2] == n-1:
# c and a
# double
return ((t[0], t[1]), (t[1], t[2]))
else:
# triple
return ((t[0], t[1]), (t[1], t[2]), (t[0], t[2]))
file_name = raw_input("Enter the polygon file name: ").rstrip()
file_obj = open(file_name)
vertices_raw = file_obj.read().split()
file_obj.close()
vertices = []
for i in range(len(vertices_raw)):
if i % 2 == 0:
vertices.append((float(vertices_raw[i]), float(vertices_raw[i+1])))
n = len(vertices)
def decomp(i, j):
if j <= i: return (0, [])
elif j == i+1: return (0, [])
cheap_chord = [float("infinity"), []]
old_cost = cheap_chord[0]
smallest_k = None
for k in range(i+1, j):
old_cost = cheap_chord[0]
itok = decomp(i, k)
ktoj = decomp(k, j)
cheap_chord[0] = min(cheap_chord[0], cost((vertices[i], vertices[j], vertices[k])) + itok[0] + ktoj[0])
if cheap_chord[0] < old_cost:
smallest_k = k
cheap_chord[1] = itok[1] + ktoj[1]
temp_chords = triang_to_chord(sorted((i, j, smallest_k)), n)
for c in temp_chords:
cheap_chord[1].append(c)
return cheap_chord
results = decomp(0, len(vertices) - 1)
chords = set(results[1])
print "Minimum sum of triangle perimeters = ", results[0]
print len(chords), "chords are:"
for c in chords:
print " ", c[0], " ", c[1]
I'll add the polygons I'm using, again the first one is solved right away, while the second one has been running for about 10 minutes so far.
FIRST ONE:
202.1177 93.5606
177.3577 159.5286
138.2164 194.8717
73.9028 189.3758
17.8465 165.4303
2.4919 92.5714
21.9581 45.3453
72.9884 3.1700
133.3893 -0.3667
184.0190 38.2951
SECOND ONE:
397.2494 204.0564
399.0927 245.7974
375.8121 295.3134
340.3170 338.5171
313.5651 369.6730
260.6411 384.6494
208.5188 398.7632
163.0483 394.1319
119.2140 387.0723
76.2607 352.6056
39.8635 319.8147
8.0842 273.5640
-1.4554 226.3238
8.6748 173.7644
20.8444 124.1080
34.3564 87.0327
72.7005 46.8978
117.8008 12.5129
162.9027 5.9481
210.7204 2.7835
266.0091 10.9997
309.2761 27.5857
351.2311 61.9199
377.3673 108.9847
390.0396 148.6748
It looks like you have an issue with the inefficient recurision here.
...
def decomp(i, j):
...
for k in range(i+1, j):
...
itok = decomp(i, k)
ktoj = decomp(k, j)
...
...
You've ran into the same kind of issue as a naive recursive implementation of the Fibonacci Numbers, but the way this algorithm works, it'll probably be much worst on the run time. Assuming that is the only issue with you're algorithm, then you just need to use memorization to ensure that the decomp is only calculated once for each unique input.
The way to spot this issue is to print out the values of i, j and k as the triple (i,j,k). In order to obtain a runtime of O(N^3), you shouldn't see the same exact triple twice. However, the triple (22, 24, 23), appears at least twice (in the 25), and is the first such duplicate. That shows the algorithm is calculating the same thing multiple times, which is inefficient, and is bumping up the performance well past O(N^3). I'll leave figuring out what the algorithms actual performance is to you as an exercise. Assuming there isn't something else wrong with the algorithm the algorithm should eventually stop.

Resources