Coin-row problem: There is a row of n coins whose values are some positive integers C0, C2, . . . , Cn-1, not necessarily distinct. The goal is to pick up the maximum amount of money subject to the constraint that no two coins adjacent in the initial row can be picked up.
In the below code, n is the size of my array C(or number of coins), and this code returned the right result for the values [10, 2, 4, 6, 3, 9, 5] (the right result being 25). But when I run the same code for the values [3, 12, 10] or [3, 12, 10, 2], I got the wrong result. (The result should be 13 and 14 respectively for the set of values).
Please help me fix my code.
int max(int a, int b) {
if(a > b) return a;
return b;
}
int coin_row(int[] C, int n) {
if(n==1) return C[0];
if(n==2) return max(C[0],C[1];
int F[n], i;
F[0] = 0; F[1] = C[0];
for(i = 2;i < n;i++) {
F[i] = max(C[i] + F[i-2], F[i-1]);
}
return F[n-1];
}
The statement that all numbers will be positive makes things a little easier. From that information we can determine that we never want to skip over two consecutive numbers. We just have to calculate the best sequence possible using the first number and compare it with the best sequence possible using the 2nd number. This is ideal for recursion.
int coin_row(int *C, int n)
{
int first_total;
int second_total;
if (n == 0) return 0;
if (n == 1) return *C;
if (n == 2) return max(*C, *(C+1));
first_total = *C + coin_row(C+2, n-2);
second_total = *(C+1) + coin_row(C+3, n-3);
return(max(first_total, second_total));
}
By breaking down the problem into a sequence of pairs we treat the list as a large binary tree. At every pair you can choose either the first or second number. Calculate the total for each sub-tree and return the greatest value. For example with {10, 2, 4, 6, 3, 9, 5} your paths are:
10 2
/\ /\
4 6 6 3
/\ /\ /\ /\
3 9 9 5 9 5 5 -
Your algorithm is right but there are some bugs in implementation.
You are skipping the value at C[1] as your loop starts from i=2.
Since you are including 0 coin case in your F array, it needs to be of size n+1 for F[n] to exist. With the above corrections we arrive at:
int max(int a, int b) {
if(a > b) return a;
return b;
}
int coin_row(int* C, int n) {
if(n==1) return C[0];
if(n==2) return max(C[0],C[1]);
int F[n+1], i;
F[0] = 0; F[1] = C[0];
for(i = 2 ; i <= n + 1 ; i++) {
F[i] = max(C[i-1] + F[i-2], F[i-1]);
}
return F[n];
}
Related
I'm making a program in C that factors any number using primes and saves these primes, multiplying them you find all the divisors of a number.
But I can't make an array that multiplies the previous columns and saves the results. follow the example
60 / 2
30 / 2
15 / 3
5 / 5
divisors = 2, 2, 3, 5
now i need`add 1 to array array {1, 2, 2, 3, 5}
i need this now start colune 2 {1, 2} 2 * 1 = 2 save.
next colune 3 {1, 2, 2} 2 * 1 = 2 but we already have 2 so don't save it.
continue 2 * 2 = 4 save.
colune 4 {1, 2, 2, 3} 3 * 1 = 3 save, 3 * 2 = 6 save, 3 * 4 = 12 save.
colune 5 {1, 2, 2, 3, 5} 5 * 1 = 5 save, 5* 2 = 10, 5 * 4 = 20 save, 5 * 3= 15 save, 5 * 6 = 30 save, 5 * 12 = 60 save.
now we found all divisors of 60 = 1, 2, 3, 4, 5, 6, 10 ,12 , 15,20, 30, 60.
It is important to mention that I need the program to be like this, I know there are other ways... but I only need this one, I have been unable to complete it for 1 week
video to help https://www.youtube.com/watch?v=p0v5FpONddU&t=1s&ab_channel=MATEM%C3%81TICAFORALLLUISCARLOS
my program so far
#include <stdlib.h>
#include <stdio.h>
int N = 1;
int verificarPrimo(int numero);
int main()
{
int num = 60, i, primo = 1, resultados[N], j = 1;
for (i = 0; i < 60; i++)
{
if (primo == 1)
{
resultados[N - 1] = primo;
i = 2;
primo = i;
}
if (verificarPrimo(i))
{
while (num % i == 0)
{
num = num / i;
resultados[N] = i;
N++;
}
}
}
for (i = 1; i < N; i++)
{
printf("%d \n", resultados[i]);
}
}
int verificarPrimo(int primo)
{
int i;
if (primo <= 1)
return 0;
for (i = 2; i <= primo / 2; i++)
{
if (primo % i == 0)
return 0;
}
return 1;
}
I tried out your code and ran into some issues with how the results were being stored. First off, the results array is being initially defined as an array with a size of "1", and that it not what you probably want.
int num = 60, i, primo = 1, resultados[N], j = 1;
With that in mind and determining the spirit of this project, following is tweaked version of the code to test for one or more values and their factors.
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
int verificarPrimo(int primo)
{
int sq = sqrt(primo) + 1; /* Usual checking for a prime number is from '2' to the square root of the number being evaluated */
if (primo <= 1)
return 0;
for (int i = 2; i < sq; i++)
{
if (primo % i == 0)
return 0;
}
return 1;
}
int main()
{
int N = 0;
int num = 0, entry = 0, resultados[100]; /* The results array needs to be defined with some value large enough to contain the assorted factors a number might have */
printf("Enter a number to evaluate for factors: "); /* Using a prompt to allow various values to be tested */
scanf("%d", &entry);
num = entry;
if (verificarPrimo(num)) /* Catchall in case the entered number is a prime number */
{
printf("This number is a prime number and has no factors other than one and itself\n");
return 0;
}
resultados[0] = 1; /* Normally the value '1' is implied in a list of factors, so these lines could be omitted */
N = 1;
for (int i = 2; i < entry; i++)
{
if (verificarPrimo(i))
{
while (num % i == 0)
{
num = num / i;
resultados[N] = i;
N++;
}
}
}
printf("Factors for %d\n", entry);
for (int i = 0; i < N; i++)
{
printf("%d ", resultados[i]);
}
printf("\n");
return 0;
}
Some items to point out in this tweaked code.
In the prime number verification function, it is usually customary to set up a for loop in testing for prime numbers to go from the value of "2" to the square root of the number being tested. There usually is no need travel to one half of the number being tested. For that, the #include <math.h> statement was added (FYI, "-lm" would need to be added to link in the math library).
Instead of defining the results array with a value of one element, an arbitrary value of "60" was chosen for the holding the possible number of results when evaluating factors for a given value. Your original code had the potential of storing data past the end of the array and causing a "smashing" error.
The value of "1" is usually left out of the list of factors for a number, but was left in as the initial result value. This might be left out of the completed code.
An additional entry field was added to allow for user entry to be tested to give the code some flexibility in testing numbers.
A test was also added to see if the entered number is itself a prime number, which would only have factors of "1" and itself.
Following is some sample terminal output testing out your original value of "60" along with some other values.
#Dev:~/C_Programs/Console/Factors/bin/Release$ ./Factors
Enter a number to evaluate for factors: 60
Factors for 60
1 2 2 3 5
#Dev:~/C_Programs/Console/Factors/bin/Release$ ./Factors
Enter a number to evaluate for factors: 63
Factors for 63
1 3 3 7
#Dev:~/C_Programs/Console/Factors/bin/Release$ ./Factors
Enter a number to evaluate for factors: 29
This number is a prime number and has no factors other than one and itself
Give that a try to see if it meets the spirit of your project.
I want to do this in a function: How do I find out in a C program if a number is divisible by 2, 3, 4, 5, 6, 8, 9, 25 and 125 without using the % operator and using the divisibility rules? the base should be 10*
To use divisibility rules, you have to work with digits. Perhaps task assumes no division (at least in explicit form - you can extract digits from string representation)
For divisibility by 2, check whether the last digit is in set 0,2,4,6,8
For divisibility by 4, check whether the last digit + doubled previous one is in set 0,4,8. If result is larger than 10, repeat (88=>2*8+8=24=>2*2+4=8)
Similar situation for 8, but sum last + 2*previous + 4*second_from_the_end (512 => 4*5+2*1+2=24=>2*2+4=8)
For divisibility by 5, check whether the last digit is in set 0,5, similar situation for 25, 125
For divisibility by 3, sum all digits, repeat process until result becomes < 10. So-called "digit root" should be in set 0,3,6,9, similar situation for divisibility by 9.
For 6 check divisibilty by both 2 and by 3
I am not strong in C, so my example perhaps is very weird (ideone check)
#include <stdio.h>
int divby3(int n) {
char s[10];
do {
sprintf(s, "%d", n); //transform 72 to char buffer "72"
n = 0;
int i = 0;
while(s[i]) //until nil (end of string) found, we can also use for loop
n += s[i++] - 0x30; //get difference of current char and char "0"
}
while (n >= 10); //until 1-digit value
return (n==0) || (n==3) || (n==6) || (n==9);
}
int divby5(int n) {
char s[10];
int len = sprintf(s, "%d", n);
n = s[len - 1] - 0x30; //last digit
return (n==0) || (n==5);
}
int main(void) {
printf("%d", divby3(72)); //try 71
return 0;
}
A function that uses the a - (a / b * b) implementation of the modulus operator: (credit #MikeCat)
bool isDivisible(int a, int b)
{
if((a - (a / b * b)) == 0) return true;
return false;
}
Usage:
int main(void)
{
int a = 8;
int b = 4;
int c = 3;
bool res = isDivisible(a,b);
bool res2 = isDivisible(a,c);
return 0;
}
EDIT - to address question in comments:
"how can i represent such a program with the divisibility rules? Thank you for your code, i forgott to mention that i have to use the divisibility rules in each function"
The following shows how to pass in divisibility rules as an argument...
const int div_1[] = {2, 3, 4, 5, 6, 8, 9, 25, 125};
const int div_2[] = {7, 5, 17, 12, 11};
int main()
{
size_t size = 0;
size = sizeof div_1/sizeof div_1[0];
bool res = isDivisible(2*3*4*5*6*8*9*25*125, div_1, size);
size = sizeof div_2/sizeof div_2[0];
bool res2 = isDivisible(125, div_2, size);
return 0;
}
// numerator divisor array array size
bool isDivisible(long a, long div_rules[], size_t size)
{
//divisibility rules
const int divisors[] = {2, 3, 4, 5, 6, 8, 9, 25, 125};
for(int i = 0; i<size;i++)
{
if((a - (a / div_rules[i] * div_rules[i])) != 0) return false;
}
return true;
}
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;
}
I am programming in C. What is the best method (I mean in linear time) to spit array on elements less, equals and greater than some value x.
For example if I have array
{1, 4, 6, 7, 13, 1, 7, 3, 5, 11}
and x = 7 then it should be
{1, 4, 6, 1, 3, 5, 7, 7, 13, 11 }
I don't want to sort elements because I need more efficient way. Of course in this example in could be any permutation of {1, 4, 6, 1, 3, 5} and {13, 11}.
My thougt: less or grater than some element in array... In this example it is 7.
My function is:
int x = 7;
int u =0, z = 0;
for(int i=0; i<size-1; i++) // size - 1 because the last element will be choosen value
{
if(A[i] == x)
swap(A[i], A[u]);
else if(A[i] == x)
{
swap(A[i], A[n-(++z)]);
continue;
}
i++
}
for(int i = 0; i<z; i++)
swap(A[u+i],A[size-(++z)];
where u is number of current less elements, and z is the number of equals element
But if I have every elements in array equals there it doesn't work (size-(++z)) is going under 0
This is the so-called Dutch national flag problem, named after the three-striped Dutch flag. (It was named that by E.W. Dijkstra, who was Dutch.) It's similar to the partition function needed to implement quicksort, but in most explanations of quicksort a two-way partitioning algorithm is presented whereas here we are looking for a three-way partition. The classic quicksort partitioning algorithms divide the vector into two parts, one consisting of elements no greater than the pivot and the other consisting of elements strictly greater. [See note 1]
The wikipedia article gives pseudocode for Dijkstra's solution, which (unlike the classic partition algorithm usually presented in discussions of quicksort) moves left to right through the vector:
void dutchflag(int* v, size_t n, int x) {
for (size_t lo = 0, hi = n, j = 0; j < hi; ) {
if (v[j] < x) {
swap(v, lo, j); ++lo; ++j;
} else if (v[j] > x) {
--hi; swap(v, j, hi);
} else {
++j;
}
}
There is another algorithm, discovered in 1993 by Bentley and McIlroy and published in their paper "Engineering a Sort Function" which has some nice diagrams illustrating how various partitioning functions work, as well as some discussion about why partitioning algorithms matter. The Bentley & McIlroy algorithm is better in the case that the pivot element occurs infrequently in the list while Dijkstra's is better if it appears often, so you have to know something about your data in order to choose between them. I believe that most modern quicksort algorithms use Bentley & McIlroy, because the common case is that the array to be sorted has few duplicates.
Notes
The Hoare algorithm as presented in the Wikipedia Quicksort article, does not rearrange values equal to the pivot, so they can end up being present in both partitions. Consequently, it is not a true partitioning algorithm.
You can do this:
1) Loop through the array, if element is less than x then put in new array1.
2)If element is greater than x then put in new array2.
This is linear time O(n)
I tried something like this below which I think is O(n). Took me a little bit to work the kinks out but I think it's pretty similar to the dutchflag answer above.
My ouptput
a.exe
1 4 6 5 3 1 7 7 11 13
1 4 5 6 3 1 7 7 7 11 13
code:
#define ARRAY_SIZE(x) (sizeof(x)/sizeof(x[0]))
void order(int * list, int size, int orderVal)
{
int firstIdx, lastIdx, currVal, tempVal;
firstIdx = 0;
lastIdx = size-1;
for ( ;lastIdx>firstIdx;firstIdx++)
{
currVal = list[firstIdx];
if (currVal >= orderVal)
{
tempVal = list[lastIdx];
list[lastIdx] = currVal;
lastIdx--;
list[firstIdx] = tempVal;
if (tempVal >= orderVal)
firstIdx--;
}
}
lastIdx = size-1;
for( ;lastIdx>firstIdx && middleNum>0;lastIdx--)
{
currVal = list[lastIdx];
if (currVal == orderVal)
{
tempVal = list[firstIdx];
list[firstIdx] = currVal;
firstIdx++;
list[lastIdx] = tempVal;
if (tempVal == orderVal)
lastIdx++;
}
}
}
int main(int argc, char * argv[])
{
int i;
int list[] = {1, 4, 6, 7, 13, 1, 7, 3, 5, 11};
int list2[] = {1, 4, 7, 6, 7, 13, 1, 7, 3, 5, 11};
order(list, ARRAY_SIZE(list), 7);
for (i=0; i<ARRAY_SIZE(list); i++)
printf("%d ", list[i]);
printf("\n");
order(list2, ARRAY_SIZE(list2), 7);
for (i=0; i<ARRAY_SIZE(list2); i++)
printf("%d ", list2[i]);
}
Here is an example using a bubble sort. Which type of sort algorithm is best, is up to you, this is just to demonstrate. Here, I treat values < x as -1, values == x as 0, values > x as 1.
Note that the elements < x and those > x are still in the same sequence.
#include <stdio.h>
int main(void)
{
int array[] = { 1, 4, 6, 7, 13, 1, 7, 3, 5, 11 };
int x = 7;
int len = sizeof array / sizeof array[0];
int i, j, m, n, tmp;
for (i=0; i<len-1; i++) {
m = array[i] < x ? -1 : array[i] == x ? 0 : 1;
for (j=i+1; j<len; j++) {
n = array[j] < x ? -1 : array[j] == x ? 0 : 1;
if (m > n) {
tmp = array[i]; // swap the array element
array[i] = array[j];
array[j] = tmp;
m = n; // and replace alias
}
}
}
for(i=0; i<len; i++)
printf("%d ", array[i]);
printf("\n");
return 0;
}
Program output:
1 4 6 1 3 5 7 7 13 11
This is a problem on my Computer Science final study guide. The correct answer is x[2] = 7 and x[4] = 4. When I tried interpreting the code it seemed like the value of x[2] wasn't even changed by the sort function. But it was! Could someone explain why x[2] = 7 and x[4] = 4? Thank you!
#include<stdio.h>
#define SIZE 10
void sort(int[], int);
int main()
{
int x[SIZE] = {2, 4, 6, 8, 1, 3, 5, 7, 9, 0};
sort(x, -1);
printf("x[2] = %d\n", x[2]);
sort(x, 1);
printf("x[4] = %d\n", x[4]);
return(0);
}
void sort(int x[], int dir)
{
int i;
int j;
int temp;
for(i = 1; i < SIZE; i++)
{
for(j = SIZE - 1; j >= i; j--)
{
if(dir == -1 && x[j] > x[j - 1] || dir == 1 && x[j] < x[j - 1])
{
temp = x[j - 1];
x[j - 1] = x[j];
x[j] = temp;
}
}
}
}
The sort function is a bubblesort variant. If dir is -1, it sorts the array in descending order. If dir is 1, it sorts the array in ascending order.
After the first sort, the array will be in descending order:
9 8 7 6 5 4 3 2 1 0
So x[2] will be 7.
After the second sort, the arry will be in ascending order:
0 1 2 3 4 5 6 7 8 9
So x[4] will be 4.
The code goes along these lines:
from left to right in the array
from right to left in the array, as long as you hit the upcoming count
if the current left is bigger than it's lower predecessor
swap 'em
Its a kind of an exchange sort algorithm.
X[2] is touched by the inner loop possibly two times
first since j >= i
secondly in the comparision with the predecessor