Splitting 61 into integer partitions - algorithm

In a program I am doing, I have a vector called a = [5, 6, 7] and I have to split integer 61 into additive partitions using integer from this list. So one example would be
61 = 5 + 6 + 7 + 7 + 6 + 6 + 6 + 6 + 6 + 6
There are many ways to split this. I have to do this programmatically. One approach I found is as follows. I don't know if this always will give result. First I check if 61 is divisible by any number in the list. If it is, then I can just use that number to add many times (i.e. quotient) to get 61. In this case, 61 is a prime number. So this will fail. Next step is to
take first number in the list (in our case, 5) and subtract it from 61 and try to see if the answer is divisible by any member in the list. If it is, then we again found a way to do addition. In this case, subtracting 5 from 61 gives 56, which is divisible by 7 and our solution would be
61 = 5 + 7 + 7 + 7 + 7 + 7 + 7 + 7 + 7
In this manner we continue down the list until we find some answer after subtraction which is divisible by a member in the list.
Now the given list to me, [5, 6, 7] is such that there exists an integer partition such that, we can get 61 from additions using that integer partition. So we won't have to worry whether a solution exists. So my approach seems very crude. I wonder if there is an efficient way to do this
using some algorithm from combinatorics. So my final answer should be a list
of numbers from the integer partition. So one possible answer would be
[5, 6, 7, 7, 6, 6, 6, 6, 6, 6]
thanks

The generic root of 61 is 7
Multiple of 7 nearing 61 will be 8 hence , subtracting 61-7*8 =gave 56,
Similarly multiple of 6 nearing 61 with a gap of 7 will then be 9,
subtracting 61-6*9 =gave 54,then result % remaining two from {5,7} to be satisfied should be zero
Getting intermediate sum and finding their generic root combined with displacement can give the answer.
Hope this helps. !! Happy to help further

I think I found a crude logic here. Let's say given list is [5, 6, 7] and number is 61. we need to find additive list such that total is 61. one such example is
61 = 5 + 6 + 7 + 7 + 6 + 6 + 6 + 6 + 6 + 6
another would be
61 = 5 + 7 + 7 + 7 + 7 + 7 + 7 + 7 + 7
Our job is to get the numbers on the right side as a list. So one possible solution would be
[5, 6, 7, 7, 6, 6, 6, 6, 6, 6]
My algorithm is as follows. First subtract all list members from 61. So 61 - 5 - 6 - 7 = 43. So we get first three members from the list, which are 5, 6, 7. Now remainder here is 43. To get other members, we subtract each of 5, 6, 7 from 43 , one at a time and see if the answer is divisible by any of 5, 6, 7. So
43 - 5 = 38 -> not divisible by any [5, 6, 7]
43 - 6 = 37 -> not divisible by any [5, 6, 7]
43 - 7 = 36 -> divisible by 6 in [5, 6, 7]
and quotient is 6, which means we have to use 6 of 6's and 7 which we subtracted last from 43. So the list would be original list plus 7 and a
list of 6 with length 6. So one possible solution I found is
[5, 6, 7, 7, 6, 6, 6, 6, 6, 6]
And we can verify that the sum is 61. I wrote a program in R programming language. Here it is
get_me_list <- function(number, mylist){
rest <- number - sum(mylist)
flag = FALSE
for(i in seq_along(mylist)){
answer <- rest - mylist[i]
for(j in seq_along(mylist)) {
if( answer %% mylist[j] == 0){
repeat_factor <- answer / mylist[j]
number_to_repeat <- mylist[j]
pivot <- mylist[i]
flag = TRUE
break
}
}
if(flag){
break
}
}
final_list <- c(mylist, pivot, rep(number_to_repeat, repeat_factor))
final_list
}
So get_me_list function takes two inputs. number and my_list. In my case number = 61 and my_list = [5, 6, 7] . In R, a vector is written as
c(5, 6, 7) or 5:7 if its a sequence from 5 to 7. So the output I get is
c(5, 6, 7, 7, 6, 6, 6, 6, 6, 6)
which is a vector in R. I tried giving various values of my_list and compared the solution with manual solution which I calculated using pen and paper. I am getting correct answer with the above code. I don't know if this approach would be valid always. I am off course assuming that its possible to get the sum equal to number using only the members of the my_list.
Please comment on code.
thanks

Related

given a positive number as a dividend, find out a subset from a given array, so that can get the minimum remainder

Here are some examples:
given number: 31
given array: [4, 5, 6, 7]
then the result subset will be [4] or [5] as 31 = 4 * 4 + 3 * 5, the remainder is 0,
but if given number: 31
given array: [4, 5, 6, 7, 8]
then the result subset will be [7, 8] as 31 = 3 * 8 + 1 * 7, the remainder is 0, which is the minimum one.
or if given number: 67
given array: [4, 5, 6, 9, 10, 12]
then the result subset will be [4, 9] as 67 = 7 * 9 + 1 * 4, the remainder is 0, which is the minimum one.
So what I want to ask is that if there is an algorithm to find out such subset from a given array, so that one can get the minimum remainder...
You can consider this task as variant of coin change problem (having sum and some coin nominals, choose the smallest number of coin to compose the sum).
I might be solved with dynamic programming:
Make array A of size sum, fill A[0] with 0, other entries with extreme large value.
For every coin C walk through array.
Intermediate sum i might be composed using coin C and sum i-C, so check
whether adding C to A[i-C] will diminish number of coin nominals used for A[i] and replace A[i] in positive case.
After all A[sum] will contain the smallest number of nominals. If it contain initial large value, scan lesser entries (A[sum-1] and so on).

"super ugly number" clarification

Write a program to find the nth super ugly number.
Super ugly numbers are positive numbers whose all prime factors are in the given prime list of size k. For example, [1, 2, 4, 7, 8, 13, 14, 16, 19, 26, 28, 32] is the sequence of the first 12 super ugly numbers given primes = [2, 7, 13, 19] of size 4.
I don't understand the question. That is what I need help/clarification on:
In the above statement, why are [1, 2, 4, 7, 8, 13, 14, 16, 19, 26, 28, 32] the first 12 super ugly numbers? How is that related to the given input primes = [2, 7, 13, 19]
2 -> 2
4 -> 2 * 2
7 -> 7
8 -> 2 * 2 * 2
13 -> 13
14 -> 2 * 7
16 -> 2 * 2 * 2 * 2
19 -> 19
26 -> 2 * 13
28 -> 2 * 2 * 7
32 -> 2 * 2 * 2 * 2 * 2
Not sure why 1 is on the list. ;)
Edit: The question statement says that 1 should always be a super ugly number.
You are given a list containing a selection of prime numbers : for example, [2,7,13,19].
What you must do is take each natural integer (1, 2, ...), starting from 1, and calculate its prime factors. If all those prime factors belong to the list of "authorized" prime numbers given above, then the number is declared "super ugly".
For example, the prime factors of 14 are [2, 7], which are all in the reference list ([2,7,13,19]). So, 14 is super ugly.
You job is to find the Nth super ugly number with that method.

Find the maximum number of points per game

The input is an array of cards. In one move, you can remove any group of consecutive identical cards. For removing k cards, you get k * k points. Find the maximum number of points you can get per game.
Time limit: O(n4)
Example:
Input: [1, 8, 7, 7, 7, 8, 4, 8, 1]
Output: 23
Does anyone have an idea how to solve this?
To clarify, in the given example, one path to the best solution is
Remove Points Total new hand
3 7s 9 9 [1, 8, 8, 4, 8, 1]
1 4 1 10 [1, 8, 8, 8, 1]
3 8s 9 19 [1, 1]
2 1s 4 23 []
Approach
Recursion would fit well here.
First, identify the contiguous sequences in the array -- one lemma of this problem is that if you decide to remove at least one 7, you want to remove the entire sequence of three. From here on, you'll work with both cards and quantities. For instance,
card = [1, 8, 7, 8, 4, 8, 1]
quant = [1, 1, 3, 1, 1, 1, 1]
Now you're ready for the actual solving. Iterate through the array. For each element, remove that element, and add the score for that move.
Check to see whether the elements on either side match; if so, merge those entries. Recur on the remaining array.
For instance, here's the first turn of what will prove to be the optimal solution for the given input:
Choose and remove the three 7's
card = [1, 8, 8, 4, 8, 1]
quant = [1, 1, 1, 1, 1, 1]
score = score + 3*3
Merge the adjacent 8 entries:
card = [1, 8, 4, 8, 1]
quant = [1, 2, 1, 1, 1]
Recur on this game.
Improvement
Use dynamic programming: memoize the solution for every sub game.
Any card that appears only once in the card array can be removed first, without loss of generality. In the given example, you can remove the 7's and the single 4 to improve the remaining search tree.

Find local min based on the length of occurences of successive means without falling in wrong min

1. Problem description
I have the following list of values [10, 10, 10, 10, 5, 5, 5, 5, 7, 7, 7, 2, 4, 3, 3, 3, 10] It is shown in the following picture.
What I want to do is find the minimum based on the value of the element and
its duration. From the previous list we can construct the following dictionary (key:val) :[10:4, 5:4, 7:2, 2:1, 4:1, 3:3, 10:1]. Meaning we have 4 sucessive 10s followed by 4 successive 5s, 2 successive 7s and 3 successive 3s.
Based on what I said the local min is 5. But I don't want that The local min should be 3. We didn't select 2 because it happened only once.
Do you have an idea on how we can solve that problem. Is there an existing method that can be used to solve it?
Of course we can sort the dictionary by values [10:4, 5:4, 7:2, 3:3, 10:1] and select the lowest key that has a value different than 1. Is that a good solution?
2. Selection criteria
must be a local min (find_local_min(prices))
must have the highest numbers of succession
the min succession must be > 1
AND I AM STUCK! because now I have 3 as local minimum but it is repeated only 3 times. I was testing if My idea is correct and I tried to find a counter example and I shot my foot
3. source code
the following code extracts the minimums with the dictionary:
#!/usr/bin/env python
import csv
import sys
import os
from collections import defaultdict
def find_local_min(prices):
i = 1
minPrices = []
while i < len(prices):
if prices[i] < prices[i-1]:
minPrices.append(prices[i])
j = i + 1
while j < len(prices) and prices[j] == prices[j-1]:
minPrices.append(prices[j])
j += 1
i = j
else:
i += 1
return minPrices
if __name__ == "__main__":
l = [10, 10, 10, 10, 5, 5, 5, 5, 7, 7, 7, 2,4, 3, 3, 3, 10]
minPrices = find_local_min(l)
minPriceDict = defaultdict(int)
for future in minPrices :
minPriceDict[future] += 1
print minPriceDict
As output if gives the following: defaultdict(<type 'int'>, {2: 1, 3:
3, 5: 4}) Based on this output the algorithm will select 5 as the min
because it is repeated 5 successive times. But that's wrong! it
should be 3. I really want to know how to solve that problem

Equality Between Base 10 and Base 16

From my textbook:
What does it mean when it says 37 subscript(16) = 55 subscript(10)?
It means 37 base 16 (Hexadecimal), and 55 base 10 (Decimal). The 0x preceding a number denotes that it is base 16 hexadecimal.
To see how they are equal lets first look at the place values of 55
5, 5 (digits)
10, 1 (place values)
They are 10 to the power of the number of places over they are so 10^0 = 1 for the ones, and 10^1 = 10 for the tens.
You have a 5 in the ones place giving you 5, and 5 in the tens place giving you 50 when you add them together you get 55.
5 * 10 = 50
5 * 1 = 5
5 + 50 = 55
The 37 is in Hexadecimal which means its base is 16 so the place values are 16 to the power of the number of places over which gives you
3, 7 (digits)
16, 1 (place values)
3 * 16 = 48
7 * 1 = 7
48 + 7 = 55
Because the Hexadecimal system requires 16 unique numerals it uses the letters a-f as well
0, 1, 2, 3, 4, 5, 6, 7, 8, 9, a, b, c, d, e, f
0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15
Also because you might see these 0b denotes base 2 (Binary), and 0o denotes base 8 (Octal).

Resources