zeck 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE.txt +21 -0
- package/README.md +285 -0
- package/package.json +34 -0
- package/zeckendorf_rs.d.ts +346 -0
- package/zeckendorf_rs.js +5 -0
- package/zeckendorf_rs_bg.js +527 -0
- package/zeckendorf_rs_bg.wasm +0 -0
package/LICENSE.txt
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Peter Ryszkiewicz
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
ADDED
|
@@ -0,0 +1,285 @@
|
|
|
1
|
+
# Zeckendorf Compression
|
|
2
|
+
|
|
3
|
+
A Rust library for compressing and decompressing data using the Zeckendorf representation algorithm.
|
|
4
|
+
|
|
5
|
+
## Overview
|
|
6
|
+
|
|
7
|
+
The Zeckendorf algorithm represents numbers as a sum of non-consecutive Fibonacci numbers. This library interprets input data as a big integer (either big-endian or little-endian), converts it to its Zeckendorf representation, and sometimes achieves compression. However, compression is not guaranteed; the algorithm may result in a larger representation depending on the input data. The library can automatically try both endian interpretations and select the one that produces the best compression.
|
|
8
|
+
|
|
9
|
+
## Features
|
|
10
|
+
|
|
11
|
+
- **Compression & Decompression**: Convert data to/from Zeckendorf representation
|
|
12
|
+
- **Multiple Endian Interpretations**: Support for both big-endian and little-endian input interpretations
|
|
13
|
+
- **Automatic Best Compression**: Try both endian interpretations and automatically select the best result
|
|
14
|
+
- **Multiple Fibonacci Algorithms**:
|
|
15
|
+
- Slow recursive (memoized, for small numbers)
|
|
16
|
+
- Slow iterative (memoized, for large numbers)
|
|
17
|
+
- Fast Doubling (optimized, ~160x faster for large indices)
|
|
18
|
+
- **BigInt Support**: Handle arbitrarily large numbers using `num-bigint`
|
|
19
|
+
- **Memoization**: Thread-safe caching for improved performance
|
|
20
|
+
- **Statistics & Visualization**: Generate compression statistics and plots
|
|
21
|
+
- **Benchmarking**: Comprehensive performance benchmarks
|
|
22
|
+
- **WebAssembly Support**: Available as a WebAssembly module for use in web browsers
|
|
23
|
+
|
|
24
|
+
## WebAssembly
|
|
25
|
+
|
|
26
|
+
This library is also available as a WebAssembly module for use in web browsers. Available functions are marked with the `#[wasm_bindgen]` attribute. The WebAssembly module can be built using the convenience script at `scripts/build_wasm_bundle.sh` that builds the WebAssembly module with the `wasm-pack` tool.
|
|
27
|
+
|
|
28
|
+
You can see a live demo of the WebAssembly module in action at <https://prizz.github.io/zeckendorf-webapp/>. The source code for the demo is available at <https://github.com/pRizz/zeckendorf-webapp>.
|
|
29
|
+
|
|
30
|
+
## Installation
|
|
31
|
+
|
|
32
|
+
### Install from crates.io
|
|
33
|
+
|
|
34
|
+
Run:
|
|
35
|
+
```bash
|
|
36
|
+
cargo add zeckendorf
|
|
37
|
+
```
|
|
38
|
+
|
|
39
|
+
Or add this to your `Cargo.toml`:
|
|
40
|
+
|
|
41
|
+
```toml
|
|
42
|
+
[dependencies]
|
|
43
|
+
zeckendorf = "0.1.0"
|
|
44
|
+
```
|
|
45
|
+
|
|
46
|
+
For plotting features:
|
|
47
|
+
|
|
48
|
+
```toml
|
|
49
|
+
[dependencies]
|
|
50
|
+
zeckendorf = { version = "0.1.0", features = ["plotting"] }
|
|
51
|
+
```
|
|
52
|
+
|
|
53
|
+
### Install from GitHub (development version)
|
|
54
|
+
|
|
55
|
+
Run:
|
|
56
|
+
```bash
|
|
57
|
+
cargo add zeckendorf --git https://github.com/pRizz/zeckendorf
|
|
58
|
+
```
|
|
59
|
+
|
|
60
|
+
Or add this to your `Cargo.toml`:
|
|
61
|
+
|
|
62
|
+
```toml
|
|
63
|
+
[dependencies]
|
|
64
|
+
zeckendorf = { git = "https://github.com/pRizz/zeckendorf" }
|
|
65
|
+
```
|
|
66
|
+
|
|
67
|
+
For plotting features:
|
|
68
|
+
|
|
69
|
+
```toml
|
|
70
|
+
[dependencies]
|
|
71
|
+
zeckendorf = { git = "https://github.com/pRizz/zeckendorf", features = ["plotting"] }
|
|
72
|
+
```
|
|
73
|
+
|
|
74
|
+
## Usage
|
|
75
|
+
|
|
76
|
+
### Basic Compression/Decompression
|
|
77
|
+
|
|
78
|
+
#### Big-Endian Interpretation
|
|
79
|
+
|
|
80
|
+
```rust
|
|
81
|
+
use zeckendorf_rs::{zeckendorf_compress_be, zeckendorf_decompress_be};
|
|
82
|
+
|
|
83
|
+
// Compress data (interpreted as big-endian integer)
|
|
84
|
+
let data = vec![12u8];
|
|
85
|
+
let compressed = zeckendorf_compress_be(&data);
|
|
86
|
+
|
|
87
|
+
// Decompress data
|
|
88
|
+
let decompressed = zeckendorf_decompress_be(&compressed);
|
|
89
|
+
assert_eq!(data, decompressed);
|
|
90
|
+
```
|
|
91
|
+
|
|
92
|
+
#### Little-Endian Interpretation
|
|
93
|
+
|
|
94
|
+
```rust
|
|
95
|
+
use zeckendorf_rs::{zeckendorf_compress_le, zeckendorf_decompress_le};
|
|
96
|
+
|
|
97
|
+
// Compress data (interpreted as little-endian integer)
|
|
98
|
+
let data = vec![12u8];
|
|
99
|
+
let compressed = zeckendorf_compress_le(&data);
|
|
100
|
+
|
|
101
|
+
// Decompress data
|
|
102
|
+
let decompressed = zeckendorf_decompress_le(&compressed);
|
|
103
|
+
assert_eq!(data, decompressed);
|
|
104
|
+
```
|
|
105
|
+
|
|
106
|
+
#### Automatic Best Compression
|
|
107
|
+
|
|
108
|
+
```rust
|
|
109
|
+
use zeckendorf_rs::{zeckendorf_compress_best, zeckendorf_decompress_be, zeckendorf_decompress_le, CompressionResult};
|
|
110
|
+
|
|
111
|
+
// Try both endian interpretations and get the best result
|
|
112
|
+
let data = vec![1, 0];
|
|
113
|
+
let result = zeckendorf_compress_best(&data);
|
|
114
|
+
|
|
115
|
+
match result {
|
|
116
|
+
CompressionResult::BigEndianBest { compressed_data, le_size } => {
|
|
117
|
+
// Big-endian produced the best compression
|
|
118
|
+
let decompressed = zeckendorf_decompress_be(&compressed_data);
|
|
119
|
+
assert_eq!(data, decompressed);
|
|
120
|
+
}
|
|
121
|
+
CompressionResult::LittleEndianBest { compressed_data, be_size } => {
|
|
122
|
+
// Little-endian produced the best compression
|
|
123
|
+
let decompressed = zeckendorf_decompress_le(&compressed_data);
|
|
124
|
+
assert_eq!(data, decompressed);
|
|
125
|
+
}
|
|
126
|
+
CompressionResult::Neither { be_size, le_size } => {
|
|
127
|
+
// Neither method compressed the data (both were larger than original)
|
|
128
|
+
println!("Neither method compressed: BE size = {}, LE size = {}", be_size, le_size);
|
|
129
|
+
}
|
|
130
|
+
}
|
|
131
|
+
```
|
|
132
|
+
|
|
133
|
+
### Fibonacci Numbers
|
|
134
|
+
|
|
135
|
+
```rust
|
|
136
|
+
use zeckendorf_rs::memoized_slow_fibonacci_recursive;
|
|
137
|
+
|
|
138
|
+
// Calculate Fibonacci numbers (for indices up to 93)
|
|
139
|
+
let fib_10 = memoized_slow_fibonacci_recursive(10); // Returns 55
|
|
140
|
+
|
|
141
|
+
// For larger numbers, use BigInt versions
|
|
142
|
+
use zeckendorf_rs::fast_doubling_fibonacci_bigint;
|
|
143
|
+
let fib_100 = fast_doubling_fibonacci_bigint(100);
|
|
144
|
+
```
|
|
145
|
+
|
|
146
|
+
### Zeckendorf Representation
|
|
147
|
+
|
|
148
|
+
```rust
|
|
149
|
+
use zeckendorf_rs::memoized_zeckendorf_list_descending_for_integer;
|
|
150
|
+
|
|
151
|
+
// Get Zeckendorf representation as a list of Fibonacci indices
|
|
152
|
+
let zld = memoized_zeckendorf_list_descending_for_integer(12);
|
|
153
|
+
// Returns [6, 4, 2] meaning F(6) + F(4) + F(2) = 8 + 3 + 1 = 12
|
|
154
|
+
```
|
|
155
|
+
|
|
156
|
+
## Binaries
|
|
157
|
+
|
|
158
|
+
The project includes several utility binaries:
|
|
159
|
+
|
|
160
|
+
### Main Playground
|
|
161
|
+
|
|
162
|
+
```bash
|
|
163
|
+
cargo run --release --bin zeckendorf
|
|
164
|
+
```
|
|
165
|
+
|
|
166
|
+
A playground/scratchpad for testing library functions.
|
|
167
|
+
|
|
168
|
+
### Generate Test Data
|
|
169
|
+
|
|
170
|
+
```bash
|
|
171
|
+
cargo run --release --bin generate_data <size_in_bytes> [filename]
|
|
172
|
+
```
|
|
173
|
+
|
|
174
|
+
Generates random test data files in the `generated_data/` directory.
|
|
175
|
+
|
|
176
|
+
Example:
|
|
177
|
+
```bash
|
|
178
|
+
cargo run --release --bin generate_data 1024 my_file.bin
|
|
179
|
+
```
|
|
180
|
+
|
|
181
|
+
### Generate Statistics
|
|
182
|
+
|
|
183
|
+
```bash
|
|
184
|
+
cargo run --release --bin generate_statistics --features plotting
|
|
185
|
+
```
|
|
186
|
+
|
|
187
|
+
Generates comprehensive compression statistics and plots:
|
|
188
|
+
- Compression ratios across different input sizes
|
|
189
|
+
- Chance of compression being favorable
|
|
190
|
+
- Average and median compression ratios
|
|
191
|
+
- Statistics saved to `statistics_history/` directory
|
|
192
|
+
- Plots saved to `plots/` directory
|
|
193
|
+
|
|
194
|
+
### Plot Compression Ratios
|
|
195
|
+
|
|
196
|
+
```bash
|
|
197
|
+
cargo run --release --bin plot --features plotting
|
|
198
|
+
```
|
|
199
|
+
|
|
200
|
+
Generates visualization plots of:
|
|
201
|
+
- Fibonacci numbers
|
|
202
|
+
- Compression ratios for various input ranges
|
|
203
|
+
|
|
204
|
+
## Benchmarks
|
|
205
|
+
|
|
206
|
+
### Zeckendorf Compression Benchmarks
|
|
207
|
+
|
|
208
|
+
```bash
|
|
209
|
+
cargo bench --bench zeckendorf_bench
|
|
210
|
+
```
|
|
211
|
+
|
|
212
|
+
Benchmarks compression, decompression, and round-trip performance for various data sizes (4 bytes to 16KB).
|
|
213
|
+
|
|
214
|
+
### Fibonacci Benchmarks
|
|
215
|
+
|
|
216
|
+
```bash
|
|
217
|
+
cargo bench --bench fibonacci_bench
|
|
218
|
+
```
|
|
219
|
+
|
|
220
|
+
Compares performance of different Fibonacci calculation algorithms:
|
|
221
|
+
- Slow iterative method
|
|
222
|
+
- Fast doubling method (~160x faster for large indices)
|
|
223
|
+
|
|
224
|
+
### Working with Benchmark Baselines
|
|
225
|
+
|
|
226
|
+
Save a new baseline:
|
|
227
|
+
```bash
|
|
228
|
+
cargo bench --bench zeckendorf_bench -- --save-baseline <name>
|
|
229
|
+
```
|
|
230
|
+
|
|
231
|
+
Compare to an existing baseline:
|
|
232
|
+
```bash
|
|
233
|
+
cargo bench --bench zeckendorf_bench -- --baseline <name>
|
|
234
|
+
```
|
|
235
|
+
|
|
236
|
+
## Performance Characteristics
|
|
237
|
+
|
|
238
|
+
- **Fast Doubling Fibonacci**: ~160x faster than iterative method for the 100,000th Fibonacci number
|
|
239
|
+
- **Memoization**: Thread-safe caching significantly improves repeated calculations. The trade-off is that the cache takes up memory.
|
|
240
|
+
- **Compression Effectiveness**: Varies by input; compression ratios oscillate and become less favorable as input size increases
|
|
241
|
+
|
|
242
|
+
## Algorithm Details
|
|
243
|
+
|
|
244
|
+
### Zeckendorf Representation
|
|
245
|
+
|
|
246
|
+
Every positive integer can be uniquely represented as a sum of non-consecutive Fibonacci numbers. For example:
|
|
247
|
+
- 12 = 8 + 3 + 1 = F(6) + F(4) + F(2)
|
|
248
|
+
|
|
249
|
+
### Compression Process
|
|
250
|
+
|
|
251
|
+
1. Input data is interpreted as either a big-endian or little-endian integer (you can choose, or use `zeckendorf_compress_best` to try both)
|
|
252
|
+
2. The integer is converted to its Zeckendorf representation (list of Fibonacci indices)
|
|
253
|
+
3. The representation is encoded as bits (use/skip bits)
|
|
254
|
+
4. Bits are packed into bytes (little-endian output)
|
|
255
|
+
|
|
256
|
+
The library provides functions to compress with either interpretation, or you can use `zeckendorf_compress_best` to automatically try both and select the one that produces the smallest output.
|
|
257
|
+
|
|
258
|
+
### Effective Fibonacci Indices
|
|
259
|
+
|
|
260
|
+
The library uses "Effective Fibonacci Indices" (EFI) starting from 0, where:
|
|
261
|
+
- EFI 0 = Fibonacci Index 2 (value 1)
|
|
262
|
+
- EFI 1 = Fibonacci Index 3 (value 2)
|
|
263
|
+
- etc.
|
|
264
|
+
|
|
265
|
+
This avoids redundant Fibonacci numbers (F(0)=0 and F(1)=F(2)=1).
|
|
266
|
+
|
|
267
|
+
## Limitations
|
|
268
|
+
|
|
269
|
+
- Compression is not guaranteed—some inputs may result in larger output
|
|
270
|
+
- Compression effectiveness decreases as input size increases
|
|
271
|
+
- The library supports both big-endian and little-endian interpretations, but other byte orderings or word boundaries are not currently explored
|
|
272
|
+
- Compression of large amounts of data causes memory issues. It is currently not recommended to compress files larger than 100,000 bytes.
|
|
273
|
+
|
|
274
|
+
## License
|
|
275
|
+
|
|
276
|
+
This project is licensed under the MIT License - see the [LICENSE.txt](LICENSE.txt) file for details.
|
|
277
|
+
|
|
278
|
+
## Contributing
|
|
279
|
+
|
|
280
|
+
Contributions are welcome! Please feel free to submit a Pull Request. For major changes, please open an issue first to discuss what you would like to change.
|
|
281
|
+
|
|
282
|
+
## References
|
|
283
|
+
|
|
284
|
+
- [Fast Fibonacci Algorithms](https://www.nayuki.io/page/fast-fibonacci-algorithms) - Fast doubling algorithm reference
|
|
285
|
+
- [Zeckendorf's Theorem](https://en.wikipedia.org/wiki/Zeckendorf%27s_theorem) - Every positive integer has a unique representation as a sum of non-consecutive Fibonacci numbers
|
package/package.json
ADDED
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "zeck",
|
|
3
|
+
"type": "module",
|
|
4
|
+
"collaborators": [
|
|
5
|
+
"Peter Ryszkiewicz"
|
|
6
|
+
],
|
|
7
|
+
"description": "A Rust library for compressing and decompressing data using the Zeckendorf representation algorithm",
|
|
8
|
+
"version": "0.1.0",
|
|
9
|
+
"license": "MIT",
|
|
10
|
+
"repository": {
|
|
11
|
+
"type": "git",
|
|
12
|
+
"url": "https://github.com/pRizz/zeckendorf"
|
|
13
|
+
},
|
|
14
|
+
"files": [
|
|
15
|
+
"zeckendorf_rs_bg.wasm",
|
|
16
|
+
"zeckendorf_rs.js",
|
|
17
|
+
"zeckendorf_rs_bg.js",
|
|
18
|
+
"zeckendorf_rs.d.ts",
|
|
19
|
+
"LICENSE.txt"
|
|
20
|
+
],
|
|
21
|
+
"main": "zeckendorf_rs.js",
|
|
22
|
+
"types": "zeckendorf_rs.d.ts",
|
|
23
|
+
"sideEffects": [
|
|
24
|
+
"./zeckendorf_rs.js",
|
|
25
|
+
"./snippets/*"
|
|
26
|
+
],
|
|
27
|
+
"keywords": [
|
|
28
|
+
"compression",
|
|
29
|
+
"zeckendorf",
|
|
30
|
+
"fibonacci",
|
|
31
|
+
"algorithm",
|
|
32
|
+
"data-compression"
|
|
33
|
+
]
|
|
34
|
+
}
|
|
@@ -0,0 +1,346 @@
|
|
|
1
|
+
/* tslint:disable */
|
|
2
|
+
/* eslint-disable */
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* Returns the number of bits required to represent the given number. Returns 0 if the number is less than or equal to 0.
|
|
6
|
+
*
|
|
7
|
+
* # Examples
|
|
8
|
+
*
|
|
9
|
+
* ```
|
|
10
|
+
* # use zeckendorf_rs::bit_count_for_number;
|
|
11
|
+
* assert_eq!(bit_count_for_number(0), 0);
|
|
12
|
+
* assert_eq!(bit_count_for_number(1), 1); // 0b1
|
|
13
|
+
* assert_eq!(bit_count_for_number(2), 2); // 0b10
|
|
14
|
+
* assert_eq!(bit_count_for_number(3), 2); // 0b11
|
|
15
|
+
* assert_eq!(bit_count_for_number(4), 3); // 0b100
|
|
16
|
+
* ```
|
|
17
|
+
*/
|
|
18
|
+
export function bit_count_for_number(n: number): number;
|
|
19
|
+
|
|
20
|
+
/**
|
|
21
|
+
* Effective Fibonacci Index to Fibonacci Index: FI(efi) === efi + 2, where efi is the Effective Fibonacci Index
|
|
22
|
+
*
|
|
23
|
+
* # Examples
|
|
24
|
+
*
|
|
25
|
+
* ```
|
|
26
|
+
* # use zeckendorf_rs::efi_to_fi;
|
|
27
|
+
* assert_eq!(efi_to_fi(0), 2);
|
|
28
|
+
* assert_eq!(efi_to_fi(1), 3);
|
|
29
|
+
* assert_eq!(efi_to_fi(2), 4);
|
|
30
|
+
* ```
|
|
31
|
+
*/
|
|
32
|
+
export function efi_to_fi(efi: bigint): bigint;
|
|
33
|
+
|
|
34
|
+
/**
|
|
35
|
+
* ezba is Effective Zeckendorf Bits Ascending ; ezld is Effective Zeckendorf List Descending
|
|
36
|
+
*
|
|
37
|
+
* The bits represent whether the corresponding effective Fibonacci index is used. I call these "use bits" and "skip bits" where a use bit is 1 and a skip bit is 0. This is by convention that I, Peter Ryszkiewicz decided, but it is theoretically possible to use skip bits and use bits flipped.
|
|
38
|
+
*
|
|
39
|
+
* If we use a bit, we then skip the next bit, because it is impossible to use two consecutive bits, or Fibonacci numbers, due to the Zeckendorf principle.
|
|
40
|
+
* The first bit in the ezba represents whether the first effective Fibonacci index is used.
|
|
41
|
+
* The first effective Fibonacci index is always 0 and represents the Fibonacci index 2 which has a value of 1. We use effective Fibonacci indices because the first Fibonacci number, 0, is not useful for sums, and the second Fibonacci number, 1, is redundant because it is the same as the third Fibonacci number.
|
|
42
|
+
*
|
|
43
|
+
* TODO: Optimize the size of the output by using a bit vector instead of a vector of [`u8`]s. I made an initial attempt at this in the `use-bitvec` branch, but the benchmarks were slower.
|
|
44
|
+
*
|
|
45
|
+
* # Examples
|
|
46
|
+
*
|
|
47
|
+
* ```
|
|
48
|
+
* # use zeckendorf_rs::ezba_from_ezld;
|
|
49
|
+
* assert_eq!(ezba_from_ezld(&[]), vec![0]);
|
|
50
|
+
* assert_eq!(ezba_from_ezld(&[0]), vec![1]); // 0th EFI is 2nd FI, which is 1
|
|
51
|
+
* assert_eq!(ezba_from_ezld(&[1]), vec![0, 1]); // 1st EFI is 3rd FI, which is 2
|
|
52
|
+
* assert_eq!(ezba_from_ezld(&[2]), vec![0, 0, 1]); // 2nd EFI is 4th FI, which is 3
|
|
53
|
+
* assert_eq!(ezba_from_ezld(&[2, 0]), vec![1, 1]); // 2nd EFI is 4th FI, which is 3 and 0th EFI is 2nd FI, which is 1, which sums to 4
|
|
54
|
+
* assert_eq!(ezba_from_ezld(&[3]), vec![0, 0, 0, 1]); // 3rd EFI is 5th FI, which is 5
|
|
55
|
+
* ```
|
|
56
|
+
*/
|
|
57
|
+
export function ezba_from_ezld(effective_zeckendorf_list_descending: BigUint64Array): Uint8Array;
|
|
58
|
+
|
|
59
|
+
/**
|
|
60
|
+
* Converts a vector of bits (0s and 1s) from an ezba (Effective Zeckendorf Bits Ascending) into a vector of effective Fibonacci indices,
|
|
61
|
+
* the Effective Zeckendorf List Ascending.
|
|
62
|
+
*
|
|
63
|
+
* # Examples
|
|
64
|
+
*
|
|
65
|
+
* ```
|
|
66
|
+
* # use zeckendorf_rs::ezba_to_ezla;
|
|
67
|
+
* assert_eq!(ezba_to_ezla(&[0, 0, 0, 0, 0, 0, 0, 0]), vec![]);
|
|
68
|
+
* assert_eq!(ezba_to_ezla(&[1, 0, 0, 0, 0, 0, 0, 0]), vec![0]);
|
|
69
|
+
* assert_eq!(ezba_to_ezla(&[1, 1, 1, 0, 0, 0, 0, 0]), vec![0, 2, 4]);
|
|
70
|
+
* ```
|
|
71
|
+
*/
|
|
72
|
+
export function ezba_to_ezla(ezba_bits: Uint8Array): BigUint64Array;
|
|
73
|
+
|
|
74
|
+
/**
|
|
75
|
+
* Converts an Effective Zeckendorf List to a Zeckendorf List.
|
|
76
|
+
* It does not matter if the list is ascending or descending; it retains the directionality of the original list.
|
|
77
|
+
*
|
|
78
|
+
* # Examples
|
|
79
|
+
*
|
|
80
|
+
* ```
|
|
81
|
+
* # use zeckendorf_rs::ezl_to_zl;
|
|
82
|
+
* assert_eq!(ezl_to_zl(&[0]), vec![2]);
|
|
83
|
+
* assert_eq!(ezl_to_zl(&[1]), vec![3]);
|
|
84
|
+
* assert_eq!(ezl_to_zl(&[2]), vec![4]);
|
|
85
|
+
* ```
|
|
86
|
+
*/
|
|
87
|
+
export function ezl_to_zl(ezl: BigUint64Array): BigUint64Array;
|
|
88
|
+
|
|
89
|
+
/**
|
|
90
|
+
* Fibonacci Index to Effective Fibonacci Index: EFI(fi) === fi - 2, where fi is the Fibonacci Index
|
|
91
|
+
*
|
|
92
|
+
* # Examples
|
|
93
|
+
*
|
|
94
|
+
* ```
|
|
95
|
+
* # use zeckendorf_rs::fi_to_efi;
|
|
96
|
+
* # use num_bigint::BigUint;
|
|
97
|
+
* # use num_traits::{One, Zero};
|
|
98
|
+
* assert_eq!(fi_to_efi(2), 0);
|
|
99
|
+
* assert_eq!(fi_to_efi(3), 1);
|
|
100
|
+
* assert_eq!(fi_to_efi(4), 2);
|
|
101
|
+
* ```
|
|
102
|
+
*/
|
|
103
|
+
export function fi_to_efi(fi: bigint): bigint;
|
|
104
|
+
|
|
105
|
+
/**
|
|
106
|
+
* Returns a [`u64`] value with only the most significant set bit of n preserved.
|
|
107
|
+
*
|
|
108
|
+
* # Examples
|
|
109
|
+
*
|
|
110
|
+
* ```
|
|
111
|
+
* # use zeckendorf_rs::highest_one_bit;
|
|
112
|
+
* assert_eq!(highest_one_bit(0), 0);
|
|
113
|
+
* assert_eq!(highest_one_bit(1), 1);
|
|
114
|
+
* assert_eq!(highest_one_bit(2), 2);
|
|
115
|
+
* assert_eq!(highest_one_bit(3), 2);
|
|
116
|
+
* assert_eq!(highest_one_bit(4), 4);
|
|
117
|
+
* assert_eq!(highest_one_bit(5), 4);
|
|
118
|
+
* assert_eq!(highest_one_bit(6), 4);
|
|
119
|
+
* assert_eq!(highest_one_bit(7), 4);
|
|
120
|
+
* assert_eq!(highest_one_bit(8), 8);
|
|
121
|
+
* assert_eq!(highest_one_bit(9), 8);
|
|
122
|
+
* assert_eq!(highest_one_bit(10), 8);
|
|
123
|
+
* assert_eq!(highest_one_bit(11), 8);
|
|
124
|
+
* assert_eq!(highest_one_bit(12), 8);
|
|
125
|
+
* assert_eq!(highest_one_bit(13), 8);
|
|
126
|
+
* assert_eq!(highest_one_bit(14), 8);
|
|
127
|
+
* ```
|
|
128
|
+
*/
|
|
129
|
+
export function highest_one_bit(n: bigint): bigint;
|
|
130
|
+
|
|
131
|
+
/**
|
|
132
|
+
* The memoized Fibonacci function taking an Effective Fibonacci Index as input.
|
|
133
|
+
*
|
|
134
|
+
* # Examples
|
|
135
|
+
*
|
|
136
|
+
* ```
|
|
137
|
+
* # use zeckendorf_rs::memoized_effective_fibonacci;
|
|
138
|
+
* # use num_bigint::BigUint;
|
|
139
|
+
* # use num_traits::{One, Zero};
|
|
140
|
+
* assert_eq!(memoized_effective_fibonacci(0), 1);
|
|
141
|
+
* assert_eq!(memoized_effective_fibonacci(1), 2);
|
|
142
|
+
* assert_eq!(memoized_effective_fibonacci(2), 3);
|
|
143
|
+
* assert_eq!(memoized_effective_fibonacci(3), 5);
|
|
144
|
+
* assert_eq!(memoized_effective_fibonacci(4), 8);
|
|
145
|
+
* assert_eq!(memoized_effective_fibonacci(5), 13);
|
|
146
|
+
* assert_eq!(memoized_effective_fibonacci(6), 21);
|
|
147
|
+
* assert_eq!(memoized_effective_fibonacci(7), 34);
|
|
148
|
+
* assert_eq!(memoized_effective_fibonacci(8), 55);
|
|
149
|
+
* assert_eq!(memoized_effective_fibonacci(9), 89);
|
|
150
|
+
* assert_eq!(memoized_effective_fibonacci(10), 144);
|
|
151
|
+
* ```
|
|
152
|
+
*/
|
|
153
|
+
export function memoized_effective_fibonacci(efi: bigint): bigint;
|
|
154
|
+
|
|
155
|
+
/**
|
|
156
|
+
* fibonacci(x) is equal to 0 if x is 0; 1 if x is 1; else return fibonacci(x - 1) + fibonacci(x - 2)
|
|
157
|
+
*
|
|
158
|
+
* This function is slow and should not be used for large numbers. If you want a [`u64`] result, use the faster [`memoized_slow_fibonacci_biguint_iterative`] function instead. If you want a [`BigUint`] result, use the [`fast_doubling_fibonacci_biguint`] function instead.
|
|
159
|
+
*
|
|
160
|
+
* This function fails for large numbers (e.g. 100_000) with a stack overflow error.
|
|
161
|
+
*
|
|
162
|
+
* `fi` stands for Fibonacci Index.
|
|
163
|
+
*
|
|
164
|
+
* # Examples
|
|
165
|
+
*
|
|
166
|
+
* ```
|
|
167
|
+
* # use zeckendorf_rs::memoized_slow_fibonacci_recursive;
|
|
168
|
+
* // Base cases
|
|
169
|
+
* assert_eq!(memoized_slow_fibonacci_recursive(0), 0);
|
|
170
|
+
* assert_eq!(memoized_slow_fibonacci_recursive(1), 1);
|
|
171
|
+
*
|
|
172
|
+
* // Small Fibonacci numbers
|
|
173
|
+
* assert_eq!(memoized_slow_fibonacci_recursive(2), 1);
|
|
174
|
+
* assert_eq!(memoized_slow_fibonacci_recursive(3), 2);
|
|
175
|
+
* assert_eq!(memoized_slow_fibonacci_recursive(4), 3);
|
|
176
|
+
* assert_eq!(memoized_slow_fibonacci_recursive(5), 5);
|
|
177
|
+
* assert_eq!(memoized_slow_fibonacci_recursive(6), 8);
|
|
178
|
+
* assert_eq!(memoized_slow_fibonacci_recursive(7), 13);
|
|
179
|
+
* assert_eq!(memoized_slow_fibonacci_recursive(8), 21);
|
|
180
|
+
* assert_eq!(memoized_slow_fibonacci_recursive(9), 34);
|
|
181
|
+
* assert_eq!(memoized_slow_fibonacci_recursive(10), 55);
|
|
182
|
+
* ```
|
|
183
|
+
*/
|
|
184
|
+
export function memoized_slow_fibonacci_recursive(fi: bigint): bigint;
|
|
185
|
+
|
|
186
|
+
/**
|
|
187
|
+
* A descending Zeckendorf list is a sorted list of unique Fibonacci indices, in descending order, that sum to the given number.
|
|
188
|
+
*
|
|
189
|
+
* A Fibonacci index is the index of the Fibonacci number in the Fibonacci sequence.
|
|
190
|
+
* fibonacci(fibonacci_index) = fibonacci_number
|
|
191
|
+
*
|
|
192
|
+
* # Examples
|
|
193
|
+
*
|
|
194
|
+
* ```
|
|
195
|
+
* # use zeckendorf_rs::memoized_zeckendorf_list_descending_for_integer;
|
|
196
|
+
* // Base cases
|
|
197
|
+
* assert_eq!(memoized_zeckendorf_list_descending_for_integer(0), vec![]);
|
|
198
|
+
* assert_eq!(memoized_zeckendorf_list_descending_for_integer(1), vec![2]);
|
|
199
|
+
* assert_eq!(memoized_zeckendorf_list_descending_for_integer(2), vec![3]);
|
|
200
|
+
*
|
|
201
|
+
* // Small Zeckendorf numbers
|
|
202
|
+
* assert_eq!(memoized_zeckendorf_list_descending_for_integer(3), vec![4]);
|
|
203
|
+
* assert_eq!(memoized_zeckendorf_list_descending_for_integer(4), vec![4, 2]);
|
|
204
|
+
* assert_eq!(memoized_zeckendorf_list_descending_for_integer(5), vec![5]);
|
|
205
|
+
* assert_eq!(memoized_zeckendorf_list_descending_for_integer(6), vec![5, 2]);
|
|
206
|
+
* assert_eq!(memoized_zeckendorf_list_descending_for_integer(7), vec![5, 3]);
|
|
207
|
+
* assert_eq!(memoized_zeckendorf_list_descending_for_integer(8), vec![6]);
|
|
208
|
+
* assert_eq!(memoized_zeckendorf_list_descending_for_integer(9), vec![6, 2]);
|
|
209
|
+
* assert_eq!(memoized_zeckendorf_list_descending_for_integer(10), vec![6, 3]);
|
|
210
|
+
* assert_eq!(memoized_zeckendorf_list_descending_for_integer(11), vec![6, 4]);
|
|
211
|
+
* assert_eq!(memoized_zeckendorf_list_descending_for_integer(12), vec![6, 4, 2]);
|
|
212
|
+
* ```
|
|
213
|
+
*/
|
|
214
|
+
export function memoized_zeckendorf_list_descending_for_integer(n: bigint): BigUint64Array;
|
|
215
|
+
|
|
216
|
+
/**
|
|
217
|
+
* Packs a slice of bits (0s and 1s) from an ezba (Effective Zeckendorf Bits Ascending) into bytes.
|
|
218
|
+
*
|
|
219
|
+
* The output bytes are in little endian order, so the first byte is the least significant byte and the last byte is the most significant byte.
|
|
220
|
+
*
|
|
221
|
+
* Input bits and output bits are in ascending significance: bits\[0\] = LSB, bits\[7\] = MSB.
|
|
222
|
+
* Every 8 bits become a [`u8`] in the output.
|
|
223
|
+
* The last byte is padded with 0s if the number of bits is not a multiple of 8.
|
|
224
|
+
*
|
|
225
|
+
* # Examples
|
|
226
|
+
*
|
|
227
|
+
* ```
|
|
228
|
+
* # use zeckendorf_rs::pack_ezba_bits_to_bytes;
|
|
229
|
+
* assert_eq!(pack_ezba_bits_to_bytes(&[0]), vec![0]);
|
|
230
|
+
* assert_eq!(pack_ezba_bits_to_bytes(&[1]), vec![1]);
|
|
231
|
+
* assert_eq!(pack_ezba_bits_to_bytes(&[0, 1]), vec![0b10]);
|
|
232
|
+
* assert_eq!(pack_ezba_bits_to_bytes(&[0, 0, 1]), vec![0b100]);
|
|
233
|
+
* assert_eq!(pack_ezba_bits_to_bytes(&[1, 1]), vec![0b11]);
|
|
234
|
+
* ```
|
|
235
|
+
*/
|
|
236
|
+
export function pack_ezba_bits_to_bytes(ezba: Uint8Array): Uint8Array;
|
|
237
|
+
|
|
238
|
+
/**
|
|
239
|
+
* Unpacks a vector of bytes into a vector of bits (0s and 1s) from an ezba (Effective Zeckendorf Bits Ascending).
|
|
240
|
+
*
|
|
241
|
+
* # Examples
|
|
242
|
+
*
|
|
243
|
+
* ```
|
|
244
|
+
* # use zeckendorf_rs::unpack_bytes_to_ezba_bits;
|
|
245
|
+
* assert_eq!(unpack_bytes_to_ezba_bits(&[0]), vec![0, 0, 0, 0, 0, 0, 0, 0]);
|
|
246
|
+
* assert_eq!(unpack_bytes_to_ezba_bits(&[1]), vec![1, 0, 0, 0, 0, 0, 0, 0]);
|
|
247
|
+
* assert_eq!(unpack_bytes_to_ezba_bits(&[0b111]), vec![1, 1, 1, 0, 0, 0, 0, 0]);
|
|
248
|
+
* assert_eq!(unpack_bytes_to_ezba_bits(&[1, 1]), vec![1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0]);
|
|
249
|
+
* ```
|
|
250
|
+
*/
|
|
251
|
+
export function unpack_bytes_to_ezba_bits(bytes: Uint8Array): Uint8Array;
|
|
252
|
+
|
|
253
|
+
/**
|
|
254
|
+
* Compresses a slice of bytes using the Zeckendorf algorithm.
|
|
255
|
+
*
|
|
256
|
+
* Assumes the input data is interpreted as a big endian integer. The output data is in little endian order, so the first bit and byte is the least significant bit and byte and the last bit and byte is the most significant bit and byte.
|
|
257
|
+
*
|
|
258
|
+
* TODO: Technically, the way the input data is interpreted is arbitrary; we could interpret it as little endian which could result in a more compact representation. We could go even further and interpret the data at different byte or word boundaries to see if it results in a more compact representation, and signify to the caller which interpretation was used. We probably need a better understanding of random distributions of data to determine what is the optimal interpretation. More investigation is needed here.
|
|
259
|
+
*
|
|
260
|
+
* # Examples
|
|
261
|
+
*
|
|
262
|
+
* ```
|
|
263
|
+
* # use zeckendorf_rs::zeckendorf_compress_be;
|
|
264
|
+
* assert_eq!(zeckendorf_compress_be(&[0]), vec![0]);
|
|
265
|
+
* assert_eq!(zeckendorf_compress_be(&[1]), vec![1]);
|
|
266
|
+
* assert_eq!(zeckendorf_compress_be(&[12]), vec![0b111]);
|
|
267
|
+
* assert_eq!(zeckendorf_compress_be(&[54]), vec![30]);
|
|
268
|
+
* assert_eq!(zeckendorf_compress_be(&[55]), vec![0, 1]); // 55 is the 10 indexed Fibonacci number, which is the 8 indexed effective Fibonacci number, and therefore is the first number needing two bytes to contain these 8 bits, because there is 1 "use bit" and 7 "skip bits" in the effective zeckendorf bits ascending.
|
|
269
|
+
* assert_eq!(zeckendorf_compress_be(&[255]), vec![33, 2]);
|
|
270
|
+
* assert_eq!(zeckendorf_compress_be(&[1, 0]), vec![34, 2]);
|
|
271
|
+
* ```
|
|
272
|
+
*/
|
|
273
|
+
export function zeckendorf_compress_be(data: Uint8Array): Uint8Array;
|
|
274
|
+
|
|
275
|
+
/**
|
|
276
|
+
* Compresses a slice of bytes using the Zeckendorf algorithm.
|
|
277
|
+
*
|
|
278
|
+
* Assumes the input data is interpreted as a little endian integer. The output data is in little endian order, so the first bit and byte is the least significant bit and byte and the last bit and byte is the most significant bit and byte.
|
|
279
|
+
*
|
|
280
|
+
* # Examples
|
|
281
|
+
*
|
|
282
|
+
* ```
|
|
283
|
+
* # use zeckendorf_rs::zeckendorf_compress_le;
|
|
284
|
+
* assert_eq!(zeckendorf_compress_le(&[0]), vec![0]);
|
|
285
|
+
* assert_eq!(zeckendorf_compress_le(&[1]), vec![1]);
|
|
286
|
+
* assert_eq!(zeckendorf_compress_le(&[12]), vec![0b111]);
|
|
287
|
+
* assert_eq!(zeckendorf_compress_le(&[54]), vec![30]);
|
|
288
|
+
* assert_eq!(zeckendorf_compress_le(&[55]), vec![0, 1]); // 55 is the 10 indexed Fibonacci number, which is the 8 indexed effective Fibonacci number, and therefore is the first number needing two bytes to contain these 8 bits, because there is 1 "use bit" and 7 "skip bits" in the effective zeckendorf bits ascending.
|
|
289
|
+
* assert_eq!(zeckendorf_compress_le(&[255]), vec![33, 2]);
|
|
290
|
+
* assert_eq!(zeckendorf_compress_le(&[0, 1]), vec![34, 2]);
|
|
291
|
+
* ```
|
|
292
|
+
*/
|
|
293
|
+
export function zeckendorf_compress_le(data: Uint8Array): Uint8Array;
|
|
294
|
+
|
|
295
|
+
/**
|
|
296
|
+
* Decompresses a slice of bytes compressed using the Zeckendorf algorithm, assuming the original data was compressed using the big endian bytes interpretation.
|
|
297
|
+
*
|
|
298
|
+
* Assume the original input data was interpreted as a big endian integer, for now. See the TODO in the [`zeckendorf_compress_be`] function for more information.
|
|
299
|
+
*
|
|
300
|
+
* # Examples
|
|
301
|
+
*
|
|
302
|
+
* ```
|
|
303
|
+
* # use zeckendorf_rs::zeckendorf_decompress_be;
|
|
304
|
+
* assert_eq!(zeckendorf_decompress_be(&[0]), vec![0]);
|
|
305
|
+
* assert_eq!(zeckendorf_decompress_be(&[1]), vec![1]);
|
|
306
|
+
* assert_eq!(zeckendorf_decompress_be(&[0b111]), vec![12]);
|
|
307
|
+
* assert_eq!(zeckendorf_decompress_be(&[33, 2]), vec![255]);
|
|
308
|
+
* assert_eq!(zeckendorf_decompress_be(&[34, 2]), vec![1, 0]);
|
|
309
|
+
* ```
|
|
310
|
+
*/
|
|
311
|
+
export function zeckendorf_decompress_be(compressed_data: Uint8Array): Uint8Array;
|
|
312
|
+
|
|
313
|
+
/**
|
|
314
|
+
* Decompresses a slice of bytes compressed using the Zeckendorf algorithm, assuming the original data was compressed using the little endian bytes interpretation.
|
|
315
|
+
*
|
|
316
|
+
* # Examples
|
|
317
|
+
*
|
|
318
|
+
* ```
|
|
319
|
+
* # use zeckendorf_rs::zeckendorf_decompress_le;
|
|
320
|
+
* assert_eq!(zeckendorf_decompress_le(&[0]), vec![0]);
|
|
321
|
+
* assert_eq!(zeckendorf_decompress_le(&[1]), vec![1]);
|
|
322
|
+
* assert_eq!(zeckendorf_decompress_le(&[0b111]), vec![12]);
|
|
323
|
+
* assert_eq!(zeckendorf_decompress_le(&[33, 2]), vec![255]);
|
|
324
|
+
* assert_eq!(zeckendorf_decompress_le(&[34, 2]), vec![0, 1]);
|
|
325
|
+
* ```
|
|
326
|
+
*/
|
|
327
|
+
export function zeckendorf_decompress_le(compressed_data: Uint8Array): Uint8Array;
|
|
328
|
+
|
|
329
|
+
/**
|
|
330
|
+
* An Effective Zeckendorf List (EZL) has a lowest EFI of 0, which is an FI of 2.
|
|
331
|
+
* This is because it doesn't make sense for the lists to contain FIs 0 or 1 because
|
|
332
|
+
* 0 can never be added to a number and will therefore never be in a Zeckendorf List
|
|
333
|
+
* and an FI of 1 is equivalent to an FI of 2 which has a Fibonacci value of 1
|
|
334
|
+
* so let's just use FI starting at 2, which is an EFI of 0.
|
|
335
|
+
* It does not matter if the list is ascending or descending; it retains the directionality of the original list.
|
|
336
|
+
*
|
|
337
|
+
* # Examples
|
|
338
|
+
*
|
|
339
|
+
* ```
|
|
340
|
+
* # use zeckendorf_rs::zl_to_ezl;
|
|
341
|
+
* assert_eq!(zl_to_ezl(&[2]), vec![0]);
|
|
342
|
+
* assert_eq!(zl_to_ezl(&[3]), vec![1]);
|
|
343
|
+
* assert_eq!(zl_to_ezl(&[4]), vec![2]);
|
|
344
|
+
* ```
|
|
345
|
+
*/
|
|
346
|
+
export function zl_to_ezl(zl: BigUint64Array): BigUint64Array;
|
package/zeckendorf_rs.js
ADDED
|
@@ -0,0 +1,527 @@
|
|
|
1
|
+
let wasm;
|
|
2
|
+
export function __wbg_set_wasm(val) {
|
|
3
|
+
wasm = val;
|
|
4
|
+
}
|
|
5
|
+
|
|
6
|
+
function getArrayU64FromWasm0(ptr, len) {
|
|
7
|
+
ptr = ptr >>> 0;
|
|
8
|
+
return getBigUint64ArrayMemory0().subarray(ptr / 8, ptr / 8 + len);
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
function getArrayU8FromWasm0(ptr, len) {
|
|
12
|
+
ptr = ptr >>> 0;
|
|
13
|
+
return getUint8ArrayMemory0().subarray(ptr / 1, ptr / 1 + len);
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
let cachedBigUint64ArrayMemory0 = null;
|
|
17
|
+
function getBigUint64ArrayMemory0() {
|
|
18
|
+
if (cachedBigUint64ArrayMemory0 === null || cachedBigUint64ArrayMemory0.byteLength === 0) {
|
|
19
|
+
cachedBigUint64ArrayMemory0 = new BigUint64Array(wasm.memory.buffer);
|
|
20
|
+
}
|
|
21
|
+
return cachedBigUint64ArrayMemory0;
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
let cachedUint8ArrayMemory0 = null;
|
|
25
|
+
function getUint8ArrayMemory0() {
|
|
26
|
+
if (cachedUint8ArrayMemory0 === null || cachedUint8ArrayMemory0.byteLength === 0) {
|
|
27
|
+
cachedUint8ArrayMemory0 = new Uint8Array(wasm.memory.buffer);
|
|
28
|
+
}
|
|
29
|
+
return cachedUint8ArrayMemory0;
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
function passArray64ToWasm0(arg, malloc) {
|
|
33
|
+
const ptr = malloc(arg.length * 8, 8) >>> 0;
|
|
34
|
+
getBigUint64ArrayMemory0().set(arg, ptr / 8);
|
|
35
|
+
WASM_VECTOR_LEN = arg.length;
|
|
36
|
+
return ptr;
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
function passArray8ToWasm0(arg, malloc) {
|
|
40
|
+
const ptr = malloc(arg.length * 1, 1) >>> 0;
|
|
41
|
+
getUint8ArrayMemory0().set(arg, ptr / 1);
|
|
42
|
+
WASM_VECTOR_LEN = arg.length;
|
|
43
|
+
return ptr;
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
let WASM_VECTOR_LEN = 0;
|
|
47
|
+
|
|
48
|
+
/**
|
|
49
|
+
* Returns the number of bits required to represent the given number. Returns 0 if the number is less than or equal to 0.
|
|
50
|
+
*
|
|
51
|
+
* # Examples
|
|
52
|
+
*
|
|
53
|
+
* ```
|
|
54
|
+
* # use zeckendorf_rs::bit_count_for_number;
|
|
55
|
+
* assert_eq!(bit_count_for_number(0), 0);
|
|
56
|
+
* assert_eq!(bit_count_for_number(1), 1); // 0b1
|
|
57
|
+
* assert_eq!(bit_count_for_number(2), 2); // 0b10
|
|
58
|
+
* assert_eq!(bit_count_for_number(3), 2); // 0b11
|
|
59
|
+
* assert_eq!(bit_count_for_number(4), 3); // 0b100
|
|
60
|
+
* ```
|
|
61
|
+
* @param {number} n
|
|
62
|
+
* @returns {number}
|
|
63
|
+
*/
|
|
64
|
+
export function bit_count_for_number(n) {
|
|
65
|
+
const ret = wasm.bit_count_for_number(n);
|
|
66
|
+
return ret >>> 0;
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
/**
|
|
70
|
+
* Effective Fibonacci Index to Fibonacci Index: FI(efi) === efi + 2, where efi is the Effective Fibonacci Index
|
|
71
|
+
*
|
|
72
|
+
* # Examples
|
|
73
|
+
*
|
|
74
|
+
* ```
|
|
75
|
+
* # use zeckendorf_rs::efi_to_fi;
|
|
76
|
+
* assert_eq!(efi_to_fi(0), 2);
|
|
77
|
+
* assert_eq!(efi_to_fi(1), 3);
|
|
78
|
+
* assert_eq!(efi_to_fi(2), 4);
|
|
79
|
+
* ```
|
|
80
|
+
* @param {bigint} efi
|
|
81
|
+
* @returns {bigint}
|
|
82
|
+
*/
|
|
83
|
+
export function efi_to_fi(efi) {
|
|
84
|
+
const ret = wasm.efi_to_fi(efi);
|
|
85
|
+
return BigInt.asUintN(64, ret);
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
/**
|
|
89
|
+
* ezba is Effective Zeckendorf Bits Ascending ; ezld is Effective Zeckendorf List Descending
|
|
90
|
+
*
|
|
91
|
+
* The bits represent whether the corresponding effective Fibonacci index is used. I call these "use bits" and "skip bits" where a use bit is 1 and a skip bit is 0. This is by convention that I, Peter Ryszkiewicz decided, but it is theoretically possible to use skip bits and use bits flipped.
|
|
92
|
+
*
|
|
93
|
+
* If we use a bit, we then skip the next bit, because it is impossible to use two consecutive bits, or Fibonacci numbers, due to the Zeckendorf principle.
|
|
94
|
+
* The first bit in the ezba represents whether the first effective Fibonacci index is used.
|
|
95
|
+
* The first effective Fibonacci index is always 0 and represents the Fibonacci index 2 which has a value of 1. We use effective Fibonacci indices because the first Fibonacci number, 0, is not useful for sums, and the second Fibonacci number, 1, is redundant because it is the same as the third Fibonacci number.
|
|
96
|
+
*
|
|
97
|
+
* TODO: Optimize the size of the output by using a bit vector instead of a vector of [`u8`]s. I made an initial attempt at this in the `use-bitvec` branch, but the benchmarks were slower.
|
|
98
|
+
*
|
|
99
|
+
* # Examples
|
|
100
|
+
*
|
|
101
|
+
* ```
|
|
102
|
+
* # use zeckendorf_rs::ezba_from_ezld;
|
|
103
|
+
* assert_eq!(ezba_from_ezld(&[]), vec![0]);
|
|
104
|
+
* assert_eq!(ezba_from_ezld(&[0]), vec![1]); // 0th EFI is 2nd FI, which is 1
|
|
105
|
+
* assert_eq!(ezba_from_ezld(&[1]), vec![0, 1]); // 1st EFI is 3rd FI, which is 2
|
|
106
|
+
* assert_eq!(ezba_from_ezld(&[2]), vec![0, 0, 1]); // 2nd EFI is 4th FI, which is 3
|
|
107
|
+
* assert_eq!(ezba_from_ezld(&[2, 0]), vec![1, 1]); // 2nd EFI is 4th FI, which is 3 and 0th EFI is 2nd FI, which is 1, which sums to 4
|
|
108
|
+
* assert_eq!(ezba_from_ezld(&[3]), vec![0, 0, 0, 1]); // 3rd EFI is 5th FI, which is 5
|
|
109
|
+
* ```
|
|
110
|
+
* @param {BigUint64Array} effective_zeckendorf_list_descending
|
|
111
|
+
* @returns {Uint8Array}
|
|
112
|
+
*/
|
|
113
|
+
export function ezba_from_ezld(effective_zeckendorf_list_descending) {
|
|
114
|
+
const ptr0 = passArray64ToWasm0(effective_zeckendorf_list_descending, wasm.__wbindgen_malloc);
|
|
115
|
+
const len0 = WASM_VECTOR_LEN;
|
|
116
|
+
const ret = wasm.ezba_from_ezld(ptr0, len0);
|
|
117
|
+
var v2 = getArrayU8FromWasm0(ret[0], ret[1]).slice();
|
|
118
|
+
wasm.__wbindgen_free(ret[0], ret[1] * 1, 1);
|
|
119
|
+
return v2;
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
/**
|
|
123
|
+
* Converts a vector of bits (0s and 1s) from an ezba (Effective Zeckendorf Bits Ascending) into a vector of effective Fibonacci indices,
|
|
124
|
+
* the Effective Zeckendorf List Ascending.
|
|
125
|
+
*
|
|
126
|
+
* # Examples
|
|
127
|
+
*
|
|
128
|
+
* ```
|
|
129
|
+
* # use zeckendorf_rs::ezba_to_ezla;
|
|
130
|
+
* assert_eq!(ezba_to_ezla(&[0, 0, 0, 0, 0, 0, 0, 0]), vec![]);
|
|
131
|
+
* assert_eq!(ezba_to_ezla(&[1, 0, 0, 0, 0, 0, 0, 0]), vec![0]);
|
|
132
|
+
* assert_eq!(ezba_to_ezla(&[1, 1, 1, 0, 0, 0, 0, 0]), vec![0, 2, 4]);
|
|
133
|
+
* ```
|
|
134
|
+
* @param {Uint8Array} ezba_bits
|
|
135
|
+
* @returns {BigUint64Array}
|
|
136
|
+
*/
|
|
137
|
+
export function ezba_to_ezla(ezba_bits) {
|
|
138
|
+
const ptr0 = passArray8ToWasm0(ezba_bits, wasm.__wbindgen_malloc);
|
|
139
|
+
const len0 = WASM_VECTOR_LEN;
|
|
140
|
+
const ret = wasm.ezba_to_ezla(ptr0, len0);
|
|
141
|
+
var v2 = getArrayU64FromWasm0(ret[0], ret[1]).slice();
|
|
142
|
+
wasm.__wbindgen_free(ret[0], ret[1] * 8, 8);
|
|
143
|
+
return v2;
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
/**
|
|
147
|
+
* Converts an Effective Zeckendorf List to a Zeckendorf List.
|
|
148
|
+
* It does not matter if the list is ascending or descending; it retains the directionality of the original list.
|
|
149
|
+
*
|
|
150
|
+
* # Examples
|
|
151
|
+
*
|
|
152
|
+
* ```
|
|
153
|
+
* # use zeckendorf_rs::ezl_to_zl;
|
|
154
|
+
* assert_eq!(ezl_to_zl(&[0]), vec![2]);
|
|
155
|
+
* assert_eq!(ezl_to_zl(&[1]), vec![3]);
|
|
156
|
+
* assert_eq!(ezl_to_zl(&[2]), vec![4]);
|
|
157
|
+
* ```
|
|
158
|
+
* @param {BigUint64Array} ezl
|
|
159
|
+
* @returns {BigUint64Array}
|
|
160
|
+
*/
|
|
161
|
+
export function ezl_to_zl(ezl) {
|
|
162
|
+
const ptr0 = passArray64ToWasm0(ezl, wasm.__wbindgen_malloc);
|
|
163
|
+
const len0 = WASM_VECTOR_LEN;
|
|
164
|
+
const ret = wasm.ezl_to_zl(ptr0, len0);
|
|
165
|
+
var v2 = getArrayU64FromWasm0(ret[0], ret[1]).slice();
|
|
166
|
+
wasm.__wbindgen_free(ret[0], ret[1] * 8, 8);
|
|
167
|
+
return v2;
|
|
168
|
+
}
|
|
169
|
+
|
|
170
|
+
/**
|
|
171
|
+
* Fibonacci Index to Effective Fibonacci Index: EFI(fi) === fi - 2, where fi is the Fibonacci Index
|
|
172
|
+
*
|
|
173
|
+
* # Examples
|
|
174
|
+
*
|
|
175
|
+
* ```
|
|
176
|
+
* # use zeckendorf_rs::fi_to_efi;
|
|
177
|
+
* # use num_bigint::BigUint;
|
|
178
|
+
* # use num_traits::{One, Zero};
|
|
179
|
+
* assert_eq!(fi_to_efi(2), 0);
|
|
180
|
+
* assert_eq!(fi_to_efi(3), 1);
|
|
181
|
+
* assert_eq!(fi_to_efi(4), 2);
|
|
182
|
+
* ```
|
|
183
|
+
* @param {bigint} fi
|
|
184
|
+
* @returns {bigint}
|
|
185
|
+
*/
|
|
186
|
+
export function fi_to_efi(fi) {
|
|
187
|
+
const ret = wasm.fi_to_efi(fi);
|
|
188
|
+
return BigInt.asUintN(64, ret);
|
|
189
|
+
}
|
|
190
|
+
|
|
191
|
+
/**
|
|
192
|
+
* Returns a [`u64`] value with only the most significant set bit of n preserved.
|
|
193
|
+
*
|
|
194
|
+
* # Examples
|
|
195
|
+
*
|
|
196
|
+
* ```
|
|
197
|
+
* # use zeckendorf_rs::highest_one_bit;
|
|
198
|
+
* assert_eq!(highest_one_bit(0), 0);
|
|
199
|
+
* assert_eq!(highest_one_bit(1), 1);
|
|
200
|
+
* assert_eq!(highest_one_bit(2), 2);
|
|
201
|
+
* assert_eq!(highest_one_bit(3), 2);
|
|
202
|
+
* assert_eq!(highest_one_bit(4), 4);
|
|
203
|
+
* assert_eq!(highest_one_bit(5), 4);
|
|
204
|
+
* assert_eq!(highest_one_bit(6), 4);
|
|
205
|
+
* assert_eq!(highest_one_bit(7), 4);
|
|
206
|
+
* assert_eq!(highest_one_bit(8), 8);
|
|
207
|
+
* assert_eq!(highest_one_bit(9), 8);
|
|
208
|
+
* assert_eq!(highest_one_bit(10), 8);
|
|
209
|
+
* assert_eq!(highest_one_bit(11), 8);
|
|
210
|
+
* assert_eq!(highest_one_bit(12), 8);
|
|
211
|
+
* assert_eq!(highest_one_bit(13), 8);
|
|
212
|
+
* assert_eq!(highest_one_bit(14), 8);
|
|
213
|
+
* ```
|
|
214
|
+
* @param {bigint} n
|
|
215
|
+
* @returns {bigint}
|
|
216
|
+
*/
|
|
217
|
+
export function highest_one_bit(n) {
|
|
218
|
+
const ret = wasm.highest_one_bit(n);
|
|
219
|
+
return BigInt.asUintN(64, ret);
|
|
220
|
+
}
|
|
221
|
+
|
|
222
|
+
/**
|
|
223
|
+
* The memoized Fibonacci function taking an Effective Fibonacci Index as input.
|
|
224
|
+
*
|
|
225
|
+
* # Examples
|
|
226
|
+
*
|
|
227
|
+
* ```
|
|
228
|
+
* # use zeckendorf_rs::memoized_effective_fibonacci;
|
|
229
|
+
* # use num_bigint::BigUint;
|
|
230
|
+
* # use num_traits::{One, Zero};
|
|
231
|
+
* assert_eq!(memoized_effective_fibonacci(0), 1);
|
|
232
|
+
* assert_eq!(memoized_effective_fibonacci(1), 2);
|
|
233
|
+
* assert_eq!(memoized_effective_fibonacci(2), 3);
|
|
234
|
+
* assert_eq!(memoized_effective_fibonacci(3), 5);
|
|
235
|
+
* assert_eq!(memoized_effective_fibonacci(4), 8);
|
|
236
|
+
* assert_eq!(memoized_effective_fibonacci(5), 13);
|
|
237
|
+
* assert_eq!(memoized_effective_fibonacci(6), 21);
|
|
238
|
+
* assert_eq!(memoized_effective_fibonacci(7), 34);
|
|
239
|
+
* assert_eq!(memoized_effective_fibonacci(8), 55);
|
|
240
|
+
* assert_eq!(memoized_effective_fibonacci(9), 89);
|
|
241
|
+
* assert_eq!(memoized_effective_fibonacci(10), 144);
|
|
242
|
+
* ```
|
|
243
|
+
* @param {bigint} efi
|
|
244
|
+
* @returns {bigint}
|
|
245
|
+
*/
|
|
246
|
+
export function memoized_effective_fibonacci(efi) {
|
|
247
|
+
const ret = wasm.memoized_effective_fibonacci(efi);
|
|
248
|
+
return BigInt.asUintN(64, ret);
|
|
249
|
+
}
|
|
250
|
+
|
|
251
|
+
/**
|
|
252
|
+
* fibonacci(x) is equal to 0 if x is 0; 1 if x is 1; else return fibonacci(x - 1) + fibonacci(x - 2)
|
|
253
|
+
*
|
|
254
|
+
* This function is slow and should not be used for large numbers. If you want a [`u64`] result, use the faster [`memoized_slow_fibonacci_biguint_iterative`] function instead. If you want a [`BigUint`] result, use the [`fast_doubling_fibonacci_biguint`] function instead.
|
|
255
|
+
*
|
|
256
|
+
* This function fails for large numbers (e.g. 100_000) with a stack overflow error.
|
|
257
|
+
*
|
|
258
|
+
* `fi` stands for Fibonacci Index.
|
|
259
|
+
*
|
|
260
|
+
* # Examples
|
|
261
|
+
*
|
|
262
|
+
* ```
|
|
263
|
+
* # use zeckendorf_rs::memoized_slow_fibonacci_recursive;
|
|
264
|
+
* // Base cases
|
|
265
|
+
* assert_eq!(memoized_slow_fibonacci_recursive(0), 0);
|
|
266
|
+
* assert_eq!(memoized_slow_fibonacci_recursive(1), 1);
|
|
267
|
+
*
|
|
268
|
+
* // Small Fibonacci numbers
|
|
269
|
+
* assert_eq!(memoized_slow_fibonacci_recursive(2), 1);
|
|
270
|
+
* assert_eq!(memoized_slow_fibonacci_recursive(3), 2);
|
|
271
|
+
* assert_eq!(memoized_slow_fibonacci_recursive(4), 3);
|
|
272
|
+
* assert_eq!(memoized_slow_fibonacci_recursive(5), 5);
|
|
273
|
+
* assert_eq!(memoized_slow_fibonacci_recursive(6), 8);
|
|
274
|
+
* assert_eq!(memoized_slow_fibonacci_recursive(7), 13);
|
|
275
|
+
* assert_eq!(memoized_slow_fibonacci_recursive(8), 21);
|
|
276
|
+
* assert_eq!(memoized_slow_fibonacci_recursive(9), 34);
|
|
277
|
+
* assert_eq!(memoized_slow_fibonacci_recursive(10), 55);
|
|
278
|
+
* ```
|
|
279
|
+
* @param {bigint} fi
|
|
280
|
+
* @returns {bigint}
|
|
281
|
+
*/
|
|
282
|
+
export function memoized_slow_fibonacci_recursive(fi) {
|
|
283
|
+
const ret = wasm.memoized_slow_fibonacci_recursive(fi);
|
|
284
|
+
return BigInt.asUintN(64, ret);
|
|
285
|
+
}
|
|
286
|
+
|
|
287
|
+
/**
|
|
288
|
+
* A descending Zeckendorf list is a sorted list of unique Fibonacci indices, in descending order, that sum to the given number.
|
|
289
|
+
*
|
|
290
|
+
* A Fibonacci index is the index of the Fibonacci number in the Fibonacci sequence.
|
|
291
|
+
* fibonacci(fibonacci_index) = fibonacci_number
|
|
292
|
+
*
|
|
293
|
+
* # Examples
|
|
294
|
+
*
|
|
295
|
+
* ```
|
|
296
|
+
* # use zeckendorf_rs::memoized_zeckendorf_list_descending_for_integer;
|
|
297
|
+
* // Base cases
|
|
298
|
+
* assert_eq!(memoized_zeckendorf_list_descending_for_integer(0), vec![]);
|
|
299
|
+
* assert_eq!(memoized_zeckendorf_list_descending_for_integer(1), vec![2]);
|
|
300
|
+
* assert_eq!(memoized_zeckendorf_list_descending_for_integer(2), vec![3]);
|
|
301
|
+
*
|
|
302
|
+
* // Small Zeckendorf numbers
|
|
303
|
+
* assert_eq!(memoized_zeckendorf_list_descending_for_integer(3), vec![4]);
|
|
304
|
+
* assert_eq!(memoized_zeckendorf_list_descending_for_integer(4), vec![4, 2]);
|
|
305
|
+
* assert_eq!(memoized_zeckendorf_list_descending_for_integer(5), vec![5]);
|
|
306
|
+
* assert_eq!(memoized_zeckendorf_list_descending_for_integer(6), vec![5, 2]);
|
|
307
|
+
* assert_eq!(memoized_zeckendorf_list_descending_for_integer(7), vec![5, 3]);
|
|
308
|
+
* assert_eq!(memoized_zeckendorf_list_descending_for_integer(8), vec![6]);
|
|
309
|
+
* assert_eq!(memoized_zeckendorf_list_descending_for_integer(9), vec![6, 2]);
|
|
310
|
+
* assert_eq!(memoized_zeckendorf_list_descending_for_integer(10), vec![6, 3]);
|
|
311
|
+
* assert_eq!(memoized_zeckendorf_list_descending_for_integer(11), vec![6, 4]);
|
|
312
|
+
* assert_eq!(memoized_zeckendorf_list_descending_for_integer(12), vec![6, 4, 2]);
|
|
313
|
+
* ```
|
|
314
|
+
* @param {bigint} n
|
|
315
|
+
* @returns {BigUint64Array}
|
|
316
|
+
*/
|
|
317
|
+
export function memoized_zeckendorf_list_descending_for_integer(n) {
|
|
318
|
+
const ret = wasm.memoized_zeckendorf_list_descending_for_integer(n);
|
|
319
|
+
var v1 = getArrayU64FromWasm0(ret[0], ret[1]).slice();
|
|
320
|
+
wasm.__wbindgen_free(ret[0], ret[1] * 8, 8);
|
|
321
|
+
return v1;
|
|
322
|
+
}
|
|
323
|
+
|
|
324
|
+
/**
|
|
325
|
+
* Packs a slice of bits (0s and 1s) from an ezba (Effective Zeckendorf Bits Ascending) into bytes.
|
|
326
|
+
*
|
|
327
|
+
* The output bytes are in little endian order, so the first byte is the least significant byte and the last byte is the most significant byte.
|
|
328
|
+
*
|
|
329
|
+
* Input bits and output bits are in ascending significance: bits\[0\] = LSB, bits\[7\] = MSB.
|
|
330
|
+
* Every 8 bits become a [`u8`] in the output.
|
|
331
|
+
* The last byte is padded with 0s if the number of bits is not a multiple of 8.
|
|
332
|
+
*
|
|
333
|
+
* # Examples
|
|
334
|
+
*
|
|
335
|
+
* ```
|
|
336
|
+
* # use zeckendorf_rs::pack_ezba_bits_to_bytes;
|
|
337
|
+
* assert_eq!(pack_ezba_bits_to_bytes(&[0]), vec![0]);
|
|
338
|
+
* assert_eq!(pack_ezba_bits_to_bytes(&[1]), vec![1]);
|
|
339
|
+
* assert_eq!(pack_ezba_bits_to_bytes(&[0, 1]), vec![0b10]);
|
|
340
|
+
* assert_eq!(pack_ezba_bits_to_bytes(&[0, 0, 1]), vec![0b100]);
|
|
341
|
+
* assert_eq!(pack_ezba_bits_to_bytes(&[1, 1]), vec![0b11]);
|
|
342
|
+
* ```
|
|
343
|
+
* @param {Uint8Array} ezba
|
|
344
|
+
* @returns {Uint8Array}
|
|
345
|
+
*/
|
|
346
|
+
export function pack_ezba_bits_to_bytes(ezba) {
|
|
347
|
+
const ptr0 = passArray8ToWasm0(ezba, wasm.__wbindgen_malloc);
|
|
348
|
+
const len0 = WASM_VECTOR_LEN;
|
|
349
|
+
const ret = wasm.pack_ezba_bits_to_bytes(ptr0, len0);
|
|
350
|
+
var v2 = getArrayU8FromWasm0(ret[0], ret[1]).slice();
|
|
351
|
+
wasm.__wbindgen_free(ret[0], ret[1] * 1, 1);
|
|
352
|
+
return v2;
|
|
353
|
+
}
|
|
354
|
+
|
|
355
|
+
/**
|
|
356
|
+
* Unpacks a vector of bytes into a vector of bits (0s and 1s) from an ezba (Effective Zeckendorf Bits Ascending).
|
|
357
|
+
*
|
|
358
|
+
* # Examples
|
|
359
|
+
*
|
|
360
|
+
* ```
|
|
361
|
+
* # use zeckendorf_rs::unpack_bytes_to_ezba_bits;
|
|
362
|
+
* assert_eq!(unpack_bytes_to_ezba_bits(&[0]), vec![0, 0, 0, 0, 0, 0, 0, 0]);
|
|
363
|
+
* assert_eq!(unpack_bytes_to_ezba_bits(&[1]), vec![1, 0, 0, 0, 0, 0, 0, 0]);
|
|
364
|
+
* assert_eq!(unpack_bytes_to_ezba_bits(&[0b111]), vec![1, 1, 1, 0, 0, 0, 0, 0]);
|
|
365
|
+
* assert_eq!(unpack_bytes_to_ezba_bits(&[1, 1]), vec![1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0]);
|
|
366
|
+
* ```
|
|
367
|
+
* @param {Uint8Array} bytes
|
|
368
|
+
* @returns {Uint8Array}
|
|
369
|
+
*/
|
|
370
|
+
export function unpack_bytes_to_ezba_bits(bytes) {
|
|
371
|
+
const ptr0 = passArray8ToWasm0(bytes, wasm.__wbindgen_malloc);
|
|
372
|
+
const len0 = WASM_VECTOR_LEN;
|
|
373
|
+
const ret = wasm.unpack_bytes_to_ezba_bits(ptr0, len0);
|
|
374
|
+
var v2 = getArrayU8FromWasm0(ret[0], ret[1]).slice();
|
|
375
|
+
wasm.__wbindgen_free(ret[0], ret[1] * 1, 1);
|
|
376
|
+
return v2;
|
|
377
|
+
}
|
|
378
|
+
|
|
379
|
+
/**
|
|
380
|
+
* Compresses a slice of bytes using the Zeckendorf algorithm.
|
|
381
|
+
*
|
|
382
|
+
* Assumes the input data is interpreted as a big endian integer. The output data is in little endian order, so the first bit and byte is the least significant bit and byte and the last bit and byte is the most significant bit and byte.
|
|
383
|
+
*
|
|
384
|
+
* TODO: Technically, the way the input data is interpreted is arbitrary; we could interpret it as little endian which could result in a more compact representation. We could go even further and interpret the data at different byte or word boundaries to see if it results in a more compact representation, and signify to the caller which interpretation was used. We probably need a better understanding of random distributions of data to determine what is the optimal interpretation. More investigation is needed here.
|
|
385
|
+
*
|
|
386
|
+
* # Examples
|
|
387
|
+
*
|
|
388
|
+
* ```
|
|
389
|
+
* # use zeckendorf_rs::zeckendorf_compress_be;
|
|
390
|
+
* assert_eq!(zeckendorf_compress_be(&[0]), vec![0]);
|
|
391
|
+
* assert_eq!(zeckendorf_compress_be(&[1]), vec![1]);
|
|
392
|
+
* assert_eq!(zeckendorf_compress_be(&[12]), vec![0b111]);
|
|
393
|
+
* assert_eq!(zeckendorf_compress_be(&[54]), vec![30]);
|
|
394
|
+
* assert_eq!(zeckendorf_compress_be(&[55]), vec![0, 1]); // 55 is the 10 indexed Fibonacci number, which is the 8 indexed effective Fibonacci number, and therefore is the first number needing two bytes to contain these 8 bits, because there is 1 "use bit" and 7 "skip bits" in the effective zeckendorf bits ascending.
|
|
395
|
+
* assert_eq!(zeckendorf_compress_be(&[255]), vec![33, 2]);
|
|
396
|
+
* assert_eq!(zeckendorf_compress_be(&[1, 0]), vec![34, 2]);
|
|
397
|
+
* ```
|
|
398
|
+
* @param {Uint8Array} data
|
|
399
|
+
* @returns {Uint8Array}
|
|
400
|
+
*/
|
|
401
|
+
export function zeckendorf_compress_be(data) {
|
|
402
|
+
const ptr0 = passArray8ToWasm0(data, wasm.__wbindgen_malloc);
|
|
403
|
+
const len0 = WASM_VECTOR_LEN;
|
|
404
|
+
const ret = wasm.zeckendorf_compress_be(ptr0, len0);
|
|
405
|
+
var v2 = getArrayU8FromWasm0(ret[0], ret[1]).slice();
|
|
406
|
+
wasm.__wbindgen_free(ret[0], ret[1] * 1, 1);
|
|
407
|
+
return v2;
|
|
408
|
+
}
|
|
409
|
+
|
|
410
|
+
/**
|
|
411
|
+
* Compresses a slice of bytes using the Zeckendorf algorithm.
|
|
412
|
+
*
|
|
413
|
+
* Assumes the input data is interpreted as a little endian integer. The output data is in little endian order, so the first bit and byte is the least significant bit and byte and the last bit and byte is the most significant bit and byte.
|
|
414
|
+
*
|
|
415
|
+
* # Examples
|
|
416
|
+
*
|
|
417
|
+
* ```
|
|
418
|
+
* # use zeckendorf_rs::zeckendorf_compress_le;
|
|
419
|
+
* assert_eq!(zeckendorf_compress_le(&[0]), vec![0]);
|
|
420
|
+
* assert_eq!(zeckendorf_compress_le(&[1]), vec![1]);
|
|
421
|
+
* assert_eq!(zeckendorf_compress_le(&[12]), vec![0b111]);
|
|
422
|
+
* assert_eq!(zeckendorf_compress_le(&[54]), vec![30]);
|
|
423
|
+
* assert_eq!(zeckendorf_compress_le(&[55]), vec![0, 1]); // 55 is the 10 indexed Fibonacci number, which is the 8 indexed effective Fibonacci number, and therefore is the first number needing two bytes to contain these 8 bits, because there is 1 "use bit" and 7 "skip bits" in the effective zeckendorf bits ascending.
|
|
424
|
+
* assert_eq!(zeckendorf_compress_le(&[255]), vec![33, 2]);
|
|
425
|
+
* assert_eq!(zeckendorf_compress_le(&[0, 1]), vec![34, 2]);
|
|
426
|
+
* ```
|
|
427
|
+
* @param {Uint8Array} data
|
|
428
|
+
* @returns {Uint8Array}
|
|
429
|
+
*/
|
|
430
|
+
export function zeckendorf_compress_le(data) {
|
|
431
|
+
const ptr0 = passArray8ToWasm0(data, wasm.__wbindgen_malloc);
|
|
432
|
+
const len0 = WASM_VECTOR_LEN;
|
|
433
|
+
const ret = wasm.zeckendorf_compress_le(ptr0, len0);
|
|
434
|
+
var v2 = getArrayU8FromWasm0(ret[0], ret[1]).slice();
|
|
435
|
+
wasm.__wbindgen_free(ret[0], ret[1] * 1, 1);
|
|
436
|
+
return v2;
|
|
437
|
+
}
|
|
438
|
+
|
|
439
|
+
/**
|
|
440
|
+
* Decompresses a slice of bytes compressed using the Zeckendorf algorithm, assuming the original data was compressed using the big endian bytes interpretation.
|
|
441
|
+
*
|
|
442
|
+
* Assume the original input data was interpreted as a big endian integer, for now. See the TODO in the [`zeckendorf_compress_be`] function for more information.
|
|
443
|
+
*
|
|
444
|
+
* # Examples
|
|
445
|
+
*
|
|
446
|
+
* ```
|
|
447
|
+
* # use zeckendorf_rs::zeckendorf_decompress_be;
|
|
448
|
+
* assert_eq!(zeckendorf_decompress_be(&[0]), vec![0]);
|
|
449
|
+
* assert_eq!(zeckendorf_decompress_be(&[1]), vec![1]);
|
|
450
|
+
* assert_eq!(zeckendorf_decompress_be(&[0b111]), vec![12]);
|
|
451
|
+
* assert_eq!(zeckendorf_decompress_be(&[33, 2]), vec![255]);
|
|
452
|
+
* assert_eq!(zeckendorf_decompress_be(&[34, 2]), vec![1, 0]);
|
|
453
|
+
* ```
|
|
454
|
+
* @param {Uint8Array} compressed_data
|
|
455
|
+
* @returns {Uint8Array}
|
|
456
|
+
*/
|
|
457
|
+
export function zeckendorf_decompress_be(compressed_data) {
|
|
458
|
+
const ptr0 = passArray8ToWasm0(compressed_data, wasm.__wbindgen_malloc);
|
|
459
|
+
const len0 = WASM_VECTOR_LEN;
|
|
460
|
+
const ret = wasm.zeckendorf_decompress_be(ptr0, len0);
|
|
461
|
+
var v2 = getArrayU8FromWasm0(ret[0], ret[1]).slice();
|
|
462
|
+
wasm.__wbindgen_free(ret[0], ret[1] * 1, 1);
|
|
463
|
+
return v2;
|
|
464
|
+
}
|
|
465
|
+
|
|
466
|
+
/**
|
|
467
|
+
* Decompresses a slice of bytes compressed using the Zeckendorf algorithm, assuming the original data was compressed using the little endian bytes interpretation.
|
|
468
|
+
*
|
|
469
|
+
* # Examples
|
|
470
|
+
*
|
|
471
|
+
* ```
|
|
472
|
+
* # use zeckendorf_rs::zeckendorf_decompress_le;
|
|
473
|
+
* assert_eq!(zeckendorf_decompress_le(&[0]), vec![0]);
|
|
474
|
+
* assert_eq!(zeckendorf_decompress_le(&[1]), vec![1]);
|
|
475
|
+
* assert_eq!(zeckendorf_decompress_le(&[0b111]), vec![12]);
|
|
476
|
+
* assert_eq!(zeckendorf_decompress_le(&[33, 2]), vec![255]);
|
|
477
|
+
* assert_eq!(zeckendorf_decompress_le(&[34, 2]), vec![0, 1]);
|
|
478
|
+
* ```
|
|
479
|
+
* @param {Uint8Array} compressed_data
|
|
480
|
+
* @returns {Uint8Array}
|
|
481
|
+
*/
|
|
482
|
+
export function zeckendorf_decompress_le(compressed_data) {
|
|
483
|
+
const ptr0 = passArray8ToWasm0(compressed_data, wasm.__wbindgen_malloc);
|
|
484
|
+
const len0 = WASM_VECTOR_LEN;
|
|
485
|
+
const ret = wasm.zeckendorf_decompress_le(ptr0, len0);
|
|
486
|
+
var v2 = getArrayU8FromWasm0(ret[0], ret[1]).slice();
|
|
487
|
+
wasm.__wbindgen_free(ret[0], ret[1] * 1, 1);
|
|
488
|
+
return v2;
|
|
489
|
+
}
|
|
490
|
+
|
|
491
|
+
/**
|
|
492
|
+
* An Effective Zeckendorf List (EZL) has a lowest EFI of 0, which is an FI of 2.
|
|
493
|
+
* This is because it doesn't make sense for the lists to contain FIs 0 or 1 because
|
|
494
|
+
* 0 can never be added to a number and will therefore never be in a Zeckendorf List
|
|
495
|
+
* and an FI of 1 is equivalent to an FI of 2 which has a Fibonacci value of 1
|
|
496
|
+
* so let's just use FI starting at 2, which is an EFI of 0.
|
|
497
|
+
* It does not matter if the list is ascending or descending; it retains the directionality of the original list.
|
|
498
|
+
*
|
|
499
|
+
* # Examples
|
|
500
|
+
*
|
|
501
|
+
* ```
|
|
502
|
+
* # use zeckendorf_rs::zl_to_ezl;
|
|
503
|
+
* assert_eq!(zl_to_ezl(&[2]), vec![0]);
|
|
504
|
+
* assert_eq!(zl_to_ezl(&[3]), vec![1]);
|
|
505
|
+
* assert_eq!(zl_to_ezl(&[4]), vec![2]);
|
|
506
|
+
* ```
|
|
507
|
+
* @param {BigUint64Array} zl
|
|
508
|
+
* @returns {BigUint64Array}
|
|
509
|
+
*/
|
|
510
|
+
export function zl_to_ezl(zl) {
|
|
511
|
+
const ptr0 = passArray64ToWasm0(zl, wasm.__wbindgen_malloc);
|
|
512
|
+
const len0 = WASM_VECTOR_LEN;
|
|
513
|
+
const ret = wasm.zl_to_ezl(ptr0, len0);
|
|
514
|
+
var v2 = getArrayU64FromWasm0(ret[0], ret[1]).slice();
|
|
515
|
+
wasm.__wbindgen_free(ret[0], ret[1] * 8, 8);
|
|
516
|
+
return v2;
|
|
517
|
+
}
|
|
518
|
+
|
|
519
|
+
export function __wbindgen_init_externref_table() {
|
|
520
|
+
const table = wasm.__wbindgen_externrefs;
|
|
521
|
+
const offset = table.grow(4);
|
|
522
|
+
table.set(0, undefined);
|
|
523
|
+
table.set(offset + 0, undefined);
|
|
524
|
+
table.set(offset + 1, null);
|
|
525
|
+
table.set(offset + 2, true);
|
|
526
|
+
table.set(offset + 3, false);
|
|
527
|
+
};
|
|
Binary file
|