Algorithms_in_C 1.0.0
Set of algorithms implemented in C.
Loading...
Searching...
No Matches
sol1.c File Reference

Problem 20 solution More...

#include <stdio.h>
#include <stdlib.h>
#include <time.h>
Include dependency graph for sol1.c:

Data Structures

struct  _big_int
 store arbitratily large integer values as a linked list of digits. More...
 

Typedefs

typedef struct _big_int big_int
 store arbitratily large integer values as a linked list of digits.
 

Functions

big_intadd_digit (big_int *digit, char value)
 Function that allocates memory to add another digit at the MSB. More...
 
char remove_digits (big_int *digit, int N)
 Function to remove digits preceeding the current digit. More...
 
int main (int argc, char **argv)
 Main function. More...
 

Detailed Description

Problem 20 solution

Author
Krishna Vedala

Implementation uses a custom big_int structure that can store arbitrarily large integer numbers.

Function Documentation

◆ add_digit()

big_int * add_digit ( big_int digit,
char  value 
)

Function that allocates memory to add another digit at the MSB.

38{
39 if (digit == NULL)
40 {
41 digit = (big_int *)malloc(sizeof(big_int));
42 if (!digit)
43 {
44 perror("Unable to allocate memory!");
45 return NULL;
46 }
47 digit->value = value;
48 digit->next_digit = NULL;
49 digit->prev_digit = NULL;
50
51 return digit;
52 }
53
54 if (digit->next_digit)
55 {
56 digit->next_digit->value = value;
57 return digit->next_digit;
58 }
59
60 digit->next_digit = (big_int *)malloc(sizeof(big_int));
61 if (digit->next_digit == NULL)
62 {
63 perror("Unable to allocate memory!");
64 return NULL;
65 }
66 digit->next_digit->value = value;
67 digit->next_digit->next_digit = NULL;
68 digit->next_digit->prev_digit = digit;
69 return digit->next_digit;
70}
#define malloc(bytes)
This macro replace the standard malloc function with malloc_dbg.
Definition: malloc_dbg.h:18
store arbitratily large integer values as a linked list of digits.
Definition: sol1.c:18
struct _big_int * next_digit
hundreds place
Definition: sol1.c:20
char value
tens place (single digit)
Definition: sol1.c:19
struct _big_int * prev_digit
units place
Definition: sol1.c:21

◆ main()

int main ( int  argc,
char **  argv 
)

Main function.

96{
97 unsigned int N = 5;
98 big_int *ptr = add_digit(NULL, 1); /* start with 1 */
99 const big_int *ptr0 = ptr; /* save the first location */
100 unsigned long sum_digits = 0;
101 unsigned long num_digits = 0;
102
103 if (argc == 2)
104 N = atoi(argv[1]);
105
106 clock_t start_time = clock();
107
108 for (unsigned int i = 1; i <= N; i++)
109 {
110 int carry = 0;
111#ifdef DEBUG
112 printf("%3d: ", i);
113#endif
114 ptr = (big_int *)ptr0; /* multiply every digit with i */
115 while (ptr)
116 {
117#ifdef DEBUG
118 printf("%p\t", ptr);
119#endif
120 unsigned int tmp = ptr->value * i + carry;
121 if (tmp >= 10)
122 {
123 div_t tmp2 = div(tmp, 10);
124 carry = tmp2.quot;
125 tmp = tmp2.rem;
126 }
127 else
128 carry = 0;
129
130 if (carry > 0 && ptr->next_digit == NULL)
131 add_digit(ptr, 0);
132
133 ptr->value = tmp;
134
135 if (i == N)
136 /*
137 * sum digits on the last iteration
138 * this avoid having another loop over all digits
139 */
140 sum_digits += tmp;
141
142 if (ptr->next_digit)
143 /* more digits available */
144 ptr = ptr->next_digit;
145 else
146 /* no more digits left - reached MSB */
147 break;
148 }
149#ifdef DEBUG
150 printf("\n");
151#endif
152 }
153
154 clock_t end_time = clock();
155
156#ifdef DEBUG
157 printf("ptr = %p\n", ptr);
158 printf("%d! = ", N);
159#endif
160
161 /* Notice that in the loop above, we make sure that at the end of the loop,
162 * ptr is pointing to the last digit. Thus we can avoid using another loop.
163 */
164 // ptr = &my_int;
165 // /* move ptr to the MSB digit */
166 // while (ptr->next_digit)
167 // ptr = ptr->next_digit;
168 do
169 {
170 putchar(ptr->value + 0x30); /* convert digit to ASCII char */
171 ptr = ptr->prev_digit;
172 num_digits++;
173 } while (ptr); /* after coming to units place, there will be no valid ptr */
174
175 printf("\nTime taken: %.4g millisecond\n",
176 1e3 * (end_time - start_time) / CLOCKS_PER_SEC);
177 printf(
178 "Digit Sum = %lu\tNumber of digits = %lu\tStorage space = %.3gkb\t \n",
179 sum_digits, num_digits, num_digits * sizeof(big_int) / 1024.0);
180
181 remove_digits((big_int *)ptr0, -1);
182 return 0;
183}
big_int * add_digit(big_int *digit, char value)
Function that allocates memory to add another digit at the MSB.
Definition: sol1.c:37
char remove_digits(big_int *digit, int N)
Function to remove digits preceeding the current digit.
Definition: sol1.c:76
Here is the call graph for this function:

◆ remove_digits()

char remove_digits ( big_int digit,
int  N 
)

Function to remove digits preceeding the current digit.

77{
78 if (digit == NULL)
79 return 0;
80
81 if (digit->next_digit == NULL)
82 {
83 free(digit);
84 digit = NULL;
85 return 0;
86 }
87
88 if (N > 0)
89 return remove_digits(digit->next_digit, N - 1);
90
91 return remove_digits(digit->next_digit, 0);
92}
#define free(ptr)
This macro replace the standard free function with free_dbg.
Definition: malloc_dbg.h:26
Here is the call graph for this function: