how to implement a circular counter? - c

I want to make a circular counter in C programming.
First variable can store value from 0-3.
Second variable asks the value from user (from 0-3).
Third variable asks user to move either left or right
If third variable is left
the second variable should move left:
3->2
2->1
1->0
0->3
Similarly if third variable is right
the second variable should move right:
0->1
1->2
2->3
3->0

#include <stdio.h>
int main(void)
{
int max = 3, num, i;
num = 0;
for (i = 0; i < 10; i++) {
printf("%d\n", num);
num = (num + 1) % (max + 1);
}
puts("--");
num = max;
for (i = 0; i < 10; i++) {
printf("%d\n", num);
num = (max - -num) % (max + 1);
}
return 0;
}
Output:
0
1
2
3
0
1
2
3
0
1
--
3
2
1
0
3
2
1
0
3
2

If you wrap at a power of two, then this technique will work.
#include <stdio.h>
typedef struct
{
unsigned int x : 2; /* Holds up to 4 values */
} SmallInt;
int main()
{
SmallInt up = {0};
SmallInt down = {0};
for (int z = 0; z < 10; z++)
{
printf("%d %d\n", up.x, down.x);
up.x++;
down.x--;
}
return 0;
}

Related

Counting sort does not order the last element C

I have written this code in order to implement the Counting Sort in C. However it does not seem working properly.
I create an array of 10 elements and then I apply the steps of counting sort. Basically it orders the first elements, and then as last elements it uses the last elements of the original array. I am not understanding where is the problem.
The code:
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
int main() {
// create an array of 100 random elements
// int my_array[10];
int my_array[] = { 10, 10, 9, 9, 6, 5, 4, 3, 2, 1 };
srand(time(NULL));
int i;
int N = 10;
/* for (i = 0; i < 10; i++) {
my_array[i] = rand() % 100 + 1;
} */
// print the array
for (i = 0; i < 10; i++) {
printf("%d\n", my_array[i]);
}
// define the minimum and the maximum as the first element of the array
int min_array = my_array[0];
int max_array = my_array[0];
printf("--------------\n");
// find the minimum and the maximum of the array
for (i = 0; i < N; i++) {
if (my_array[i] < min_array) {
min_array = my_array[i];
}
else if (my_array[i] > max_array) {
max_array = my_array[i];
}
}
// check if it worked
printf("max_array %d\n", max_array);
printf("min_array %d\n", min_array);
//
int range_array;
range_array = max_array - min_array + 1;
int count_array[range_array + 1];
for (i = 0; i < range_array; i++)
count_array[i] = 0;
int j = 0;
for (int i = 0; i < 10; i++) {
count_array[my_array[i] - min_array] = count_array[my_array[i] - min_array] + 1;
}
int z = 0;
for (i = min_array; i < max_array; i++) {
for (j = 0; j < count_array[i - min_array]; j++)
my_array[z++] = i;
// z = z + 1;
}
for (i = 0; i < N; i++) {
printf("%d\n", my_array[i]);
}
}
And one possible output:
10 10 9 9 6 5 4 3 2 1
--------------
max_array 10
min_array 1
--------------
1 2 3 4 5 6 9 9 2 1
So as you can see the numbers from 1 to 9 are ordered, while the last one, 10, is not ordered, and it uses the first numbers, so 1 and 2.
When rebuilding the array, you want to include the elements with a value of max_array.
i<max_array
should be
i<=max_array
As a side note, you never use the last element of count_array, so it should be one element smaller.
int count_array[range_array + 1];
should be
int count_array[range_array];
(Spotted by #user3386109)

Why this code is working for 1 and 2 yet fails for input that is more than 3?

So I am trying to print patterns in C.
For n = 2
Output:
2 2 2
2 1 2
2 2 2
for n = 3
Output:
3 3 3 3 3
3 2 2 2 3
3 2 1 2 3
3 2 2 2 3
3 3 3 3 3
and so on.
My Code:
#include <stdio.h>
#include <stdlib.h>
int main()
{
int n;
scanf("%d",&n);
int nn = n;
int *arr;
arr = (int*)malloc(n*sizeof(int));
int f = 0; //flag to check if I reached the mid of the pattern
int l = 2*n-1; //Lenght of square to be generated
int temp1 = 0;
int temp2 = l;
for(int i = 0;i<l;i++)
{
for(int j = temp1;j<temp2;j++) //change values in range temp1 to temp2
{
arr[j] = n;
}
for(int k = 0;k<l;k++)
{
printf("%d ",arr[k]);
}
printf("\n");
if(n == 1)
{
f = 1;
}
if(f==0) //For upper half of pattern
{
n=n-1;
temp1=temp1+1;
temp2=temp2-1;
}
else if(f==1) //For lower half of pattern
{
n=n+1;
temp1=temp1-1;
temp2=temp2+1;
}
}
return(0);
}
I am getting the correct output for n = 2 but when I am inputting anything above 2 the code is crashing.
I am not able to find what should be done. Can someone help me out and tell me what am I doing wrong?
It would be better to check distances by axis and take a maximum of them to be printed.
Something like:
#include <stdio.h>
#include <stdlib.h>
int main()
{
int vertical_distance;
int horizontal_distance;
int n;
scanf("%d",&n);
for(int i = 0; i < n * 2 + 1; i++)
{
for(int j = 0; j < n * 2 + 1; j++)
{
vertical_distance = abs(n - i);
horizontal_distance = abs(n - j);
if (vertical_distance > horizontal_distance)
printf("%d ", vertical_distance);
else
printf("%d ", horizontal_distance);
}
printf("\n");
}
return(0);
}
Also, when I ran your code it worked nicely with large numbers (3, 7, 15).
I just pasted your code to onlinegdb.com/online_c_compiler and ran it. Can you please add the error message that you have got?
(sry for my English)
in this code piece
for(int j = temp1;j<temp2;j++) //change values in range temp1 to temp2
{
arr[j] = n;
}
j can be bigger than n. but arr malloc space is n. the array overflowed.
it will work with a small change
arr = (int*)malloc(2*n*sizeof(int));

for loop unexpectedly jumping down in value

Goldbach's conjecture states that every even integer over 4 is the sum of two primes, I am writing a program in C to find these pairs. To do this it first finds all the primes less than a user given number. I have a for loop to iterate from 4 to the user given number and find the pairs within the loop body. When that loop gets to about around 40, suddenly jumps back down by about 30 and then continues to iterate up (with user input 50 it jumped from 38 to 9, with input 60 it jumped from 42 to 7). I can't figure out why this is happening. Here is my code:
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include <sys/types.h>
#include <unistd.h>
struct pair{
int a;
int b;
}pair_t;
int main(){
int N;
int numPrimes = 1;
int *primes = malloc(100*sizeof(int));
int isPrime = 1;
primes[0] = 2;
int timesRealloc = 0;
int availableSlots = 100;
printf("Please enter the largest even number you want to find the Goldbach pair for: \n");
scanf("%d", &N);
struct pair pairs[N/2 + 4];
int j = 0;
int i;
for (i = 3; i <= N; i+=2){
j = 0;
isPrime = 1;
while (primes[j] <= sqrt(i)) {
if (i%primes[j] == 0) {
isPrime = 0;
break;
}
j++;
}
if (isPrime == 1){
primes[numPrimes] = i;
numPrimes++;
}
if (availableSlots == numPrimes){
timesRealloc++;
availableSlots += 100;
primes = realloc(primes, availableSlots*sizeof(int));
}
}
printf("The largest prime I found was %d\n", primes[(numPrimes-1)]);
int k;
for (i=4; i<=N; i+=2){
printf("i is %d, N is %d\n", i, N);
if (i > N){ break; }
for (j=0; j<numPrimes; j++){
for (k=0; k<numPrimes; k++){
int sum = primes[j] + primes[k];
if(sum == i){
pairs[i].a = primes[j];
pairs[i].b = primes[k];
}
}
}
}
for (i=4; i<=N; i+=2){
printf("%d is the sum of %d and %d\n", i, pairs[i].a, pairs[i].b);
}
return 0;
}
You attempt to be space efficient by compressing the pairs array to just hold every other (even) number and start from 4 instead of zero. However, you miscalculate its size and then when you go to use it, you treat it like it hasn't been compressed and that there's a slot for every natural number.
The code suffers from having the prime array calculation in main() along with the other code, this is best separated out. And when it looks for pairs, it doesn't quit when it finds one, nor when it starts getting sums greater than the target. My rework below attempts to address all of these issues:
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include <stdbool.h>
#define INITIAL_SLOTS (100)
struct pair {
int a;
int b;
} pair_t;
int compute_primes(int limit, unsigned **primes, int size) {
int numPrimes = 0;
(*primes)[numPrimes++] = 2;
for (int i = 3; i <= limit; i += 2) {
bool isPrime = true;
for (int j = 0; (*primes)[j] <= i / (*primes)[j]; j++) {
if (i % (*primes)[j] == 0) {
isPrime = false;
break;
}
}
if (isPrime) {
(*primes)[numPrimes++] = i;
}
if (numPrimes == size) {
size *= 2;
*primes = realloc(*primes, size * sizeof(unsigned));
}
}
return numPrimes;
}
int main() {
int N;
printf("Please enter the largest even number you want to find the Goldbach pair for: \n");
scanf("%d", &N);
unsigned *primes = calloc(INITIAL_SLOTS, sizeof(unsigned));
int numPrimes = compute_primes(N, &primes, INITIAL_SLOTS);
printf("The largest prime I found was %d\n", primes[numPrimes - 1]);
struct pair pairs[(N - 4) / 2 + 1]; // compressed data structure
for (int i = 4; i <= N; i += 2) {
int offset = (i - 4) / 2; // compressed index
bool found = false;
for (int j = 0; ! found && j < numPrimes; j++) {
for (int k = 0; ! found && k < numPrimes; k++) {
int sum = primes[j] + primes[k];
if (sum == i) {
pairs[offset].a = primes[j];
pairs[offset].b = primes[k];
found = true;
} else if (sum > i) {
break;
}
}
}
}
for (int i = 4; i <= N; i += 2) {
int offset = (i - 4) / 2; // compressed index
printf("%d is the sum of %d and %d\n", i, pairs[offset].a, pairs[offset].b);
}
free(primes);
return 0;
}
OUTPUT
> ./a.out
Please enter the largest even number you want to find the Goldbach pair for:
10000
The largest prime I found was 9973
4 is the sum of 2 and 2
6 is the sum of 3 and 3
8 is the sum of 3 and 5
10 is the sum of 3 and 7
12 is the sum of 5 and 7
14 is the sum of 3 and 11
...
9990 is the sum of 17 and 9973
9992 is the sum of 19 and 9973
9994 is the sum of 53 and 9941
9996 is the sum of 23 and 9973
9998 is the sum of 31 and 9967
10000 is the sum of 59 and 9941
>

Split digits in array [closed]

Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 4 years ago.
Improve this question
I'm totally beginner and I have problem in C. So I have array:
A[5] = {14, 2, 7, 3, 2};
And I want make something like this:
A[6] = {1, 4, 2, 7, 3, 2};
From 14 to 1, 4. Any idea how to do that?
So I making the problem from Cs50. Here is a link: https://docs.cs50.net/2018/x/psets/1/credit/credit.html
And here is my code:
#include <stdio.h>
#include <cs50.h>
#include <string.h>
#include <math.h>
int main(void)
{
long long cc_number = 0;
do
{
printf("Number: ");
cc_number = get_long_long();
}
while(cc_number <= 0);
int num_of_digits = 0;
long long valid = cc_number;
while(valid > 0)
{
valid /= 10;
num_of_digits++;
}
if (num_of_digits != 13 && num_of_digits != 15 && num_of_digits != 16 ) //checking if number have more or less than 13,15,16 digits
{
printf("Number is invalid!\n");
}
long long k = 1; //create array for store each number from the card
int A[16], d, num = 0;
for(num = 0; num < 16; num++)
{
d = (cc_number/(1*k)) % 10;
A[num] = d;
k *=10;
}
///////////////////////////////////////////////////////////////////////
if (num_of_digits == 16)
{
for (int i = 0; i < 16; i = i + 2)
{
A[i] *= 2; // multiplay each second digit by 2
printf("this is %i\n", A[i]);
}
}
else if (num_of_digits == 15 || num_of_digits == 13 )
{
int sum = 0;
for (int i = 1; i < 15; i = i + 2)
{
int y = A[i];
A[i] *= 2; // multiplay each second digit by 2
if (A[i] > 9) // try to split digit from array
{
y = A[i] % 10;
A[i] /= 10;
}
sum += A[i];
printf("this is %i\n", A[i]);
}
printf("this is sum %i\n", sum);
}
///////////////////////////////////////////////////////////////////////////
}
And this is what i want to do:
For the sake of discussion, let’s first underline every other digit,
starting with the number’s second-to-last digit:
378282246310005
Okay, let’s multiply each of the underlined digits by 2:
7•2 + 2•2 + 2•2 + 4•2 + 3•2 + 0•2 + 0•2
That gives us:
14 + 4 + 4 + 8 + 6 + 0 + 0
Now let’s add those products' digits (i.e., not the products themselves) together:
1 + 4 + 4 + 4 + 8 + 6 + 0 + 0 = 27
Now let’s add that sum (27) to the sum of the digits that weren’t multiplied by 2:
27 + 3 + 8 + 8 + 2 + 6 + 1 + 0 + 5 = 60
Yup, the last digit in that sum (60) is a 0, so my card is legit!
Assuming you want to create an array of single digit integers from array of multi-digit integers
#include <stdio.h>
#define MAX 1024
void printarr(int *a, int n) { // function to print array
for(int i = 0; i < n; i++) {
printf("%d ", a[i]);
}
printf("\n");
}
int main() {
int a[5] = {14, 2, 7, 3, 2};
int b[MAX];
int k = 0;
printarr(a, 5);
char s[MAX]; // char buffer to store char array
for(int i = 0; i < 5; i++) {
sprintf(s, "%d", a[i]);// convert int to char array
int j = 0;
while(s[j]!='\0') { // for each digit, create a new integer
b[k++] = s[j++] - '0';
}
}
printarr(b, k);
return 0;
}
Output:
14 2 7 3 2
1 4 2 7 3 2
Else for specific case
#include <stdio.h>
#define MAX 1024
void printarr(int *a, int n) { // function to print array
for(int i = 0; i < n; i++) {
printf("%d ", a[i]);
}
printf("\n");
}
int main() {
int a[5] = {14, 2, 7, 3, 2};
int b[6];
printarr(a, 5);
b[0] = 1;
b[1] = 4;
for(int i = 2; i < 6; i++) {
b[i] = a[i - 1];
}
printarr(b, 6);
return 0;
}
Output:
14 2 7 3 2
1 4 2 7 3 2
Here is a solution that does not use strings.
First of all, we have to determine how long the new array will be. To this end, we determine how many digits each entry has. For n > 0 the number of digits is ⌊log10(n) + 1⌋.
After that, we extract the digits. 123 can be split into its digits by using integer division / and modulo % (remainder of integer division):
123 % 10 = 3 least significant digit
123 / 10 = 12
repeat
12 % 10 = 2 second least significant digit
12 / 10 = 1
repeat
1 % 10 = 1 third least significant digit
1 / 10 = 0
end
As you can see, the digits are extracted from the back, therefore we also fill the output array from the back.
#include <stdio.h>
#include <math.h>
int digitCount(int n) {
if (n)
return (int) log10(n) + 1;
return 1;
}
int main() {
int inputLength = 5;
int input[] = {14, 1, 9, 0, 5819};
int outputLength = 0;
for (int i = 0; i < inputLength; ++i)
outputLength += digitCount(input[i]);
int output[outputLength];
int o = outputLength;
for (int i = inputLength - 1; i >= 0; --i) {
int n = input[i];
do {
output[--o] = n % 10;
n /= 10;
} while (n);
}
while (o < outputLength) {
printf("%d ", output[o++]);
}
}
clang -lm file.c && ./a.out prints 1 4 1 9 0 5 8 1 9.

Increment a value up to a specific value, and then decrement back down to the initial starting point?

Apologies for the title, but I could not find a similar question that has already been posed. As implied, my question is how to implement a counter which starts at an initial value and increments upwards until a specific point is reached, then decrements back down to the original value. Allow me to provide an example to better suggest showcase what I mean
#include <stdio.h>
int main(void) {
int i = 0;
for(i = 0; i <= 10; i++) {
printf("i = %d\n", i);
if(i == 5) {
int j = i;
for(j = i; j >= 0; j--) {
printf("j = %d\n", j);
}
}
}
return 0;
}
When run, the program will print values 0-5 for i, then print 5-0 for j and then finish printing 6-10 for i. Instead of this, I just want to have the program print 0-5 for i and then 5-0 for i (or j if another variable is needed).
You could use two separate loops like Rafalon in the comments suggested.
If you want one loop you can do something like this (modified it with the information from OPs comment):
int ctr_dir = 80;
int upper_value = 500;
for(int i = 0; i >= 0; i += ctr_dir)
{
printf("%d", i);
if (i > upper_value)
ctr_dir = -80;
}
You are making this needlessly complicated.
for(int i=0; i<6; i++) // print 0 to 5
{
printf("%d\n", i);
}
for(int i=0; i<6; i++) // print 5 to 0
{
printf("%d\n", 5-i);
}
Whilst I don't fully understand the reasons behind the way you've written the code, the missing ingredient from it is a break inside the if statement which will exit the loop rather than continuing on and printing out 6 to 10.
for(i = 0; i <= 10; i++) {
printf("i = %d\n", i);
if(i == 5) {
int j = i;
for(j = i; j >= 0; j--) {
printf("j = %d\n", j);
}
break; // Exit the loop
}
}
I think simple is best, but you said "my problem is more complex" (I don't know how much more !?), I wrote a more "complex" version...
You can do this something like this,
But the problem with this code is overshoots. i.e. if step is more than 1, you can pass maximum value. :)
#include <stdio.h>
void WaveGenerator(int start, int step, int max, int times)
{
int value = start;
times *= 2;
printf("%d", value);
while(times)
{
value += step;
if ((value <= start) || (value >= max))
{
step *= -1;
times--;
}
printf("%d", value);
}
}
int main()
{
int i;
WaveGenerator(1, 1, 5, 2);
return 0;
}
There have been many different solutions here, including the one I already posted as a comment.
Let me add another one here, similar to #izlin's but yet different:
int i=0;
int j=0;
int max=10;
for(i=0;i<=max;i++)
{
printf("%d\n", j);
if(i<max/2)
j++;
else
j--;
}
// max=10 > 0 1 2 3 4 5 4 3 2 1 0
// max=11 > 0 1 2 3 4 5 4 3 2 1 0 -1
Note that depending on the parity of max, this will go down to either 0 or -1.
This can be tweaked this way:
int i=0;
int j=0;
int max=10;
for(i=0;i<=max;i++)
{
Console.WriteLine(j);
if(i<max/2)
j++;
else if(i>(max-1)/2)
j--;
}
// max=10 > 0 1 2 3 4 5 4 3 2 1 0
// max=11 > 0 1 2 3 4 5 5 4 3 2 1 0
so it writes the top number twice if max is odd, and once if it is even, but always starts and ends with 0.
I would however still use 2 loops instead, as I suggested in my comment:
int i=0;
int max=5;
for(i=0;i<=max;i++)
{
printf("%d\n", i);
}
// 0 1 2 3 4 5
for(i=max;i>=0;i--)
{
printf("%d\n", i);
}
// 5 4 3 2 1 0
Since the work you want to perform is the same whether you are going up or down, you don't want to use separate loops as you'd be repeating yourself.
You can do this in a single loop by using a flag that indicates whether you've hit the upper limit. If the flag isn't set you increment, if it is you decrement.
int increment = 5, limit = 50;
int i = 0, go_back = 0;
while (i>=0) {
printf("%d\n", i);
if (i >= limit) {
go_back = 1;
}
if (go_back) {
i -= increment;
} else {
i += increment;
}
}

Resources