How can I locate the same highest digit? - c

This code can locate the same digit in a multiple numbering system. The problem I have is that how can I locate the same highest digit if there is another same digit but lower?
Example Output
Can locate the same digit
Enter the random number: 32432
Greatest digit that occurred more than once = 3
Cannot locate the same highest digit because the program can only locate the lowest
Enter the random number: 34745676
Greatest digit that occurred more than once = 4
#include <stdio.h>
int main() {
char c;
int counts[10] = {0,0,0,0,0,0,0,0,0,0};
int max = 0;
printf("Enter the random number: ");
while(c=getc(stdin)){
if (c=='\n') break;
counts[c-'0']++;
}
for(int i=3; i<8; i++) {
if(counts[i] > counts[max]) max=i;
}
printf("Greatest digit that occurred more than once = %i",max);
return 0;
}

Rather then search only for digits 3 to 7, search digits 0 to 9.
Look for counts > 1
Recognize that there may be no solution with a digit that occurs 2 or more times.
There may exist more than 1 digit with the same max count greater than 1. Below simply reports the first one. You may want something different.
Use an int c to distinguish the 257 different results from getc().
Be prepared to handle input that is not a digit nor '\n'.
Append a '\n' to output.
...
// char c;
int c;
int counts[10] = {0,0,0,0,0,0,0,0,0,0};
int max = 0;
printf("Enter the random number: ");
while(c=getc(stdin)){
// if (c=='\n') break;
if (!isdigit(c)) break;
counts[c-'0']++;
}
// for(int i=3; i<8; i++) {
for(int i=0; i<10; i++) { // Note 1
// if(counts[i] > counts[max]) max=i;
if(counts[i] > 1 && counts[i] > counts[max]) max=i; // Note 2
}
if (counts[max] > 1) {
printf("Greatest digit that occurred more than once = %i\n",max);
} else {
printf("Greatest digit that occurred more than once did not occur\n", max);
}
Note 1: Could start at 1 as 0 is the default max.
Note 2: Could omit the counts[i] > 1 && as that consideration is tested after the loop. Left it in here as conceptually we only want to consider cases where the count is > 1.

Assumptions
You for loop runs from 3 to 8 which means it does not scan every cell of the array. Even if you scan it from 0 to 9 you will still not be able to get the output you want.
Explanation
If i understood corectly, for the input 34745676 the correct result is 7.
If that's the case you have to change your for in some way, because right now as soon as it finds the max value the condition won't be true if another digit later (which means higher digit) has the same value in order to change the value of max.
One Solution
Change your for loop to:
int max = 0;
for (int i = 1; i < 10; i++)
if (counts[i] >= counts[max])
max = i;
Demonstration
With input = 34745676 your array will look something like this after the while loop:
counts[10] = { 0, 0, 0, 1, 2, 1, 2, 2, 0, 0 }
Since the condition inside for is true if there is a greater value or the same value from the current max value, 2 >= 2 is true, hence the assignment max = i will occur on equal values as well and since the array is scanned 0 to 9, position of higher digit will be assigned last each time even if there is the same value on a lower digit.

Related

function that returns the sum of the longest arithmetic sequence(without using arrays)

So I have this problem I'm trying to solve for a couple of days now, and I just feel lost.
The function basically needs to get the size(n) of a sequence.
The user inputs the size, and then the function will ask him to put the numbers of the sequence one after the other.
Once he puts all the numbers, the function needs to return the sum of the longest sequence.
For example, n=8, and the user put [1,3,5,7,11,13,15,16].
The result will be 16 because [1,3,5,7] is the longest sequence.
If n=8 and the user put [1,3,5,7,11,15,19,20], the result will be 52, because although there are 2 sequences with the length of 4, the sum of [7,11,15,19] is bigger then [1,3,5,7].
The sequence doesn't necessarily needs to be increasing, it can be decreasing too.
The function can't be recursive, and arrays can't be used.
I hope it's clear enough what the problem is, and if not, please let me know so I'll try to explain better.
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
int main()
{
int i, size, num, nextNum, diff, prevDiff, currSeqLength = 0, currSum, prevSum = 0;
printf("Please enter the arithmetic list size: ");
scanf_s("%d", &size);
for (i = 1; i <= size; i++)
{
printf("Please enter num: ");
scanf_s("%d", &num);
while (i == 1)
{
prevSum = num;
nextNum = num;
currSeqLength++;
break;
}
while (i == 2)
{
currSum = prevSum + num;
diff = num - nextNum;
nextNum = num;
currSeqLength++;
break;
}
while (i >= 3)
{
prevDiff = diff;
diff = num - nextNum;
nextNum = num;
if (prevDiff == diff)
{
currSum += num;
currSeqLength++;
break;
}
else
{
prevDiff = diff;
// diff now should be the latest num - previous one
}
}
}
}
This is basically what I've managed so far. I know some things here aren't working as intended, and I know the code is only half complete, but I've tried so many things and I can't seem to put my finger on what's the problem, and would really love some guidance, I'm really lost.
A few problems I encountered.
When I enter a loop in which the difference between the new number and the old one is different than the previous loops(for instance, [4,8,11]), I can't seem to manage to save the old number(in this case 8) to calculate the next difference(which is 3). Not to mention the first 2 while loops are probably not efficient and can be merged together.
P.S I know that the code is not a function, but I wrote it this way so I can keep track on each step, and once the code works as intended I convert it into a function.
I tried out your code, but as noted in the comments, needed to keep track at various stages in the sequence checks which sequence had the longest consistent difference value. With that I added in some additional arrays to perform that function. Following is a prototype of how that might be accomplished.
#include <stdio.h>
#include <stdlib.h>
int main()
{
int len, diff, longest;
printf("Enter the size of your sequence: ");
scanf("%d", &len);
int num[len], seq[len], sum[len];
for (int i = 0; i < len; i++)
{
printf("Enter value #%d: ", i + 1);
scanf("%d", &num[i]);
seq[i] = 0; /* Initialize these arrays as the values are entered */
sum[i] = 0;
}
for (int i = 0; i < len - 1; i++)
{
seq[i] = 1; /* The sequence length will always start at "1" */
sum[i] = num[i];
diff = num[i + 1] - num[i];
for (int j = i; j < len - 1; j++)
{
if (diff == num[j + 1] - num[j])
{
sum[i] += num[j + 1]; /* Accumulate the sum for this sequence */
seq[i] += 1; /* Increment the sequence length for this sequence portion */
}
else
{
break;
}
}
}
longest = 0; /* Now, determine which point in the lise of numbers has the longest sequence and sum total */
for (int i = 1; i < len; i++)
{
if ((seq[i] > seq[longest]) || ((seq[i] == seq[longest]) && (sum[i] > sum[longest])))
{
longest = i;
}
}
printf("The sequence with the longest sequence and largest sum is: [%d ", num[longest]);
diff = num[longest + 1] - num[longest];
for (int i = longest + 1; i < len; i++)
{
if ((num[i] - num[i - 1]) == diff)
{
printf("%d ", num[i]);
}
else
{
break;
}
}
printf("]\n");
return 0;
}
Some points to note.
Additional arrays are defined to track sequence length and sequence summary values.
A brute force method is utilized reading through the entered value list starting with the first value to determine its longest sequence length and continuing on to the sequence starting with the second value in the list and continuing on through the list.
Once all possible starting points are evaluated for length and total, a check is then made for the starting point that has the longest sequence or the longest sequence and largest sum value.
Following is a some sample terminal output utilizing the list values in your initial query.
#Dev:~/C_Programs/Console/Longest/bin/Release$ ./Longest
Enter the size of your sequence: 8
Enter value #1: 1
Enter value #2: 3
Enter value #3: 5
Enter value #4: 7
Enter value #5: 11
Enter value #6: 13
Enter value #7: 15
Enter value #8: 16
The sequence with the longest sequence and largest sum is: [1 3 5 7 ]
#Dev:~/C_Programs/Console/Longest/bin/Release$ ./Longest
Enter the size of your sequence: 8
Enter value #1: 1
Enter value #2: 3
Enter value #3: 5
Enter value #4: 7
Enter value #5: 11
Enter value #6: 15
Enter value #7: 19
Enter value #8: 20
The sequence with the longest sequence and largest sum is: [7 11 15 19 ]
No doubt this code snippet could use some polish, but give it a try and see if it meets the spirit of your project.
I know code-only answers are frowned upon, but this is the simplest I can come up with and its logic seems easy to follow:
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
int main()
{
int i, size;
int currNum, currDiff;
int prevNum = 0, prevDiff = 0;
int currSum = 0, currSeqLen = 0;
int bestSum = 0, bestSeqLen = 0;
printf("Please enter the arithmetic list size: ");
scanf_s("%d", &size);
for (i = 0; i < size; i++)
{
printf("Please enter num: ");
scanf_s("%d", &currNum);
if (currSeqLen > 0)
{
currDiff = currNum - prevNum;
if (currSeqLen > 1 && currDiff != prevDiff)
{
/* New arithmetic sequence. */
currSeqLen = 1;
currSum = prevNum;
}
prevDiff = currDiff;
}
currSum += currNum;
prevNum = currNum;
currSeqLen++;
if (currSeqLen > bestSeqLen ||
currSeqLen == bestSeqLen && currSum > bestSum)
{
/* This is the best sequence so far. */
bestSeqLen = currSeqLen;
bestSum = currSum;
}
}
printf("\nbest sequence length=%d, sum=%d\n", bestSeqLen, bestSum);
return 0;
}
I have omitted error checking for the scanf_s calls. They can be changed to scanf for non-Windows platforms.

How to make a series that adds up by 5 every 5 counts using for loop?

I'm kind of new in C programming and I'm trying to make a program that prints the nth term of a series and every 5 counts, it adds up by 5.
Example: 1, 2, 3, 4, 9, 10, 11, 12, 17, 18, 19, 20, 25......
Here is my code
int num,digit,count = 1;
printf("Enter n: ");
scanf("%d", &num);
for(int i=1; i<=num; i++){
count++;
if(count > 5){
count = 0;
i+=4;
}
printf("%d ",i);
}
My code doesn't get to the specific nth term that I'm asking for. For example, I've inputted 10 and it only shows up until the 6th term
The thing to do is get clear in your head what you want to do and how you are going to do it. Rather than tinkering with code, break things down into simple parts and make them clear.
#include <stdio.h>
int main(void)
{
int num = 10;
// Method 1: Spell everything out.
// i counts number of terms printed.
// j counts number of terms since last multiple of four terms.
// k is current term.
for (
int i = 0, j = 0, k = 1; // Initialize all counters.
i < num; // Continue until num terms are printed.
++i) // Update count.
{
printf("%d ", k); // Print current term.
++j; // Increment four-beat count.
if (4 <= j)
{
// Every fourth term, reset j and increment the term by 5.
j = 0;
k += 5;
}
else
// Otherwise, increment the term by 1.
k += 1;
}
printf("\n");
// Method 2: Use one counter and calculate term.
// Iterate i to print num terms.
for (int i = 0; i < num; ++i)
/* Break the loop count into two parts: the number of groups of 4
(i/4) and a subcount within each group (i%4). Looking at the
starts of each group (1, 9, 17, 25...), we see each is eight
greater than the previous one. So we multiply the group number by
8 to get the right offsets for them. Within each group, the term
increments by 1, so we use i%4 directly (effectively multiplied by
1). Then (i/4)*8 + i%4 would start us at 0 for i=0, but we want to
start at 1, so we add 1.
*/
printf("%d ", (i/4)*8 + i%4 + 1);
printf("\n");
}
You shall not change the variable i within the body of the for loop.
You need to introduce one more variable that will store the current outputted number.
Here is a demonstration program.
#include <stdio.h>
int main(void)
{
unsigned int n = 0;
printf( "Enter n: " );
scanf( "%u", &n );
for ( unsigned int i = 0, value = 0, count = 1; i < n; i++ )
{
if ( count == 5 )
{
value += 5;
count = 1;
}
else
{
++value;
}
printf( "%u ", value );
++count;
}
}
The program output is
Enter n: 13
1 2 3 4 9 10 11 12 17 18 19 20 25
Here's another take that I think is a bit less complicated, with explanations in the comments:
#include <stdio.h>
int main(void)
{
int num, count = 1;
num = 20;
// if you look closely, you actually have an initial condition before the
// main pattern starts. Once the pattern starts, its actually every _fourth_
// term that gets added by 5. You'll make things easier on yourself if you
// print out this initial condition, then handle the pattern in the loop.
// If you really want to be correct, you can wrap this in a if (num > 0) check
printf("%d ", count++);
// start at 1, because we already printed the first item
for(int i=1; i<num; i++, count++)
{
// now we can focus on every fourth term
if (i % 4 == 0)
{
// if it's the fourth one, add 5 to the previous value
// Of course this simplifies to count += 4
count = (count-1) + 5;
}
printf("%d ",count);
}
}
Demonstration

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.

Count the number of integers in C

so I want to create a code that finds the quantity of numbers in a number. So this may sound weird, but it works something like this.
Input
12893012
Output
1 2 2 1 0 0 0 0 1 1
So the output means that in 12893012, there is one 0, two 1's, two 2's, one 3, no 4, no 5, no 6, no 7, one 8, and one 9.
#include <stdio.h>
int main()
{
int n,count=0;
printf("Enter an integer: ");
scanf("%d", &n);
while(n!=0)
{
n/=10; /* n=n/10 */
++count;
}
printf("Number of digits: %d",count);
}
My code only seems to find the number of digits in the number, any ideas? Thanks a lot btw.
Put it in an array and count.
Roughly,
int count[10] = {0};
while(n != 0)
{
count[n % 10]++;
n /= 10;
}
Print out the result.
You keep incrementing count but without checking the digit. This will just give you the number of digits. You need an array in which you can store the count for each digit.
int digitCounts[10];
//...
while (n != 0){
digitCounts[n % 10]++;
n /= 10;
}
You can use mod (%) to make it easier, because % 10 gives the last digit.
Make an array that stores the digit count. Remainder operator will give you the last digit which will be between 0 and 9.
int digit[10];
//...
while(n!=0)
{
int d = n % 10;
digit[d]++
//...
And then print it in a loop.
I suggest creating an array (or 10 variables) which hold quantitiy of digits, then reading digits one by one and checking what digit it is.
You can read single digit using
scanf(%1d, &variableName)
or
getchar()
functions.
all thanks go to #rohit89,#this and #Arc676
this is just a correction when zero (0) is entered
int count[10] = {0};
if(n){
while(n != 0)
{
count[n % 10]++;
n /= 10;
}
}else
count[0]=1;

Determine Prime Numbers using SINGLE do-while Loop

I wrote this program per my professor's instruction. Turns out he wanted us to use a SINGLE do-while loop. While I did technically do that... this won't fly. I can't figure out how to do it without using a for-loop or at least another loop of some other type. He said it could use continue or break statements--but that it might not be necessary.
I would appreciate not just re-writing my code--while this is handy, I don't learn from it well.
I appreciate any and all help.
int main() {
int max, x, n = 2; //init variables
//start n at 2 because 1 isn't prime ever
//asks user for max value
printf("Enter max number: ");
scanf("%i", &max);
/*prints prime numbers while the max value
is greater than the number being checked*/
do {
x = 0; //using x as a flag
for (int i = 2; i <= (n / 2); i++) {
if ((n % i) == 0) {
x = 1;
break;
}
}
if (x == 0) //if n is prime, print it!
printf("%i\n", n);
n++; //increase number to check for prime-ness
} while (n < max);
return 0;
}
This is definitely doable. The trick is to have a test variable, and each iteration through your while loop, check the test variable against your current number. Always start the test variable at 2 (every natural number > 0 is divisible by 1)
Cases to consider:
Our current number is divisible by the test variable -- number is NOT prime, increase the current number and reset the test variable.
Our test variable is greater than the square root of the current number. By definition, it CANNOT divide the current number, so the current number has to be prime (we have tried all numbers lower than the square root of the current number and none of them divide it). Increase the current number and reset the test variable.
Lastly, if either above case isn't true, we have to try the next number higher. Increment the test variable.
I have not provided the code as you asked to not have it re-written, but can provide if you would like.
EDIT
#include <stdio.h>
#include <math.h>
int main(void)
{
int max = 20;
int current = 4;
int checker = 2;
do{
if(checker > sqrt((double)current))
{
checker = 2;
printf("%d is prime\n",current);
current++;
}
else if(current % checker == 0)
{
checker = 2;
printf("%d is NOT prime\n",current);
current++;
}
else
checker++;
}while(current < max);
}
Output:
4 is NOT prime
5 is prime
6 is NOT prime
7 is prime
8 is NOT prime
9 is NOT prime
10 is NOT prime
11 is prime
12 is NOT prime
13 is prime
14 is NOT prime
15 is NOT prime
16 is NOT prime
17 is prime
18 is NOT prime
19 is prime
I won't give you the exact code, but two pointers that should help you:
First, a for loop can be written as a while loop (and, vice versa)
for (int i=0; i< 100; ++i)
...
would become:
int i=0;
while (i < 100)
{
...
++i;
}
Second, two nested loops can become a single one, in any number of ways:
for (int i=0; i< 100; ++i)
for (int j=0; j< 100; ++j)
...
Becomes
for (int z=0; z< 100*100; ++z)
{
i = z / 100;
j = z % 100;
}
The above shows two for loops, but you can perform similar transforms on other loops.
Think Eratosthenes sieve. In this method we strike composite numbers out of a table, so that in the end only primes remain. For simplicity, the table contains only odd numbers. You start pointing at 3, which is a prime. Strike out 3*3, 3*5... Finish your run over the table (it's finite), point at 5. It's not striked out, thus a prime. Strike out 15, 25... check 7, prime, strike 21, 35... check 9, already striked out, move on to 11...
Questions:
You have just checked a number, what is the next number to check?
How do you know you've ran out of numbers to check?
Write down answers to these questions, and you have a one-loop prime-finding algorithm.

Resources