HP Code Wars Check digit algorithm error - c

QUESTION:
http://www.hpcodewars.org/past/cw17/problems/Prob02--CheckDigit.pdf
Here's my code:
int checkdigit(){
int n,i,j,sum1,sum2,k;
char ch;
printf("Enter the number of lines.Then enter ther the codes!");
scanf("%d",&n);
char *codes[n];
int msum[n];
int fsum[n];
for(i=0;i<n;++i){
scanf("%s",codes[i]);
}
for(i=0;i<n;++i){
for(j=0,k=3;j<21;j+=3,k+=3){
char *num;
num=codes[i];
ch=num[j];
sum1+=atoi(ch);
if(k<21)
ch=num[k];
sum2+=atoi(ch);
}
msum[i]=sum1*3;
fsum[i]=((msum[i]+sum2)%10);
if(fsum[i]!=0)
fsum[i]-=10;
}
for(k=0;k<sizeof(fsum);k++){
printf("%s %d",codes[k],fsum[k]);
}
return 0;
}
The Code now crashes after taking the first UPC code as input.

Change
fsum[i]=((msum+sum2)%10);
to
fsum[i]=((msum[i]+sum2)%10);
That is because msum is an array of integers, and msum[i] is an integer. As msum is an array, it is of type int* and is not compatible with int for the binary operator %

Here
char *codes[n];
is array of n pointers and you don't allocate memory for these pointers and try to scan values to this location so you see a crash

#include <stdio.h>
int checkdigit(int data[12]){
int i, even, odd, result;
even = odd = 0;
for(i = 0; i < 11; ++i){
if(i & 1)
even += data[i];
else
odd += data[i];
}
result = (odd * 3 + even) % 10;
if(result)
result = 10 - result;
return data[11] = result;
}
int main(){
int n;
scanf("%d", &n);
int codes[n][12];
int i, j;
for(i = 0; i < n; ++i){
for(j = 0; j < 11; ++j){
scanf("%d", &codes[i][j]);
}
checkdigit(codes[i]);
}
for(i = 0; i < n; ++i){
for(j = 0; j < 12; ++j){
if(j) putchar(' ');
printf("%d", codes[i][j]);
}
putchar('\n');
}
return 0;
}

Related

How can I move all elements in an array with a K number and make the numbers rotate when it comes to the end?

#include <stdio.h>
#include <stdlib.h>
int main()
{
int N, K, i;
printf("Enter size of array: ");
scanf("%d", &N);
printf("Please enter value of K: ");
scanf("%d", &K);
int arr[N];
for (i = 0; i < N; i++)
{
scanf("%d", &arr[i]);
}
for (i = 0; i < N; i++)
{
int temp = arr[i];
arr[i + K] = arr[i];
arr[i] = temp;
}
for (i = 0; i < N; i++)
{
printf("%d", arr[i]);
}
return 0;
}
I know the current code is totally wrong It was just another test.
Basically what I need to do is something like this:
the array before: arr[N]={1,2,3,4,5,6,7,8,9,10}
the array after if K is 2: arr[N]={10,9,1,2,3,4,5,6,7,8}
Like #whozcraig pointed out for in-place rotation of array members.
Define a function to reverse(in-place) array members in a range :
static inline void
arr_reverse (const int start, const int end, int arr[]) {
for (int ai = start, zi = end; ai < zi; ++ai, --zi) {
int tmp = arr[ai];
arr[ai] = arr[zi];
arr[zi] = tmp;
}
}
Then you call it like :
K %= N;
if (K != 0) {
arr_reverse (0, N-1, arr);
arr_reverse (0, K-1, arr);
arr_reverse (K, N-1, arr);
}
I write something like this but it creates new array instead of modifying current one but it works.
#include <stdio.h>
#include <stdlib.h>
int main()
{
int N, K, i;
printf("Enter size of array: ");
scanf("%d", &N);
printf("Please enter value of K: ");
scanf("%d", &K);
int arr[N], newArr[N];
for (i = 0; i < N; i++)
{
scanf("%d", &arr[i]);
}
for (i = 0; i < K; i++)
{
newArr[i] = arr[N-1-i];
}
for (int x = 0; i < N; i++)
{
newArr[i] = arr[x];
x++;
}
for (i = 0; i < N; i++)
{
printf("%d ", newArr[i]);
}
return 0;
}
Thank you guys, for all the comments and answers. I've tried them and they worked.
I have found a way to do it as well. It's bit different. I did it with a function which moves all the elements with 1 position and then repeat the func as much as needed (K times).
#Cheatah helped me come up with it. I will post it in case somebody likes this solution in the future.
Here it is:
#include <stdio.h>
#include <stdlib.h>
int moveOnePos(int num, int array[num])
{
int temp = array[num - 1];
for (int b = num - 1; b > 0; b--)
{
array[b] = array[b - 1];
}
array[0] = temp;
return 0;
}
int main()
{
int N, K, i;
printf("Please enter size of array: ");
scanf("%d", &N);
printf("Please enter K: ");
scanf("%d", &K);
int arr[N];
for (i = 0; i < N; i++)
{
scanf("%d", &arr[i]);
}
for (i = 0; i < K; i++)
{
moveOnePos(N, arr);
}
for (i = 0; i < N; i++)
{
printf("%d", arr[i]);
}
return 0;
}

why output is 0 here. i am a newbie (20 days experience)

*i want to copy inputed array in sum_of_elements function as argument and then sum all the elements of array, but i am getting output 0.
#include <stdio.h>
int i, num, sum;
int sum_of_elements(int arr[]) {
for (i = 0; i < num; i++) {
for (i = 0; sum = 0, i < num; i++) {
sum += arr[i];
}
return sum;
}
}
int main() {
printf("enter number of digits you want to add\n");
scanf("%d", & num);
int arr[num];
for (i = 0; i < num; i++) {
printf("enter number %d\n", i + 1);
scanf("%d", & arr[i]);
}
int total = sum_of_elements(arr);
printf("%d", total);
return 0;
Look at this line of code:
for (i = 0; sum = 0, i < num; i++) {
This resets sum to 0 every loop.
It should be
for (i = 0, sum = 0; i < num; i++) {
But it's probably better to do this:
sum = 0;
for (i = 0; i < num; i++) {
The issue was with the double for loop in your sum_of_elements function.
Removing the extra for loop, resolves the error.
#include <stdio.h>
int i, num, sum;
int sum_of_elements(int arr[]) {
for (i = 0; i < num; i++) {
sum += arr[i];
}
return sum;
}
int main() {
printf("enter number of digits you want to add\n");
scanf("%d", & num);
int arr[num];
for (i = 0; i < num; i++) {
printf("enter number %d\n", i + 1);
scanf("%d", &arr[i]);
}
int total = sum_of_elements(arr);
printf("%d", total);
return 0;
}

Adding a second loop

I want to add a second loop to my program, in which I let the user enter an number x in each loop and form the sum over the entered numbers. the result of this code is 378 but must be for example 378+x=380
int main()
{
int i;
int sum = 0;
for (i = 1; i <= 27; i++) {
sum += i;
}
printf("%d\n", sum);
return 0;
}
You write a loop inside your loop and add a scanf.
int i, j;
int sum = 0;
for (int i = 0; i <= 27; i++) {
for (j = 0; j < 10; j++) {
int x= 0;
scanf ("%d", &x);
sum += x;
}
}
If you add a second loop you will need to input y*x inputs where y is the frequency of 2nd loop.
The code you may be looking for is
int main () {
int i,x;
int sum = 0;
for(i = 1; i <= 27; i++)
{
scanf("%d",&x);
sum += i+x;
}
printf("%d\n", sum);
return 0;
}

Explain Fibonacci code

#include<stdio.h>
#define max 2000
int arr1[max], arr2[max], arr3[max];
void fib();
int main()
{
int num, i, j, flag = 0;
for(i = 0; i<max; i++)
arr1[i] = arr2[i] = arr3[i] = 0;
arr2[max - 1] = 1;
printf("Enter the term : ");
scanf("%d", &num);
for(i = 0; i<num; i++)
{
fib();
if(i == num - 3)
break;
for(j = 0; j<max; j++)
arr1[j] = arr2[j];
for(j = 0; j<max; j++)
arr2[j] = arr3[j];
}
for(i = 0; i<max; i++)
{
if(flag || arr3[i])
{
flag = 1;
printf("%d", arr3[i]);
}
}
getch();
return 1;
}
void fib()
{
int i, temp;
for(i = 0; i<max; i++)
arr3[i] = arr1[i] + arr2[i];
for(i = max - 1; i>0; i--)
{
if(arr3[i]>9)
{
temp = arr3[i];
arr3[i] %= 10;
arr3[i - 1] += (temp / 10);
}
}
}
The above code generates the nth Fibonacci number. I am not able to understand how this works. Basically the Fibonacci number get stored in a very large array arr3[].
Please explain the logic involved in this code.
How does the fib() function work as well?
Here is a simple Fibonacci loop.
#include <stdio.h>
int main()
{
int term = 20, last2=0, last1=1, fib, i;
for (i=0; i<term; i++) {
fib = last2 + last1;
last2 = last1;
last1 = fib;
}
printf ("Term %d = %d\n", i, fib);
return 0;
}
Program output:
Term 20 = 10946
Although there is more than one idea as to where the sequence starts.
The example code in the original post is dealing with large numbers by storing 1 decimal digit per element in each of the arrays. It initializes arr[3] = arr2[] = arr1[] = 0, then arr2[] = 1. In the loop, fib() performs one instance of arr3[] = arr1[] + arr2[], handling the carries, then the loop does arr[1] = arr2[], arr2[] = arr3[]. If num < 3, the for loop exits on the loop condition i < num, if n >= 3, the loop exit when i == (num-3). (This could be avoided). The print loop skips leading zeroes in arr3[], setting flag once a non-zero value is found. The code needs some minor fixes. Here is a fixed example. Note that getch() may be _getch() in some environments (from conio.h). The second example below only uses two arrays. Fibonacci numbers starting from 0 are 0 1 1 2 3 5 8 ...
#include <conio.h>
#include <stdio.h>
#define max 2000
int arr1[max], arr2[max], arr3[max];
void fib();
int main()
{
int num, i, j;
for(i = 0; i<max; i++)
arr1[i] = arr2[i] = arr3[i] = 0;
arr1[max - 1] = 1;
printf("Enter the term : ");
scanf("%d", &num);
for(i = 0; i<num; i++)
{
fib();
for(j = 0; j<max; j++)
arr1[j] = arr2[j];
for(j = 0; j<max; j++)
arr2[j] = arr3[j];
}
for(i = 0; i < max-1; i++)
if(arr3[i])
break;
for( ; i < max; i++)
printf("%d", arr3[i]);
getch();
return 0;
}
void fib()
{
int i, temp;
for(i = 0; i<max; i++)
arr3[i] = arr1[i] + arr2[i];
for(i = max - 1; i>0; i--)
{
if(arr3[i]>9)
{
temp = arr3[i];
arr3[i] %= 10;
arr3[i - 1] += (temp / 10);
}
}
}
This example only uses two arrays, by alternating which array contains the sum (a1 += a0, a0 += a1). It uses Duff's device to enter the loop. Since the largest sum from digit + digit + carry is < 20, the carry loop in fib() was simplified.
#include <conio.h>
#include <stdio.h>
#define max 2000
void fib(unsigned char *a0, unsigned char *a1);
int main()
{
unsigned char a0[max], a1[max];
size_t i;
int n;
printf("Enter the term : ");
scanf("%d", &n);
for(i = 0; i < max; i++)
a0[i] = a1[i] = 0;
a0[max-1] = n & 1; /* if n even, a0=0=fib(0), a1=1=fib(-1) */
a1[max-1] = 1 - a0[max-1]; /* if n odd, a1=0=fib(0), a0=1=fib(-1) */
switch(n&1){
do{
fib(a0, a1);
case 1:
fib(a1, a0);
case 0:
continue;
}while(0 <= (n -= 2));
}
for(i = 0; i < max-1; i++)
if(a0[i])break;
for( ; i < max; i++)
printf("%d", a0[i]);
getch();
return 0;
}
void fib(unsigned char *a0, unsigned char *a1)
{
size_t i;
for(i = 0; i < max; i++)
a1[i] += a0[i];
for(i = max - 1; i > 0; i--){
if(a1[i] >= 10){
a1[i] -= 10;
a1[i-1] += 1;
}
}
}
Here's a much better implementation of the Fibonacci series
#include<iostream>
using namespace std;
main()
{
int n, c, first = 0, second = 1, next;
cout << "Enter the number of terms of Fibonacci series you want" << endl;
cin >> n;
cout << "First " << n << " terms of Fibonacci series are :- " << endl;
for ( c = 0 ; c < n ; c++ )
{
if ( c <= 1 )
next = c;
else
{
next = first + second;
first = second;
second = next;
}
cout << next << endl;
}
return 0;
}

C programming with functions

I have got some more problems with the code. This program ask the user to specify the nr of throws then it throws 3 dices and add these 3 dices to sum.
Then another function sorts the sum form the smallest to the largest with a bubble sorting algorithm.
the first two functions seems to work but the program does not print out the result of the 3rd sorting function.
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#define MAX 100
//This function ask the user for the amout of throws
int numberofthrows() {
int throws
printf("Type in the number of throws");
scanf("%d", &throws);
return throws;
}
//This function makes the random throws of 3 dices with regard to the number of throws
int filler(int thrownr, int dice1[MAX], int dice2[MAX], int dice3[MAX], int sum[MAX]) {
int i, nr;
srand(time(NULL));
for(i = 0; i <= thrownr; i++) {
nr = rand()%6;
dice1[i] = nr + 1;
nr = rand()%6;
dice2[i] = nr + 1;
nr = rand()%6;
dice3[i] = nr + 1;
sum[i] = dice1[i] + dice2[i] + dice3[i];
}
int j;
for(j = 0; j <= thrownr; j++) {
printf("%d ", dice1[j]);
printf("%d ", dice2[j]);
printf("%d ", dice3[j]);
printf("%d\n", sum[j]);
}
}
//This function sorts the result in form the sum array
int sorter(int thrownr, int sum[MAX], int sortsum[MAX]) {
int tmp, i, j, k, m;
for(i = 0; i <= thrownr; i++) {
sortsum[i] = sum[i];
}
for(m = 0; m <= 10; m++) {
for(j = 0; j <= thrownr; i++) {
if (sortsum[j] > sortsum[j+1]) {
tmp = sortsum[j];
sortsum[j] = sortsum[j+1];
sortsum[j+1] = tmp;
}
}
}
for(k = 0; k <= thrownr; k++) {
printf("%d\n", sortsum[k]);
printf("%d\n", sum[k]);
}
}
int main(void) {
srand(time(NULL));
int dice1[MAX];
int dice2[MAX];
int dice3[MAX];
int sum[MAX];
int sortsum[MAX];
int numberofthrows2;
numberofthrows2 = numberofthrows();
filler(numberofthrows2, dice1, dice2, dice3, sum);
sorter(numberofthrows2, sum, sortsum);
return 0;
}
The code for sorting is a bit wrong. Change
for(m = 0; m <= 10; m++)
To
for(m = 0; m <= thrownr-1; m++)
And
for(j = 0; j <= thrownr; i++)
To
for(j = 0; j < thrownr-m-1; i++)
To fix it. Also, call srand once at the start of main. Don't call it more than once in a program or you might get the same "random" numbers everytime you run your program.

Resources