So, I was working out some exercises from a recommended beginner's book: C Programming: A Modern Approach (2nd Edition) While working out one of the questions I found myself unable to proceed, as I couldn't return the number closest to the user's input.
Note: The question was asked before loops, functions and arrays were covered, thus I am assuming that these should not be required.
I managed to extract and simplify the problem to the following. Lets say I have the following numbers, and I want to return the number closest to the user's input:
10 20 30 40 50 60 70 80
printf("Enter a number to find closest value: ");
scanf("%d", &num);
For example:
User's input: 28
Closest number: 30
Next, I decided to find the difference between num and each of the numbers by subtracting from each.
difference1 = num - 10;
difference2 = num - 20;
and so on. (I am not using loops as these have not yet been covered in the book)
I taking into consideration, negative differences (25 - 40 = -15). If the difference is less than 0, I am multiplying the difference by -1 to get all the differences to a positive integer. By doing so I will be able to compare the differences successfully:
if (difference1 < 0) {
difference1 = difference1 * -1;
}
Next I am checking for the minimum difference in order to identify which was the closest number by doing:
if (difference1 < difference2) {
min1 = difference1;
}
else {
min1 = difference2;
}
if (difference3 < difference4) {
min2 = difference3;
}
else {
min2 = difference4;
}
if (difference5 < difference6) {
min3 = difference5;
}
else {
min3 = difference6;
}
if (difference7 < difference8) {
min4 = difference7;
}
else {
min4 = difference8;
}
if (min1 < min2) {
min5 = min1;
}
else {
min5 = min2;
}
if (min3 < min4) {
min6 = min3;
}
else {
min6 = min4;
}
if (min5 < min6) {
min = min5;
}
else {
min = min6;
}
I know this is a very long method, however I was unable to shorten the code without the use of a for-loop.
printf("Difference between the two numbers is %d\n", min);
Since min contains the difference between the user's input and the closest number I am unable to find a way to print the number closest to the user's input.
How can I trace the minimum difference to the original number which this was subtracted from ? Any suggestions would be appreciated, and please excuse the basic nature of this question.
I can help you to make the code shorter.
Here are my approach
int num = 71;
int diff,ans;
int div10 = (num / 10);
int lower = div10 * 10;
int upper = (div10 + 1) * 10;
if(lower<10) lower=10;
if(lower>80) lower=80;
if(upper<10) upper=10;
if(upper>80) upper=80;
int diff1 = lower - num;
int diff2 = upper - num;
if(diff1 < 0) diff1 *= -1;
if(diff2 < 0) diff2 *= -1;
if(diff1 < diff2) {
ans = lower;
diff = diff1;
}
else {
ans = upper;
diff = diff2;
}
printf("ans=%d, diff=%d\n",ans,diff);
Well what I would do:
int main(){
int closest;
int temp;
int a0 = 10, a1 = 20, a2 = 30; //and more..
int user_input = 28;
closest = abs(user_input - a0);
temp = abs(user_input - a1);
if (temp <= closest)
closest = temp;
//and so on
return 0;
}
Where abs is absolute value. Numbers should be in some data structure, because in the mean time you should ask if you still have something to check.
If you're dealing with 10s this should be quite simple:
num += 5;
closest_10 = num/10;
closest_10 *= 10;
Then you can have simple look up if you have an array of numbers. You can expand this to other multiples using a similar algorithm (say for 8s just replace 5 with 4 and 10 with).
As all numbers are fixed, the best approach (at least the most efficient once compiled) is to use the following snippet of code:
int closest(int number)
{
switch(number) {
case 0: case 1: case 2: case 3: case 4:
return 0;
case 5: case 6: case 7: case 8: case 9:
case 10: case 11: case 12: case 13: case 14:
return 10;
...
case 95: case 96: case 97: case 98: case 99: case 100:
return 100;
} /* switch */
} /* closest */
Even more efficient if you can inline the code instead of writing a function.
You need to better define: Lets say I have the following numbers.
How many numbers is the big question. Your example has them all as evenly divisible by 10. Your numbers are 10, 20, 30, and so on, and you mention a total of 8 numbers. Is it only 8 numbers maximum? Can they be any number? Will they all be integers? If its all integers and all divisible by 10, then you can use the modulo or modulus operator instead of subtraction.
The mod operator % only works on integers.
int a, b, c;
a = 3;
b = 25
c = a % 10; /* c will equal 3, 0 / 10 = 0 with remainder 3 */
c = b % 10; /* c will equal 5, 25 / 10 = 2 but remainder is 5 */
/* check if a number is even, just mod by 2 if zero then even */
if ( ( b % 2 ) == 0 )
printf(" value in b is even number\n");
else
printf(" value in b is odd number\n");
Related
I'm trying a challenge where I need to get a random number, and print the sum of the digits inside the number without duplicates:
for example, 123 will print 6 ( 1 + 2 + 3 ), and 32111 will do the same ( because we don't add duplicates to our sum, the sum of this number is similar to the sum of 123. )
In my solution I thought about using switch case for each number, and use a flag that its value is one, than in each case I add 1 to the flag, and when the flag is 2 I add the number to the sum, but I don't know how to avoid a case after it happend, which if I see it correctly will avoid me using multiple flags for each number (because if we could avoid a case after it happend, i just could set the flag back to one after the switch and do all the process again )
can you help me out? thanks a lot!
#include <stdio.h>
#define TEN 10
#define NINE 9
#define EIGHT 8
#define SEVEN 7
#define SIX 6
#define FIVE 5
#define FOUR 4
#define THREE 3
#define TWO 2
#define ONE 1
int main(void)
{
int answer = 0, i = 0, remain = 0, sum = 0, flag = 1;
printf("Enter a number: ");
scanf("%d", &answer);
while(answer >= ONE)
{
remain = answer % TEN;
answer /= TEN;
printf("%d\n", remain);
switch (remain)
{
case ONE:
{
flag++;
if (flag == TWO)
{
sum = sum + ONE;
}
break;
}
case TWO:
{
flag++;
if (flag == TWO)
{
sum = sum + TWO;
}
break;
}
case THREE:
{
flag++;
if (flag == TWO)
{
sum = sum + THREE;
}
break;
}
case FOUR:
{
flag++;
if (flag == TWO)
{
sum = sum + FOUR;
}
break;
}
case FIVE:
{
flag++;
if (flag == TWO)
{
sum = sum + FIVE;
}
break;
}
case SIX:
{
flag++;
if (flag == TWO)
{
sum = sum + SIX;
}
break;
}
case SEVEN:
{
flag++;
if (flag == TWO)
{
sum = sum + SEVEN;
}
break;
}
case EIGHT:
{
flag++;
if (flag == TWO)
{
sum = sum + EIGHT;
}
break;
}
case NINE:
{
flag++;
if (flag == TWO)
{
sum = sum + NINE;
}
break;
}
default:
{
}
}
}
printf("The sum of the number is: %d", sum);
return 0;
}
Try using a bitmask representing each case. The main idea is to keep track for each number (from 0 to 9) using only one integer. Some bit of this single integer can be used as to find whether this number was seen before or not. If the bit is 0 then the corresponding number is seen for the first time (and we now set the bit to 1), and if we see that the bit is already 1, then we don't add it into our final sum.
int mask = 0;
switch (remain) {
case 1: // 001
if ((mask & 1) == 0) { // 1 = 1 << 0
sum += 1;
mask |= 1;
}
break;
...
case 3: // 100
if ((mask & 4) == 0) { // 4 = 1 << 2
sum += 3;
mask |= 4;
}
break;
...
case n:
if ((mask & k) == 0) { // k = 1 << (n-1)
sum += n;
mask |= k;
}
break;
...
Now you can see a pattern in the last case I used, we can simplify this switch-case into a single if statement.
int mask = 0;
int sum = 0;
while (answer) {
remain = answer % 10;
answer /= 10;
int offset = remain;
int flag = 1 << offset;
if ((mask & flag) == 0) {
sum += remain;
mask |= flag;
}
}
// sum contains the required answer
Each bit represents one of the cases, since you have only 10 cases this is the most efficient way to track the flags as you have more than 10 bits for an integer and it will be wastage to have a separate boolean flag for 0 to 9.
A case-term is a compile time constant, so you cannot "disable" it at runtime at the c language level. You would have to introduce a separate flag for each digit then.
I'd say - and have a look at you code - the switch-case approach is not the best as you duplicate a lot of similar code. A much easier way would be to have an array of 10 ints, each standing for a particular digit, and once a digit is encountered, set the respective array element to 1. At the end sum up in a loop.
If you have troubles getting this approach running, don't hesitate to ask again...
Can you help me? When I execute this statement, it keeps saying out of upper bound even if it isn't. What is the problem? Thanks.
if(number_o_1 <= higher)
{
printf("Random number has reached upper bound.\n");
}
else
{
printf("Number 1: %d\n", number_o_1);
number_o_up=number_o_1+n_multiple*(x-1);
while(number_o_up<=higher)
for(x=2;x<number_r;x++)
printf("Number %d: %d\n", x,number_o_up);
}
number_o_1<= higher
Sure you want to print that the number has reached the upper bound when it's lesser than or equal to your upper bound?
It is little hard to figure the logic you would like to implement, but please see the example with exact values and comments to hit the else block.
#include <stdio.h>
int x = 2;
int higher = 100;
int number_o_1 = 10;
int number_r = 4;
int number_o_up = 1;
int n_multiple = 2;
int main()
{
if(number_o_1 >= higher) // probably want >= here to hit else
{
printf("Random number has reached upper bound.\n");
}
else
{
printf("Number 1: %d\n", number_o_1);
number_o_up = number_o_1 + n_multiple * (x-1); // number_o_up = 12
while(number_o_up <= higher) // 12 <= 100
{
for(x = 2; x < number_r; x++) // cond. 2 < 4
{
printf("Number %d: %d\n", x, number_o_up);
}
number_o_up++; //needs to change higher or number_o_up to get out of while
}
}
}
Output:
sh-4.3$ main
Number 1: 10
Number 2: 12
Number 3: 12
Number 2: 13
Number 3: 13
Number 2: 14
...
Number 3: 100
Hello Guys I am trying to solve one problem given on the Hacker Rank. Though the problem is quite simple, I was thinking to solve the problem using some other concepts.
The problem is
Desription
You are given an integer N. Find the digits in this number that exactly divide N (division that leaves 0 as remainder) and display their count. For N=24, there are 2 digits (2 & 4). Both of these digits exactly divide 24. So our answer is 2.
Input Format
The first line contains T (the number of test cases), followed by T lines (each containing an integer N).
Constraints
1≤T≤15
0
I solved the problem earlier by defining variable N as of type long long but that i guess will not be the efficient way to solve the problem.
So i thought why not declare the variable N as an character array. This way we can also use the program to store the number greater then the max limit of long long also rt?
Say i used the following code
#include <stdio.h>
#include <string.h>
int main()
{
int i,t;
char n[20];
scanf("%d",&t);
while(t--)
{
scanf("%s",n);
int len=strlen(n);
int f2,f3,f5,f7,f4,count;
f2=f3=f5=f7=f4=count=0;
for( i=0;i<len;++i)
{ int sum=0;
switch((int)n[i])
{
case 48: break;
case 49: ++count;break;
case 50: if((int)n[len-1]%2==0) // divisibility by 2
{
++count;f2=1;
}break;
case 51: for(i=0;n[i]!='\0';++i) // divisibility by 3
{
sum+=(int)n[i];
}
if(sum%3==0)
{
++count;
f3=1;
}break;
case 52: if(f2==1) // divisibility by 4
{
++count;
f4=1;
} break;
case 53: if(n[len-1]=='5' || n[len-1]=='0') // divisibility by 5
{
++count;
f5=1;
}break;
case 54: if(f2==1 && f3==1) // divisibility by 6
{
++count;
break;
}
case 55: // Code for divisibilty by 7
case 56: if(f2==1 && f4==1) // divisibility by 8
{ ++count;
break;
}
case 57: if(f3==1) // divisibility by 9
{
++count;
break;
}
}
}
printf("%d\n",count);
}
return 0;
}
The program is working fine but the only problem is I am not able to rt the code for divisibility by 7 anu suggestions will be helpful, And also which is the better way to solve the problem , This way in which the variable N is declared as the character array or by declaring the variable N as long long.
Any improvements for the above code would also be appreciated .....:)
Divisibility by 7 can be checked by this rule
Also you can use this mod() function to check divisibility by any number :
int mod(char *n, int val)
{
int sum = 0;
for(int i=0; n[i]; i++)
{
sum = sum*10 + (n[i]-'0');
if(sum >= val)
sum = sum % val;
}
return sum;
}
it will return 0, if the number n is divisible by number val :)
And you don't need to check for every redundant digit.
First check the available digit then check for divisibility once for each digit.
Here's what you can do -
#include <stdio.h>
#include <string.h>
int mod(char *n, int val)
{
int sum = 0;
for(int i=0; n[i]; i++)
{
sum = sum*10 + (n[i]-'0');
if(sum >= val)
sum = sum % val;
}
return sum;
}
int main()
{
int i,t;
int digit[10];
char n[20];
scanf("%d",&t);
while(t--)
{
scanf("%s",n);
int len=strlen(n);
int cnt=0;
memset(digit,0,sizeof(digit)); // setting all the digit to 0
for(i=0;i<len;i++)
digit[n[i]-'0']++;
for(i=1;i<10;i++)
{
if(digit[i]==0) // number doesn't contain any of this digit
continue;
if(mod(n,i)==0)
cnt+=digit[i]; // Adding the digit to the answer
}
printf("%d\n",cnt);
}
return 0;
}
How this works :
for n = 147 and val = 7
sum = 0
1st iter >> sum = 0*10 + 1 = 1
sum < val, so continue
2nd iter >> sum = 1*10 + 4 = 14
sum >= val, so sum = sum % val = 14 % 7 = 0
3rd iter >> sum = 0*10 + 7 = 7
sum >= val, so sum = sum % val = 7 % 7 = 0
as the final sum is 0, so we can say that n is divisible by val :)
I got stuck in one algorithm question. Please suggest me some efficient algorithm for the below problem
Question is
Find numbers of subarrays(in range between 0 < R < N) whose sum is divisible by given number.
My approach:
Input: 0 5 3 8 2 1
Sum: 0 0 5 8 16 18 19
Mod 3: 0 0 2 2 1 0 1
No. of ways to chooses 0 , 1 or 2 is NC2
Problem: Is i am have asked to choose between some range i.e from 2 to 5 so array will become:
3 8 2 1
Does I have to recalculate the sum and Mod again or the original MOd array will give me a correct answerSecond Problem: What IF i change one element i.e 8 is change to 11 , How it will be effectFor the above problem I am considering using BIT dp[4][Max. Element] if mod is 0 update dp[0] if 1 update dp[1] so on How To update if VAlue at index is change
check this out:
this subroutine findes the largest subarray which its sum divided by 3.
It goes only once over at the array with no extra space.
here c++ code:
int largest_3_divider_subarray(int* a, int len){
int cum_sum = 0;
int index_of_first_one = -1;
int index_of_first_two = -1;
int absolute_maximal = 0;
int current_maximal = 0;
bool flag1 = 1, flag2 = 1;
for(int i = 0; i < len; ++i){
cum_sum += a[i];
switch (cum_sum%3)
{
case 1:
if(flag1){
index_of_first_one = i;
flag1 = 0;
}else
current_maximal = i - index_of_first_one;
break;
case 2:
if(flag2){
index_of_first_two = i;
flag2 = 0;
}else
current_maximal = i - index_of_first_two;
break;
case 0:
current_maximal = i;
}
if(current_maximal > absolute_maximal)
absolute_maximal = current_maximal;
}
return absolute_maximal + 1;
}
int main()
{
int A[]= {6,8,-2,0,9,13,1};
int k = largest_3_divider_subarray(A,7);
return 0;
}
It could be a running contest problem however there's a dp approach for that. you need to combine it with segment tree if you want to solve the running contest problem.
the basic idea:
take care of %3 value of the sum of the digits of the substrings/subarrays which end at the current character/digit.
Then take it as a subproblem and try to get the number of subarrays which end at the next character/digit with different mod values using the previously obtained data.
(characteristics of dp: we try to solve a subproblem then using the values obtained we try to solve a subproblem of bigger instance).
You just have to combine with segment trees if you want to solve the running contest problem in codechef
There are some good tutorials available for segment tree
public static int largest_3_divider_subarray(int a[]){
int cum_sum = 0;
int index_of_first_one = -1;
int index_of_first_two = -1;
int absolute_maximal = 0;
int current_maximal = 0;
boolean flag1 = true, flag2 = true;
for(int i = 0; i < a.length; ++i){
cum_sum += a[i];
switch ((cum_sum%3))
{
case 1:
case -2:
if(flag1){
index_of_first_one = i;
flag1 = false;
}else
current_maximal = i - index_of_first_one;
break;
case 2:
case -1:
if(flag2){
index_of_first_two = i;
flag2 = false;
}else
current_maximal = i - index_of_first_two;
break;
case 0:
current_maximal = i+1;
}
if(current_maximal > absolute_maximal)
absolute_maximal = current_maximal;
}
return absolute_maximal ;
}
I am accepting a composite number as an input. I want to print all its factors and also the largest prime factor of that number. I have written the following code. It is working perfectly ok till the number 51. But if any number greater than 51 is inputted, wrong output is shown. how can I correct my code?
#include<stdio.h>
void main()
{
int i, j, b=2, c;
printf("\nEnter a composite number: ");
scanf("%d", &c);
printf("Factors: ");
for(i=1; i<=c/2; i++)
{
if(c%i==0)
{
printf("%d ", i);
for(j=1; j<=i; j++)
{
if(i%j > 0)
{
b = i;
}
if(b%3==0)
b = 3;
else if(b%2==0)
b = 2;
else if(b%5==0)
b = 5;
}
}
}
printf("%d\nLargest prime factor: %d\n", c, b);
}
This is a bit of a spoiler, so if you want to solve this yourself, don't read this yet :). I'll try to provide hints in order of succession, so you can read each hint in order, and if you need more hints, move to the next hint, etc.
Hint #1:
If divisor is a divisor of n, then n / divisor is also a divisor of n. For example, 100 / 2 = 50 with remainder 0, so 2 is a divisor of 100. But this also means that 50 is a divisor of 100.
Hint #2
Given Hint #1, what this means is that we can loop from i = 2 to i*i <= n when checking for prime factors. For example, if we are checking the number 100, then we only have to loop to 10 (10*10 is <= 100) because by using hint #1, we will get all the factors. That is:
100 / 2 = 50, so 2 and 50 are factors
100 / 5 = 20, so 5 and 20 are factors
100 / 10 = 10, so 10 is a factor
Hint #3
Since we only care about prime factors for n, it's sufficient to just find the first factor of n, call it divisor, and then we can recursively find the other factors for n / divisor. We can use a sieve approach and mark off the factors as we find them.
Hint #4
Sample solution in C:
bool factors[100000];
void getprimefactors(int n) {
// 0 and 1 are not prime
if (n == 0 || n == 1) return;
// find smallest number >= 2 that is a divisor of n (it will be a prime number)
int divisor = 0;
for(int i = 2; i*i <= n; ++i) {
if (n % i == 0) {
divisor = i;
break;
}
}
if (divisor == 0) {
// we didn't find a divisor, so n is prime
factors[n] = true;
return;
}
// we found a divisor
factors[divisor] = true;
getprimefactors(n / divisor);
}
int main() {
memset(factors,false,sizeof factors);
int f = 1234;
getprimefactors(f);
int largest;
printf("prime factors for %d:\n",f);
for(int i = 2; i <= f/2; ++i) {
if (factors[i]) {
printf("%d\n",i);
largest = i;
}
}
printf("largest prime factor is %d\n",largest);
return 0;
}
Output:
---------- Capture Output ----------
> "c:\windows\system32\cmd.exe" /c c:\temp\temp.exe
prime factors for 1234:
2
617
largest prime factor is 617
> Terminated with exit code 0.
I presume you're doing this to learn, so I hope you don't mind a hint.
I'd start by stepping through your algorithm on a number that fails. Does this show you where the error is?
You need to recode so that your code finds all the prime numbers of a given number, instead of just calculating for the prime numbers 2,3, and 5. In other words, your code can only work with the number you are calculating is a prime number or is a multiple of 2, 3, or 5. But 7, 11, 13, 17, 19 are also prime numbers--so your code should simply work by finding all factors of a particular number and return the largest factor that is not further divisible.
Really, this is very slow for all but the smallest numbers (below, say, 100,000). Try finding just the prime factors of the number:
#include <cmath>
void addfactor(int n) {
printf ("%d\n", n);
}
int main()
{
int d;
int s;
int c = 1234567;
while (!(c&1)) {
addfactor(2);
c >>= 1;
}
while (c%3 == 0) {
addfactor(3);
c /= 3;
}
s = (int)sqrt(c + 0.5);
for (d = 5; d <= s;) {
while (c % d == 0) {
addfactor(d);
c /= d;
s = (int)sqrt(c + 0.5);
}
d += 2;
while (c % d == 0) {
addfactor(d);
c /= d;
s = (int)sqrt(c + 0.5);
}
d += 4;
}
if (c > 1)
addfactor(c);
return 0;
}
where addfactor is some kind of macro that adds the factor to a list of prime factors. Once you have these, you can construct a list of all the factors of the number.
This is dramatically faster than the other code snippets posted here. For a random input like 10597959011, my code would take something like 2000 bit operations plus 1000 more to re-constitute the divisors, while the others would take billions of operations. It's the difference between 'instant' and a minute in that case.
Simplification to dcp's answer(in an iterative way):
#include <stdio.h>
void factorize_and_print(unsigned long number) {
unsigned long factor;
for(factor = 2; number > 1; factor++) {
while(number % factor == 0) {
number = number / factor;
printf("%lu\n",factor);
}
}
}
/* example main */
int main(int argc,char** argv) {
if(argc >= 2) {
long number = atol(argv[1]);
factorize_and_print(number);
} else {
printf("Usage: %s <number>%<number> is unsigned long", argv[0]);
}
}
Note: There is a number parsing bug here that is not getting the number in argv correctly.