/
words.c
158 lines (132 loc) · 3.1 KB
/
words.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
/*
* words.c
*
* This file provides functions to perform basic operations on
* words in a group. Such a word is given as a null-terminated array of
* integers. A positive integer g stands for the g-th generator and
* a negative integer -g for the inverse of the g-th generator.
*
* The file provides the function
*
* int *invert_group_word(int *word);
*
* which reverses the order and the flips the signs, as well as the
* function
*
* int *concat_group_words(int *word0, int *word1);
*
* which concatenates two words and reduces the result by
* cancelling inverses that appear at the end of the first
* and beginning of the second word as much as possible.
*
* The file also provides
*
* int *copy_group_word(int *word);
*
* to just make a copy of a null-terminated array of integers.
*/
/*
* File added by MG 2022-01-24
*/
#include "kernel.h"
#include "kernel_namespace.h"
static int length_of_group_word(int *word);
/*
* Compute length of null-terminated word, not including null terminator,
* similar to strlen.
*/
static int length_of_group_word(
int *word)
{
int l = 0;
while (*(word + l) != 0) l++;
return l;
}
int* concat_group_words(
int *word0,
int *word1)
{
int *prod;
int *pos;
int *word0_last;
if (word0 == NULL)
return NULL;
if (word1 == NULL)
return NULL;
/*
* Look at last letter of first word.
*/
word0_last = word0 + length_of_group_word(word0) - 1;
/*
* Eat last letter of first word and first letter of second word
* while one is the inverse (the negative) of the other.
*/
while (word0 <= word0_last && *word0_last == -*word1) {
word0_last--; word1++;
}
/*
* Allocate memory for result.
*
* Note that word0_last points to the byte before word0 if word0
* is empty (or was completely cancelled).
*/
prod = NEW_ARRAY((word0_last - word0 + 1) + length_of_group_word(word1) + 1,
int);
/*
* Copy each word into result.
*/
pos = prod;
while (word0 <= word0_last)
*(pos++) = *(word0++);
while (*word1 != 0)
*(pos++) = *(word1++);
*pos = 0;
return prod;
}
int* invert_group_word(
int * word)
{
int l;
int *inv;
int *back;
if (word == NULL)
return NULL;
/*
* Allocate memory for result.
*/
l = length_of_group_word(word);
inv = NEW_ARRAY(l + 1, int);
/*
* Fill the result backwards starting with null-terminator.
*/
back = inv + l;
*(back--) = 0;
/*
* Copy into result backward.
*/
while (*word != 0)
*(back--) = -*(word++);
return inv;
}
int * copy_group_word(
int *word)
{
int *new_word;
int *pos;
if (word == NULL) {
return NULL;
}
/*
* Allocate memory for result.
*/
new_word = NEW_ARRAY(length_of_group_word(word) + 1, int);
/*
* And copy into it.
*/
pos = new_word;
while (*word != 0)
*(pos++) = *(word++);
*pos = 0;
return new_word;
}
#include "end_namespace.h"