storing large integer consisting of zeroes and ones - c

I am stuck at a question where i have to read an integer D such that D follows the following rules:
-> D contains only zeros and ones
-> 1 ≤ Length of the number D ≤ 10^5.
-> D may begin with zero
And further, I have to store this number in array such that each digit of the no is stored in one cell of the array.
for example, if the number is 001011 it should be stored in the array like
arr[0]=0 arr[1]=0 arr[2]=1 arr[3]=0 arr[4]=1 arr[5]=1
How can this be done?

Your question is known as an XY problem (see https://meta.stackexchange.com/questions/66377/what-is-the-xy-problem).
The real problem (as you linked in a comment) doesn't require storing digits of D. Instead just count the number of ones and zeros.
Something like:
#include <stdio.h>
int main(int argc, const char *argv[]) {
int rc;
char c;
int numZero = 0;
int numOne = 0;
while(((rc = scanf("%c", &c)) == 1) && (c == '0' || c == '1'))
{
if (c == '0')
++numZero ;
else
++numOne;
printf("%c", c);
}
printf("\n");
printf("Zeros: %d Ones: %d\n", numZero, numOne);
return 0;
}
Input:
111000111
Output:
111000111
Zeros: 3 Ones: 6
Now you can do some logic on the counters to find out if the actual output shall be "Yes" or "No".
Good luck.

Related

How to find if an int value contains a specific number?

Odd question, but I'm currently working on an assignment where I am asked to do the following:
Write a program that prompts the user for an integer between 1 and 1000, then prints from 1 to the entered number EXCEPT when the following conditions are met:
If the current number is a multiple of 3 OR contains a 3, print "Hello"
if the current number is a multiple of 7 OR contains a 7, print "Goodbye"
I understand how to determine if a number is a multiple of 3 or 7, but how would I determine if it contained a 3 or 7? I have all of my code written except for this part, and I am just a little lost and unsure what to do.
Thanks!
You should use mod % to find if somethings is dividable with 3 or 7.
To find the last digit of a number you should use mod 10 and then divide it by 10 to get the next digit.
The digits could also be obtained by using three nested loops from 0 to 10 with a break at final number or with a function like this:
#include <stdio.h>
int contains(unsigned long num,int x){
while(num){
if(num % 10 == x){
return 1;
}
num/=10;
}
return 0;
}
int main(){
printf("%d\n",contains(1237002,7));
printf("%d\n",contains(10000002,7));
printf("%d\n",contains(1234002,7));
printf("%d\n",contains(123002,7));
printf("%d\n",contains(7237002,7));
printf("%d\n",contains(1237007,7));
printf("%d\n",contains(7,7));
}
As #chux-ReinstateMonica suggested, you could print the integer to a buffer and then search for the '3' and '7' characters.
#include <string.h>
#include <stdbool.h>
bool contains_3_or_7(int num) {
char buffer[15];
sprintf(buffer,"%i",num);
return (strchr(buffer,'3') || strchr(buffer,'7'))
}
I think you must split the 2 parts:
First with your % comparaison which determine if it's a multiple like if (x % 7 == 0) (0 means x is a multiple of 7)
and for the seconde part convert your int into an str with itoa function or by coding your own like this:
char* itoa(int i, char b[]){
char const digit[] = "0123456789";
char* p = b;
if(i<0){
*p++ = '-';
i *= -1;
}
int shifter = i;
do{ //Move to where representation ends
++p;
shifter = shifter/10;
}while(shifter);
*p = '\0';
do{ //Move back, inserting digits as u go
*--p = digit[i%10];
i = i/10;
}while(i);
return b;
}
then you can determine for each condition if they are true or false

C Programming: How to determine an exact match between 2 numbers

I am trying to find the exact match between two numbers and have my counter stop at the first instance when they are not a match. However the code I have written counts the entire string length of my numbers. Is there an alternative way to do this?
Since my counter is starting from the first decimal place and not 0. , it counts to 15 but should stop at 10.
#include<stdio.h>
#include<math.h>
#include<string.h>
#include<stdlib.h>
int main(){
char str[100];
char buf[100];
double l,m,a,b;
int c,d,t,u,r,q;
int count =0;
l=59874.141715197809000;
m=59874.141715197817000;
a= (l - (int)l);
b= (m -(int)m);
sprintf(str,"%.15f",a);
sprintf(buf,"%.15f",b);
c = strlen(str);
d = strlen(buf);
for(t=3;t<c;t++){
for(u=3;u<d;u++){
if(str[t]==buf[u]){
count++;
break;
}
}
}
printf("matching decimal places = %d \n",count);
return 0;
}
First, when comparing two strings, you only need to iterate to the length of the smallest string if the two strings differ in length.. That is, if you want to count the amount of sequential character matches in a string.
For example:
A = 0.99997552
B = 0.9999753
would need one for loop to compare.. You would only iterate up to the length of B to determine that 6 decimals match. Why? Because going any further is irrelevant since none of the extra digits would exist in B. Iterating past the end of an array is undefined behaviour anyway.
In your case both buffers are the same length so no worries there, but again, the shorter string won't have the extra digits found in the longer string.. Hence: Iterate up to the smallest length.
The solution can be done as follows:
#include <stdio.h>
#include <math.h>
#include <string.h>
#include <stdlib.h>
int main() {
//Create large enough buffer to hold 100 digits/characters..
char str[100] = {0};
char buf[100] = {0};
//Two doubles to be compared..
double l = 59874.141715197809000;
double m = 59874.141715197817000;
//Counter keeps track of matching digits..
int count = 0;
//Get rid of the base and keep only the decimals..
double a = (l - (int)l);
double b = (m - (int)m);
//Copy a maximum of 15 decimal places to `str` and `buf`
sprintf(str, "%.15f", a);
sprintf(buf,"%.15f", b);
//Get the length of both strings..
int c = strlen(str);
int d = strlen(buf);
//If C is smaller, iterate to length(c) else iterate to length(d).
for (int i = 2; i < (c < d ? c : d); ++i)
{
//If the two characters match, increment the count..
if (str[i] == buf[i])
{
++count;
}
}
//Print the amount of matching decimals..
printf("matching decimal places = %d \n", count);
return 0;
}
This may not be the answer, but do
if (number1 == number2)
{
// do something to stop it
}

Finding numbers with unique digits in C

I have to write a program that finds every number (except 0) which can be factored by numbers from 2-9.
For example first such a number would be number 2520 as it can be divided by every single number from 2 to 9.
It also has to be a number that contains only 1 type of digit of its own (no multiple digits in a number). So for example 2520 will not meet this requirement since there are two same digits (2). The example of a number that meets both requirements is number 7560. That is the point I don't how to do it. I was thinking about converting value in an array to string, and then putting this string in another array so every digit would be represented by one array entry.
#include <stdio.h>
#include <math.h>
int main() {
int i, n, x, flag, y = 0;
scanf("%d", &n);
double z = pow(10, n) - 1;
int array[(int)z];
for (i = 0; i <= z; i++) {
flag = 0;
array[i] = i;
if (i > 0) {
for (x = 2; x <= 9; x++) {
if (array[i] % x != 0) {
flag = 1;
}
}
if (flag == 0) {
y = 1;
printf("%d\n", array[i]);
}
}
}
if (y == 0) {
printf("not exist");
}
return 0;
}
This should give you a base:
#include <stdio.h>
#include <string.h>
int main()
{
char snumber[20];
int number = 11235;
printf("Number = %d\n\n", number);
sprintf(snumber, "%d", number);
int histogram[10] = { 0 };
int len = strlen(snumber);
for (int i = 0; i < len; i++)
{
histogram[snumber[i] - '0']++;
}
for (int i = 0; i < 10; i++)
{
if (histogram[i] != 0)
printf("%d occurs %d times\n", i, histogram[i]);
}
}
Output:
Number = 11235
1 occurs 2 times
2 occurs 1 times
3 occurs 1 times
5 occurs 1 times
That code is a mess. Let's bin it.
Theorem: Any number that divides all numbers in the range 2 to 9 is a
multiple of 2520.
Therefore your algorithm takes the form
for (long i = 2520; i <= 9876543210 /*Beyond this there must be a duplicate*/; i += 2520){
// ToDo - reject if `i` contains one or more of the same digit.
}
For the ToDo part, see How to write a code to detect duplicate digits of any given number in C++?. Granted, it's C++, but the accepted answer ports verbatim.
If i understand correctly, your problem is that you need to identify whether a number is consisted of multiple digits.
Following your proposed approach, to convert the number into a string and use an array to represent digits, i can suggest the following solution for a function that implements it. The main function is used to test the has_repeated_digits function. It just shows a way to do it.
You can alter it and use it in your code.
#include <stdio.h>
#define MAX_DIGITS_IN_NUM 20
//returns 1 when there are repeated digits, 0 otherwise
int has_repeated_digits(int num){
// in array, array[0] represents how many times the '0' is found
// array[1], how many times '1' is found etc...
int array[10] = {0,0,0,0,0,0,0,0,0,0};
char num_string[MAX_DIGITS_IN_NUM];
//converts the number to string and stores it in num_string
sprintf(num_string, "%d", num);
int i = 0;
while (num_string[i] != '\0'){
//if a digit is found more than one time, return 1.
if (++array[num_string[i] - '0'] >= 2){
return 1; //found repeated digit
}
i++;
}
return 0; //no repeated digits found
}
// test tha function
int main()
{
int x=0;
while (scanf("%d", &x) != EOF){
if (has_repeated_digits(x))
printf("repeated digits found!\n");
else
printf("no repeated digits\n");
}
return 0;
}
You can simplify your problem from these remarks:
the least common multiple of 2, 3, 4, 5, 6, 7, 8 and 9 is 2520.
numbers larger than 9876543210 must have at least twice the same digit in their base 10 representation.
checking for duplicate digits can be done by counting the remainders of successive divisions by 10.
A simple approach is therefore to enumerate multiples of 2520 up to 9876543210 and select the numbers that have no duplicate digits.
Type unsigned long long is guaranteed to be large enough to represent all values to enumerate, but neither int nor long are.
Here is the code:
#include <stdio.h>
int main(void) {
unsigned long long i, n;
for (n = 2520; n <= 9876543210; n += 2520) {
int digits[10] = { 0 };
for (i = n; i != 0; i /= 10) {
if (digits[i % 10]++)
break;
}
if (i == 0)
printf("%llu\n", n);
}
return 0;
}
This program produces 13818 numbers in 0.076 seconds. The first one is 7560 and the last one is 9876351240.
The number 0 technically does match your constraints: it is evenly divisible by all non zero integers and it has no duplicate digits. But you excluded it explicitly.

C program which is finding "happy" nums recursively

Hello guys i am trying to implement a program which is finding the happy numbers were between two numbers A and B.
Summing the squares of all the digits of the number, we replace the number with the outcome, and repeat the process. If after some steps the result is equal to 1 (and stay there), then we say that the number N is **<happy>**. Conversely, if the process is repeated indefinitely without ever showing the number 1, then we say that the number N is **<sad>**.
For example, the number 7 is happy because the procedure described above leads to the following steps: 7, 49, 97, 130, 10, 1, 1, 1 ... Conversely, the number 42 is sad because the process leads to a infinite sequence 42, 20, 4, 16, 37, 58, 89, 145, 42, 20, 4, 16, 37 ...
I try this right down but i am getting either segm faults or no results.
Thanks in advance.
#include <stdio.h>
#include <math.h>
#include <string.h>
#include <stdlib.h>
void happy( char * A, int n);
int numPlaces (long n);
int main(void)
{
long A,B;
int npA;
char *Ap;
printf("Give 2 Numbers\n");
scanf("%li %li",&A,&B);
npA = numPlaces(A);
Ap = malloc(npA);
printf("%ld %d\n",A,npA);
//Search for happy numbers from A to B
do{
sprintf(Ap, "%ld", A);
happy(Ap,npA);
A++;
if ( npA < numPlaces(A) )
{
npA++;
Ap = realloc(Ap, npA);
}
}while( A <= B);
}
//Finds happy numbers
void happy( char * A, int n)
{
//Basic Condition
if ( n == 1)
{
if (A[0] == 1 || A[0] == 7)
printf("%c\n",A[0]);
printf("%s\n",A);
return;
}
long sum = 0 ;
char * sumA;
int nsum;
int Ai;
//Sum the squares of the current number
for(int i = 0 ; i < n;i++)
{
Ai = atoi(&A[i]);
sum = sum + (Ai*Ai);
}
nsum = numPlaces (sum);
sumA = malloc(nsum);
sprintf(sumA, "%li", sum);
happy(sumA,nsum);
free(sumA);
}
//Count digits of a number
int numPlaces (long n)
{
if (n < 0) return 0;
if (n < 10) return 1;
return 1 + numPlaces (n / 10);
}
Thanks for your time.
by the definition of your program sad numbers will cause your program to run forever
Conversely, if the process is repeated indefinitely
You need to add a stopping condition, like if I have looped for 1000 times, or if you hit a well known non terminating number (like 4) (is there a definite list of these? I dont know)
I find this solution tested and working..
Thanks for your time and I am sorry for my vagueness.
Every advice about this solution would be welcome
#include <stdio.h>
#include <math.h>
#include <string.h>
#include <stdlib.h>
void happy( char * A, int n);
int numPlaces (long n);
int happynum = 0;
int main(void)
{
long A,B;
int npA;
char *Ap;
printf("Give 2 Numbers\n");
scanf("%li %li",&A,&B);
npA = numPlaces(A);
Ap = malloc(npA);
//Search for happy numbers from A to B
do{
sprintf(Ap, "%ld", A);
happy(Ap,npA);
if (happynum ==1)
printf("%s\n",Ap);
A++;
if ( npA < numPlaces(A) )
{
npA++;
Ap = realloc(Ap, npA);
}
}while( A <= B);
}
//Finds happy numbers
void happy( char * A, int n)
{
//Basic Condition
if ( n == 1)
{
if (A[0] == '3' || A[0] == '6' || A[0] == '9')
{
happynum = 0;
}
else
{
happynum = 1;
}
return;
}
long sum = 0;
char * sumA;
int nsum;
int Ai;
//Sum the squares of the current number
for(int i = 0 ; i < n;i++)
{
Ai = (int)(A[i]-48);
sum = sum + (Ai*Ai);
}
nsum = numPlaces (sum);
sumA = malloc(nsum);
sprintf(sumA, "%li", sum);
happy(sumA,nsum);
free(sumA);
}
//Count digits of a number
int numPlaces (long n)
{
if (n < 0) return 0;
if (n < 10) return 1;
return 1 + numPlaces (n / 10);
}
Your code uses some questionable practices. Yoe may be misguided because you are concerned about performance and memory usage.
When you allocate memory for the string, you forget to allocate one character for the null terminator. But you shouldn't be allocating, re-allocating and freeing constantly anyway. Dynamic memory allocation is expensive compared to your other operations.
Your limits are long, which may be a 32-bit or 64-bit signed integer, depending on your platform. The maximum number that can be represented with e 64-bit signed integer is 9,223,372,036,854,775,807. This is a number with 19 digits. Add one for the null terminator and one for a possible minus sign, so that overflow won't hurt, you and use a buffer of 21 chars on the stack.
You probably shouldn't be using strings inthe first place. Use the basic code to extract the digits: Split off the digit by taking the remainder of a division by 10. Then divide by 10 until you get zero. (And if you use strings with a fixed buffer size, as described above, you don't have to calculate the difits separately: sprintf returns the number of characters written to the string.
Your functions shouldn't be recursive. A loop is enough. As pm100 has noted, you need a termination criterion: You must keep track of the numbers that you have already visited. Each recursive call creates a new state; it is easier to keep an array, that can be repeatedly looked at in a loop. When you see a number that you have already seen (other than 1, of course), your number is sad.
Happy and sad numbers have this property that when your sum of squares is a number with a known happiness, the original number has this happiness, too. If you visit a known das number, the original number is sad. If you visit a known happy number, the original number is happy.
The limits of your ranges may ba large, but the sum of square digits is not large; it can be at most the number of digits times 81. In particular:
type max. number number of max. square sum dss
int 2,147,483,647 1,999,999,999 730
uint 4,294,967,295 3,999,999,999 738
long 9,223,372,036,854,775,807 8,999,999,999,999,999,999 1522
ulong 18,446,744,073,709,55,1616 9,999,999,999,999,999,999 1539
That means that when you take the sum of digit squares of an unsigned long, you will get a number that is smaller than 1540. Create an array of 1540 entries and mark all known happy numbers with 1. Then you can reduce your problem to taking the sum of digit squares once and then looking up the happiness of the number in this array.
(You can do the precalculation of the array once when you start the program.)

Using a separate method is a correct solution?

I'm trying to solve a problem from the book programming challenges by Skiena and when submitted to the online judge, one solution passed while the other one failed.
I'm trying to understand why one is an acceptable answer and the other is not. The only difference seems that one uses a separate method while the other does not. In which test would the second solution fail?
problem goes as follows:
The 3n + 1 problem
Consider the following algorithm to generate a sequence of numbers. Start with an integer n. If n is even, divide by 2. If n is odd, multiply by 3 and add 1. Repeat this process with the new value of n, terminating when n = 1. For example, the following sequence of numbers will be generated for n = 22:
22 11 34 17 52 26 13 40 20 10 5 16 8 4 2 1
It is conjectured (but not yet proven) that this algorithm will terminate at n = 1 for every integer n. Still, the conjecture holds for all integers up to at least 1, 000, 000.
For an input n, the cycle-length of n is the number of numbers generated up to and including the 1. In the example above, the cycle length of 22 is 16. Given any two numbers i and j, you are to determine the maximum cycle length over all numbers between i and j, including both endpoints.
Input
The input will consist of a series of pairs of integers i and j, one pair of integers per line. All integers will be less than 1,000,000 and greater than 0.
Output
For each pair of input integers i and j, output i, j in the same order in which they appeared in the input and then the maximum cycle length for integers between and including i and j. These three numbers should be separated by one space, with all three numbers on one line and with one line of output for each line of input.
Sample Input
1 10
100 200
201 210
900 1000
Sample Output
1 10 20
100 200 125
201 210 89
900 1000 174
The acceptable solution is as follows:
#include <stdio.h>
int cylen(int n){
int count = 1;
while (n !=1 ){
if (n%2 == 0)
n = n/2;
else
n = 3*n +1;
++count;
}
return count;
}
int maxcylen(int s, int e){
int tmp,i,maxcy, sz;
if(s>e){
tmp =s;
s = e;
e = tmp;
}
maxcy = 0;
for(i=s;i<=e;i++){
sz = cylen(i);
if (sz> maxcy)
maxcy =sz;
}
return maxcy;
}
int main(){
int s,e;
while(scanf("%d %d", &s, &e) != EOF){
printf("%d %d %d\n",s,e,maxcylen(s,e));
}
return 0;
}
The unacceptable one is as follows:
#include <stdio.h>
int cylen(int n){
int count = 1;
while (n !=1 ){
if (n%2 == 0)
n = n/2;
else
n = 3*n +1;
++count;
}
return count;
}
int main(){
int s,e, tmp,i,maxcy, sz;
while(scanf("%d %d", &s, &e) != EOF){
if(s>e){
tmp =s;
s = e;
e = tmp;
}
maxcy = 0;
for(i=s;i<=e;i++){
sz = cylen(i);
if (sz> maxcy)
maxcy =sz;
}
printf("%d %d %d\n",s,e,maxcy);
}
return 0;
}
in first solution you have two variables s and e which are defined in main function and two separate variables s and e which are defined only in maxcylen function
these variables are totally different ones
in first solution you're modifying s and e, but only inside function, so during output of result old ones from main are displayed, and this is right solution
to fix second solution, you need to do this:
int s,e, tmp,i,maxcy, sz, originalS, originalE; // note 2 additional variables
while(scanf("%d %d", &s, &e) != EOF){
originalS = s; // storing of values from file
originalE = e;
if(s>e){
tmp =s;
s = e;
e = tmp;
}
maxcy = 0;
for(i=s;i<=e;i++){
sz = cylen(i);
if (sz> maxcy)
maxcy =sz;
}
printf("%d %d %d\n",originalS,originalE,maxcy); // output of variables from file, instead of modified ones
}

Resources