Skip to content

Commit bf40c25

Browse files
committed
refactor: [linked-lists] Use tests.h
1 parent 5e85ce2 commit bf40c25

File tree

4 files changed

+165
-486
lines changed

4 files changed

+165
-486
lines changed

cpp/linked-lists/reverse-k-groups.cpp

Lines changed: 35 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -10,16 +10,18 @@
1010
#include "tests.h"
1111
#include "linked-lists.h"
1212

13-
using namespace SinglyLinkedList;
14-
1513
/* ===========================================================================
1614
* Algorithms implementation
1715
* ===========================================================================
1816
*/
1917

18+
#define _rev_SinglyLinkedList_desc "Singly Linked List"
19+
2020
/* TC : O(n)
2121
* SC : O(1)
2222
*/
23+
namespace SinglyLinkedList
24+
{
2325
NodePtr reverseKGroup(NodePtr head, int k)
2426
{
2527
if (!head || !head->next || k < 2) return head;
@@ -48,42 +50,45 @@ NodePtr reverseKGroup(NodePtr head, int k)
4850
}
4951
return dummy->next;
5052
}
53+
} // namespace SinglyLinkedList
5154

5255
/* ===========================================================================
5356
* Test code
5457
* ===========================================================================
5558
*/
56-
TEST(reverseKGroup, "Singly Linked List - reverse in K groups iterative")
57-
{
58-
int k;
59-
NodePtr i, e, t, a;
60-
61-
k = 2;
62-
i = copy(vi_t{1, 2, 3, 4, 5});
63-
e = copy(vi_t{2, 1, 4, 3, 5});
64-
t = copy(i);
65-
a = reverseKGroup(t, k);
66-
67-
CHECK_EQ(e, a);
68-
SHOW_OUTPUT(i, a);
59+
#define _rev_check(i, k, e) \
60+
{ \
61+
NodePtr t = copy(i); \
62+
NodePtr a = reverseKGroup(t, k); \
63+
CHECK_EQ(e, a); \
64+
SHOW_OUTPUT(i, a); \
65+
}
6966

70-
k = 3;
71-
i = copy(vi_t{1, 2, 3, 4, 5});
72-
e = copy(vi_t{3, 2, 1, 4, 5});
73-
t = copy(i);
74-
a = reverseKGroup(t, k);
67+
#define _rev_desc_prefix "Reverse in K groups"
7568

76-
CHECK_EQ(e, a);
77-
SHOW_OUTPUT(i, a);
69+
#define _REV_NAME(var) var
70+
#define _REV_DESC(var) _rev_desc_prefix " - " _rev_##var##_desc
7871

79-
k = 2;
80-
i = copy(vi_t{1, 2, 3, 4, 5});
81-
e = copy(vi_t{3, 2, 1, 4, 5});
82-
t = copy(i);
83-
a = reverseKGroup(t, k);
72+
#define _REV_TEST(var) \
73+
TEST(_REV_NAME(var), _REV_DESC(var)) \
74+
{ \
75+
using namespace _REV_NAME(var); \
76+
NodePtr ip = copy(vi_t{1, 2, 3, 4, 5}); \
77+
vi_t _k{2, 3, 2}; \
78+
vector<NodePtr> _e{ \
79+
copy(vi_t{2, 1, 4, 3, 5}), \
80+
copy(vi_t{3, 2, 1, 4, 5}), \
81+
copy(vi_t{3, 2, 1, 4, 5}), \
82+
}; \
83+
int n = size(_e), i = 0; \
84+
for (; i < (n - 1); i++) _rev_check(ip, _k[i], _e[i]); \
85+
/* check negative case */ \
86+
NodePtr t = copy(ip); \
87+
NodePtr a = reverseKGroup(t, _k[i]); \
88+
CHECK_NE(_e[i], a); \
89+
SHOW_OUTPUT(ip, a); \
90+
}
8491

85-
CHECK_NE(e, a);
86-
SHOW_OUTPUT(i, a);
87-
}
92+
_REV_TEST(SinglyLinkedList);
8893

8994
INIT_TEST_MAIN();

cpp/linked-lists/reverse-start-end.cpp

Lines changed: 54 additions & 185 deletions
Original file line numberDiff line numberDiff line change
@@ -7,210 +7,79 @@
77
* https://leetcode.com/problems/reverse-linked-list-ii/
88
*/
99

10-
#include <bits/stdc++.h>
11-
12-
using namespace std;
13-
14-
/* ===========================================================================
15-
* Data structures
16-
* ===========================================================================
17-
*/
18-
19-
struct Node;
20-
using NodePtr = shared_ptr<Node>;
21-
inline NodePtr new_node(int data) { return make_shared<Node>(data); }
22-
23-
struct Node {
24-
int data = 0;
25-
NodePtr next = nullptr;
26-
27-
Node(int data) : data(data), next(nullptr) {}
28-
};
29-
30-
void list_append(NodePtr &tail, int data)
31-
{
32-
auto node = new_node(data);
33-
if (tail) tail->next = node;
34-
tail = node;
35-
}
36-
37-
/* ===========================================================================
38-
* Test helpers
39-
* ===========================================================================
40-
*/
41-
class _00_test
42-
{
43-
public:
44-
_00_test(const string &name) : name(name) {}
45-
46-
string getName(void) const { return name; }
47-
48-
virtual NodePtr reverseBetween(NodePtr head, int start, int end) = 0;
49-
50-
private:
51-
string name;
52-
};
10+
#include "tests.h"
11+
#include "linked-lists.h"
5312

5413
/* ===========================================================================
5514
* Algorithms implementation
5615
* ===========================================================================
5716
*/
5817

18+
#define _rev_SinglyLinkedList_desc "Singly Linked List"
19+
5920
/* TC : O(n)
6021
* SC : O(1)
6122
*/
62-
class _01_iterative : public _00_test
23+
namespace SinglyLinkedList
6324
{
64-
public:
65-
_01_iterative()
66-
: _00_test("Singly Linked List - reverse between start & end")
67-
{
25+
NodePtr reverseBetween(NodePtr head, int start, int end)
26+
{
27+
if (!head || (start == end)) return head;
28+
NodePtr curr = head, prev = nullptr, next = nullptr;
29+
int i = 0;
30+
while (i++ < start - 1 && curr) {
31+
prev = curr;
32+
curr = curr->next;
6833
}
69-
70-
NodePtr reverseBetween(NodePtr head, int start, int end) override
71-
{
72-
if (!head || (start == end)) return head;
73-
NodePtr curr = head, prev = nullptr, next = nullptr;
74-
int i = 0;
75-
while (i++ < start - 1) {
76-
prev = curr;
77-
curr = curr->next;
78-
}
79-
NodePtr rprev = prev, rtail = curr;
80-
while (i++ <= end && curr) {
81-
next = curr->next;
82-
curr->next = prev;
83-
prev = curr;
84-
curr = next;
85-
}
86-
if (rprev)
87-
rprev->next = prev;
88-
else
89-
head = prev;
90-
if (rtail) rtail->next = curr;
91-
return head;
34+
NodePtr rprev = prev, rtail = curr;
35+
while (i++ <= end && curr) {
36+
next = curr->next;
37+
curr->next = prev;
38+
prev = curr;
39+
curr = next;
9240
}
93-
};
41+
if (rprev)
42+
rprev->next = prev;
43+
else
44+
head = prev;
45+
if (rtail) rtail->next = curr;
46+
return head;
47+
}
48+
} // namespace SinglyLinkedList
9449

9550
/* ===========================================================================
9651
* Test code
9752
* ===========================================================================
9853
*/
99-
string _l2s(NodePtr node)
100-
{
101-
ostringstream out;
102-
out << "{";
103-
for (int i = 0; node; node = node->next) {
104-
out << (i++ ? ", " : "") << node->data;
105-
}
106-
out << "}";
107-
return out.str();
108-
}
109-
110-
bool _eq(NodePtr l, NodePtr r)
111-
{
112-
while (l && r) {
113-
if (l->data != r->data) return false;
114-
l = l->next, r = r->next;
115-
}
116-
return (!l && !r);
117-
}
118-
119-
bool _ne(NodePtr l, NodePtr r) { return !_eq(l, r); }
120-
121-
NodePtr _cp(NodePtr node)
122-
{
123-
NodePtr head = nullptr, tail = nullptr;
124-
for (int i = 0; node; node = node->next) {
125-
list_append(tail, node->data);
126-
if (!i++) head = tail;
127-
}
128-
return head;
129-
}
130-
131-
using ip_t = tuple<NodePtr, int, int>;
132-
133-
void test_impl(vector<ip_t> &ip, vector<NodePtr> &op, shared_ptr<_00_test> f)
134-
{
135-
for (size_t i = 0; i < ip.size(); i++) {
136-
const string test = format("test-{}", i);
137-
const auto &[n, s, e] = ip[i];
138-
NodePtr t = f->reverseBetween(_cp(n), s, e);
139-
if (_ne(t, op[i])) {
140-
cerr << f->getName() << ": " << test << " failed!"
141-
<< " list expected " << _l2s(op[i])
142-
<< ", actual " << _l2s(t) << "." << endl;
143-
exit(1);
144-
}
145-
146-
if (getenv("SHOW_TEST_OUTPUT"))
147-
cout << " " << test << ": "
148-
<< "input: list = " << _l2s(n)
149-
<< ", start = " << s << ", end = " << e
150-
<< " output: list = " << _l2s(t) << "\n";
54+
#define _rev_check(i, m, n, e) \
55+
{ \
56+
NodePtr t = copy(i); \
57+
NodePtr a = reverseBetween(t, m, n); \
58+
CHECK_EQ(e, a); \
59+
SHOW_OUTPUT(i, a); \
15160
}
152-
}
15361

154-
NodePtr _v2l(const vector<int> v)
155-
{
156-
const int n = static_cast<int>(v.size());
157-
NodePtr head = nullptr, tail = nullptr;
158-
for (int i = 0; i < n; i++) {
159-
list_append(tail, v[i]);
160-
if (!i) head = tail;
62+
#define _rev_desc_prefix "Reverse between"
63+
64+
#define _REV_NAME(var) var
65+
#define _REV_DESC(var) _rev_desc_prefix " - " _rev_##var##_desc
66+
67+
#define _REV_TEST(var) \
68+
TEST(_REV_NAME(var), _REV_DESC(var)) \
69+
{ \
70+
using namespace _REV_NAME(var); \
71+
NodePtr ip = copy(vi_t{1, 2, 3, 4, 5}); \
72+
vi_t _m{2, 2}; \
73+
vi_t _n{4, 2}; \
74+
vector<NodePtr> _e{ \
75+
copy(vi_t{1, 4, 3, 2, 5}), \
76+
copy(vi_t{1, 2, 3, 4, 5}), \
77+
}; \
78+
int n = size(_e); \
79+
for (int i = 0; i < n; i++) \
80+
_rev_check(ip, _m[i], _n[i], _e[i]); \
16181
}
162-
return head;
163-
}
164-
165-
void _append_test_data_01(vector<ip_t> &ip, vector<NodePtr> &op)
166-
{
167-
const int s = 2;
168-
const int e = 4;
169-
vector<int> t{1, 2, 3, 4, 5};
170-
NodePtr i = _v2l(t);
17182

172-
t = {1, 4, 3, 2, 5};
173-
NodePtr o = _v2l(t);
83+
_REV_TEST(SinglyLinkedList);
17484

175-
ip.emplace_back(i, s, e);
176-
op.push_back(o);
177-
}
178-
179-
void _append_test_data_02(vector<ip_t> &ip, vector<NodePtr> &op)
180-
{
181-
const int s = 2;
182-
const int e = 2;
183-
vector<int> t{1, 2, 3, 4, 5};
184-
NodePtr i = _v2l(t);
185-
186-
t = {1, 2, 3, 4, 5};
187-
NodePtr o = _v2l(t);
188-
189-
ip.emplace_back(i, s, e);
190-
op.push_back(o);
191-
}
192-
193-
int main(int, char **)
194-
{
195-
vector<ip_t> ip;
196-
vector<NodePtr> op;
197-
198-
_append_test_data_01(ip, op);
199-
_append_test_data_02(ip, op);
200-
201-
vector<shared_ptr<_00_test>> impls{
202-
make_shared<_01_iterative>(),
203-
};
204-
205-
for (size_t i = 0; i < impls.size(); i++) {
206-
if (getenv("SHOW_TEST_OUTPUT"))
207-
cout << "Testing implementation " << i + 1 << " "
208-
<< impls[i]->getName() << "\n";
209-
210-
test_impl(ip, op, impls[i]);
211-
}
212-
213-
cout << "Executed " << impls.size() << " implementations"
214-
<< " with " << ip.size() << " tests." << endl;
215-
return 0;
216-
}
85+
INIT_TEST_MAIN();

0 commit comments

Comments
 (0)