-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathadd_two_numbers.c
162 lines (129 loc) · 4 KB
/
add_two_numbers.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
/*
Copyright (c) Omar Boukli-Hacene. All rights reserved.
Distributed under an MIT-style license that can be
found in the LICENSE file.
*/
/* SPDX-License-Identifier: MIT */
#include "forfun_c/add_two_numbers.h"
#include <assert.h>
#include <stddef.h>
#include <stdlib.h>
#include "forfun_c/container/forward_list.h"
struct forfun_internal_result {
struct forfun_forward_list_node* node;
int error;
};
static struct forfun_internal_result forfun_do_add_two_numbers(
struct forfun_forward_list_node const* addend_a,
struct forfun_forward_list_node const* addend_b,
unsigned int carry
);
struct forfun_forward_list_node* forfun_iterative_add_two_numbers(
struct forfun_forward_list_node const* addend_a,
struct forfun_forward_list_node const* addend_b
)
{
unsigned int sum = 0U;
struct forfun_forward_list_node* aux_node_ptr
= (struct forfun_forward_list_node*)malloc(
sizeof(struct forfun_forward_list_node)
);
struct forfun_forward_list_node* const root_node_ptr = aux_node_ptr;
if (aux_node_ptr == NULL)
{
return NULL;
}
aux_node_ptr->next = NULL;
for (;;)
{
if (addend_a != NULL)
{
assert(addend_a->value <= 9U);
sum += addend_a->value;
addend_a = addend_a->next;
}
if (addend_b != NULL)
{
assert(addend_b->value <= 9U);
sum += addend_b->value;
addend_b = addend_b->next;
}
aux_node_ptr->value = sum % 10U;
sum = sum / 10U;
if ((addend_a == NULL) && (addend_b == NULL) && (sum == 0U))
{
assert(root_node_ptr != NULL);
return root_node_ptr;
}
aux_node_ptr->next = (struct forfun_forward_list_node*)malloc(
sizeof(struct forfun_forward_list_node)
);
aux_node_ptr = aux_node_ptr->next;
if (aux_node_ptr == NULL)
{
break;
}
aux_node_ptr->next = NULL;
}
forfun_free_node_list(root_node_ptr);
return NULL;
}
static struct forfun_internal_result forfun_do_add_two_numbers(
struct forfun_forward_list_node const* const addend_a,
struct forfun_forward_list_node const* const addend_b,
unsigned int const carry
)
{
struct forfun_internal_result result = {NULL, 0};
unsigned int sum = carry;
unsigned int const val_a = addend_a == NULL ? 0U : addend_a->value;
unsigned int const val_b = addend_b == NULL ? 0U : addend_b->value;
assert(val_a <= 9U);
assert(val_b <= 9U);
sum += val_a + val_b;
if ((carry != 0U) || (addend_a != NULL) || (addend_b != NULL))
{
struct forfun_forward_list_node* aux_node_ptr;
struct forfun_internal_result next_result;
struct forfun_forward_list_node* next_a
= addend_a == NULL ? NULL : addend_a->next;
struct forfun_forward_list_node* next_b
= addend_b == NULL ? NULL : addend_b->next;
aux_node_ptr = (struct forfun_forward_list_node*)malloc(
sizeof(struct forfun_forward_list_node)
);
if (aux_node_ptr == NULL)
{
goto error;
}
aux_node_ptr->value = sum % 10U;
next_result = forfun_do_add_two_numbers(next_a, next_b, sum / 10U);
if (next_result.error == 1)
{
free(aux_node_ptr);
goto error;
}
aux_node_ptr->next = next_result.node;
result.node = aux_node_ptr;
}
return result;
error:
result.error = 1;
return result;
}
struct forfun_forward_list_node* forfun_recursive_add_two_numbers(
struct forfun_forward_list_node const* const addend_a,
struct forfun_forward_list_node const* const addend_b
)
{
struct forfun_internal_result result;
result = forfun_do_add_two_numbers(addend_a, addend_b, 0U);
if (result.error == 1)
{
forfun_free_node_list(result.node);
return NULL;
}
assert(result.error == 0);
assert(result.node != NULL);
return result.node;
}