RDKit
Open-source cheminformatics and machine learning.
Toggle main menu visibility
Loading...
Searching...
No Matches
hanoiSort.h
Go to the documentation of this file.
1
//
2
// Copyright (C) 2014-2025 Greg Landrum and other RDKit contributors
3
// Adapted from pseudo-code from Roger Sayle
4
//
5
// @@ All Rights Reserved @@
6
// This file is part of the RDKit.
7
// The contents are covered by the terms of the BSD license
8
// which is included in the file license.txt, found at the root
9
// of the RDKit source tree.
10
//
11
12
#include <
RDGeneral/export.h
>
13
#ifndef HANOISORT_H
14
#define HANOISORT_H
15
16
#include <cstring>
17
#include <cassert>
18
#include <cstdlib>
19
#include <vector>
20
#include <span>
21
22
#if defined(_MSC_VER)
23
#pragma warning(push, 1)
24
#pragma warning(disable : 4800)
25
#endif
26
namespace
RDKit
{
27
namespace
detail
{
28
template
<
typename
CompareFunc>
29
bool
hanoi
(
int
*base,
int
nel,
int
*temp,
int
*count,
int
*changed,
30
CompareFunc compar) {
31
assert(base);
32
assert(temp);
33
assert(count);
34
assert(changed);
35
// std::cerr<<" hanoi: "<<nel<< " start " << (*base)+1 << std::endl;
36
int
*b1, *b2;
37
int
*t1, *t2;
38
int
*s1, *s2;
39
int
n1, n2;
40
int
result;
41
int
*ptr;
42
43
if
(nel == 1) {
44
count[base[0]] = 1;
45
return
false
;
46
}
else
if
(nel == 2) {
47
n1 = base[0];
48
n2 = base[1];
49
int
stat =
50
(
/*!changed || */
changed[n1] || changed[n2]) ? compar(n1, n2) : 0;
51
if
(stat == 0) {
52
count[n1] = 2;
53
count[n2] = 0;
54
return
false
;
55
}
else
if
(stat < 0) {
56
count[n1] = 1;
57
count[n2] = 1;
58
return
false
;
59
}
else
/* stat > 0 */
{
60
count[n1] = 1;
61
count[n2] = 1;
62
base[0] = n2;
/* temp[0] = n2; */
63
base[1] = n1;
/* temp[1] = n1; */
64
return
false
;
/* return True; */
65
}
66
}
67
68
n1 = nel / 2;
69
n2 = nel - n1;
70
b1 = base;
71
t1 = temp;
72
b2 = base + n1;
73
t2 = temp + n1;
74
75
if
(
hanoi
(b1, n1, t1, count, changed, compar)) {
76
if
(
hanoi
(b2, n2, t2, count, changed, compar)) {
77
s2 = t2;
78
}
else
{
79
s2 = b2;
80
}
81
result =
false
;
82
ptr = base;
83
s1 = t1;
84
}
else
{
85
if
(
hanoi
(b2, n2, t2, count, changed, compar)) {
86
s2 = t2;
87
}
else
{
88
s2 = b2;
89
}
90
result =
true
;
91
ptr = temp;
92
s1 = b1;
93
}
94
95
while
(
true
) {
96
assert(*s1 != *s2);
97
int
stat =
98
(
/*!changed || */
changed[*s1] || changed[*s2]) ? compar(*s1, *s2) : 0;
99
int
len1 = count[*s1];
100
int
len2 = count[*s2];
101
assert(len1 > 0);
102
assert(len2 > 0);
103
if
(stat == 0) {
104
count[*s1] = len1 + len2;
105
count[*s2] = 0;
106
memmove(ptr, s1, len1 *
sizeof
(
int
));
107
ptr += len1;
108
n1 -= len1;
109
if
(n1 == 0) {
110
if
(ptr != s2) {
111
memmove(ptr, s2, n2 *
sizeof
(
int
));
112
}
113
return
result;
114
}
115
s1 += len1;
116
117
// std::cerr<<" cpy: "<<*s1<<" "<<*s2<<" "<<len2<<std::endl;
118
memmove(ptr, s2, len2 *
sizeof
(
int
));
119
ptr += len2;
120
n2 -= len2;
121
if
(n2 == 0) {
122
memmove(ptr, s1, n1 *
sizeof
(
int
));
123
return
result;
124
}
125
s2 += len2;
126
}
else
if
(stat < 0 && len1 > 0) {
127
memmove(ptr, s1, len1 *
sizeof
(
int
));
128
ptr += len1;
129
n1 -= len1;
130
if
(n1 == 0) {
131
if
(ptr != s2) {
132
memmove(ptr, s2, n2 *
sizeof
(
int
));
133
}
134
return
result;
135
}
136
s1 += len1;
137
}
else
if
(stat > 0 && len2 > 0)
/* stat > 0 */
{
138
memmove(ptr, s2, len2 *
sizeof
(
int
));
139
ptr += len2;
140
n2 -= len2;
141
if
(n2 == 0) {
142
memmove(ptr, s1, n1 *
sizeof
(
int
));
143
return
result;
144
}
145
s2 += len2;
146
}
else
{
147
assert(0);
148
}
149
}
150
}
151
}
// namespace detail
152
template
<
typename
CompareFunc>
153
void
hanoisort
(std::span<int> &base, std::vector<int> &count,
154
std::vector<int> &changed, CompareFunc compar) {
155
std::vector<int> tempVec(base.size());
156
if
(
detail::hanoi
(base.data(), base.size(), tempVec.data(), count.data(),
157
changed.data(), compar)) {
158
std::copy(tempVec.begin(), tempVec.end(), base.begin());
159
}
160
}
161
}
// namespace RDKit
162
163
#if defined(_MSC_VER)
164
#pragma warning(pop)
165
#endif
166
167
#endif
/* HANOISORT_H_ */
export.h
RDKit::detail
Definition
FMCS.h:185
RDKit::detail::hanoi
bool hanoi(int *base, int nel, int *temp, int *count, int *changed, CompareFunc compar)
Definition
hanoiSort.h:29
RDKit
Std stuff.
Definition
Abbreviations.h:19
RDKit::hanoisort
void hanoisort(std::span< int > &base, std::vector< int > &count, std::vector< int > &changed, CompareFunc compar)
Definition
hanoiSort.h:153
RDGeneral
hanoiSort.h
Generated on
for RDKit by
1.17.0