Split digits in array [closed] - c

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.

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)

Printing randomly from 1 to 10 in C

I have written a code for randomly printing a number from 1 to 10 without any repetition, but it isn't working properly sometimes I get the number that is already written.
In short, I'm trying to print numbers from 1-10 randomly with no repetition.
Here is my code :
#include<stdio.h>
#include<stdlib.h>
#include<time.h>
#include<conio.h>
main() {
int no = 0, repeat[100] = { 0 }, i = 0, x = 0, j = 0;
srand(time(NULL));
while (true) {
no = (rand() % 10) + 1;
for (i = 0; i < 100; i++) {
if (no != repeat[i]) {
x = 1;
} else if (no == repeat[i]) {
x = 0;
}
}
if (x == 1) {
repeat[j] = no;
printf("\n%d", repeat[i]);
j = j + 1;
}
getch();
}
}
Don't use rand() to generate the numbers directly, instead fill a sequential array, and then use rand() to shuffle the array, e.g.
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
/** shuffle integer array of size 'n'
* (using fisher-yates method)
*/
void shuffle (int *a, int n)
{
int i, tmp;
while (n-- > 1) {
i = rand() % (n + 1);
tmp = a[i];
a[i] = a[n];
a[n] = tmp;
}
}
int main (void) {
int arr[10] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
srand (time(NULL));
shuffle (arr, 10);
for (int i = 0; i < 10; i++)
printf (" %d", arr[i]);
putchar ('\n');
}
By shuffling the array and swapping random elements within it, you eliminate all possibility of a duplicate number.
Example Use/Output
$ ./bin/shuffle_arr
3 10 7 8 4 5 6 9 1 2
#include <stdio.h>
#define N1 1
#define N2 10
void main() {
int len = N2 - N1 + 1, i, r, temp;
int num[len];
//Fill array with numbers
for (temp = 0, i = N1; temp < len; i++, temp++)
num[temp] = i;
srand(time(NULL));
for (i = len - 1; i > 0; i--) {
r = rand() % i; //pop random number
//swaping
temp = num[i];
num[i] = num[r];
num[r] = temp;
}
/*Random Numbers are stored in Array*/
//print that array
for (i = 0; i < len; i++)
printf("%d\n", num[i]);
}

Print only those arrays with 3 digits whose sum is 10 - C program

Output:
1 2 3 4
1 2 7
1 3 6
1 4 5
1 9
2 3 5
2 8
3 7
4 6
10
Expected Output:
1 2 7
1 3 6
1 4 5
2 3 5
I want only those pairs of digits whose sum is 10 and also has only 3 digits i.e, the pair of 3 distinct digits whose sum is 10 should be displayed, rest all other pairs get skip or not displayed.
Below is my full source code which I have written for this problem.
#include <stdio.h>
#include <stdlib.h>
void partition(int part) {
int *parts, *ptr, i, idx = 0, tot = 0, cur = 1, max = 1;
while ((max * (max + 1)) / 2 <= part)
max++;`
ptr = parts = malloc(sizeof(int) * max);
for (;;) {
if ((tot += *ptr++ = cur++) < part)
continue;
if (tot == part) {
for (i = 0; i < ptr-parts; i++) {
printf("%d ", parts[i]);
}
printf("\n");
}
do {
if (ptr == parts) {
free(parts);
return;
}
tot -= cur = *--ptr;
} while (++cur + tot > part);
}
}
int main(int argc, char*argv[]) {
int n;
scanf("%d", &n);
partition(n);
return 0;
}
Your code seems way too complicated. Here is a simple solution:
#include <stdio.h>
#define SUM 10
int main(void) {
for(int a = 1; a < SUM; a++) {
for(int b = a + 1; b < SUM; b++) {
for(int c = b + 1; c < SUM; c++) {
if(a + b + c == SUM) {
printf("%d %d %d\n", a, b, c);
}
}
}
}
}
Program output:
1 2 7
1 3 6
1 4 5
2 3 5
This could be more efficient but it is a simple form.
Your code is too generic for this problem: you do not need to enumerate all possible partitions and select those with 3 numbers. Just enumerate all possible triplets without duplicates.
Here is a simpler and much faster solution for your problem:
#include <stdio.h>
void partition(int sum) {
/* enumerate a, b, c such that:
a < b < c
a + b + c = sum
*/
int a, b;
for (a = 1; 3 * a + 2 <= sum; a++) {
for (b = a + 1; a + 2 * b + 1 <= sum; b++) {
printf("%d %d %d\n", a, b, sum - a - b);
}
}
}
int main(void) {
int n;
if (scanf("%d", &n) == 1)
partition(n);
return 0;
}

How can I calculate the moving average of the array?

In Question, When an array X of size n and a degree k are input,
Write a program that calculates the k-th moving average of array X.
The kth-order moving average of the array X consisting of primitive data values is the average of the last k elements up to the i-th point of X.
That is, A [i] = (X [i-k + 1] + X [i-k + 2] + ... + X [i]) / k.
If the number of the preceding element (including itself) is smaller than k,
Calculate as an average.
For example, if array X is as follows and k is 3, X = 1 3 2 10 6 8
The third moving average is as follows.
A = 1 2 2 5 6 8 A [1] = (1 + 3) / 2, A [2] = (1 + 3 + 2) / 3
However, the program must have the execution time of O (n), not O (nk).
Round off the decimal point in the average calculation and obtain it as an integer.
For exact rounding, do not use% .f, but round it using the int property.
int main()
{
int i, n1, k;
int *array1;
scanf("%d", &n1);
array1 = (int *)malloc(sizeof(int)*n1);
scanf("%d", &k);
for (i = 0; i < n1; i++)
{
scanf("%d", &array1[i]);
}
double tmp = 0;
for (int i = 0; i < n1; i++)
{
tmp += array1[i];
if (i >= k)
{
tmp -= array1[i - k];
}
if (i >= k - 1)
{
double average = tmp / k;
printf("%2lld ", llrint(average));
}
return 0;
}
The program does not work because the problem is not understood.
I would like to know how to solve it.
add) Thank you for answer but the output required by the problem is as follows.
Input : 9 4 (n = 9, k = 3)
2 7 4 5 6 8 2 8 13
Output : 2 5 4 5 6 6 5 6 8
After Modifying your code
int main()
{
int i, n1, k;
int *array1, *array2;
scanf("%d", &n1);
array1 = (int *)malloc(sizeof(int)*n1);
scanf("%d", &k);
for (i = 0; i < n1; i++)
{
scanf("%d", &array1[i]);
}
double tmp = 0;
for (int i = 0; i < n1; i++)
{
tmp += array1[i];
// now tmp contains exactly k + 1 elements sum
// so subtract elements outside of k sized window(leftmost element)
if(i >= k) {
tmp -= array1[i - k];
}
if(i >= k - 1) {
double average = tmp / k;
printf("%lf\n", average);
}
}
return 0;
}

Rough times trying to convert string to integers array [closed]

Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 6 years ago.
Improve this question
Basically the program will ask for user credit card number, capture it inside a string, convert a string to an integer array (so I can validate credit card number, for later digit sums and multiplying).
I need a variable with integers array and the code below stores ASCII values.
Tried reading lots of posts, but didn't get it.
I'd appreciate any help, so I could sleep again =)
Cordially,
#include <cs50.h>
#include <stdio.h>
#include <string.h>
int main (void)
{
string cc_string;
printf("Please enter a credit card number:\n");
//Captures credit card string
cc_string = GetString();
// Array of credit card digits integers
int cc_digits[16];
for (int i = 0; i<= 15; i++)
{
cc_digits[i] = (int) cc_string[i];
//Just checking what value has been stored
printf("position %d with %d \n", i, cc_digits[i]);
}
//to be continued
}
Instead of cc_digits[i] = (int) cc_string[i] try cc_digits[i] = cc_string[i] - '0' If you just cast to int you'll get the ASCII code for the character, but if you subtract the code of character 0 then you should get the actual digit.
Instead of casting to int with (int), use atoi()
Found the solution, want to share with you guys.Thank you all for the help, time and learnings.
#include <cs50.h>
#include <stdio.h>
int main (void)
{
long long cc_num;
int array_dig[15];
int static sum_evens, sum_odds, sum_tot, valid = 0;
printf("Enter your credit card number for validation: \n");
cc_num = GetLongLong();
for (int i=15; i >= 0; i--)
{
array_dig[i] = cc_num % 10;
cc_num = cc_num / 10;
//Sanity check
printf("pos %d = %d\n", i, array_dig[i]);
}
//Summing digits
for (int j=0; j < 16; j++)
{
if (j % 2 == 0)
{
sum_evens += array_dig[j];
//Sanity check
printf("sum_evens = %d/n", sum_evens);
}
else if (j % 2 == 1)
{
if (array_dig[j] < 5)
{
sum_odds += 2 * array_dig[j];
//Sanity check
printf("sum_odds for char < 5 = %d\n", sum_odds);
}
else
{
sum_odds += (2 * array_dig[j]) % 10 + 1;
//Sanity check
printf("sum_odds for char >= 5 = %d\n", sum_odds);
}
}
}
sum_tot = sum_evens + sum_odds;
//Validation (if sum % 10 = 0 it is valid)
valid = sum_tot % 10;
printf("sum_tot = %d, valid = %d \n", sum_tot, valid);
if (valid % 10 == 0)
{
printf("Valid credit card \n");
}
else
{
printf("Invalid credit card\n");
}
}
Not so soon. =(
Program looses precision when passes values (digits) to the long long variable cc_num.
#include <cs50.h>
#include <stdio.h>
#include <string.h>
int main (void)
{
long long cc_num;
char cc_num_str[15];
int static sum_evens, sum_odds, sum_tot, valid = 0;
int static size;
do
{
printf("Enter your credit card number for validation: \n");
cc_num = GetLongLong();
sprintf(cc_num_str, "%lld", cc_num);
size = strlen (cc_num_str);
}
while (cc_num < 1 || cc_num > 9999999999999999 || size < 13 || size > 16);
int array_dig[size];
for (int i = size - 1; i >= 0; i--)
{
array_dig[i] = cc_num % 10;
cc_num = cc_num / 10;
//Sanity check
printf("pos %d = %d\n", i, array_dig[i]);
}
//Summing digits
for (int j=0; j < size; j++)
{
if (j % 2 == 0)
{
sum_evens += array_dig[j];
//Sanity check
printf("sum_evens = %d/n", sum_evens);
}
else if (j % 2 == 1)
{
if (array_dig[j] < 5)
{
sum_odds += 2 * array_dig[j];
//Sanity check
printf("sum_odds for char < 5 = %d\n", sum_odds);
}
else
{
sum_odds += (2 * array_dig[j]) % 10 + 1;
//Sanity check
printf("sum_odds for char >= 5 = %d\n", sum_odds);
}
}
}
sum_tot = sum_evens + sum_odds;
//Validation (if sum % 10 = 0 it is valid)
valid = sum_tot % 10;
printf("sum_tot = %d, valid = %d \n", sum_tot, valid);
if (valid % 10 == 0)
{
//code that will verifies card type (to be written)
printf("Valid credit card \n");
}
else
{
printf("Invalid. \n");
}
return 0;
}
Here is the output:
Enter your credit card number for validation:
1234567809874366
pos 15 = 8
pos 14 = 3
pos 13 = 6
pos 12 = 9
pos 11 = 5
pos 10 = 8
pos 9 = 9
pos 8 = 0
pos 7 = 8
pos 6 = 7
pos 5 = 6
pos 4 = 5
pos 3 = 4
pos 2 = 3
pos 1 = 2
pos 0 = 1
sum_evens = 1/nsum_odds for char < 5 = 4
sum_evens = 4/nsum_odds for char < 5 = 12
sum_evens = 9/nsum_odds for char >= 5 = 15
sum_evens = 16/nsum_odds for char >= 5 = 22
sum_evens = 16/nsum_odds for char >= 5 = 31
sum_evens = 24/nsum_odds for char >= 5 = 32
sum_evens = 33/nsum_odds for char >= 5 = 35
sum_evens = 36/nsum_odds for char >= 5 = 42
sum_tot = 78, valid = 8
Invalid.

Resources