This repository has been archived by the owner on Jun 2, 2022. It is now read-only.
forked from stacksmashing/gb-wordle
-
Notifications
You must be signed in to change notification settings - Fork 1
/
word-db.c
85 lines (73 loc) · 2.47 KB
/
word-db.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
#include "word-db.h"
word_number_t from_b26(char word[const WORD_LENGTH+1]) {
word_number_t res = 0;
word_number_t pow = 1;
for(uint8_t i = WORD_LENGTH; i > 0; i--) {
word_number_t digit = word[i-1]-'A';
res += digit*pow;
pow *= 26;
}
return res;
}
void to_b26(word_number_t word_number, char word[WORD_LENGTH+1]) {
uint8_t i = 0;
while(word_number > 0) {
word[WORD_LENGTH - 1 - i] = 'A' + (word_number % 26);
word_number /= 26;
i++;
}
for(;i < WORD_LENGTH; i++) {
word[WORD_LENGTH - 1 - i] = 'A';
}
}
bool query_word(char word[const WORD_LENGTH+1]) {
if(true == query_word_compressed(word_guesses, guesses_index, word)) {
return true;
}
if(true == query_word_compressed(word_answers, answers_index, word)) {
return true;
}
return false;
}
void add_unpack_varint(const uint8_t* const varint, word_number_t *current_word, wordlist_size_t *current_offset) {
*current_word += 1;
for(uint8_t i = 0; ; i++) {
const uint8_t b = varint[(*current_offset)++];
const uint32_t value = b & 0x7F;
const uint8_t more = b & 0x80;
*current_word += value << (7*i);
if(more == 0) {
break;
}
}
}
bool query_word_compressed(const uint8_t* const words, const index_entry* const index, char word[const WORD_LENGTH+1]) {
// TODO: permutation optimization
const word_number_t word_number = from_b26(word);
const word_index_size_t bucket_idx = word[0] - 'A';
const index_entry *bucket = &index[bucket_idx];
const index_entry *bucket_end = &index[bucket_idx+1];
if(bucket->start_word == word_number) {
return true;
}
word_number_t current_word = bucket->start_word;
wordlist_size_t current_offset = bucket->offset;
while(current_offset < bucket_end->offset) {
add_unpack_varint(words, ¤t_word, ¤t_offset);
if(word_number == current_word) {
return true;
}
}
return false;
}
void get_word(wordlist_size_t index, char word[WORD_LENGTH+1]) {
get_word_compressed(word_answers, index, word);
}
void get_word_compressed(const uint8_t* const words, wordlist_size_t index, char word[const WORD_LENGTH+1]) {
word_number_t current_word = 0;
wordlist_size_t current_offset = 0;
for(wordlist_size_t i = 0; i <= index; i++) {
add_unpack_varint(words, ¤t_word, ¤t_offset);
}
to_b26(current_word, word);
}