Finding the k-th largest number in a vector recursively - recursion

I have an unsorted vector and i want to return the k-th largest number in this vector recursively. There is a way to do this?
Ex: 2 3 41 67 0 9
And I want to return the second largest number which is 41.
Thanks!

Well,
search for the highest number in the vector, remove it from the vector, repeat k times.
In pseudo-code:
function findKthHighestNumber(vetor, k):
i := findIndexOfHighestNumber(vector)
if k = 1:
return vector[i]
else
return findKthHighestNumber(concat(vector[0..i-1], vector[i+1..vector.length]), k-1)
Of course, the actual implementation would depend on the programming language used. Also, findIndexOfHighestNumber should be provided as well, but that's a different task ...

You use a helper like
(define (nth-max vec nth cur-idx cur-max lower-than)
...)
or the same as named let. The logic in it should:
If cur-idx is same as vector-length
A. nth is larger than 1: recur with lower-than as cur-max and reduce nth by 1 and set cur-idx to 0.
B. Else cur-max is the solution.
Recur with cur-idx as cur-max if it's higher than cur-max and lower than lower-than
You can start off lower-than as +Inf.0 and cur-max as first element as -Inf.0. If the result is -Inf.0 then there is no solution.. eg. Find second largest in #(5 5 5 5)

Related

Translating recursion to divide and conquer

I'm trying to return the three smallest items in a list. Below is an O(n) solution I've written:
def three_smallest(L):
# base case
if (len(L) == 3):
return sorted(L)
current = L[0]
(first_smallest,second_smallest,third_smallest) = three_smallest(L[1:])
if (current < first_smallest):
return (current, first_smallest, second_smallest)
elif (current < second_smallest):
return (first_smallest, current, second_smallest)
elif (current < third_smallest):
return (first_smallest, second_smallest, current)
else:
return (first_smallest,second_smallest,third_smallest)
Now I'm trying to write a divide and conquer approach but I'm not sure how I should divide the list. Any help would be appreciated.
Note that this solution (to my understanding) is NOT divide and conquer. It is just a basic recursive solution as divide and conquer involves dividing a list of length n by integer b, and calling the algorithm on those parts.
For divide and conquer you generally want to divide a set (roughly) in half rather than whittle it away one by one. Perhaps the following would meet your needs?
def three_smallest(L):
if (len(L) <= 3): # base case, technically up to 3 (can be fewer)
return sorted(L)
mid = len(L) // 2 # find the midpoint of L
# find (up to) the 3 smallest in first half, ditto for the second half, pool
# them to a list with no more than 6 items, sort, and return the 3 smallest
return sorted(three_smallest(L[:mid]) + three_smallest(L[mid:]))[:3]
Note that due to the inequality in the base case, this implementation does not have a minimum list size requirement.
At the other end of the scale, your original implementation is limited to lists with fewer than a thousand values or it will blow out the recursion stack. The implementation given above was able to handle a list of a million values with no problem.

Calculating the index of an element in non-repetitive permutation

The following question is about math. The matter is, how to calculate the index of an element in a non-repetitive permutation. Example,
A={a,b,c} The permutation is then 3!=6 therefore: (a,b,c);(a,c,b);(b,a,c);(b,c,a);(c,a,b);(c,b,a)
I researched for algorithm to get the index of an element in this permutation. In internet there are only repetitive permutation algorithms.
The index of (b,c,a) is in this zero-based list, obviously 3. Is there an easy way to calculate the position directly by formula ?
I do not need the itertools from python. Because i use very large permutations.(Example 120!) I messed once with python's itertools' permutations function to get the index of an element over the list iterator. But the results were weary. I need a mathematical solution to get the index directly.
Thanks for reading.
Some clues:
You have n! permutations. Note that (n-1)! permutations start from the first element (a), next (n-1)! permutations start from the second element (b) and so on.
So you can calculate the first term of permutation rank as (n-1)! * Ord(P[0]) where Ord gives ordering number of the first element of permutation in initial sequence (0 for a, 1 for b etc).
Then continue with the second element using (n-2)! multiplier and so on.
Don't forget to exclude used elements from order - for your example b is used, so at the second stage c has index 1 rather 0, ad rank is 2!*1 + 1!*1 + 0! * 0 = 3

Recursive method to finding the k element subsets of a set with n elements

Consider the problem of finding the k element subsets of a set with n elements. Write a recursive function that takes an array of integers representing the set, the number of integers in the set (n), and the required subset size (k) as input, and displays all subsets with k elements on the screen. You may assume that the elements in the array have unique values. For example, if the array (set) contains the elements [ 8 2 6 7 ], n is 4, and k is 2, then the output is 82 86 87 26 27 67.
Can you help me with this, at least tell what way should I follow?
The type of thing you're talking about is a **combination&&.
There's a recursive definition of the calculation tucked in the middle of the Wikipedia page.
$$\binom{n}{k}=\binom{n-1}{k-1}+\binom{n-1}{k}$$
Figuring out what your base cases are might be tricky, but I think everything you need is there.
I would've right something like this:
subset ( numbers, n, k, index)
{
if (index < n) // end for the recursion. passed through all elements
{
if (k == 0) // end for the recursion. no more elements needed
print ' '
else
{
print numbers[index]
subset(numbers, n, k-1, index+1) // uses the number in the current index
subset(numbers, n, k, index+1) // doesn't use the number in the current index
}
}
call subset(numbers, n, k, 0) to start
notice that because order doesn't play a role in sets, its enough to pass over the elements in one direction

How to find n as sum of dustinct prime numbers (when n is even number)

This problem gives you a positive integer number which is less than or equal to 100000 (10^5). You have to find out the following things for the number:
i. Is the number prime number? If it is a prime number, then print YES.
ii. If the number is not a prime number, then can we express the number as summation of unique prime numbers? If it is possible, then print YES. Here unique means, you can use any prime number only for one time.
If above two conditions fail for any integer number, then print NO. For more clarification please see the input, output section and their explanations.
Input
At first you are given an integer T (T<=100), which is the number of test cases. For each case you will be given a positive integer X which is less than or equal 100000.
Output
For every test case, print only YES or NO.
Sample
Input Output
3
7
6
10 YES
NO
YES
Case – 1 Explanation: 7 is a prime number.
Case – 2 Explanation: 6 is not a prime number. 6 can be expressed as 6 = 3 + 3 or 6 = 2 + 2 + 2. But you can’t use any prime number more than 1 time. Also there is no way to express 6 as two or three unique prime numbers summation.
Case – 3 Explanation: 10 is not prime number but 10 can be expressed as 10 = 3 + 7 or 10 = 2 + 3 + 5. In this two expressions, every prime number is used only for one time.
Without employing any mathematical tricks (not sure if any exist...you'd think as a mathematician I'd have more insight here), you will have to iterate over every possible summation. Hence, you'll definitely need to iterate over every possible prime, so I'd recommend the first step being to find all the primes at most 10^5. A basic (Sieve of Eratosthenes)[https://en.wikipedia.org/wiki/Sieve_of_Eratosthenes] will probably be good enough, though faster sieves exist nowadays. I know your question is language agnostic, but you could consider the following as vectorized pseudocode for such a sieve.
import numpy as np
def sieve(n):
index = np.ones(n+1, dtype=bool)
index[:2] = False
for i in range(2, int(np.sqrt(n))):
if index[i]:
index[i**2::i] = False
return np.where(index)[0]
There are some other easy optimizations, but for simplicity this assumes that we have an array index where the indices correspond exactly to whether the number is prime or not. We start with every number being prime, mark 0 and 1 as not prime, and then for every prime we find we mark every multiple of it as not prime. The np.where() at the end just returns the indices where our index corresponds to True.
From there, we can consider a recursive algorithm for actually solving your problem. Note that you might feasibly have a huge number of distinct primes necessary. The number 26 is the sum of 4 distinct primes. It is also the sum of 3 and 23. Since the checks are more expensive for 4 primes than for 2, I think it's reasonable to start by checking the smallest number possible.
In this case, the way we're going to do that is to define an auxiliary function to find whether a number is the sum of precisely k primes and then sequentially test that auxiliary function for k from 1 to whatever the maximum possible number of addends is.
primes = sieve(10**5)
def sum_of_k_primes(x, k, excludes=()):
if k == 1:
if x not in excludes and x in primes:
return (x,)+excludes
else:
return ()
for p in (p for p in primes if p not in excludes):
if x-p < 2:
break
temp = sum_of_k_primes(x-p, k-1, (p,)+excludes)
if temp:
return temp
return ()
Running through this, first we check the case where k is 1 (this being the base case for our recursion). That's the same as asking if x is prime and isn't in one of the primes we've already found (the tuple excludes, since you need uniqueness). If k is at least 2, the rest of the code executes instead. We check all the primes we might care about, stopping early if we'd get an impossible result (no primes in our list are less than 2). We recursively call the same function for smaller k, and if we succeed we propagate that result up the call stack.
Note that we're actually returning the smallest possible tuple of unique prime addends. This is empty if you want your answer to be "NO" as specified, but otherwise it allows you to easily come up with an explanation for why you answered "YES".
partial = np.cumsum(primes)
def max_primes(x):
return np.argmax(partial > x)
def sum_of_primes(x):
for k in range(1, max_primes(x)+1):
temp = sum_of_k_primes(x, k)
if temp:
return temp
return ()
For the rest of the code, we store the partial sums of all the primes up to a given point (e.g. with primes 2, 3, 5 the partial sums would be 2, 5, 10). This gives us an easy way to check what the maximum possible number of addends is. The function just sequentially checks if x is prime, if it is a sum of 2 primes, 3 primes, etc....
As some example output, we have
>>> sum_of_primes(1001)
(991, 7, 3)
>>> sum_of_primes(26)
(23, 3)
>>> sum_of_primes(27)
(19, 5, 3)
>>> sum_of_primes(6)
()
At a first glance, I thought caching some intermediate values might help, but I'm not convinced that the auxiliary function would ever be called with the same arguments twice. There might be a way to use dynamic programming to do roughly the same thing but in a table with a minimum number of computations to prevent any duplicated efforts with the recursion. I'd have to think more about it.
As far as the exact output your teacher is expecting and the language this needs to be coded in, that'll be up to you. Hopefully this helps on the algorithmic side of things a little.

How to vectorize complex iterative loop in r

I usually have no problem with vectorization in r, but I am having a tough time in the example below where there are both iterative and non-iterative components in the for loop.
In the code below, I have a calculation that I have to perform based on a set of constants (Dini), a vector of values (Xs), where the ith value of the output vector (Ys) is also dependent on i-1 value:
Dini=128 #constant
Xs=c(6.015, 5.996, 5.989, 5.911, 5.851, 5.851, 5.858, 5.851)
Y0=125.73251 #starting Y value
Ys=c(Y0) #starting of output vector, first value is known
for (Vi in Xs[2:length(Xs)]){
ytm1=Ys[length(Ys)]
y=(955.74301-2*((Dini+ytm1-Vi)^2-ytm1^2)^0.5+2*ytm1*acos(ytm1/(Dini+ytm1-Vi)))/pi/2
Ys=c(Ys, y)
}
df=data.frame(Xs, Ys)
df
Xs Ys
1 6.015 125.7325
2 5.996 125.7273
3 5.989 125.7251
4 5.911 125.7036
5 5.851 125.6859
6 5.851 125.6849
7 5.858 125.6868
8 5.851 125.6850
For this case, where there is a mix of both iterative and non iterative components in the for loop, my mind has got twisted in a non-vectorized knot.
Any suggestions?
You might want to look into use Reduce in this case. For example
Ys<-Reduce(function(prev, cur) {
(955.74301-2*((Dini+prev-cur)^2-prev^2)^0.5 + 2*prev*acos(prev/(Dini+prev-cur)))/pi/2
}, Xs, init=Y0, accumulate=T)[-1]
From the ?Reduce help page: "Reduce uses a binary function to successively combine the elements of a given vector and a possibly given initial value." This makes it easier to create vectors where a given value depends on a previous value.

Resources