Input n. Put + or - betweeen 1,2,3,4,5,6,7,8,9 to found a expression equal to n
(122 = 12 + 34 - 5 - 6 + 78 + 9 or 146 = 123 + 45 + 67 - 89)
My idea is that we could fill between 2 numbers 3 values: 0 for no blank, 1 for + and 2 for -
for example 1 + 2 + 3456 - 78 + 9 is 11000201. And this is base-3-number
There are 3^8 expressions to test because we have 8 position to fill, each one has 3 ways.
Start for loop, i from 1 to 3^8. Convert each i to base-3-number and and convert each character of i into + - or no blank to calculate if the present expression is equal to n or not. If equal, print out the expression and end the loop...
My problem is that the program give me the wrong answer and I can't find out a bug.
for example I input 145 but it give me 123 + 45 + 67 - 89 (=146)
This is the code:
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
int main()
{
int n, result, a[100],count, i,j, test,temp, checkpoint,num,checkresult=0;
printf("Input n\n");
scanf("%d",&n);
for (num=1;num<=6561;num++)
{
count=1;
test = num;
result = 0;
checkpoint=0;
a[0]=1;
//convert to base 3
while (test>0)
{
a[count]=test%3;
//printf("%d ",a[count]);
test = test/3;
count++;
}
count--;
//put 0 to fill full 8 blank
while (count<8)
{
count++;
a[count]=0;
//printf("%d ",a[count]);
}
//inverse the sequence to have the right
for (i=1;i<=count/2;i++)
{
temp = a[i];
a[i] = a[count+1-i];
a[count+1-i] = temp;
}
//calculate the number
//1 is +, 2 is -, 0 is no blank
for (i=1;i<=8;i++)
{
if ((a[i]==1) || (a[i]==2))
{
if (a[checkpoint]==1)
for (j=checkpoint+1;j<=i;j++)
result = result + j*pow(10,i-j);
if (a[checkpoint]==2)
for (j=checkpoint+1;j<=i;j++)
result = result - j*pow(10,i-j);
checkpoint=i;
}
}
if (i==9)
{
if (a[checkpoint]==1)
for (j=checkpoint+1;j<=i;j++)
result = result + j*pow(10,i-j);
if (a[checkpoint]==2)
for (j=checkpoint+1;j<=i;j++)
result = result - j*pow(10,i-j);
}
//check if the result is correct or not. If correct, print it out and break the loop
if (result == n)
{
checkresult=1;
for (i=1;i<=8;i++)
{
printf("%d",i);
if (a[i]==1)
printf("+");
if (a[i]==2)
printf("-");
}
printf("9\n");
break;
}
}
if (checkresult==0)
printf("Can't found...");
return 0;
}
I have solved the problem.
Just have to change the result variable's type into double. Because pow statement require a double type variable
Your code is running fine for me, here is the screenshot for the output:
Input: n=145 Output: 123-4-56-7+89
Related
I have an assignment that requires me to make a quiz which generates random math questions. I'm fine with everything but i'm struggling to find a way to randomly choose between the mathematical operators "+" and "-".
#include <stdio.h>
#include <time.h>
#include <stdlib.h>
int main(){
int choice = 0;
int lives = 0;
int question = 1;
int a;
int b;
int answer = 0;
int ans = 0;
int correct = 0;
printf("\n Welcome to Maths Tester Pro.");
printf("\n Please Select a difficulty:");
printf("\n 1) Easy");
printf("\n 2) Medium");
printf("\n 3) Hard \n");
scanf("%d%*c",&choice);
switch(choice)
{
case 1:
printf("You have selected Easy mode!");
lives = lives+3;
while ((lives !=0)&&(question !=6)){
if(question !=5){
//Ask Question
printf("\nQuestion %d of 5. You have %d lives remaining", question, lives);
srand(time(NULL));
a = (rand() % (10 - 1 + 1)) + 1; //make the sign random
b = (rand() % (10 - 1 + 1)) + 1;
printf("\n%d + %d = ",a ,b);
scanf("%d", &answer);
ans = a+b;
//If answer is correct
if((a+b) == answer){
printf("Correct!\n");
correct = correct + 1;
}
//If answer is incorrect
else{
printf("Incorrect! The correct answer was %d\n",ans);
lives=lives-1;
}
question = question + 1;
}
In my code I have it written as ans=a+b but I want it to be able to randomly pick either "+" or "-".
The easiest way to go would be to change the sign of b. To do so, simply multiply it by either 1 (keeps positive sign) or -1 (makes it a negative):
b = b * ((rand() - (RAND_MAX / 2)) > 0 ? 1 : -1);
Upon execution, you will randomly get a + b or a + (-b).
Example print of the resulting operator:
printf("%d%s%d = %d\n", a, (b > 0 ? "+" : ""), b, a + b);
Note: as pointed in earlier comments, you may also want to randomize the seed in order to prevent you application to keep providing the "same" random numbers with:
/* Randomize seed (needed once). */
srand(time(NULL));
/* Then make your calls to `rand()`. */
...
I offer this as an example of how to cleanly generate and print the sort of problems that you seem to want.
This produces 20 'sum' and/or 'difference' equations. You can simply suppress printing the total in order to pose the question to the user.
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
int main() {
srand( time( NULL ) );
for( int i = 0; i < 20; i++ ) {
int a = (rand() % 10) + 1; // 1 <= a <= 10
int b = (rand() % 20) - 9; // -9 <= b <= 10
printf( "%d %c %d = %d\n", a, "+-"[b<0], abs( b ), a+b );
}
return 0;
}
1 + 3 = 4
1 - 6 = -5
4 + 10 = 14
8 + 2 = 10
10 + 0 = 10
4 + 4 = 8
8 + 10 = 18
8 + 9 = 17
8 - 2 = 6
8 - 4 = 4
2 + 1 = 3
8 - 5 = 3
2 - 6 = -4
4 + 9 = 13
6 + 6 = 12
5 + 0 = 5
3 + 4 = 7
1 + 0 = 1
9 - 5 = 4
8 + 8 = 16
The keen eyed reader will notice that even "10 + 0" is a reasonable problem. Zero is the identity operator(?) for addition (like 1 being the identity operator(?) for multiplication.)
You're free to adjust the ranges of the terms to suit your questions.
You can use rand() function, which is defined in stdlib. And if you want your program to give you different random numbers every time you run it, you need to put srand(time(NULL)) at the beginning, but for the time function, you need to include time.h library
Example Of Code
#include <stdio.h>
int sum(int n); //Prototype
int main(void){
int number;
printf("Enter number: ");
scanf("%d", &number);
printf("%d = %d\n", number, sum(number));
}
//Sum Function
int sum(int n){
int total = 0;
while (n != 0)
{
total += n % 10;
n /= 10;
}
return total;
}
How do I print the below sentence taking into account that the number can be dynamically chosen by the user using a scanf function and I already have a dynamic function that calculates the sum of each digit.
Current Output: "12345 = 15"
Desired Output: "1 + 2 + 3 + 4 + 5 = 15"
Edit: Hi all! I have updated my question to include my original code to make it clearer what I was trying to achieve. Thank you guys so much for your help!
Simply recursion can be used to print the first digits when the value is 10 or more, along with the " + ".
#include <limits.h>
#include <stdlib.h>
#include <stdio.h>
// Print each digit with a trailing " + "
static int sum_helper(int x) {
int sum = 0;
if (x >= 10) {
sum += sum_helper(x / 10);
x %= 10;
}
printf("%d + ", x);
return sum + x;
}
void sum_line(int x) {
printf("%11d: ", x);
int last_digit = abs(x % 10);
int sum = last_digit;
int first_digits = abs(x / 10);
if (first_digits) {
sum += sum_helper(first_digits);
}
printf("%d = %d\n", last_digit, sum);
}
Test code
void sum_line(int x);
int main(int argc, char **argv) {
sum_line(123);
sum_line(12345);
sum_line(0);
sum_line(1);
sum_line(-12345);
sum_line(INT_MAX);
sum_line(INT_MIN);
return 0;
}
Output
123: 1 + 2 + 3 = 6
12345: 1 + 2 + 3 + 4 + 5 = 15
0: 0 = 0
1: 1 = 1
-12345: 1 + 2 + 3 + 4 + 5 = 15
2147483647: 2 + 1 + 4 + 7 + 4 + 8 + 3 + 6 + 4 + 7 = 46
-2147483648: 2 + 1 + 4 + 7 + 4 + 8 + 3 + 6 + 4 + 8 = 47
If the input is coming in as a string, the easiest thing to do is to leave it as a string. Don't ever convert it to an int. (eg, if you are reading the data with scanf using %d, just use %s instead). If the data is already an integer, the easiest thing to do is (probably) to convert it to a string:
#include <stdio.h>
#include <stdint.h>
int
main(void)
{
int number = 12345;
char buf[128];
int sum = 0;
snprintf(buf, sizeof buf, "%d", number);
for( char *s = buf; *s; s++ ){
if( s != buf ){
fputs(" + ", stdout);
}
putchar(*s);
sum += *s - '0';
}
printf(" = %d\n", sum);
}
Easiest by far (and probably fastest too actually) is to stick with strings. Here's an example, error handling yet to be implemented:
#include <stdio.h>
int main (void)
{
char str[128];
scanf("%s", str);
int sum = 0;
for(int i=0; str[i]!='\0'; i++)
{
sum += str[i] - '0'; // convert to integer digit, then add to sum
printf("%c ", str[i]);
if( str[i+1] == '\0' )
printf("= ");
else
printf("+ ");
}
printf("%d", sum);
}
We can add another solution using POSIX div (added to C99), that is essentially a divide and mod in a single operation using an anonymous struct. To handle conversion of an integer to an addition expression of each digit (considered a positive digit regardless of the initial sign of the integer) and allowing for definition of separator string (SEP below) to place between each digit, you could do something like the following:
#include <stdio.h>
#include <stdlib.h>
#include <limits.h>
#define MAXDIGIT 32 /* max number of digits */
#define SEP " + " /* separator */
#define SLEN sizeof(SEP) - 1 /* separator length */
void itosexpr (int n)
{
char buf[MAXDIGIT * SLEN] = "", /* buffer to hold digits + sep */
*p = buf + MAXDIGIT * SLEN - 1; /* pointer to end of buffer */
div_t d = { .quot = n }; /* quotient/remainder type */
long sum = 0;
do {
d = div (d.quot, 10); /* compute quotient/remainder */
sum += abs(d.rem); /* add remainder to sum */
*--p = abs(d.rem) + '0'; /* decrement & add char to buf */
for (int i = 0; d.quot && SEP[i]; i++) /* add sep to buf */
*--p = SEP[i];
} while (d.quot); /* test quotient non-zero */
printf ("% 11d: %s = %ld\n", n, p, sum); /* output expression & sum */
}
int main (void) {
int number = 12345;
itosexpr (number);
itosexpr (0);
itosexpr (1);
itosexpr (INT_MAX);
itosexpr (INT_MIN);
}
Note, this method isn't any superior or worse than any of the others, it's just another option and exposure to the div set of functions (with ldiv and lldiv for long and long long respectively)
Example Use/Output
$ ./bin/number_to_add_expr
12345: 1 + 2 + 3 + 4 + 5 = 15
0: 0 = 0
1: 1 = 1
2147483647: 2 + 1 + 4 + 7 + 4 + 8 + 3 + 6 + 4 + 7 = 46
-2147483648: 2 + 1 + 4 + 7 + 4 + 8 + 3 + 6 + 4 + 8 = 47
If you #define SEP "+", then you would have:
$ ./bin/number_to_add_expr2
12345: 1+2+3+4+5 = 15
0: 0 = 0
1: 1 = 1
2147483647: 2+1+4+7+4+8+3+6+4+7 = 46
-2147483648: 2+1+4+7+4+8+3+6+4+8 = 47
(note: SEP must be defined and must be at least a string of one valid character)
This is not the most efficient but it's a charmingly recursive solution.
The challenge isn't totally digits. The challenge is outputting them in decreasing order of significance unless you're always provided with the number as a character string!
Expected Output:
0 -> 0 = 0
1 -> 1 = 1
-1 -> 1 = 1
5 -> 5 = 5
15 -> 1 + 5 = 6
12345 -> 1 + 2 + 3 + 4 + 5 = 15
123456 -> 1 + 2 + 3 + 4 + 5 + 6 = 21
49 -> 4 + 9 = 13
-78 -> 7 + 8 = 15
9 -> 9 = 9
-9 -> 9 = 9
10 -> 1 + 0 = 1
-10 -> 1 + 0 = 1
-2147483648 -> 2 + 1 + 4 + 7 + 4 + 8 + 3 + 6 + 4 + 8 = 47
2147483647 -> 2 + 1 + 4 + 7 + 4 + 8 + 3 + 6 + 4 + 7 = 46
#include <stdio.h>
#include <limits.h>
int sum(int n){
int r=0;
if(n>=10 || n<=-10){
r=sum(n/10);
printf(" + ");
}
int d=n%10;
if(d<0){
d=-d;
}
r+=d;
printf("%d",d);
return r;
}
void show(int n){
printf("%d -> ",n);
int r=sum(n);
printf(" = %d\n",r);
}
int main() {
show(0);
show(1);
show(-1);
show(5);
show(15);
show(12345);
show(123456);
show(49);
show(-78);
show(9);
show(-9);
show(10);
show(-10);
show(INT_MIN);
show(INT_MAX);
return 0;
}
You can try something like this.
#include <stdio.h>
#define MAX 100
void printIndiviualDigits(int number)
{
int arr[MAX];
int i = 0;
int j, r,sum=0;
// Till number becomes 0
while (number != 0) {
// Extract the last digit of number
r = number % 10;
// Put the digit in arr[]
arr[i] = r;
i++;
// Update number to number/10 to extract
// next last digit
number = number/ 10;
}
// Print the digit of number by traversing
// arr[] reverse
for (j = i - 1; j > -1; j--) {
printf("%d", arr[j]);
sum += arr[j];
if(j > 0){
printf("+");
}
}
printf("=%d",sum);
}
// main function
int main()
{
int number;
printf("Enter any number:\n");
scanf("%d",&number);
printIndiviualDigits(number);
return 0;
}
Here's a solution without recursion or strings...
Works on the same principle as a base2 bitmask, but works in base10.
Can be made to work for 0 or negative numbers, too (but this is just an exercise, right?)
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
int main( void ) {
int values[] = { 1, 35, 654, 2048, 10000, 65365, 1234567889 };
for( int i = 0; i < sizeof values/sizeof values[0]; i++ ) {
int val = values[i];
int b10mask = (int)pow( 10, (int)log10( val ) );
printf( "value(%d): ", val );
char *pref = "";
int sum = 0;
// EDIT: Missed testing when rightmost digits '0'
// while( val ) { // insufficient
while( val || b10mask ) { // better.
int dgt = b10mask ? val/b10mask : val;
sum += dgt;
printf( "%s%d", pref, dgt );
pref = " + ";
val -= dgt * b10mask;
b10mask /= 10;
}
printf( " = %d\n", sum );
}
return 0;
}
Output:
value(1): 1 = 1
value(35): 3 + 5 = 8
value(654): 6 + 5 + 4 = 15
value(2048): 2 + 0 + 4 + 8 = 14
value(10000): 1 + 0 + 0 + 0 + 0 = 1 ## New and working after edit.
value(65365): 6 + 5 + 3 + 6 + 5 = 25
value(1234567889): 1 + 2 + 3 + 4 + 5 + 6 + 7 + 8 + 8 + 9 = 53
I am learning c and encountered maximum cost path question in which
Rules:
matrix is n x n size
Starting from the cell (bottommost leftmost cell), you want to go to the topmost
rightmost cell in a sequence of steps. In each step, you can go either right or up from
your current location.
I tried to solve using dynamic programming and this is the function I have written
computecost(int *utr,int n)//utr is the input matrix
{
int *str;
int i,j;
str=(int *)malloc(n*n*sizeof(int));
for(j=0;j<n;j++)//intialization of bottom row
{
str[n*(n-1)+j]=utr[n*(n-1)+j];
}
for(i=n-2;i>=0;i--)
{
for(j=0;j<n;j++)
{
str[n*i+j]=utr[n*i+j]+max(str[n*(i+1)+j],str[n*(i+1)+(j+1)]);
}
}
printf("%d",str[n*0+0]);
return 0;
}
and this is the input
for(i=0;i<n;i++)
{
for(j=0;j<n;j++)
{
scanf("%d",&str[n*i+j]);
}
}
but
for the matrix 5 x5
1 4 8 2 9
32 67 18 42 1
4 86 12 7 1
8 4 12 17 44
1 43 11 45 2
the desired output is 272 but I am getting 211.
the output matrix for my case
1 43 11 45 2
51 47 57 62 46
55 143 74 69 47
175 210 92 111 52
211 214 119 113 64
Can anyone help me?
You don't need dynamic programming for this since there are no overlapping sub-problems. Just use a simple recursion.
const int n = 5;
int mat[n][n] = {
{1,4,8,2,9},
{32,67,18,42,1},
{4,86,12,7,1},
{8,4,12,17,44},
{1,43,11,45,2}
}; // input matrix
int f(int x, int y, int sum){
if(x == 0 && y == 4)
return sum;
int p = 0, q = 0;
if(x - 1 >= 0)
p = f(x-1, y, sum + mat[x-1][y]);
if(y + 1 <= 4)
q = f(x, y+1, sum+mat[x][y+1]);
return max(p,q);
}
int main(){
int maxSum = f(4,0, mat[4][0]);
printf("%d\n", maxSum);
}
You were not very far to succeed.
In practice, you did not initialize correctly the bottom row.
Moreover, there was a little mistake in the iteration calculation.
This is the corrected code.
As said in a comment, it could be further simplified, by avoiding the use of a new array, simply updating the input array.
#include <stdio.h>
#include <stdlib.h>
int max (int a, int b) {
return (a > b) ? a : b;
}
int computecost(int *utr,int n) { //utr is the input matrix
int *str;
str = malloc (n*n*sizeof(int));
str[n*n - 1] = utr[n*n - 1];
for (int j = n-2; j >= 0; j--) { //intialization of bottom row {
str[n*(n-1)+j] = utr[n*(n-1)+j] + str[n*(n-1)+j+1]; // corrected
}
for (int i=n-2; i>=0; i--) {
str[n*i+n-1] = utr[n*i+n-1] + str[n*(i+1)+n-1];
for(int j = n-2; j >= 0; j--) {
str[n*i+j] = utr[n*i+j] + max(str[n*(i+1)+j],str[n*i + j+1]); // corrected
}
}
int cost = str[0];
free (str);
return cost;
}
int main() {
int A[25] = {
1,43,11,45,2,
8,4,12,17,44,
4,86,12,7,1,
32,67,18,42,1,
1,4,8,2,9
};
int ans = computecost (A, 5);
printf ("%d\n", ans);
return 0;
}
I can't understand why the result of effe(10) procedure is 110. (Thats a code taken from an exercise)
I tried to write down what is happening in the code, but there are too many recursions and i can't understand what is happening.
int effe(int);
int gi(int);
int main(){
int test = effe(10);
printf("%d\n", test); //this prints 110
system("pause");
return 0;
}
int effe(int a){
if(a < 2)
return a * 2;
else
return (gi(a - 1) + gi(a - 2));
}
int gi(int a){
if (a < 2)
return effe(a);
else
return (effe(a - 1) + effe(a - 2));
}
To some extent, this is variation of Fibonacci.
Calculate the values starting with efff(0), gi(0), and calculate efff(1), gi(1),efff(2), gi(2), until you reach efff(10), gi(10)
a efff(a) gi(a)
0 0 0
1 2 2
2 2=2+0 2=2+0
3 4=2+2 4=2+2
4 6=2+4 6=2+4
5 10=4+6 10=4+6
6 16=6+10 16=6+10
7 26 26
8 42 42
9 68 68
10 110 110
Note that each item is 2 times the Fibonacci value (1,1,2,3,5,8,13,21,34,55).
i am working on a program where the input is an ID of 9 numbers :
program checks if the id is correct or not by :-
checking if the string is formed by numbers only .
every number has a weight of 1 or 2 so it should be 1 2 1 2 1 2 1 2
1
multiply the weight and the number
if the number is bigger than 9 then add the numbers forming it .
if the number is from multiplication of 10 then the ID is correct ..
example :-
1 7 9 3 7 9 2 5 0-ID
1 2 1 2 1 2 1 2 1-Weight
1 14 9 6 7 18 2 10 0-num x weight
1 5 9 6 7 9 2 1 0-(4)
sum = 40 then it is a correct ID.
I wrote most of it but then i noticed that it has to be a string . so my questions are :
is there a way to put a string into an array?as doing it with an
array is way easier.
how do i locate a place in a string ? like if i want the third
character in a string how do i locate it?.
and here is the code that i did it does not work yet and it needs alot of changes but i guess i will put it anyways :-
#include<stdio.h>
#define N 9
void input(int num[N]);
int check(int num[N]);
int main()
{
int num[N],a;
input(num);
a = check(num);
if (a = 1)
printf("ID is correct");
else printf("ID is NOT correct");
}
void input(int num[N])
{
int i;
printf("Enter your ID (9digits) :-");
for (i = 0;i < N;i++)
scanf("%d",num[i]);
}
int check(int num[N])
{
int w[N] = { 1,2,1,2,1,2,1,2,1 },wxnum[N],i,tota[N],sum,g;
for (i = 0;i < N;i++)
wxnum[i] = num[i] * w[i];
for (i = 0;i < N;i++)
{
if (wxnum[i] > 9)
tota[i] = wxnum[i] / 10 + wxnum[i] % 10;
else tota[i] = wxnum[i];
}
sum = tota[0] + tota[1] + tota[2] + tota[3] + tota[4] + tota[5] + tota[6] + tota[7] + tota[8];
g = sum % 10;
if (g = 0)
return 1;
else
return 0;
}
Thanks everyone for your help.
You can get a string by doing
/*N is defined as 9 in your code.*/
/*Considering there is always a '\0' in every string, we should allocat N + 1 slot for your nine numbers and the extra '\0'.*/
char chStr[N + 1];
scanf("%s", chStr);
After you got the string, you can take advantage of the values of charactor '0' - '9' (their values are from 48 to 57 correspondingly) in ASCII table, and easily transfer the charactors into integers by doing:
int i = 0;
for (i = 0; i < N; i++)
{
chStr[i] = chStr[i] - '0';
}
If you are restrict on the type, you can transfer these char values into int values by adding extra two lines:
int num[N];
int i = 0;
for (i = 0; i < N; i++)
{
chStr[i] = chStr[i] - '0';
num[i] = (int) chStr[i];
}
Please note that my code didn't check the validation of user input. To make it more secure, you can use
scanf("%9s", chStr);
to declare the maximum length that the user can input.