every k-th digit of a number in c - arrays

Given some natural numbers n and k, my goal is to write a C program that outputs a number formed by every k-th digit of n. I wrote a program as follows:
#include <stdio.h>
#include <math.h>
#define MAX 100
void printDigit(int n, int k)
{
int arr[MAX];
int i = 0;
int j, r;
while (n != 0) {
r = n % pow(10,k);
arr[i] = r;
i++;
n = n / pow(10,k);
}
for (j = i - 1; j > -1; j--) {
printf("%d ", arr[j]);
}
}
int main()
{
int n = 12345678;
int k = 2;
printDigit(n,k);
return 0;
}
The compiler says
error: invalid operands to binary % (have 'int' and 'double')
16 | r = n % pow(10,k);
I can't figure out what's the problem. Both n and 10^k are integers and % operation should be valid

Related

How to make competitive coding solutions more efficient (BIT wise operations)?

How do I make my code more efficient (in time) pertaining to a competitive coding question (source: codechef starters 73 div 4):
(Problem) Chef has an array A of length N. Chef wants to append a non-negative integer X to the array A such that the bitwise OR of the entire array becomes = Y .
Determine the minimum possible value of X. If no possible value of X exists, output -1.
Input Format
The first line contains a single integer T — the number of test cases. Then the test cases follow.
The first line of each test case contains two integers N and Y — the size of the array A and final bitwise OR of the array A.
The second line of each test case contains N space-separated integers A_1, A_2, ..., A_N denoting the array A.
Please don't judge me for my choice of language .
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
int* binary_number(int n) // returns pointer to a array of length 20(based on given constrains) representing binary
{
int* ptc;
ptc = (int*) malloc(20*sizeof(int));
for(int i = 0; i < 20; i++)
{
if((n / (int) pow(2,19-i)) > 0){*(ptc + i) = 1;}
else {*(ptc + i) = 0;}
n = n % (int) pow(2,19-i) ;
}
return ptc;
}
int or_value(int* ptc, int n) // Takes in pointers containing 1 or zero and gives the logical OR
{
for(int k = 0; k < n; n++)
{
if(*ptc == *(ptc + 20*k)){continue;} // pointers are 20 units apart
else{return 1;break;}
}
return *ptc;
}
int main(void) {
int t; scanf("%d", &t);
for (int i = 0; i < t; i++)
{
int n, y;
scanf("%d %d", &n, &y);
int a[n];
for(int j = 0; j < n ; j++)
{
scanf("%d", &a[j]);
}
int b[20*n];
for (int j = 0; j < n; j++)
{
for (int k = 0; k < 20; k++)
{
b[20*j + k] = *(binary_number(a[n])+k);
}
}
int c = 0;
int p = 0;
for (int j = 0; j < 20; j++)
{
if ((*(binary_number(y) + j) == 1) && (or_value((&b[0] + j),n) == 0)){c = c + pow(2,19 - j);}
else if ((*(binary_number(y) + j) == 0) && (or_value((&b[0] + j),n) == 1)){p = 1; break;}
}
if (p==1){printf("-1");}
else {printf("%d\n", c);}
}
return 0;
}

Runtime error on a Codechef problem: modified Fibonacci series. What's the mistake?

I'm trying to solve a problem on codechef, here's the link:
https://www.codechef.com/problems/KFIB
The given problem statement is:
Chef recently had been studying about Fibonacci numbers and wrote a code to print out the k-th term of the Fibonacci series (1, 1, 2, 3, 5, 8, 13….). He was wondering whether he could write a program to generate the k-th term for similar series. More specifically:
T(n, k) is 1 if n <= k and
T(n, k) = T(n-1, k) + T(n-2, k) + T(n-3, k) … + T(n-k, k) if n > k.
Given n and k, output T(n, k) % (1000000007) as the answer could be very large
Input : Two integers, N and K
Output : One integer, the nth term of the series mod 1000000007
Constraints : 1 ≤ N, K ≤ 2*105
example:
Input: 7 5
Output: 9
The series is as follows {1, 1, 1, 1, 1, 5, 9}
void fibo(int n, unsigned long k) {
unsigned long *a, c;
a = (unsigned long *)malloc(sizeof(unsigned long) * k);
for (unsigned long i = 0; i < k; i++) { //T(n,k)=1 when n<=k
*(a + i)=1;
}
for (unsigned long m = 0; m < n - 1; m++) {
c = *(a);
for (unsigned long j = 0; j < k - 1; j++) {
*(a + j) = *(a + j + 1);
c = c + *(a + j);
}
*(a + k - 1) = c;
}
printf("%d ", *(a) % 1000000007);
}
This works with smaller values but not with very large values. I got the result of the example but when I enter the values 200000 500, I get incorrect answers
The problem is you compute the value modulo ULONG_MAX and reduce the result modulo 1000000007 at the end. This does not give the correct result. You must reduce modulo 1000000007 at each step to avoid potential arithmetic overflow (which does not cause undefined behavior for type unsigned long but gives a different result from the expected one).
Here is a modified version of your code with a faster alternative (more than twice as fast on my laptop):
#include <stdio.h>
#include <stdlib.h>
#define DIVIDER 1000000007ul
unsigned long fibo(unsigned long n, unsigned long k) {
unsigned long c = 1;
if (n > k) {
unsigned long *a = (unsigned long *)malloc(sizeof(*a) * k);
for (unsigned long i = 0; i < k; i++) { //T(n,k)=1 when n<=k
a[i] = 1;
}
for (unsigned long m = k; m < n; m++) {
c = a[0];
for (unsigned long j = 0; j < k - 1; j++) {
a[j] = a[j + 1];
#if 0
// slower version using modulo
c = (c + a[j]) % DIVIDER;
#else
// faster version with a test
if ((c += a[j]) >= DIVIDER)
c -= DIVIDER;
#endif
}
a[k - 1] = c;
}
free(a);
}
return c;
}
int main(int argc, char *argv[]) {
if (argc <= 2) {
printf("usage: fibo n k");
return 1;
} else {
unsigned long n = strtoul(argv[1], NULL, 10);
unsigned long k = strtoul(argv[2], NULL, 10);
printf("%lu\n", fibo(n, k));
}
return 0;
}
Output:
$ time ./fibo 200000 100000
871925546
real 0m34.667s
user 0m34.288s
sys 0m0.113s
$ time ./fibo-faster 200000 100000
871925546
real 0m15.073s
user 0m14.846s
sys 0m0.064s
Given the restrictions on input values:
the values of T(n, k) are in the range [0..1000000006] which fits in an int32_t.
the sum of k terms is in the range [0..200000*1000000006] which fits in an int64_t.
hence we can compute the next term in 64 bits and use a single modulo on the result.
This gives an even faster version (more than 3 times faster):
#include <stdio.h>
#include <stdint.h>
#include <stdlib.h>
#define DIVIDER 1000000007
uint32_t fibo(uint32_t n, uint32_t k) {
uint32_t c = 1;
if (n > k) {
uint32_t *a = (uint32_t *)malloc(sizeof(*a) * k);
uint64_t temp;
for (uint32_t i = 0; i < k; i++) { //T(n,k)=1 when n<=k
a[i] = 1;
}
for (uint32_t m = k; m < n; m++) {
temp = a[0];
for (uint32_t j = 0; j < k - 1; j++) {
temp += a[j] = a[j + 1];
}
a[k - 1] = c = temp % DIVIDER;
}
free(a);
}
return c;
}
int main(int argc, char *argv[]) {
if (argc <= 2) {
printf("usage: fibo n k");
return 1;
} else {
uint32_t n = strtoul(argv[1], NULL, 10);
uint32_t k = strtoul(argv[2], NULL, 10);
printf("%lu\n", (unsigned long)fibo(n, k));
}
return 0;
}
Output:
$ time ./fibo-faster 200000 100000
871925546
real 0m3.854s
user 0m3.800s
sys 0m0.018s
To avoid overflow, you can change below statement
c=c+*(a+j);
To
c=(c+*(a+j))%1000000007;
That means only the remainder will be keep in your heap. This won't impact the final results.
Here is the updated code and compiled by clang.(updated according to #bruno's comments)
#include <stdlib.h>
#include <stdio.h>
#define DIVIDER 1000000007ul
#define U4 unsigned long
U4 fibo(U4 n,U4 k)
{
U4 *a,c ;
if(n<=k) return 1;
a= (U4*) malloc (sizeof(U4)*k);
for (U4 i=0;i<k;i++) //T(n,k)=1 when n<=k
{
*(a+i)=1;
}
for (U4 m=k;m<n; m++)
{
c=*(a);
for (U4 j=0;j<k-1;j++)
{
*(a+j)= *(a+j+1);
c=(c+*(a+j))%DIVIDER;
}
*(a+k-1)=c;
}
free(a);
return c;
}
int main(int argc, char *argv[])
{
U4 n, k;
char *endptr;
if(argc <= 2){
printf("usage: t.exe n k");
return 0;
}
n = strtoul(argv[1], &endptr, 10);
k = strtoul(argv[2], &endptr, 10);
printf("%lu", fibo(n,k));
}
Compiler command:
$ clang test.c -o test.exe
$ test.exe 200000 500
80391289

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
>

Segmentation error in C after printing a method in a for loop

I have a problem when trying to print the numbers in the n given row of Pascal's triangle in C:
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
int main(int argc, char *argv[])
{
int n, k;
double result1, result2;
scanf("%d", &n);
scanf("%d", &k);
result2 = knumberinnrowofpascal(8, 4);
printf("%f\n", result2);
int i = 0;
for (i; i<n; i++) {
result2 = knumberinnrowofpascal(n, i);
printf("%f\n", result2);
}
return 0;
}
int combinations(int n, int k) // calculates combinations of (n,k).
{
if (k == 0)
return 1;
else if (k > n)
return 0;
else
return (combinations(n - 1, k) + combinations(n - 1, k - 1));
}
int knumberinnrowofpascal(int n, int k)
{
double rightmultipier, leftmultiplier, result;
rightmultipier = (double)(n + 1 - k) / k;
leftmultiplier = (double)combinations(n, k - 1);
result = (double)leftmultiplier * rightmultipier;
return result;
}
The function "knumberinnrowofpascal" works, I've tested it above (the 4th element in the 8th row ). The problem is when I try to print these results in a for loop.
rightmultipier = (double)(n + 1 - k) / k;
This will fail if k is 0. And even if it didn't, it would on the next row, because you would have infinite recursion there.
Change:
int i = 0;
for (i; i <= n; i++) {
to
int i;
for (i=1; i <= n; i++) {
I made two improvements there. I fixed the bug and moved the initialization to the for header.
return (combinations(n - 1, k) + combinations(n - 1, k - 1));
when k!=0 and n<k, you recurse with combinations(n-1,k). Decrementing n in this recursion does not change k!=0, and it certainly does not make n > k until it overflows, which means you are in a practically infinite recursion and it segfaults.

A simple program for splitting numbers does not display zeroes

I wrote a simple program in c that accepts two numbers and then splits the first number considering the digits of the second number like this:
Input:
362903157 2313
Output:
36
290
3
157
Everything works just fine, except when there are zeroes in the first number, my program skips them. For instance the upper example gives me this output:
36 293 1 570
And that is mycode:
#include <stdio.h>
int nDigits(unsigned i) {
int n = 1;
while (i > 9) {
n++;
i /= 10;
}
return n;
}
// find the highest multiple of 10
int multipleOfTen(int num){
int multiple = 1;
while(multiple <= num){
multiple *= 10;
if(multiple > num){
multiple /= 10;
break;
}
}
return multiple;
}
int main(){
int n, m, digit;
scanf("%d %d", &n, &m);
int lengthOfM = nDigits(m);
for (int i = 0; i < lengthOfM; i++){
digit = m / multipleOfTen(m); //2
for(int j = 1; j <= digit; j++){
printf("%d", n/multipleOfTen(n));
n = n% multipleOfTen(n);
}
printf("\n");
m = m % multipleOfTen(m);
}
return 0;
}
What should I change in my program so that the zeroes won't be ignored?
Instead of calling multipleOfTen() in each loop, call it once and save the result for both n and m. Then in each loop divide those results by 10
#include <stdio.h>
int nDigits(unsigned i) {
int n = 1;
while (i > 9) {
n++;
i /= 10;
}
return n;
}
// find the highest multiple of 10
int multipleOfTen(int num){
int multiple = 1;
while(multiple <= num){
multiple *= 10;
if(multiple > num){
multiple /= 10;
break;
}
}
return multiple;
}
int main(){
int n, m, digit;
int i, j;
int n10, m10;
scanf("%d %d", &n, &m);
int lengthOfM = nDigits(m);
n10 = multipleOfTen(n); //get the multiple of ten once
m10 = multipleOfTen(m);
for ( i = 0; i < lengthOfM; i++){
digit = m / m10;
m10 /= 10;
for( j = 0; j < digit; j++){
printf("%d", n/n10);
n = n% n10;
n10 /= 10;// divide by 10
}
printf("\n");
m = m % multipleOfTen(m);
}
return 0;
}
I suppose an approach like this is inadmissible?
#include <stdio.h>
#include <string.h>
int main ( void ) {
char n[64];
char m[64];
char * p = n;
int i = 0;
int c;
scanf("%63[0-9] %63[0-9]", n, m);
while ((c = m[i++]) != '\0') {
int j = c - '0';
while (j-- > 0) if (*p) putchar(*p++);
putchar(' ');
}
putchar('\n');
return 0;
}
when n=903157 and after n = n% multipleOfTen(n); n becomes 3157 not 03157 so when u dividing again in line printf("%d", n/multipleOfTen(n)); it prints 3 not 0 what you want!!
Fix your code to produce right output.

Resources