I have tried to solve the following problem unsuccessfully:
You are given 16 clocks, all set at some position between 1 and 12. The initial configuration is:
12, 9, 3, 12, 6, 6, 9, 3, 12, 9, 12, 9, 12, 12, 6, 6
You are given a set of switch lines:
# define max_switch 10
int switchLines[max_switch][5] =
{
{0,1,2,-1,-1},
{3,7,9,11,-1},
{4,10,14,15,-1},
{0,4,5,6,7},
{6,7,8,10,12},
{0,2,14,15,-1},
{3,14,15,-1,-1},
{4,5,7,14,15},
{1,2,3,4,5},
{3,4,5,9,13}
};
Entries equal to -1 are ignored. When you press a switch, the value of the clocks listed in the switch line increases by 3.
For example pressing the first switch in the initial configuration would yield:
3, 12, 6, 12, 6, 6, 9, 3, 12, 9, 12, 9, 12, 12, 6, 6
You are allowed to press any switch any number of time in any order.
What is the minimum number of switch presses needed to set all the clocks to 12 ?
I am looking for an algorithm to solve the above problem.
Below is the solution I am trying
#include <stdio.h>
#include <stdlib.h>
int clock1[16] ={12, 9, 3, 12 ,6, 6 ,9 ,3 ,12, 9, 12, 9 ,12 ,12, 6 ,6};
int swicthApplied = 0;
#define mac_sw 10
int switchLink[mac_sw][5]=
{
{0,1,2,-1,-1},
{3,7,9,11,-1},
{4,10,14,15,-1},
{0,4,5,6,7},
{6,7,8,10,12},
{0,2,14,15,-1},
{3,14,15,-1,-1},
{4,5,7,14,15},
{1,2,3,4,5},
{3,4,5,9,13}
};
int isSwicthRequired()
{
int i=0, need = 0;
for(i=0;i<16;i++)
{
if(clock1[i] < 12)
{
need = 1;
}
}
return need;
}
int findmax(int array[], int size)
{
int maximum, c, location = 0;
maximum = array[0];
if(array[0] == 0) location = -2;
for (c = 1; c < size; c++)
{
if (array[c] > maximum)
{
maximum = array[c];
location = c ;
}
}
return location +1;
}
runSwicth(int pos)
{
int i =0;
for(i=0;i<5;i++)
{
int valu = switchLink[pos][i];
if(valu == -1 ) continue;
if(clock1 [valu] == 12)
{
// continue;
clock1 [valu] = 3;
}
else
clock1 [valu] = clock1[valu] + 3;
}
printClock(clock1,16);
swicthApplied = 1 + swicthApplied;
//exit(0);
}
int findBestMatchSwitch( void)
{
//if(maxSwicth >=10) return -1;
int maxSwicth = mac_sw,numberofSwicths = 5,i,j;
int array[10] = {0,0,0,0,0,0,0,0,0,0};
for( i = 0;i<maxSwicth;i++)
{
for(j=0;j<numberofSwicths;j++)
{
int pos = switchLink[i][j] ;
if(pos == -1) continue;
if(clock1[pos] != 12)
{
array[i] = array[i] +1;
}
}
}
int loc = findmax(array,10);
if(loc == -1) return -1;
applySwicth(loc -1);
//omitLoc[loc-1] = -1;
return 0;
//exit(0);
}
int runAlignment()
{
int need =0;
while(1)
{
need = isSwicthRequired();
if (need ==0) break;
if(findBestMatchSwitch() == -1)
{
return -1;
}
}
return need;
}
int main(void) {
runAlignment();
printf("Swicthes Required [%d]",swicthApplied);
//getClockneed();
//printClock(clockNeed,16);
return EXIT_SUCCESS;
}
By definition, a solution is a list of switches of minimum length such that, when the switches are pressed in sequence, the initial configuration is transformed into the desired one.
Note that the order in which the switches are pressed doesn't actually matter. Note also that in a minimal solution no switch is pressed more than three times.
Hence for each of ten switches, you have four choices (0 to 3 presses) to consider, i.e. the total number of possibilities to examine is 4^10 or about a million.
Related
This is a problem from competitive programmer's handbook:
We are given the prices of k
products over n days, and we want to buy each product exactly once. However,
we are allowed to buy at most one product in a day. What is the minimum total
price?
Day
0
1
2
3
4
5
6
7
Product 0
6
9
5
2
8
9
1
6
Product 1
8
2
6
2
7
5
7
2
Product 2
5
3
9
7
3
5
1
4
The Optimal Selection is:
product 0 on day 3 at price 2,
product 1 on day 1 at price 2,
product 2 on days 6 at price 1.
which gives us the total of 5.
The solution:
We either do not buy any product on day d or buy a product x
that belongs to set S. In the latter case, we remove x from set S and add the price of x to the total price.
Here's the code from book:
#include <stdio.h>
#ifndef min
#define min(a, b) ((a) < (b) ? (a) : (b))
#endif
int main()
{
int price[3][8] = {{ 6, 9, 5, 2, 8, 9, 1, 6 },
{ 8, 2, 6, 2, 7, 5, 7, 2 },
{ 5, 3, 9, 7, 3, 5, 1, 4 }};
int n = 8, k = 3;
int total[1<<10][10];
//Buy all products on day 0
for (int x = 0; x < k; x++) {
total[1<<x][0] = price[x][0];
}
for (int d = 1; d < n; d++) {
for (int s = 0; s < (1<<k); s++) {
total[s][d] = total[s][d-1];
for (int x = 0; x < k; x++) {
if (s & (1<<x)) {
total[s][d] = min(total[s][d], total[s ^ (1<<x)][d-1] + price[x][d]);
break;
}
}
}
}
//Output
for (int i = 0; i < 8; i++) {
for (int j = 0; j < 8; j++) {
printf("%d", total[i][j]);
}
printf("\n");
}
}
The problem restricts us to buy only one product a day but the code seems to not address that issue at all (also, we buy all products on first day which is fine). The output is just the minimum for each product available by that day [1,2,1]. What am I doing wrong here?
After quite a bit of time in the debugger I was able to make the algo from the book work. Suffice to say the snippet provided in the book is completely broken.
Most major edits:
we will only update a more complex sum if we are updating it from an adjacent sum, that is, we do not update a sum at 111 from the sum of 001 or 010. We use __builtin_popcount to find the difference between the current set index and the one we are tryign to update from.
we will only update higher order sets if enough days has passed for prior sets to be filled.
I hope that I didn't make a mistake here(again). If I did, feel free to correct me. I did try to verify multiple inputs this time and this seems to be working.
Note that I am using multiple local variables that are completely unnecessary. I just wanted some clarity and readability.
This is essentially the same algorithm as in the book, but with a set of restrictions necessary for it to function correctly. Without those restrictions it adds up completely incompatible stuff or adds up at the wrong time and ends up not working.
The algo does address that you can only buy 1 item a day in the sol[xorIndex][dayIndex-1] + currentPrice part. The sol part being accessed was filled on previous days with items excluding the one we are adding.
int optimalSelection(int products, int days, int prices[products][days]){
int sol[1<<products][days];
memset(sol, 0, sizeof(sol));
for (int x = 0; x < products; x++) {
sol[1<<x][0] = prices[x][0];
}
for (int dayIndex = 1; dayIndex < days; dayIndex++) {
int allPossibleSetsCount = 1<<products;
for (int setIndex = 0; setIndex < allPossibleSetsCount; setIndex++) {
int currentMin = sol[setIndex][dayIndex-1];
for (int productIndex = 0; productIndex < products; productIndex++) {
if (setIndex&(1<<productIndex)) {
// this is the index of the set WITHOUT current product
int xorIndex = setIndex^(1<<productIndex);
if(__builtin_popcount(xorIndex) > dayIndex)
continue;
if (__builtin_popcount(setIndex ^ xorIndex) == 1){
// minimum for the prior day for the set excluding this product
int previousMin = sol[xorIndex][dayIndex-1];
// current price of the product
int currentPrice = prices[productIndex][dayIndex];
sol[setIndex][dayIndex] = currentMin == 0 ? previousMin + currentPrice : std::min(previousMin + currentPrice, currentMin);
currentMin = sol[setIndex][dayIndex];
}
}
}
}
}
return sol[(1<<products)-1][days-1];
}
The posted algorithm has a time and space complexity of n.k.2k which seems very expensive and likely to cause a stack overflow for moderately large sets.
Furthermore, the output is not very informative and the constraint at most one product per day does not seem enforceable.
Here is an alternative approach using recursion, with similar time complexity nk but a much smaller memory footprint:
#include <stdio.h>
enum { N = 8, K = 3 };
struct optim {
const int (*price)[N];
int bestsol[K];
int bestprice;
};
void test(struct optim *p, int i, int set, int price, int *sol) {
if (i >= K) {
if (p->bestprice > price) {
p->bestprice = price;
for (int j = 0; j < K; j++) {
p->bestsol[j] = sol[j];
}
}
} else {
for (int d = 0; d < N; d++) {
if (set & (1 << d)) {
continue; // constaint: only 1 product per day
}
sol[i] = d;
test(p, i + 1, set | (1 << d), price + p->price[i][d], sol);
}
}
}
int main() {
int price[K][N] = { { 6, 9, 5, 2, 8, 9, 1, 6 },
{ 8, 2, 6, 2, 7, 5, 7, 2 },
{ 5, 3, 9, 7, 3, 5, 1, 4 } };
struct optim data = { price, { 0, 1, 2 }, price[0][0] + price[1][1] + price[2][2] };
int sol[K];
test(&data, 0, 0, 0, sol);
printf("price: %d, days: [", data.bestprice);
for (int i = 0; i < K; i++) {
printf(" %d", data.bestsol[i]);
}
printf(" ]\n");
return 0;
}
Output: price: 5, days: [ 3 1 6 ]
Turns out the solution that was provided in the book was incomplete. For the program to return the correct result, all subsets of first day have to be populated but in the book only the subsets containing single element that were mapped to powers of two i.e., the indices 1,2,4,etc of total[][] were populated which left the other subsets to have value of 0. This made each of the subsequent day calculation to take minimum value which is 0.
code in line 14 to 16
for (int x = 0; x < k; x++) {
total[1<<x][0] = price[x][0];
}
must be replaced with:
for (int s = 0; s < (1 << k); s++) {
for (int x = 0; x < k; x++) {
if (s & (1 << x)) {
total[s][0] = price[x][0];
}
}
}
Minimum Total Sum for each day will be the set that contains all the elements i.e. total[(1<<k)-1][index of day].
With all the changes the working code is:
#include <stdio.h>
#ifndef min
#define min(a, b)((a) < (b) ? (a) : (b))
#endif
int main()
{
int price[3][8] = {
{ 6, 9, 5, 2, 8, 9, 1, 6 },
{ 8, 2, 6, 2, 7, 5, 7, 2 },
{ 5, 3, 9, 7, 3, 5, 1, 4 }
};
int n = 8, k = 3;
//Changed to scale with input
int total[1 << k][n];
//Buy all products on day 0
//Changes here
for (int s = 0; s < (1 << k); s++)
{
for (int x = 0; x < k; x++)
{
if (s &(1 << x))
{
total[s][0] = price[x][0];
}
}
}
for (int d = 1; d < n; d++)
{
for (int s = 0; s < (1 << k); s++)
{
total[s][d] = total[s][d - 1];
for (int x = 0; x < k; x++)
{
if (s &(1 << x))
{
total[s][d] = min(total[s][d], total[s ^ (1 << x)][d - 1] + price[x][d]);
break;
}
}
}
}
//Output
//Changes here
printf("%d", total[(1 << k) - 1][n - 1]);
}
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;
}
I am trying to see how to use C to check if two 2d arrays are symmetrical/mirror to each other.
So for example, if
array1 = { { 2, 5, 10 }, { 2, 1, 9 } };
array2 = { { 10, 5, 2 }, { 9, 1, 2 } };
The arrays are really 2d arrays.
How should I approach this? So far I tried to read both 2d arrays and use if/else statements and a bool to check if both arrays are equal to each other or not. But I'm not sure how to check if they are mirror matrices of each other or not.
2 5 10 | 10 5 2
2 1 9 | 9 1 2
The compiler is from 89.
You wanted to read values to both matrices the same way (hint 1: use functions). So they will both look like this:
First one:
{{m1[0][0], m1[0][1], m1[0][2],..., m1[0][99]},
{m1[1][0], m1[1][1], m1[1][2],..., m1[1][99]},
...
{m1[99][0], m1[99][1], ..., m1[99][99]}}
second one:
{{m2[0][0], m2[0][1], m2[0][2],..., m2[0][99]},
{m2[1][0], m2[1][1], m2[1][2],..., m2[1][100]},
...
{m2[99][0], m2[99][1], ..., m2[99][99]}}
But you have an error in first loop of reading m1 array:
for (a = 0; b < row; i++)
And then inside your comparison loop, you have :
m1[row][col] != m2[row][col]
Which compares values of both matrices with the same indices. So instead of comparing m1[0][0] with m2[0][99] you are comparing m1[0][0] with m2[0][0].
You can verify this property with 2 nested loops:
#include <stdio.h>
#define COLS 3
#define ROWS 2
int main(void) {
int array1[ROWS][COLS] = { { 2, 5, 10 }, { 2, 1, 9 } };
int array2[ROWS][COLS] = { { 10, 5, 2 }, { 9, 1, 2 } };
int xmirror = 1;
int ymirror = 1;
int xymirror = 1;
for (int i = 0; i < ROWS; i++) {
for (int j = 0; j < COLS; j++) {
if (array1[i][j] != array2[i][COLS - 1 - j])
xmirror = 0;
if (array1[i][j] != array2[ROWS - 1 - i][j])
ymirror = 0;
if (array1[i][j] != array2[ROWS - 1 - i][COLS - 1 - j])
xymirror = 0;
}
}
if (xymirror)
printf("Mirror image to each other rowwise and columnwise\n");
if (ymirror)
printf("Mirror image to each other rowwise\n");
if (xmirror)
printf("Mirror image to each other columnwise\n");
if (xmirror + ymirror + xymirror == 0)
printf("Not a mirror image of each other\n");
return 0;
}
Simple and short:
#include <stdio.h>
#define size 3
int main (void){
int i,j,k,flag=1;
int array1[][size] = { { 2, 5, 10},{ 2, 1, 9 } }, array2[][size] = { {10, 5, 2 }, { 9, 1, 2 } };
//Check mirror image or not
for(i=0;i<size-1;i++) {
for(j=0,k=size-1;j<size;j++,k--) {
if(array1[i][j]!=array2[i][k]) {
flag=0;
break;
}
}
}
if(flag)
printf("Mirror image to each other");
else
printf("Not a mirror image to each other");
return 0;
}
I am trying to make a program that will count the number of even numbers in the provided arrays. When I run the program now, it will return the amount of numbers in the array, but not the amount of even numbers. For some reason my count_even function doesn't work. Can anyone help?
#include <stdio.h>
int main()
{
int data_array_1[] = { 1, 3, 5, 7, 9, 11 };
int data_array_2[] = { 2, -4, 6, -8, 10, -12, 14, -16 };
int data_array_3[] = { 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0 };
int data_array_4[] = { 6, 2, 4, 5, 1, -9 };
int data_array_5[] = { 1, 3, 9, 23, 5, -2, 4 };
int result_1 = count_even(data_array_1, 6);
printf("data_array_1 has %d even numbers.\n", result_1);
int result_2 = count_even(data_array_2, 8);
printf("data_array_2 has %d even numbers.\n", result_2);
int result_3 = count_even(data_array_3, 11);
printf("data_array_3 has %d even numbers.\n", result_3);
int result_4 = count_even(data_array_4, 6);
printf("data_array_4 has %d even numbers.\n", result_4);
int result_5 = count_even(data_array_5, 7);
printf("data_array_5 has %d even numbers.\n", result_5);
return 0;
}
int count_even(int* data_array, int size)
{
int even_num = 0;
for (int i = 0; i == size; i++)
{
if (data_array[size] % 2 == 0)
{
even_num++;
}
}
return even_num;
}
The condition in your for loop is wrong.
The correct condition should say "as long as the index is smaller than size", but yours say "as long as the index equal to to size".
The condition should be i < size.
As for the result, it seems like it should return 0 (for the non-working code), not size.
Also, you are using size as an index, when you should use i.
In your count_even function, you are using the size attribute as the array index, when it should be i
int count_even(int* data_array, int size)
{
int even_num = 0
for(int i = 0; i <= size, ++i)
{
if(data_array[i] % 2 == 0)
{
even_num++;
}
}
return even_num;
}
these two lines are the root of the problems in the code:
for (int i = 0; i == size; i++)
{
if (data_array[size] % 2 == 0)
the for() statement, should be:
for (int i = 0; i < size; i++)
so the loop exits when reaching the end of the array
the if() statement is always looking at the same entry beyond the end of the array, This is undefined behaviour
The if() statement should be:
if (data_array[i] % 2 == 0)
However, the modulo operator & is not a good choice for negative numbers
a better choice would be:
if ( !(data_array[i] & 1 ) )
Following from here, I am trying to develop my own logic to generate a sequence of ugly numbers. But every time all the numbers are printed.
I am determining if the first 3 prime factors of the number are 2, 3 and 5 and placing them in a count variable determining the total count of prime factors of a number x.
If the count is greater than 3, the number is not ugly.
Here is the code:
/* To generate a sequence of Ugly numbers
Ugly numbers are numbers whose only prime factors are 2, 3 or 5. The sequence
1, 2, 3, 4, 5, 6, 8, 9, 10, 12, 15, …
shows the first 11 ugly numbers. By convention, 1 is included.
*/
#include<stdio.h>
#include<math.h>
int isprime(int x)
{
int i;
for(i=2;i<=sqrt(x);i++)
if(x%i==0)
return 0;
return 1;
}
int isUgly(int x)
{
int count=0; //To maintain the count of the prime factors. If count > 3, then the number is not ugly
int i;
for(i=2;i<=sqrt(x);i++)
{
if(isprime(i) && x%i==0)
{
count++;
if(count > 3)
return 0; // Not ugly
}
}
return 1;
}
int main(void)
{
int i,n=10;
printf("\n The ugly numbers upto %d are : 1 ",n);
for(i=2;i<=n;i++)
{
if(isUgly(i))
printf(" %d ",i);
}
return 0;
}
Here's a version of isUgly() that seems to work for me.
int isUgly(int x)
{
int i;
static int factors[] = {2, 3, 5};
// Boundary case...
// If the input is 2, 3, or 5, it is an ugly number.
for ( i = 0; i < 3; ++i )
{
if ( factors[i] == x )
{
return 1;
}
}
if ( isprime(x) )
{
// The input is not 2, 3, or 5 but it is a prime number.
// It is not an ugly number.
return 0;
}
// The input is not a prime number.
// If it is divided by 2, 3, or 5, call the function recursively.
for ( i = 0; i < 3; ++i )
{
if ( x%factors[i] == 0 )
{
return isUgly(x/factors[i]);
}
}
// If the input not a prime number and it is not divided by
// 2, 3, or 5, then it is not an ugly number.
return 0;
}
Try this one:
#include<stdio.h>
long int n, count=1;
void check(long int i)
{
if(i==1){
++count;
return;
}
else if(i%2==0)
check(i/2);
else if(i%3==0)
check(i/3);
else if(i%5==0)
check(i/5);
else
return;
}
void main(){
for(n=1;;n++){
check(n);
if(count==1000){
printf("%ldth no is %ld\n",count,n);
break;
}
}
}