Can 0 and 1 come together in other positions of the Pisano Period except the first two positions? I am trying to solve a problem where it’s needed to know the Pisano Period length. So I was thinking about searching 0 and 1 in the period.
Yes, if 0 and 1 are adjacent, you're at a point where the sequence is repeating.
A quick proof idea: suppose that you find 0 and 1 adjacent to one another in a Fibonacci sequence mod some number n. In other words, you've found some positions k and k+1 in the sequence such that the kth position is equal to F0 mod n and the (k+1)st position is equal to F1 mod n. That means that position k+2 is equal to F0 + F1 = F2 mod n, and the position after that is equal to F1 + F2 = F3 mod n, etc. This means that if you see 0 and 1 adjacent in the sequence, what follows must be equivalent to the sequence of numbers that you'd find if you started the Fibonacci sequence again from scratch.
Hope this helps!
Here's a quick Python code to determine the Pisano Period
def pisanoPeriod(m):
previous, current = 0, 1
for i in range(0, m * m):
previous, current \
= current, (previous + current) % m
# A Pisano Period starts with 01
if (previous == 0 and current == 1):
return i + 1
Related
Problem : 5 monkeys, 5 snakes and 5 tigers are standing in a line in a grocery store, with animals of the same species being indistinguishable. A monkey stands in the front of the line, and a tiger stands at the end of the line. Unfortunately, tigers and monkeys are sworn enemies, so monkeys and tigers cannot stand in adjacent places in line. Compute the number of possible arrangements of the line.
Solving this problem by hand is daunting. I want to write a program to output the possible arrangements and also count the total arrangements. My first thought was to use a brute force. Monkeys, snakes, and tigers can be represented by the letters M, S, and T respectively. With 1 M at start of string and 1 T at the end, there are 13!/(4!4!5!) = 90,090 possibilities. I would then remove arrangements that do not satisfy the second condition about adjacency.
My second thought was to first compute the number of arrangements where M and T are adjacent and then subtract this number from 90,090. I am new to programming so I am not sure how to do this.
Is there a better way to approach these types of problems? Any hints?
Thank you.
TL;DR: python solution using sympy
import sympy # sympy.ntheory.multinomial_coefficients
import math # math.comb
def count_monkeytigers(n_monkeys, n_snakes, n_tigers):
return sum(
m * math.comb(n_monkeys - 1, mb_minus1) * math.comb(n_tigers - 1, tb_minus1)
for (mb_minus1, eb, tb_minus1), m in
sympy.ntheory.multinomial_coefficients(3, n_snakes-1).items()
)
Explanation
We already know that there is an M at the beginning, a T at the end, and five S in the string:
M?? S ?? S ?? S ?? S ?? S ??T
Since M and T cannot be adjacent, and the only way to separate them is with an S, you can think of the S as separators; the five S are cutting the string into 6 "bins". Every bin can either be empty, or contain one or more M, or contain one or more T. Furthermore, the first bin contains at least an M, and the last bin contains at least a T.
To count all permutations of the string, we can do the following:
Loop over the triplets (monkey_bins, empty_bins, tiger_bins) deciding how many bins have monkeys, are empty, or have tigers;
For the loop, we can use bounds 1 <= monkey_bins <= 5; 0 <= empty_bins <= 5 - monkey_bins; tiger_bins = 6 - monkey_bins - empty_bins;
Count the number m of ways to choose monkey_bins bins, empty_bins bins and tiger_bins bins among 6 bins (Multinomial coefficient);
Count the number monkey_partitions of ways to place n_monkeys 'M' into monkey_bins bins with at least one M per bin (Stars and bars theorem 1);
Count the number tiger_partitions of ways to place n_tigers 'T' into tiger_bins bins with at least one T per bin (Stars and bars theorem 1;
Add m * monkey_partitions * tiger_partitions to the count.
Python code with loops
import math
def multinomial(*params):
return math.prod(math.comb(sum(params[:i]), x) for i, x in enumerate(params, 1))
def count_monkeytigers(n_monkeys, n_snakes, n_tigers):
result = 0
for monkey_bins in range(1, n_snakes + 1):
for empty_bins in range(0, n_snakes + 1 - monkey_bins):
tiger_bins = n_snakes + 1 - monkey_bins - empty_bins
m = multinomial(monkey_bins - 1, empty_bins, tiger_bins - 1) # nb permutations of the 3 types of bins
monkey_partitions = math.comb(n_monkeys - 1, monkey_bins - 1)
tiger_partitions = math.comb(n_tigers - 1, tiger_bins - 1)
result += m * monkey_partitions * tiger_partitions
return result
print(count_monkeytigers(5, 5, 5))
# 1251
print(count_monkeytigers(2,2,2))
# 3
# = len(['MMSSTT', 'MSMSTT', 'MMSTST'])
The code for multinomial comes from this question:
Does python have a function which computes multinomial coefficients?
Note that we're only using a "trinomial" coefficient here, so you can replace function multinomial with this simpler function if you want:
def trinomial(k1,k2,k3):
return math.comb(k1+k2+k3, k1) * math.comb(k2+k3, k2)
Python code using sympy
In the previous python code, we're manually looping over the possible triplets (monkey_bins, empty_bins, tiger_bins) and using the corresponding binomial coefficients. As it turns out, sympy.ntheory.multinomial_coefficients(m, n) returns a dictionary that contains specifically those triplets as keys and the corresponding multinomial coefficients as values!
We can use that to shorten our code:
import sympy # sympy.ntheory.multinomial_coefficients
import math # math.comb
def count_monkeytigers(n_monkeys, n_snakes, n_tigers):
return sum(
m * math.comb(n_monkeys - 1, mb_minus1) * math.comb(n_tigers - 1, tb_minus1)
for (mb_minus1, eb, tb_minus1), m in
sympy.ntheory.multinomial_coefficients(3, n_snakes-1).items()
)
print(count_monkeytigers(5, 5, 5))
# 1251
print(count_monkeytigers(2,2,2))
# 3
# = len(['MMSSTT', 'MSMSTT', 'MMSTST'])
Note that the dictionary multinomial_coefficients(3, n) contains all triplets of nonnegative numbers summing to n, including those where the middle-element empty_bins is equal to n, and the other two elements are 0. But we want at least one bin with monkeys, and at least one bin with tigers; hence I called the triplet (mb_minus1, eb, tb_minus1) rather than (mb, eb, tb), and accordingly I used n_snakes-1 rather than n_snakes+1 as the sum of the triplet.
Before writing code directly , Just solve the question on paper upto the factorial notations , then you can easily find factorial in Code
At first , fix 1 monkey at front and 1 tiger at end .
Then try to fix remaining tigers , then fix snakes in adjancent of tigers , Atleast one snake must be in adjacent of a tiger and then fix monkeys in adjacent of snakes
x <- c(2,5,4,3,9,8,11,6)
count <- 0
for (val in x) {
if (val %% 2 == 0) {
count <- count + 1
}
} print(count)
# [1] 4
I do not get why it is 4 and not 5, could someone give me a hint?
So from x <-c(2,5,4,3,9,8,11,6), there are only four numbers in which the remainder will be 0 when divided by 2.
Knowing that, let's look at what each part of the code does. You are defining a variable count and assigning it the value of 0. Already from the beginning, count starts at 0. The next line is a for loop. What the loop does is go through each value of x (recall that x <-c(2,5,4,3,9,8,11,6)). Now, the if statement says that for each value of x, if the value is divisible by 2 and has no remainder, add 1 to count (which is why you have the line count <- count + 1, you are adding 1 to count, which started at zero, and reassigning the new value to count - think of it as rewriting the value of count, replacing it). Now there are four values in x that are divisible by 2 and have a remainder of zero, so doing the math: 0 + 4 = 4. You should get:
print(count)
[1] 4
Hope this helps explain every aspect of the code. I highly recommend you understand and read about for loops, if statements, and overall just any R basics. There are several tutorials online explaining all these components.
I am writing a solution for the following problem.
A is a list containing all elements 2^I * 3^Q where I and Q are integers in an ascending order.
Write a function f such that:
f(N) returns A[N]
The first few elements are:
A[0] = 1
A[1] = 2
A[2] = 3
A[3] = 4
A[4] = 6
A[5] = 8
A[6] = 9
A[7] = 12
My solution was to generate a list containing the first 225 elements by double looping in 15 times each, then sorted this list and return A[N]
Is there any way to generate the N'th element of this sequence without creating and sorting a list first?
Here are two approaches that solve your problem without creating such a large list. Each approach has its disadvantages.
First, you could set a counter to 0. Then scan all the integers from 1 on up. For each integer, divide out all the multiples of 2 and of 3 in its factorization. If 1 remains, increment the counter; otherwise, leave the counter unchanged. When the counter reaches N you have found the value of A[N]. For example, you increase the counter for integers 1, 2, 3, and 4, but not for 5. This approach uses very little memory but would take much time.
A second approach uses a min priority queue, such as Python's heapq. Again, set a counter to zero, but also initialize the priority queue to hold only the number 1 and note that the highest power of 3 seen so far is also 1. Increment the counter then peek at the minimum number in the queue. If the counter is N you just got your value of A[N]. Otherwise, pop that min value and immediately push double its value. (The pop and push can be done in one operation in many priority queues.) If that value was a the highest power of 3 seen so far, also push three times its value and note that this new value is now the highest power of 3.
This second approach uses a priority queue that takes some memory but the largest size will only be on the order of the square root of N. I would expect the time to be roughly equal to your sorting the large list, but I am not sure. This approach has the most complicated code and requires you to have a min priority queue.
Your algorithm has the advantage of simplicity and the disadvantage of a large list. In fact, given N it is not at all obvious the maximum powers of 2 and of 3 are, so you would be required to make the list much larger than needed. For example, your case of calculating "the first 225 elements by double looping in 15 times each" actually only works up to N=82.
Below I have Python code for all three approaches. Using timeit for N=200 I got these timings:
1.19 ms for sorting a long list (your approach) (powerof2=powerof3=30)
8.44 s for factoring increasing integers
88 µs for the min priority queue (maximum size of the queue was 17)
The priority queue wins by a large margin--much larger than I expected. Here is the Python 3.6.4 code for all three approaches:
"""A is a list containing all elements 2^I * 3^Q where I and Q are
integers in an ascending order. Write a function f such that
f(N) returns A[N].
Do this without actually building the list A.
Based on the question <https://stackoverflow.com/questions/49615681/
generating-an-item-from-an-ordered-sequence-of-exponentials>
"""
import heapq # min priority queue
def ordered_exponential_0(N, powerof2, powerof3):
"""Return the Nth (zero-based) product of powers of 2 and 3.
This uses the questioner's algorithm
"""
A = [2**p2 * 3**p3 for p2 in range(powerof2) for p3 in range(powerof3)]
A.sort()
return A[N]
def ordered_exponential_1(N):
"""Return the Nth (zero-based) product of powers of 2 and 3.
This uses the algorithm of factoring increasing integers.
"""
i = 0
result = 1
while i < N:
result += 1
num = result
while num % 2 == 0:
num //= 2
while num % 3 == 0:
num //= 3
if num == 1:
i += 1
return result
def ordered_exponential_2(N):
"""Return the Nth (zero-based) product of powers of 2 and 3.
This uses the algorithm using a priority queue.
"""
i = 0
powerproducts = [1] # initialize min priority queue to only 1
highestpowerof3 = 1
while i < N:
powerproduct = powerproducts[0] # next product of powers of 2 & 3
heapq.heapreplace(powerproducts, 2 * powerproduct)
if powerproduct == highestpowerof3:
highestpowerof3 *= 3
heapq.heappush(powerproducts, highestpowerof3)
i += 1
return powerproducts[0]
x and y are integers greater than 1.
A Special number can be expressed as x^y.
Note that the special number sequence is in ascending order (4, 8, 9, 16, 25, 27, 32, ...).
Given an integer i, the program should return the ith special number.
i=0 -> num=4
i=4 -> num=25
Would like some insights. Faced this in a coding round for a company. Brute force ended up with TLEs.
Edit 1: Found a link: https://codegolf.stackexchange.com/questions/78985/find-the-n-th-perfect-power.
Edit-2: I shared the codegolf link to help check some of the solutions that are already available and are expected to exceed the time limit. I tried both with the Mathematica solution and the sage solution approach, faced TLE on both of them.
This problem is equivalent to finding an integer j where log_j k is an integer, and j is in a sequence with an upper bound k such that sum [floor(log_j k) - 1 | j <- [2..floor(sqrt k)] == i
We can make a rough estimate of where the ith element would be by binary search with a limited iteration. If we guess the number at m^2, the highest base that may be counted is:
m
Then we can examine lower bases and add up their log counts. For example, i = 10:
Guess: 10^2
Highest base: 10
Then at minimum we have (10 - 1) + (floor(log2 (10^2)) - 1)
= 15 elements. Too many.
Guess: 5^2
Highest base: 5
Minimum element count: (5 - 1) + (floor(log2 (5^2)) - 1) = 8
Iterate over logs:
-- Because of the exponential nature of the problem,
-- if the guess is too large, the bulk of the elements will appear
-- early in the iteration; and if it's too small, the limit on
-- exponents will drop early allowing for early exit in either case.
[floor(logBase x 25) - 1 | x <- [2..4]] = [3,1,1]
sum ([1] ++ [3,1,1]) = 6. Too few.
Guess: 7^2
Highest base: 7
Minimum element count: (7 - 1) + (floor(log2 (7^2)) - 1) = 10
Iterate over logs:
[floor(logBase x 49) - 1 | x <- [2..6]] = [4,2,1,1,1]
sum ([1] ++ [4,2,1,1,1]) = 10
Answer: 7^2
For example,
n = 4 (4x1) 1 way
n = 10 (4x1, 6x1) (10x1) 2 ways
Is there any equation can express the number of way?
You have used recurrence-relation tag - yes, it is possible to use recurrence to calculate the number of ways.
P(N) = P(N-10) + P(N-6) + P(N-4)
P(0) = 1
Explanation - you can get sum N, using (N-10) cents sum and 10-cent coin and so on.
For rather large values of N recursive algorithm will work too long, so one could build dynamic programming algorithm to accelerate calculations (DP will reuse calculated values for smaller sums)
Suppose you have a list of denominations. In your case it is A = [4,6,10]. So suppose you have the following things:
A = [4,6,10]
Length of list A = N
Sum = K
The problem can be written as:
# Given the list of denominations, its length and the sum.
P(A,N,K) = 0 if N < 0 or K < 0,
1 if K = 0,
P(A,N-1,K) + P(A,N-1,k-A[N]) #A[N]-> Nth element of list
As we can see the possibility of re-using sub-problems, DP will work wonderfully.