aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorIgor Pashev <pashev.igor@gmail.com>2023-01-02 19:24:28 +0200
committerIgor Pashev <pashev.igor@gmail.com>2023-01-03 13:31:08 +0200
commitb883d90c632d7c6fb585ee23327705e308d65594 (patch)
treed558de92f2d5a68b1005e92f62c502fb05b23784
parent9cd4f96eb320b59313fc7f83db56d63aa9b82891 (diff)
downloadmendeleev-b883d90c632d7c6fb585ee23327705e308d65594.tar.gz
Use ranges like in RustHEADmaster
-rw-r--r--mendeleev.c21
-rw-r--r--mendeleev.cpp19
-rw-r--r--mendeleev.f9025
-rw-r--r--mendeleev.lisp21
-rw-r--r--mendeleev.py36
5 files changed, 52 insertions, 70 deletions
diff --git a/mendeleev.c b/mendeleev.c
index cad0308..5739cde 100644
--- a/mendeleev.c
+++ b/mendeleev.c
@@ -15,8 +15,6 @@ static const char *const ELEMENTS[] = { "?",
"Tm", "Ts", "U", "V", "W", "Xe", "Y", "Yb", "Zn", "Zr"
};
-static const size_t NELEMENTS = sizeof (ELEMENTS) / sizeof (const char *) - 1;
-
typedef struct element
{
size_t n;
@@ -26,12 +24,12 @@ typedef struct element
} element_t;
static void
-search (size_t *start, size_t *len, size_t shift, char c)
+search (size_t *start, size_t *end, size_t shift, char c)
{
size_t l, m, u;
c |= ' ';
- u = *start + *len;
+ u = *end;
l = *start;
while (l < u)
{
@@ -42,13 +40,13 @@ search (size_t *start, size_t *len, size_t shift, char c)
u = m;
}
- if ((l == *start + *len) || ((ELEMENTS[l][shift] | ' ') != c))
+ if ((l == *end) || ((ELEMENTS[l][shift] | ' ') != c))
{
- *len = 0;
+ *end = 0;
return;
}
- u = *start + *len;
+ u = *end;
*start = l;
while (l < u)
{
@@ -59,7 +57,7 @@ search (size_t *start, size_t *len, size_t shift, char c)
l = m + 1;
}
- *len = u - *start;
+ *end = u;
}
static element_t *
@@ -69,13 +67,13 @@ split (const char *tail)
element_t *last = NULL;
size_t start = 1;
- size_t len = NELEMENTS;
+ size_t end = sizeof (ELEMENTS) / sizeof (ELEMENTS[0]);
size_t shift = 0;
while (tail[shift])
{
- search (&start, &len, shift, tail[shift]);
- if (!len)
+ search (&start, &end, shift, tail[shift]);
+ if (start >= end)
break;
shift++;
@@ -94,7 +92,6 @@ split (const char *tail)
last->n = start;
last->tail = &tail[shift];
start++;
- len--;
}
}
diff --git a/mendeleev.cpp b/mendeleev.cpp
index cd2a8d3..7a52e48 100644
--- a/mendeleev.cpp
+++ b/mendeleev.cpp
@@ -34,11 +34,11 @@ struct Element {
: eid(eid_), next(next_) {}
};
-static void search(size_t &start, size_t &len, size_t shift, char c) {
+static void search(size_t &start, size_t &end, size_t shift, char c) {
size_t l, m, u;
c |= ' ';
- u = start + len;
+ u = end;
l = start;
while (l < u) {
m = (l + u) / 2;
@@ -48,12 +48,12 @@ static void search(size_t &start, size_t &len, size_t shift, char c) {
u = m;
}
- if ((l == start + len) || ((ELEMENTS[l][shift] | ' ') != c)) {
- len = 0;
+ if ((l == end) || ((ELEMENTS[l][shift] | ' ') != c)) {
+ end = 0;
return;
}
- u = start + len;
+ u = end;
start = l;
while (l < u) {
m = (l + u) / 2;
@@ -63,26 +63,25 @@ static void search(size_t &start, size_t &len, size_t shift, char c) {
l = m + 1;
}
- len = u - start;
+ end = u;
}
static list<Split> split(string_view tail) {
auto x = list<Split>();
size_t start = 1;
- size_t len = ELEMENTS.size() - 1;
+ size_t end = ELEMENTS.size();
size_t shift = 0;
while (shift < tail.length()) {
- search(start, len, shift, tail[shift]);
- if (!len)
+ search(start, end, shift, tail[shift]);
+ if (start >= end)
break;
shift++;
if (shift == ELEMENTS[start].length()) {
x.emplace_back(start, tail.substr(shift));
start++;
- len--;
}
}
diff --git a/mendeleev.f90 b/mendeleev.f90
index 95640d0..e36bef7 100644
--- a/mendeleev.f90
+++ b/mendeleev.f90
@@ -67,15 +67,15 @@ contains
end function tolower
- pure subroutine search(start, length, sh, c)
- integer, intent(in out) :: start, length
+ pure subroutine search(start, end, sh, c)
+ integer, intent(in out) :: start, end
integer, intent(in) :: sh
character(len=1), intent(in) :: c
integer :: l, m, u, c_
c_ = tolower(c)
- u = start + length
+ u = end
l = start
do while (l < u)
m = (u + l) / 2
@@ -86,17 +86,17 @@ contains
endif
end do
- if (l == start + length) then
- length = 0
+ if (l == end) then
+ end = 0
return
end if
if (tolower(ELEMENTS(l)(sh:sh)) /= c_) then
- length = 0
+ end = 0
return
end if
- u = start + length
+ u = end
start = l
do while (l < u)
m = (u + l) / 2
@@ -107,23 +107,23 @@ contains
endif
end do
- length = u - start
+ end = u
end subroutine search
function split(tail) result(head)
character(len=:), pointer, intent(in) :: tail
type(element_t), pointer :: head, last, el
- integer :: start, length, sh
+ integer :: start, end, sh
head => null()
last => null()
start = 1
- length = ubound(ELEMENTS, 1)
+ end = ubound(ELEMENTS, 1) + 1
do sh = 1, len(tail)
- call search(start, length, sh, tail(sh:sh))
- if (length == 0) exit
+ call search(start, end, sh, tail(sh:sh))
+ if (start >= end) exit
if (sh == len_trim(ELEMENTS(start))) then
allocate(el)
@@ -138,7 +138,6 @@ contains
last%tail => tail(sh+1:)
start = start + 1
- length = length - 1
end if
end do
diff --git a/mendeleev.lisp b/mendeleev.lisp
index a7e7945..611fd57 100644
--- a/mendeleev.lisp
+++ b/mendeleev.lisp
@@ -11,9 +11,6 @@
"Sg" "Si" "Sm" "Sn" "Sr" "Ta" "Tb" "Tc" "Te" "Th" "Ti" "Tl"
"Tm" "Ts" "U" "V" "W" "Xe" "Y" "Yb" "Zn" "Zr"))
-(defconstant +nelems+
- (1- (length +elements+)))
-
(defconstant +elems+
(map 'vector #'string-downcase +elements+))
@@ -21,37 +18,33 @@
(schar (elt +elems+ el) sh))
(defun search-el (range sh ch)
- (prog* ((top (+ (car range) (cdr range)))
- (u top)
- (l (car range))
- m)
+ (prog ((l (car range)) (u (cdr range)) m)
(loop while (< l u) do
(setf m (truncate (+ l u) 2))
(if (char< (get-part m sh) ch)
(setf l (1+ m))
(setf u m)))
- (when (or (= l top) (char/= ch (get-part l sh)))
+ (when (or (= l (cdr range)) (char/= ch (get-part l sh)))
(setf (cdr range) 0) (return))
- (setf u top
- (car range) l)
+ (setf (car range) l u (cdr range))
(loop while (< l u) do
(setf m (truncate (+ l u) 2))
(if (char< ch (get-part m sh))
(setf u m)
(setf l (1+ m))))
- (setf (cdr range) (- u (car range))) (return)))
+ (setf (cdr range) u) (return)))
(defun split (tail)
- (prog ((range (cons 1 +nelems+))
+ (prog ((range (cons 1 (length +elements+)))
(sh 0)
(r ()))
(loop
(search-el range sh (schar tail sh))
- (when (= 0 (cdr range)) (return))
+ (when (>= (car range) (cdr range)) (return))
(incf sh)
(when (= sh (length (elt +elems+ (car range))))
(push (cons (car range) (subseq tail sh)) r)
- (incf (car range)) (decf (cdr range)))
+ (incf (car range)))
(when (= sh (length tail)) (return)))
(when (null r) (push (cons 0 (subseq tail 1)) r))
(return (reverse r))))
diff --git a/mendeleev.py b/mendeleev.py
index f5ab020..6c01e0d 100644
--- a/mendeleev.py
+++ b/mendeleev.py
@@ -19,9 +19,9 @@ ELEMENTS = [
elements = [el.lower().encode() for el in ELEMENTS]
-def search(start, length, shift, char):
- upper = start + length
- lower = start
+def search(rng, shift, char):
+ upper = rng[1]
+ lower = rng[0]
while lower < upper:
mid = int((lower + upper) / 2)
if elements[mid][shift] < char:
@@ -29,14 +29,12 @@ def search(start, length, shift, char):
else:
upper = mid
- if lower == start + length:
- return (0, 0)
+ if lower == rng[1] or elements[lower][shift] != char:
+ rng[1] = 0
+ return
- if elements[lower][shift] != char:
- return (0, 0)
-
- upper = start + length
- start = lower
+ upper = rng[1]
+ rng[0] = lower
while lower < upper:
mid = int((lower + upper) / 2)
if char < elements[mid][shift]:
@@ -44,28 +42,24 @@ def search(start, length, shift, char):
else:
lower = mid + 1
- length = upper - start
-
- return (start, length)
+ rng[1] = upper
def split(tail):
result = []
- start = 0
- length = len(ELEMENTS)
+ rng = [0, len(ELEMENTS)]
shift = 0
while shift < len(tail):
- start, length = search(start, length, shift, tail[shift])
- if length == 0:
+ search(rng, shift, tail[shift])
+ if rng[0] >= rng[1]:
break
shift += 1
- if len(elements[start]) == shift:
- result.append((ELEMENTS[start], tail[shift:]))
- start += 1
- length -= 1
+ if len(elements[rng[0]]) == shift:
+ result.append((ELEMENTS[rng[0]], tail[shift:]))
+ rng[0] += 1
return result or [("?", tail[1:])]