Ways to fill a hole of length L with sticks of lengths s and t - permutation

I need help to modify the solution I came up with for a programming challenge. The problem statement says as follows:
Martin the zebra of Madagascar (the movie) wants to fill the hole that's left to cover in the floor of the hut that is building in the edge of the beach. The hole has length L and Martin has many pieces of wood, some with length s and others with length t. As Martin is very distracted he wants to know in how many ways the hole can be filled by putting pieces of wood at will.
Input specification
The only line of input contains three integers L, s and t separated with a space (1 <= L, s, t <= 10^6, s != t).
Output specification
A line with the number of different ways to fill the hole modulo 10^9 + 7 (1000000007).
Sample input
6 2 3
Sample output
2
The solution I submitted, uses this function to count:
#include <iostream>
#include <vector>
using namespace std;
int ** create(int n, int m) {
int ** a = new int*[
for (int i = 0; i < n; i++) {
a[i] = new int[m];
a[i][0] = 1; // I assumed there is one way to fill a hole of length zero
}
return a;
}
int count(vector<int> stick, int n, int m) { // Counts ways to fill the hole
int ** fill = create(n + 1, m + 1);
for (int i = 1; i <= n; i++)
for (int j = 1; j <= m; j++)
if (j < stick[i - 1])
fill[i][j] = fill[i - 1][j] % 1000000007;
else
fill[i][j] = (fill[i - 1][j] + fill[i][j - stick[i - 1]]) % 1000000007;
return fill[n][m];
}
int main() {
int l, a, b;
cin >> l >> a >> b;
vector<int> stick{a, b};
cout << count(stick, stick.size(), l) << endl;
return 0;
}
The problem is that this only counts the different sets that can fill the hole completely, for example:
Say we have a hole of length L = 6 and sticks of lengths s = 1 and t = 2, my function returns 4. This are the four sets that my function is counting:
{1, 1, 1, 1, 1, 1}
{1, 1, 1, 1, 2}
{1, 1, 2, 2}
{2, 2, 2}
But what it's required are all the permutations of this sets, hence this should return 13, that is:
{1, 1, 1, 1, 1, 1}
{1, 1, 1, 1, 2}
{1, 1, 1, 2, 1}
{1, 1, 2, 1, 1}
{1, 2, 1, 1, 1}
{2, 1, 1, 1, 1}
{1, 1, 2, 2}
{1, 2, 1, 2}
{2, 1, 1, 2}
{1, 2, 2, 1}
{2, 1, 2, 1}
{2, 2, 1, 1}
{2, 2, 2}
How can I modify my function to count all the permutations? Is there any material that can help me understand how to build a dynamic programming solutions for this kind of problems?

let d[i] - number of ways to fill the hole of length i
then d[i] = d[i-s] + d[i-t]
d[0] = 1
d[i < 0] = 0 obviously

Related

How can I reduce the execution time in this code?

Problem
Consider the sequence D of the last decimal digits of the first N Fibonacci numbers, i.e. D = (F0%10,F1%10,…,FN−1%10).
Now, you should perform the following process:
Let D=(D1,D2,…,Dl)
If l=1, the process ends.
Create a new sequence
E=(D2,D4,…,D2⌊l/2⌋)
In other words, E is the sequence created by removing all odd-indexed elements from D
Change D to E
When this process terminates, the sequence D
contains only one number. You have to find this number.
Input
The first line of the input contains a single integer T
denoting the number of test cases.
The description of T test cases follows.
The first and only line of each test case contains a single integer N
Output
For each test case, print a single line containing one integer ― the last remaining number.
Code
#include <stdio.h>
#include <stdlib.h>
int test(int *arr, int n);
int main() {
int t;
scanf("%d", &t);
while (t--) {
int n;
scanf("%d", &n);
int *arr;
arr = (int *)malloc((n + 1) * sizeof(int));
arr[1] = 0;
arr[2] = 1;
for (int i = 3; i <= n; i++) {
arr[i] = arr[i - 1] + arr[i - 2];
}
/*
for(int k=1;k<=n;k++){
printf("%d ",arr[k] );
}
printf("\n");
*/
printf("%d\n", (test(arr, n)) % 10);
}
}
int test(int *arr, int n) {
if (n == 1) {
return arr[1];
} else {
for (int i = 1; i <= (n / 2); i++) {
arr[i] = arr[2 * i];
}
return test(arr, n / 2);
}
}
Using the algorithm from https://math.stackexchange.com/questions/681674/recursively-deleting-every-second-element-in-a-list,
Find the largest integer A, such that 2^A < N.
Find Fibonnaci(2^A - 1) % 10
Adding to Bill Lynch's answer, which is itself based on this other answer by happymath:
You will always end up getting 2n − 1 where n is maximum integer such that 2n < K
I'd like to point out another useful mathematical property.
In number theory, the nth Pisano period, written π(n), is the period with which the sequence of Fibonacci numbers taken modulo n repeats.
(https://en.wikipedia.org/wiki/Pisano_period)
Here we need to consider the case where n = 10, π(10) = 60 and the last decimal digits correspond to the OEIS sequence A003893:
0, 1, 1, 2, 3, 5, 8, 3, 1, 4, 5, 9, 4, 3, 7, 0, 7, 7, 4, 1, 5, 6, 1, 7, 8, 5, 3, 8, 1, 9, 0, 9, 9, 8, 7, 5, 2, 7, 9, 6, 5, 1, 6, 7, 3, 0, 3, 3, 6, 9, 5, 4, 9, 3, 2, 5, 7, 2, 9, 1
So that there's no need to calculate the actual Fibonacci number, nor to generate all the sequence up to N.

What is the minimum number of swaps needed so that the difference of sums of arrays a and b is minimum?

Given 2 arrays of integers a[] and b[] with the same size of n (1 <= n <= 100) numbered from 1 to n.
(0 <= a[i], b[i] <= 6)
You can swap any a[i] with b[i].
What is the minimum number of swaps needed so that the difference of the sums of array a[] and b[] is minimum ?
Then print out:
The number of swaps
The swapped indexes
The difference of sums of both arrays
Example
n = 6
a[] = { 1, 1, 4, 4, 0, 6 }
b[] = { 6, 3, 1, 1, 6, 1 }
Result
- 2 (The number of swaps)
- 5, 6 (The swapped indexes)
- 0 (The difference of sums of the arrays)
Explanation
If you swap a[5] with b[5] and a[6] with b[6] which requires 2 swaps, arrays a[] and b[] will become:
a[] = {1, 1, 4, 4, 6, 1}
b[] = {6, 3, 1, 1, 0, 6}
Sum of a[] is 1 + 1 + 4 + 4 + 6 + 1 = 17
Sum of b[] is 6 + 3 + 1 + 1 + 0 + 6 = 17
So the difference of the two sums is 0.
Here's an iterative method that saves the differences so far and updates the smallest list of indexes needed to swap to achieve them.
JavaScript code:
function update(obj, d, arr){
if (!obj[d] || obj[d].length > arr.length)
obj[d] = arr;
}
function f(A, B){
let diffs = {0: []};
for (let i=0; i<A.length; i++){
const newDiffs = {};
for (d in diffs){
// Swap
let d1 = Number(d) + B[i] - A[i];
if (diffs.hasOwnProperty(d1) && diffs[d1].length < diffs[d].length + 1)
update(newDiffs, d1, diffs[d1]);
else
update(newDiffs, d1, diffs[d].concat(i+1));
d1 = Number(d) + A[i] - B[i];
if (diffs.hasOwnProperty(d1) && diffs[d1].length < diffs[d].length)
update(newDiffs, d1, diffs[d1]);
else
update(newDiffs, d1, diffs[d]);
}
diffs = newDiffs;
}
console.log(JSON.stringify(diffs) + '\n\n');
let best = Infinity;
let idxs;
for (let d in diffs){
const _d = Math.abs(Number(d));
if (_d < best){
best = _d;
idxs = diffs[d];
}
}
return [best, idxs];
};
var A = [1, 1, 4, 4, 0, 6];
var B = [6, 3, 1, 1, 6, 1];
console.log(JSON.stringify(f(A, B)));
Here's a C++ implementation of mine based on Javascript answer of גלעד ברקן.
Short Explanation:
We maintain a mapping of all differences and their minimum swaps seen so far and try to extend all of the differences seen so far based on new values to get new mapping of such kind. We have 2 choices at each step when considering ith items in A and B, either consider the items as it is or swap the ith items.
Code:
#include <iostream>
#include <climits>
#include <unordered_map>
#include <vector>
using namespace std; // Pardon me for this sin
void update_keeping_existing_minimum(unordered_map<int, vector<int> >& mp, int key, vector<int>& value){
if(mp.find(key) == mp.end() || mp[key].size() > value.size())mp[key] = value;
}
// Prints minimum swaps, indexes of swaps and minimum difference of sums
// Runtime is O(2^size_of_input) = 2^1 + 2^2 .. + 2^n = 2*2^n
// This is a bruteforce implementation.
// We try all possible cases, by expanding our array 1 index at time.
// For each previous difference,
// we use new index value and expand our possible difference outcomes.
// In worst case we may get 2 unique differences never seen before for every index.
void get_minimum_swaps(vector<int>& a, vector<int>& b){
int n = a.size();
unordered_map<int, vector<int> > prv_differences_mp;
prv_differences_mp[0] = {}; // initial state
for(int i = 0 ; i < n ; i++){
unordered_map<int, vector<int> > new_differences_mp;
for (auto& it: prv_differences_mp) {
// possibility 1, we swap and expand previous difference
int d = it.first;
int d1 = d + b[i] - a[i];
if(prv_differences_mp.find(d1) != prv_differences_mp.end() && prv_differences_mp[d1].size() < (prv_differences_mp[d].size() + 1)){
update_keeping_existing_minimum(new_differences_mp, d1, prv_differences_mp[d1]);
} else {
// only place we are modifying the prv map, lets make a copy so that changes don't affect other calculations
vector<int> temp = prv_differences_mp[d];
temp.push_back(i+1);
update_keeping_existing_minimum(new_differences_mp, d1, temp);
}
// possibility 2, we don't swap and expand previous difference
int d2 = d + a[i] - b[i];
if(prv_differences_mp.find(d2) != prv_differences_mp.end() && prv_differences_mp[d2].size() < prv_differences_mp[d].size()){
update_keeping_existing_minimum(new_differences_mp, d2, prv_differences_mp[d2]);
} else {
update_keeping_existing_minimum(new_differences_mp, d2, prv_differences_mp[d]);
}
}
cout<<i<<":index\n";
for(auto& it: prv_differences_mp){
cout<<it.first<<": [ ";
for(auto& item: it.second)cout<<item<<" ";
cout<<"] ; ";
}
cout<<"\n";
prv_differences_mp = new_differences_mp;
}
int best = INT_MAX;
vector<int> min_swap_ans;
for(auto& it: prv_differences_mp){
int _d = it.first >= 0 ? it.first: -it.first;
if(_d < best){
best = _d;
min_swap_ans = it.second;
}
}
cout<<"Number of swaps: "<<min_swap_ans.size()<<"\n";
cout<<"Swapped indexes:\n";
for(auto idx: min_swap_ans)cout<<idx<<" ";
cout<<"\nDifference: "<<best<<"\n";
}
int main(){
vector<int> A{ 1, 1, 4, 4, 0, 6 };
vector<int> B{ 6, 3, 1, 1, 6, 1 };
get_minimum_swaps(A, B);
return 0;
}

Making sure a user's input matches characters generated by my program

This is for Homework
I'm programming a simplified game of scrabble where I have my program randomly generate characters then the user would try and create a word from those generated characters, then get a score afterwards. The issue I'm having is making sure the user is actually using the characters provided. I have no clue on how to approach this problem. I don't need any code but hints would be appreciated or even links for a point to start at. Thanks for any help!
EDIT - About half my program [The part that creates the letter set]
void generate_letter_set(int letter_set[] , int size_let , int num_let)
{
int arr[N];
const char let[] =
{'K','J','X','Q','Z','B','C','M','P','F','H','V','W','Y','G','L','S','U','D','N','R','T','O','A','I','E'};
const int freq[] =
{ 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 3, 4, 4, 4, 4, 6, 6, 6, 8, 9, 9, 12 };
int score[] =
{ 5, 8, 8, 10, 10, 3, 3, 3, 3, 4, 4, 4, 4, 4, 2, 1, 1, 1, 2, 1, 1, 1, 1, 1, 1, 1};
int index = 0;
for(int i = 0 ; i < 26 ; i++) {
for(int f = 0 ; f < freq[i]; f++) {
arr[index++] = let[i]; //All the 96 letters are stored in let[i]
//printf("%c " , let[i]); // Created the letter bank for all the letters
}
} int letter;
printf("Your letters are: ");
for(int l = 0; l < 7; l++){
letter = rand() % 97;
printf("%c ", arr[letter]);
}
}
There are a lot of different ways to search an array for certain characters. The basis of what you need is a very simple search function.
One simple solution would be to use two nested for loops. Assuming let[] is your 'haystack' to check and word is your user input:
// Check each letter of word[]...
for (int ii = 0; ii <= lengthOfUserInput; ii++)
{
char characterToValidate = word[ii];
// ... for not existing in let[]
for (int jj = 0; jj <= lengthOfStringOfValues; jj++)
{
if (characterToValidate != let[jj])
}
}

Replace number by sum of other numbers in a list without subtraction

I was asked:
Replace each number in a list by sum of remaining elements, the list is not sorted.
So suppose if we have a list of numbers like {2, 7, 1, 3, 8}, now we are to replace each element with sum of rest of elements. The output should be:
{(7 + 1 + 3 + 8), (2 + 1 + 3 + 8), (2 + 7 + 3 + 8), (2 + 7 + 1 + 8), (2 + 7 + 1 + 3)}
== {19, 14, 20, 18, 13}
I answered an obvious solution:
First evaluate sum of all numbers then subtract each element from sum.
So for above list sum is 2 + 7 + 1 + 3 + 8 = 21, then for output do like:
{sum - 2, sum - 7, sum - 1, sum - 3, sum - 8}
{21 - 2, 21 - 7, 21 - 1, 21 - 3, 21 - 8}
== {19, 14, 20, 18, 13}
It needs only two iterations of list.
Then Interviewer asked me: Now do it without subtraction? and I couldn't answer :(
Is other solution possible? Can some share any other trick? A better trick is possible?
Lets extra memory space can be used (I asked after a few minutes of try, even then I couldn't answer).
One possibility would be to compute prefix and suffix sums of your array and then combine the appropriate entries. This would still be O(n) but needs more memory space so I think your original method is better.
In other words, from {2, 7, 1, 3, 8} compute {2, 2+7, 2+7+1, 2+7+1+3, 2+7+1+3+8} and {2+7+1+3+8, 7+1+3+8, 1+3+8, 3+8, 8} and then add the appropriate entries.
The solution is to sum everything but the element. Then you don't have to subtract after the fact. You just skip adding the element at the current index.
Alternatively, you could get a subset of the list that excludes the element at the current index, then just sum the subset together. Pretty much the same thing as my first suggestion with more implementation detail.
C++ implementation. O(n) and done by keeping sums of all elements before and after a certain index.
#include <iostream>
int main() {
int a[] = {2,7,1,3,8};
int prefix[5]; // Sum of all values before current index
int suffix[5]; // Sum of all values after current index
prefix[0] = 0;
suffix[4] = 0;
for(int i = 1; i < 5; i++) {
prefix[i] = prefix[i-1] + a[i-1];
suffix[4 - i] = suffix[4 - i + 1] + a[4 - i + 1];
}
// Print result
for (int i = 0; i < 5; i++) {
std::cout << prefix[i] + suffix[i] << " ";
}
std::cout << std::endl;
}
I can't think anything better than yours.
But how about this :
Create a (n-1)xn matrix:
[ 2, 7, 1, 3, 8 ]
| 7, 1, 3, 8, 2 | rotate by 1
| 1, 3, 8, 2, 7 | by 2
| 3, 8, 2, 7, 1 | by 3
| 8, 2, 7, 1, 3 | by 4
Then Sum up the columns
C++'s std::rotate_copy can be used to create matrix
std::vector<int> v1 {2, 7, 1, 3, 8 };
std::vector<int> v2 (v1.size());
int i,j;
std::vector< std::vector<int> > mat;
for (int i=1; i<v1.size();++i){
std::rotate_copy(v1.begin(),v1.begin()+i,v1.end(),v2.begin());
mat.push_back(v2);
}
for(j=0;j<v1.size();++j)
for(i=0;i<v1.size()-2;++i)
v2[j]+=mat[i][j];
for(i=0;i<v2.size();++i)
std::cout<<v2[i]<<" ";
#include <iostream.h>
#include <stdio.h>
int main() {
int a[] = {2,7,1,3,8};
int sum[5]={0};
for(int j = 0; j < 5; j++){
for(int i = 1; i < 5; i++) {
sum[j]=sum[j]+a[(j+i+5)%5];
}
printf("%d ", sum[j]); }
}
Instead of subtracting the element you can add the element multiplied by -1. Multiplication and addition are allowed operations, I guess.

Interview test - rearrange the array [duplicate]

This question already has answers here:
Closed 11 years ago.
Possible Duplicate:
Reordering of array elements
In given array of elements like [a1,a2,a3,..an,b1,b2,b3,..bn,c1,c2,c3,...cn] Write a program to merge them like [a1,b1,c1,a2,b2,c2,...an,bn,cn].
We have to do it in O(1) extra space.
Sample Testcases:
Input #00:
{1,2,3,4,5,6,7,8,9,10,11,12}
Output #00:
{1,5,9,2,6,10,3,7,11,4,8,12}
Explanation:
Here as you can notice, the array is of the form
{a1,a2,a3,a4,b1,b2,b3,b4,c1,c2,c3,c4}
EDIT:
I got it in Amazon placement test. Have been trying it for a long time.
PLease provide psuedo code. What i tried is finding new position p for second element e(1st is already at correct position), inserting e at p and repeating the same for the old element at position p. But this is ending in a cycle.
I tried detecting cycle and incrementing the starting position by 1. But even this is not working.
EDIT2:
#include <iostream>
using namespace std;
int pos(int i, int n)
{
if(i<n)
{
return 3*i;
}
else if(i>=n && i<2*n)
{
return 3*(i-n) + 1;
}
else if(i>=2*n && i<3*n)
{
return 3*(i-2*n) + 2;
}
return -1;
}
void printn(int* A, int n)
{
for(int i=0;i<3*n;i++)
cout << A[i]<<";";
cout << endl;
}
void merge(int A[], int n)
{
int j=1;
int k =-1;
int oldAj = A[1];
int count = 0;
int temp;
while(count<3*n-1){
printn(A,n);
k = pos(j,n);
temp = A[k];
A[k] = oldAj;
oldAj = temp;
j = k;
count++;
if(j==1) {j++;}
}
}
int main()
{
int A[21] = {1,4,7,10,13,16,19,2,5,8,11,14,17,20,3,6,9,12,15,18,21};
merge(A,7);
cin.get();}
This is the so called in-place in-shuffle algorithm, and it's an extremely hard task if you want to do it efficiently. I'm just posting this entry so people don't post their so called "solutions" claiming that it can be extended to work with O(1) space, without any proof...
Here is a paper for a simpler case when the list is in the form: a1 a2 a3 ... an b1 b2 b3 .. bn:
http://arxiv.org/PS_cache/arxiv/pdf/0805/0805.1598v1.pdf
Here's is a description of an algorithm with 3 elements of extra space and O(n^2) complexity:
sa, sb, sc are, respectively, next source index for a, b and c sequences.
d is the copy destination index.
On each iterarion:
Copy elements at sa, sb and sc to temporary storage
Shift the array elements to the left to fill in the now vacant indices sa, sb and sc
This leaves three empty positions at d
Copy the three elements from temporary storage to empty positions.
Example (dots indicate "empty" positions):
First iteration:
copy to tmp: ., 2, 3, 4, ., 6, 7, 8, .,10,11,12
1 5 9
shift: ., ., ., 2, 3, 4, 6, 7, 8,10,11,12
copy to dst: 1, 5, 9, 2, 3, 4, 6, 7, 8,10,11,12
Second iteration:
copy to tmp: 1, 5, 9, ., 3, 4, ., 7, 8, .,11,12
2 6 10
shift: 1, 5, 9, ., ., ., 3, 4, 7, 8,11,12
copy to dst: 1, 5, 9, 2, 6,10, 3, 4, 7, 8,11,12
Third iteration:
copy to tmp: 1, 5, 9, 2, 6,10, ., 4, ., 8, .,12
3 7 11
shift: 1, 5, 9, 2, 6,10, ., ., ., 4, 8,12
copy to dst: 1, 5, 9, 2, 6,10, 3, 7 11, 4, 8,12
EDIT:
And here's a working program (it takes a bit more than a verbal description :)))
#include <stdio.h>
#define N 4
int a[] = {1, 2,3, 4, 5, 6, 7, 8, 9, 10, 11, 12};
void
rearrange ()
{
int i;
int d;
int sa, sb, sc;
int tmp [3];
d = 0;
sa = 0;
sb = sa + N;
sc = sb + N;
while (sc < N*3)
{
/* Copy out. */
tmp [0] = a [sa];
tmp [1] = a [sb];
tmp [2] = a [sc];
/* Shift */
for (i = sc; i > sb + 1; --i)
a [i] = a [i - 1];
for (i = sb + 1; i > sa + 2; --i)
a [i] = a [i - 2];
sa += 3;
sb += 2;
sc++;
/* Copy in. */
a [d++] = tmp [0];
a [d++] = tmp [1];
a [d++] = tmp [2];
}
}
int
main ()
{
int i;
rearrange ();
for (i = 0; i < N*3; ++i)
printf ("%d\n", a [i]);
putchar ('\n');
return 0;
}
Appears to work. shrug
This is the general solution to the problems like yours.
First of all, for each source index you know the destination index. Now, you go like that:
Take the first item. Find its final place. Memorize the item at that place, and store the first item there. Now, find the place where the memorized item belongs to, and put that item there, memorizing that replaced item. Continue the process until it hits the place of the first item (obviously).
If you've replaced all the items, you are finished. If not, take the first non-transferred item and continue repeat the procedure from step 1, starting with that item.
You'll need to mark which items you've transferred already. There are different ways to do it: for example, you can use one bit from the item's storage.
Okay, the solution above is not exactly O(1), as it requires N extra bits. Here is the outline of O(1) solution by place, though less efficient:
Consider the items a1, b1, c1. They need to be located at the first 3 places of the result. So we are doing the following: remembering a1, b1, c1, compacting the array except these three items to the back (so it looks like this: , , , a2, a3, ..., an, b2, b3, ..., bn, c2, c3, ..., cn), and put the items a1, b1, c1 at their places at the beginning. Now, we found the place for the first 3 items, so continue this procedure for a2, b2, c2 and so on.
Edit:
let's consider the time complexity of the outline above. Denote list size 3*n. We need n steps. Each single compactification of the list can be done in one pass, and therefore is O(n). All the other operations inside a step are O(1), so we get altogether n * O(n) = O(n^2) complexity. This is far from the best solution, however, as #yi_H mentions, linear-time solution requires heavy usage of more-or-less advanced mathematics.
I can't find any O(n) algorithm but this is O(n^2) in-place one, I'll move triples to the last each time code is tested by given input, is in C#, may be is buggy, If is so let me know:
int[] a = new[] { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12 };
int m = a.Length / 3;
int firstB = a[m];
for (int i = m-1; i > 0; i--)
{
int second = a[3 * m - 3];
int third = a[3 * m - 2];
//a[i + 2 * m] = a[i +2 * m];
a[3 * m - 2] = a[2 * m - 1];
a[3 * m - 3] = a[m - 1];
for (int j = m - 1; j < 2 * m - 1; j++)
{
a[j] = a[j + 1];
}
for (int j = 2 * m - 2; j < 3 * m - 3; j++)
{
a[j] = a[j + 2];
}
a[3 * m - 5] = second;
a[3 * m - 4] = third;
m--;
}
a[1] = firstB;
Here we have x * y numbers:
a_11, a_12, ..., a_1x,
a_21, a_22, ..., a_2x,
...
a_y1, a_y2, ..., a_yx
then the number a_ij has the index i*x + j in an array;
after your program, the new index will be
j * y + i
in your interview
{a1,a2,a3,a4,b1,b2,b3,b4,c1,c2,c3,c4}
x is 4, and y is 3,
so with the index ``n''
i = (n - (n % 4)) / 4;
j = n % 4;
now you can calculate the new index with i, j, x, y.
Good Luck.

Resources