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 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;
@@ -0,0 +1,5 @@
1
+ import * as wasm from "./zeckendorf_rs_bg.wasm";
2
+ export * from "./zeckendorf_rs_bg.js";
3
+ import { __wbg_set_wasm } from "./zeckendorf_rs_bg.js";
4
+ __wbg_set_wasm(wasm);
5
+ wasm.__wbindgen_start();
@@ -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