lpn 0.2.0

Software to study attacks on the Learning Parity with Noise problem
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
1001
1002
1003
1004
1005
1006
1007
1008
1009
1010
1011
1012
1013
1014
1015
1016
1017
1018
1019
1020
1021
1022
1023
1024
1025
1026
1027
1028
1029
1030
1031
1032
1033
1034
1035
1036
1037
1038
1039
1040
1041
1042
1043
1044
1045
1046
1047
1048
1049
1050
1051
1052
1053
1054
1055
1056
1057
1058
1059
1060
1061
1062
1063
1064
1065
1066
1067
1068
1069
1070
1071
1072
1073
1074
1075
1076
1077
1078
1079
1080
1081
1082
1083
1084
1085
1086
1087
1088
1089
1090
1091
1092
1093
1094
1095
1096
1097
1098
1099
1100
1101
1102
1103
1104
1105
1106
1107
1108
1109
1110
1111
1112
1113
1114
1115
1116
1117
1118
1119
1120
1121
1122
1123
1124
1125
1126
1127
1128
1129
1130
1131
1132
1133
1134
1135
1136
1137
1138
1139
1140
1141
1142
1143
1144
1145
1146
1147
1148
1149
1150
1151
1152
1153
1154
1155
1156
1157
1158
1159
1160
1161
1162
1163
1164
1165
1166
1167
1168
1169
1170
1171
1172
1173
1174
1175
1176
1177
1178
1179
1180
1181
1182
1183
1184
1185
1186
1187
1188
1189
1190
1191
1192
1193
1194
1195
1196
1197
1198
1199
1200
1201
1202
1203
1204
1205
1206
1207
1208
1209
1210
1211
1212
1213
1214
1215
1216
1217
1218
1219
1220
1221
1222
1223
1224
1225
1226
1227
1228
1229
1230
1231
1232
1233
1234
1235
1236
1237
1238
1239
1240
1241
1242
1243
1244
1245
1246
1247
1248
1249
1250
1251
1252
1253
1254
1255
1256
1257
1258
1259
1260
1261
1262
1263
1264
1265
1266
1267
1268
1269
1270
1271
1272
1273
1274
1275
1276
1277
1278
1279
1280
1281
1282
1283
1284
1285
1286
1287
1288
1289
1290
1291
1292
1293
1294
1295
1296
1297
1298
1299
1300
1301
1302
1303
1304
1305
1306
1307
1308
1309
1310
1311
1312
1313
1314
1315
1316
1317
1318
1319
1320
1321
1322
1323
1324
1325
1326
1327
1328
1329
1330
1331
1332
1333
1334
1335
1336
1337
1338
1339
1340
1341
1342
1343
1344
1345
1346
1347
1348
1349
1350
1351
1352
1353
1354
1355
1356
1357
1358
1359
1360
1361
1362
1363
1364
1365
1366
1367
1368
1369
use std::boxed::Box;
use std::default::Default;
use std::sync::Once;

use fnv::FnvHashMap;

use m4ri_rust::friendly::BinMatrix;
use m4ri_rust::friendly::BinVector;

use crate::codes::BinaryCode;

/// ``[23, 13]`` Guava code
///
/// Best code found from the GUAVA database version 3.15
///
/// Decodes using Syndrome decoding
#[derive(Clone, Serialize)]
pub struct GuavaCode23_13;

static INIT: Once = Once::new();
static mut GENERATOR_MATRIX: *const BinMatrix = 0 as *const BinMatrix;
static mut PARITY_MATRIX: *const BinMatrix = 0 as *const BinMatrix;
static mut PARITY_MATRIX_T: *const BinMatrix = 0 as *const BinMatrix;
static mut SYNDROME_MAP: *const FnvHashMap<u64, &'static [usize; 1]> = 0 as *const FnvHashMap<u64, &'static [usize; 1]>;

fn init() {
    INIT.call_once(|| {
        unsafe {
            let matrix = Box::new(BinMatrix::from_slices(&[
                &[ 966657 ],
                &[ 6602754 ],
                &[ 3907588 ],
                &[ 3719176 ],
                &[ 5414928 ],
                &[ 5963808 ],
                &[ 3104832 ],
                &[ 4563072 ],
                &[ 7856384 ],
                &[ 6939136 ],
                &[ 7087104 ],
                &[ 7309312 ],
                &[ 7671808 ],
                
            ], 23));
            GENERATOR_MATRIX = Box::into_raw(matrix);

            let matrix = Box::new(BinMatrix::from_slices(&[
                &[ 6731777 ],
                &[ 7972866 ],
                &[ 3012612 ],
                &[ 3947016 ],
                &[ 3592720 ],
                &[ 6091296 ],
                &[ 4758080 ],
                &[ 5470336 ],
                &[ 7074560 ],
                &[ 7019520 ],
                
            ], 23));
            let matrix_t = Box::new(matrix.transposed());
            PARITY_MATRIX = Box::into_raw(matrix);
            PARITY_MATRIX_T = Box::into_raw(matrix_t);

            let mut map = Box::new(FnvHashMap::with_capacity_and_hasher(1024, Default::default()));
            map.insert(0, &[0]);     // 0 => [0]
            map.insert(1, &[1]);     // 1 => [1]
            map.insert(2, &[2]);     // 2 => [2]
            map.insert(4, &[4]);     // 4 => [4]
            map.insert(8, &[8]);     // 8 => [8]
            map.insert(16, &[16]);     // 16 => [16]
            map.insert(32, &[32]);     // 32 => [32]
            map.insert(64, &[64]);     // 64 => [64]
            map.insert(128, &[128]);     // 128 => [128]
            map.insert(256, &[256]);     // 256 => [256]
            map.insert(376, &[512]);     // 376 => [512]
            map.insert(512, &[1024]);     // 512 => [1024]
            map.insert(719, &[2048]);     // 719 => [2048]
            map.insert(1021, &[4096]);     // 1021 => [4096]
            map.insert(431, &[8192]);     // 431 => [8192]
            map.insert(436, &[16384]);     // 436 => [16384]
            map.insert(375, &[32768]);     // 375 => [32768]
            map.insert(902, &[65536]);     // 902 => [65536]
            map.insert(913, &[131072]);     // 913 => [131072]
            map.insert(61, &[262144]);     // 61 => [262144]
            map.insert(878, &[524288]);     // 878 => [524288]
            map.insert(186, &[1048576]);     // 186 => [1048576]
            map.insert(799, &[2097152]);     // 799 => [2097152]
            map.insert(995, &[4194304]);     // 995 => [4194304]
            map.insert(3, &[3]);     // 3 => [3]
            map.insert(5, &[5]);     // 5 => [5]
            map.insert(9, &[9]);     // 9 => [9]
            map.insert(17, &[17]);     // 17 => [17]
            map.insert(33, &[33]);     // 33 => [33]
            map.insert(65, &[65]);     // 65 => [65]
            map.insert(129, &[129]);     // 129 => [129]
            map.insert(257, &[257]);     // 257 => [257]
            map.insert(377, &[513]);     // 377 => [513]
            map.insert(513, &[1025]);     // 513 => [1025]
            map.insert(718, &[2049]);     // 718 => [2049]
            map.insert(1020, &[4097]);     // 1020 => [4097]
            map.insert(430, &[8193]);     // 430 => [8193]
            map.insert(437, &[16385]);     // 437 => [16385]
            map.insert(374, &[32769]);     // 374 => [32769]
            map.insert(903, &[65537]);     // 903 => [65537]
            map.insert(912, &[131073]);     // 912 => [131073]
            map.insert(60, &[262145]);     // 60 => [262145]
            map.insert(879, &[524289]);     // 879 => [524289]
            map.insert(187, &[1048577]);     // 187 => [1048577]
            map.insert(798, &[2097153]);     // 798 => [2097153]
            map.insert(994, &[4194305]);     // 994 => [4194305]
            map.insert(6, &[6]);     // 6 => [6]
            map.insert(10, &[10]);     // 10 => [10]
            map.insert(18, &[18]);     // 18 => [18]
            map.insert(34, &[34]);     // 34 => [34]
            map.insert(66, &[66]);     // 66 => [66]
            map.insert(130, &[130]);     // 130 => [130]
            map.insert(258, &[258]);     // 258 => [258]
            map.insert(378, &[514]);     // 378 => [514]
            map.insert(514, &[1026]);     // 514 => [1026]
            map.insert(717, &[2050]);     // 717 => [2050]
            map.insert(1023, &[4098]);     // 1023 => [4098]
            map.insert(429, &[8194]);     // 429 => [8194]
            map.insert(438, &[16386]);     // 438 => [16386]
            map.insert(373, &[32770]);     // 373 => [32770]
            map.insert(900, &[65538]);     // 900 => [65538]
            map.insert(915, &[131074]);     // 915 => [131074]
            map.insert(63, &[262146]);     // 63 => [262146]
            map.insert(876, &[524290]);     // 876 => [524290]
            map.insert(184, &[1048578]);     // 184 => [1048578]
            map.insert(797, &[2097154]);     // 797 => [2097154]
            map.insert(993, &[4194306]);     // 993 => [4194306]
            map.insert(12, &[12]);     // 12 => [12]
            map.insert(20, &[20]);     // 20 => [20]
            map.insert(36, &[36]);     // 36 => [36]
            map.insert(68, &[68]);     // 68 => [68]
            map.insert(132, &[132]);     // 132 => [132]
            map.insert(260, &[260]);     // 260 => [260]
            map.insert(380, &[516]);     // 380 => [516]
            map.insert(516, &[1028]);     // 516 => [1028]
            map.insert(715, &[2052]);     // 715 => [2052]
            map.insert(1017, &[4100]);     // 1017 => [4100]
            map.insert(427, &[8196]);     // 427 => [8196]
            map.insert(432, &[16388]);     // 432 => [16388]
            map.insert(371, &[32772]);     // 371 => [32772]
            map.insert(898, &[65540]);     // 898 => [65540]
            map.insert(917, &[131076]);     // 917 => [131076]
            map.insert(57, &[262148]);     // 57 => [262148]
            map.insert(874, &[524292]);     // 874 => [524292]
            map.insert(190, &[1048580]);     // 190 => [1048580]
            map.insert(795, &[2097156]);     // 795 => [2097156]
            map.insert(999, &[4194308]);     // 999 => [4194308]
            map.insert(24, &[24]);     // 24 => [24]
            map.insert(40, &[40]);     // 40 => [40]
            map.insert(72, &[72]);     // 72 => [72]
            map.insert(136, &[136]);     // 136 => [136]
            map.insert(264, &[264]);     // 264 => [264]
            map.insert(368, &[520]);     // 368 => [520]
            map.insert(520, &[1032]);     // 520 => [1032]
            map.insert(711, &[2056]);     // 711 => [2056]
            map.insert(1013, &[4104]);     // 1013 => [4104]
            map.insert(423, &[8200]);     // 423 => [8200]
            map.insert(444, &[16392]);     // 444 => [16392]
            map.insert(383, &[32776]);     // 383 => [32776]
            map.insert(910, &[65544]);     // 910 => [65544]
            map.insert(921, &[131080]);     // 921 => [131080]
            map.insert(53, &[262152]);     // 53 => [262152]
            map.insert(870, &[524296]);     // 870 => [524296]
            map.insert(178, &[1048584]);     // 178 => [1048584]
            map.insert(791, &[2097160]);     // 791 => [2097160]
            map.insert(1003, &[4194312]);     // 1003 => [4194312]
            map.insert(48, &[48]);     // 48 => [48]
            map.insert(80, &[80]);     // 80 => [80]
            map.insert(144, &[144]);     // 144 => [144]
            map.insert(272, &[272]);     // 272 => [272]
            map.insert(360, &[528]);     // 360 => [528]
            map.insert(528, &[1040]);     // 528 => [1040]
            map.insert(735, &[2064]);     // 735 => [2064]
            map.insert(1005, &[4112]);     // 1005 => [4112]
            map.insert(447, &[8208]);     // 447 => [8208]
            map.insert(420, &[16400]);     // 420 => [16400]
            map.insert(359, &[32784]);     // 359 => [32784]
            map.insert(918, &[65552]);     // 918 => [65552]
            map.insert(897, &[131088]);     // 897 => [131088]
            map.insert(45, &[262160]);     // 45 => [262160]
            map.insert(894, &[524304]);     // 894 => [524304]
            map.insert(170, &[1048592]);     // 170 => [1048592]
            map.insert(783, &[2097168]);     // 783 => [2097168]
            map.insert(1011, &[4194320]);     // 1011 => [4194320]
            map.insert(96, &[96]);     // 96 => [96]
            map.insert(160, &[160]);     // 160 => [160]
            map.insert(288, &[288]);     // 288 => [288]
            map.insert(344, &[544]);     // 344 => [544]
            map.insert(544, &[1056]);     // 544 => [1056]
            map.insert(751, &[2080]);     // 751 => [2080]
            map.insert(989, &[4128]);     // 989 => [4128]
            map.insert(399, &[8224]);     // 399 => [8224]
            map.insert(404, &[16416]);     // 404 => [16416]
            map.insert(343, &[32800]);     // 343 => [32800]
            map.insert(934, &[65568]);     // 934 => [65568]
            map.insert(945, &[131104]);     // 945 => [131104]
            map.insert(29, &[262176]);     // 29 => [262176]
            map.insert(846, &[524320]);     // 846 => [524320]
            map.insert(154, &[1048608]);     // 154 => [1048608]
            map.insert(831, &[2097184]);     // 831 => [2097184]
            map.insert(963, &[4194336]);     // 963 => [4194336]
            map.insert(192, &[192]);     // 192 => [192]
            map.insert(320, &[320]);     // 320 => [320]
            map.insert(312, &[576]);     // 312 => [576]
            map.insert(576, &[1088]);     // 576 => [1088]
            map.insert(655, &[2112]);     // 655 => [2112]
            map.insert(957, &[4160]);     // 957 => [4160]
            map.insert(495, &[8256]);     // 495 => [8256]
            map.insert(500, &[16448]);     // 500 => [16448]
            map.insert(311, &[32832]);     // 311 => [32832]
            map.insert(966, &[65600]);     // 966 => [65600]
            map.insert(977, &[131136]);     // 977 => [131136]
            map.insert(125, &[262208]);     // 125 => [262208]
            map.insert(814, &[524352]);     // 814 => [524352]
            map.insert(250, &[1048640]);     // 250 => [1048640]
            map.insert(863, &[2097216]);     // 863 => [2097216]
            map.insert(931, &[4194368]);     // 931 => [4194368]
            map.insert(384, &[384]);     // 384 => [384]
            map.insert(504, &[640]);     // 504 => [640]
            map.insert(640, &[1152]);     // 640 => [1152]
            map.insert(591, &[2176]);     // 591 => [2176]
            map.insert(893, &[4224]);     // 893 => [4224]
            map.insert(303, &[8320]);     // 303 => [8320]
            map.insert(308, &[16512]);     // 308 => [16512]
            map.insert(503, &[32896]);     // 503 => [32896]
            map.insert(774, &[65664]);     // 774 => [65664]
            map.insert(785, &[131200]);     // 785 => [131200]
            map.insert(189, &[262272]);     // 189 => [262272]
            map.insert(1006, &[524416]);     // 1006 => [524416]
            map.insert(58, &[1048704]);     // 58 => [1048704]
            map.insert(927, &[2097280]);     // 927 => [2097280]
            map.insert(867, &[4194432]);     // 867 => [4194432]
            map.insert(120, &[768]);     // 120 => [768]
            map.insert(768, &[1280]);     // 768 => [1280]
            map.insert(975, &[2304]);     // 975 => [2304]
            map.insert(765, &[4352]);     // 765 => [4352]
            map.insert(175, &[8448]);     // 175 => [8448]
            map.insert(180, &[16640]);     // 180 => [16640]
            map.insert(119, &[33024]);     // 119 => [33024]
            map.insert(646, &[65792]);     // 646 => [65792]
            map.insert(657, &[131328]);     // 657 => [131328]
            map.insert(317, &[262400]);     // 317 => [262400]
            map.insert(622, &[524544]);     // 622 => [524544]
            map.insert(442, &[1048832]);     // 442 => [1048832]
            map.insert(543, &[2097408]);     // 543 => [2097408]
            map.insert(739, &[4194560]);     // 739 => [4194560]
            map.insert(888, &[1536]);     // 888 => [1536]
            map.insert(951, &[2560]);     // 951 => [2560]
            map.insert(645, &[4608]);     // 645 => [4608]
            map.insert(215, &[8704]);     // 215 => [8704]
            map.insert(204, &[16896]);     // 204 => [16896]
            map.insert(15, &[33280]);     // 15 => [33280]
            map.insert(766, &[66048]);     // 766 => [66048]
            map.insert(745, &[131584]);     // 745 => [131584]
            map.insert(325, &[262656]);     // 325 => [262656]
            map.insert(534, &[524800]);     // 534 => [524800]
            map.insert(450, &[1049088]);     // 450 => [1049088]
            map.insert(615, &[2097664]);     // 615 => [2097664]
            map.insert(667, &[4194816]);     // 667 => [4194816]
            map.insert(207, &[3072]);     // 207 => [3072]
            map.insert(509, &[5120]);     // 509 => [5120]
            map.insert(943, &[9216]);     // 943 => [9216]
            map.insert(948, &[17408]);     // 948 => [17408]
            map.insert(887, &[33792]);     // 887 => [33792]
            map.insert(390, &[66560]);     // 390 => [66560]
            map.insert(401, &[132096]);     // 401 => [132096]
            map.insert(573, &[263168]);     // 573 => [263168]
            map.insert(366, &[525312]);     // 366 => [525312]
            map.insert(698, &[1049600]);     // 698 => [1049600]
            map.insert(287, &[2098176]);     // 287 => [2098176]
            map.insert(483, &[4195328]);     // 483 => [4195328]
            map.insert(306, &[6144]);     // 306 => [6144]
            map.insert(864, &[10240]);     // 864 => [10240]
            map.insert(891, &[18432]);     // 891 => [18432]
            map.insert(952, &[34816]);     // 952 => [34816]
            map.insert(329, &[67584]);     // 329 => [67584]
            map.insert(350, &[133120]);     // 350 => [133120]
            map.insert(754, &[264192]);     // 754 => [264192]
            map.insert(417, &[526336]);     // 417 => [526336]
            map.insert(629, &[1050624]);     // 629 => [1050624]
            map.insert(464, &[2099200]);     // 464 => [2099200]
            map.insert(300, &[4196352]);     // 300 => [4196352]
            map.insert(594, &[12288]);     // 594 => [12288]
            map.insert(585, &[20480]);     // 585 => [20480]
            map.insert(650, &[36864]);     // 650 => [36864]
            map.insert(123, &[69632]);     // 123 => [69632]
            map.insert(108, &[135168]);     // 108 => [135168]
            map.insert(960, &[266240]);     // 960 => [266240]
            map.insert(147, &[528384]);     // 147 => [528384]
            map.insert(839, &[1052672]);     // 839 => [1052672]
            map.insert(226, &[2101248]);     // 226 => [2101248]
            map.insert(30, &[4198400]);     // 30 => [4198400]
            map.insert(27, &[24576]);     // 27 => [24576]
            map.insert(216, &[40960]);     // 216 => [40960]
            map.insert(553, &[73728]);     // 553 => [73728]
            map.insert(574, &[139264]);     // 574 => [139264]
            map.insert(402, &[270336]);     // 402 => [270336]
            map.insert(705, &[532480]);     // 705 => [532480]
            map.insert(277, &[1056768]);     // 277 => [1056768]
            map.insert(688, &[2105344]);     // 688 => [2105344]
            map.insert(588, &[4202496]);     // 588 => [4202496]
            map.insert(195, &[49152]);     // 195 => [49152]
            map.insert(562, &[81920]);     // 562 => [81920]
            map.insert(549, &[147456]);     // 549 => [147456]
            map.insert(393, &[278528]);     // 393 => [278528]
            map.insert(730, &[540672]);     // 730 => [540672]
            map.insert(270, &[1064960]);     // 270 => [1064960]
            map.insert(683, &[2113536]);     // 683 => [2113536]
            map.insert(599, &[4210688]);     // 599 => [4210688]
            map.insert(753, &[98304]);     // 753 => [98304]
            map.insert(742, &[163840]);     // 742 => [163840]
            map.insert(330, &[294912]);     // 330 => [294912]
            map.insert(537, &[557056]);     // 537 => [557056]
            map.insert(461, &[1081344]);     // 461 => [1081344]
            map.insert(616, &[2129920]);     // 616 => [2129920]
            map.insert(660, &[4227072]);     // 660 => [4227072]
            map.insert(23, &[196608]);     // 23 => [196608]
            map.insert(955, &[327680]);     // 955 => [327680]
            map.insert(232, &[589824]);     // 232 => [589824]
            map.insert(828, &[1114112]);     // 828 => [1114112]
            map.insert(153, &[2162688]);     // 153 => [2162688]
            map.insert(101, &[4259840]);     // 101 => [4259840]
            map.insert(940, &[393216]);     // 940 => [393216]
            map.insert(255, &[655360]);     // 255 => [655360]
            map.insert(811, &[1179648]);     // 811 => [1179648]
            map.insert(142, &[2228224]);     // 142 => [2228224]
            map.insert(114, &[4325376]);     // 114 => [4325376]
            map.insert(851, &[786432]);     // 851 => [786432]
            map.insert(135, &[1310720]);     // 135 => [1310720]
            map.insert(802, &[2359296]);     // 802 => [2359296]
            map.insert(990, &[4456448]);     // 990 => [4456448]
            map.insert(980, &[1572864]);     // 980 => [1572864]
            map.insert(113, &[2621440]);     // 113 => [2621440]
            map.insert(141, &[4718592]);     // 141 => [4718592]
            map.insert(933, &[3145728]);     // 933 => [3145728]
            map.insert(857, &[5242880]);     // 857 => [5242880]
            map.insert(252, &[6291456]);     // 252 => [6291456]
            map.insert(7, &[7]);     // 7 => [7]
            map.insert(11, &[11]);     // 11 => [11]
            map.insert(19, &[19]);     // 19 => [19]
            map.insert(35, &[35]);     // 35 => [35]
            map.insert(67, &[67]);     // 67 => [67]
            map.insert(131, &[131]);     // 131 => [131]
            map.insert(259, &[259]);     // 259 => [259]
            map.insert(379, &[515]);     // 379 => [515]
            map.insert(515, &[1027]);     // 515 => [1027]
            map.insert(716, &[2051]);     // 716 => [2051]
            map.insert(1022, &[4099]);     // 1022 => [4099]
            map.insert(428, &[8195]);     // 428 => [8195]
            map.insert(439, &[16387]);     // 439 => [16387]
            map.insert(372, &[32771]);     // 372 => [32771]
            map.insert(901, &[65539]);     // 901 => [65539]
            map.insert(914, &[131075]);     // 914 => [131075]
            map.insert(62, &[262147]);     // 62 => [262147]
            map.insert(877, &[524291]);     // 877 => [524291]
            map.insert(185, &[1048579]);     // 185 => [1048579]
            map.insert(796, &[2097155]);     // 796 => [2097155]
            map.insert(992, &[4194307]);     // 992 => [4194307]
            map.insert(13, &[13]);     // 13 => [13]
            map.insert(21, &[21]);     // 21 => [21]
            map.insert(37, &[37]);     // 37 => [37]
            map.insert(69, &[69]);     // 69 => [69]
            map.insert(133, &[133]);     // 133 => [133]
            map.insert(261, &[261]);     // 261 => [261]
            map.insert(381, &[517]);     // 381 => [517]
            map.insert(517, &[1029]);     // 517 => [1029]
            map.insert(714, &[2053]);     // 714 => [2053]
            map.insert(1016, &[4101]);     // 1016 => [4101]
            map.insert(426, &[8197]);     // 426 => [8197]
            map.insert(433, &[16389]);     // 433 => [16389]
            map.insert(370, &[32773]);     // 370 => [32773]
            map.insert(899, &[65541]);     // 899 => [65541]
            map.insert(916, &[131077]);     // 916 => [131077]
            map.insert(56, &[262149]);     // 56 => [262149]
            map.insert(875, &[524293]);     // 875 => [524293]
            map.insert(191, &[1048581]);     // 191 => [1048581]
            map.insert(794, &[2097157]);     // 794 => [2097157]
            map.insert(998, &[4194309]);     // 998 => [4194309]
            map.insert(25, &[25]);     // 25 => [25]
            map.insert(41, &[41]);     // 41 => [41]
            map.insert(73, &[73]);     // 73 => [73]
            map.insert(137, &[137]);     // 137 => [137]
            map.insert(265, &[265]);     // 265 => [265]
            map.insert(369, &[521]);     // 369 => [521]
            map.insert(521, &[1033]);     // 521 => [1033]
            map.insert(710, &[2057]);     // 710 => [2057]
            map.insert(1012, &[4105]);     // 1012 => [4105]
            map.insert(422, &[8201]);     // 422 => [8201]
            map.insert(445, &[16393]);     // 445 => [16393]
            map.insert(382, &[32777]);     // 382 => [32777]
            map.insert(911, &[65545]);     // 911 => [65545]
            map.insert(920, &[131081]);     // 920 => [131081]
            map.insert(52, &[262153]);     // 52 => [262153]
            map.insert(871, &[524297]);     // 871 => [524297]
            map.insert(179, &[1048585]);     // 179 => [1048585]
            map.insert(790, &[2097161]);     // 790 => [2097161]
            map.insert(1002, &[4194313]);     // 1002 => [4194313]
            map.insert(49, &[49]);     // 49 => [49]
            map.insert(81, &[81]);     // 81 => [81]
            map.insert(145, &[145]);     // 145 => [145]
            map.insert(273, &[273]);     // 273 => [273]
            map.insert(361, &[529]);     // 361 => [529]
            map.insert(529, &[1041]);     // 529 => [1041]
            map.insert(734, &[2065]);     // 734 => [2065]
            map.insert(1004, &[4113]);     // 1004 => [4113]
            map.insert(446, &[8209]);     // 446 => [8209]
            map.insert(421, &[16401]);     // 421 => [16401]
            map.insert(358, &[32785]);     // 358 => [32785]
            map.insert(919, &[65553]);     // 919 => [65553]
            map.insert(896, &[131089]);     // 896 => [131089]
            map.insert(44, &[262161]);     // 44 => [262161]
            map.insert(895, &[524305]);     // 895 => [524305]
            map.insert(171, &[1048593]);     // 171 => [1048593]
            map.insert(782, &[2097169]);     // 782 => [2097169]
            map.insert(1010, &[4194321]);     // 1010 => [4194321]
            map.insert(97, &[97]);     // 97 => [97]
            map.insert(161, &[161]);     // 161 => [161]
            map.insert(289, &[289]);     // 289 => [289]
            map.insert(345, &[545]);     // 345 => [545]
            map.insert(545, &[1057]);     // 545 => [1057]
            map.insert(750, &[2081]);     // 750 => [2081]
            map.insert(988, &[4129]);     // 988 => [4129]
            map.insert(398, &[8225]);     // 398 => [8225]
            map.insert(405, &[16417]);     // 405 => [16417]
            map.insert(342, &[32801]);     // 342 => [32801]
            map.insert(935, &[65569]);     // 935 => [65569]
            map.insert(944, &[131105]);     // 944 => [131105]
            map.insert(28, &[262177]);     // 28 => [262177]
            map.insert(847, &[524321]);     // 847 => [524321]
            map.insert(155, &[1048609]);     // 155 => [1048609]
            map.insert(830, &[2097185]);     // 830 => [2097185]
            map.insert(962, &[4194337]);     // 962 => [4194337]
            map.insert(193, &[193]);     // 193 => [193]
            map.insert(321, &[321]);     // 321 => [321]
            map.insert(313, &[577]);     // 313 => [577]
            map.insert(577, &[1089]);     // 577 => [1089]
            map.insert(654, &[2113]);     // 654 => [2113]
            map.insert(956, &[4161]);     // 956 => [4161]
            map.insert(494, &[8257]);     // 494 => [8257]
            map.insert(501, &[16449]);     // 501 => [16449]
            map.insert(310, &[32833]);     // 310 => [32833]
            map.insert(967, &[65601]);     // 967 => [65601]
            map.insert(976, &[131137]);     // 976 => [131137]
            map.insert(124, &[262209]);     // 124 => [262209]
            map.insert(815, &[524353]);     // 815 => [524353]
            map.insert(251, &[1048641]);     // 251 => [1048641]
            map.insert(862, &[2097217]);     // 862 => [2097217]
            map.insert(930, &[4194369]);     // 930 => [4194369]
            map.insert(385, &[385]);     // 385 => [385]
            map.insert(505, &[641]);     // 505 => [641]
            map.insert(641, &[1153]);     // 641 => [1153]
            map.insert(590, &[2177]);     // 590 => [2177]
            map.insert(892, &[4225]);     // 892 => [4225]
            map.insert(302, &[8321]);     // 302 => [8321]
            map.insert(309, &[16513]);     // 309 => [16513]
            map.insert(502, &[32897]);     // 502 => [32897]
            map.insert(775, &[65665]);     // 775 => [65665]
            map.insert(784, &[131201]);     // 784 => [131201]
            map.insert(188, &[262273]);     // 188 => [262273]
            map.insert(1007, &[524417]);     // 1007 => [524417]
            map.insert(59, &[1048705]);     // 59 => [1048705]
            map.insert(926, &[2097281]);     // 926 => [2097281]
            map.insert(866, &[4194433]);     // 866 => [4194433]
            map.insert(121, &[769]);     // 121 => [769]
            map.insert(769, &[1281]);     // 769 => [1281]
            map.insert(974, &[2305]);     // 974 => [2305]
            map.insert(764, &[4353]);     // 764 => [4353]
            map.insert(174, &[8449]);     // 174 => [8449]
            map.insert(181, &[16641]);     // 181 => [16641]
            map.insert(118, &[33025]);     // 118 => [33025]
            map.insert(647, &[65793]);     // 647 => [65793]
            map.insert(656, &[131329]);     // 656 => [131329]
            map.insert(316, &[262401]);     // 316 => [262401]
            map.insert(623, &[524545]);     // 623 => [524545]
            map.insert(443, &[1048833]);     // 443 => [1048833]
            map.insert(542, &[2097409]);     // 542 => [2097409]
            map.insert(738, &[4194561]);     // 738 => [4194561]
            map.insert(889, &[1537]);     // 889 => [1537]
            map.insert(950, &[2561]);     // 950 => [2561]
            map.insert(644, &[4609]);     // 644 => [4609]
            map.insert(214, &[8705]);     // 214 => [8705]
            map.insert(205, &[16897]);     // 205 => [16897]
            map.insert(14, &[33281]);     // 14 => [33281]
            map.insert(767, &[66049]);     // 767 => [66049]
            map.insert(744, &[131585]);     // 744 => [131585]
            map.insert(324, &[262657]);     // 324 => [262657]
            map.insert(535, &[524801]);     // 535 => [524801]
            map.insert(451, &[1049089]);     // 451 => [1049089]
            map.insert(614, &[2097665]);     // 614 => [2097665]
            map.insert(666, &[4194817]);     // 666 => [4194817]
            map.insert(206, &[3073]);     // 206 => [3073]
            map.insert(508, &[5121]);     // 508 => [5121]
            map.insert(942, &[9217]);     // 942 => [9217]
            map.insert(949, &[17409]);     // 949 => [17409]
            map.insert(886, &[33793]);     // 886 => [33793]
            map.insert(391, &[66561]);     // 391 => [66561]
            map.insert(400, &[132097]);     // 400 => [132097]
            map.insert(572, &[263169]);     // 572 => [263169]
            map.insert(367, &[525313]);     // 367 => [525313]
            map.insert(699, &[1049601]);     // 699 => [1049601]
            map.insert(286, &[2098177]);     // 286 => [2098177]
            map.insert(482, &[4195329]);     // 482 => [4195329]
            map.insert(307, &[6145]);     // 307 => [6145]
            map.insert(865, &[10241]);     // 865 => [10241]
            map.insert(890, &[18433]);     // 890 => [18433]
            map.insert(953, &[34817]);     // 953 => [34817]
            map.insert(328, &[67585]);     // 328 => [67585]
            map.insert(351, &[133121]);     // 351 => [133121]
            map.insert(755, &[264193]);     // 755 => [264193]
            map.insert(416, &[526337]);     // 416 => [526337]
            map.insert(628, &[1050625]);     // 628 => [1050625]
            map.insert(465, &[2099201]);     // 465 => [2099201]
            map.insert(301, &[4196353]);     // 301 => [4196353]
            map.insert(595, &[12289]);     // 595 => [12289]
            map.insert(584, &[20481]);     // 584 => [20481]
            map.insert(651, &[36865]);     // 651 => [36865]
            map.insert(122, &[69633]);     // 122 => [69633]
            map.insert(109, &[135169]);     // 109 => [135169]
            map.insert(961, &[266241]);     // 961 => [266241]
            map.insert(146, &[528385]);     // 146 => [528385]
            map.insert(838, &[1052673]);     // 838 => [1052673]
            map.insert(227, &[2101249]);     // 227 => [2101249]
            map.insert(31, &[4198401]);     // 31 => [4198401]
            map.insert(26, &[24577]);     // 26 => [24577]
            map.insert(217, &[40961]);     // 217 => [40961]
            map.insert(552, &[73729]);     // 552 => [73729]
            map.insert(575, &[139265]);     // 575 => [139265]
            map.insert(403, &[270337]);     // 403 => [270337]
            map.insert(704, &[532481]);     // 704 => [532481]
            map.insert(276, &[1056769]);     // 276 => [1056769]
            map.insert(689, &[2105345]);     // 689 => [2105345]
            map.insert(589, &[4202497]);     // 589 => [4202497]
            map.insert(194, &[49153]);     // 194 => [49153]
            map.insert(563, &[81921]);     // 563 => [81921]
            map.insert(548, &[147457]);     // 548 => [147457]
            map.insert(392, &[278529]);     // 392 => [278529]
            map.insert(731, &[540673]);     // 731 => [540673]
            map.insert(271, &[1064961]);     // 271 => [1064961]
            map.insert(682, &[2113537]);     // 682 => [2113537]
            map.insert(598, &[4210689]);     // 598 => [4210689]
            map.insert(752, &[98305]);     // 752 => [98305]
            map.insert(743, &[163841]);     // 743 => [163841]
            map.insert(331, &[294913]);     // 331 => [294913]
            map.insert(536, &[557057]);     // 536 => [557057]
            map.insert(460, &[1081345]);     // 460 => [1081345]
            map.insert(617, &[2129921]);     // 617 => [2129921]
            map.insert(661, &[4227073]);     // 661 => [4227073]
            map.insert(22, &[196609]);     // 22 => [196609]
            map.insert(954, &[327681]);     // 954 => [327681]
            map.insert(233, &[589825]);     // 233 => [589825]
            map.insert(829, &[1114113]);     // 829 => [1114113]
            map.insert(152, &[2162689]);     // 152 => [2162689]
            map.insert(100, &[4259841]);     // 100 => [4259841]
            map.insert(941, &[393217]);     // 941 => [393217]
            map.insert(254, &[655361]);     // 254 => [655361]
            map.insert(810, &[1179649]);     // 810 => [1179649]
            map.insert(143, &[2228225]);     // 143 => [2228225]
            map.insert(115, &[4325377]);     // 115 => [4325377]
            map.insert(850, &[786433]);     // 850 => [786433]
            map.insert(134, &[1310721]);     // 134 => [1310721]
            map.insert(803, &[2359297]);     // 803 => [2359297]
            map.insert(991, &[4456449]);     // 991 => [4456449]
            map.insert(981, &[1572865]);     // 981 => [1572865]
            map.insert(112, &[2621441]);     // 112 => [2621441]
            map.insert(140, &[4718593]);     // 140 => [4718593]
            map.insert(932, &[3145729]);     // 932 => [3145729]
            map.insert(856, &[5242881]);     // 856 => [5242881]
            map.insert(253, &[6291457]);     // 253 => [6291457]
            map.insert(38, &[38]);     // 38 => [38]
            map.insert(70, &[70]);     // 70 => [70]
            map.insert(262, &[262]);     // 262 => [262]
            map.insert(518, &[1030]);     // 518 => [1030]
            map.insert(713, &[2054]);     // 713 => [2054]
            map.insert(1019, &[4102]);     // 1019 => [4102]
            map.insert(425, &[8198]);     // 425 => [8198]
            map.insert(434, &[16390]);     // 434 => [16390]
            map.insert(872, &[524294]);     // 872 => [524294]
            map.insert(793, &[2097158]);     // 793 => [2097158]
            map.insert(997, &[4194310]);     // 997 => [4194310]
            map.insert(42, &[42]);     // 42 => [42]
            map.insert(74, &[74]);     // 74 => [74]
            map.insert(138, &[138]);     // 138 => [138]
            map.insert(266, &[266]);     // 266 => [266]
            map.insert(522, &[1034]);     // 522 => [1034]
            map.insert(709, &[2058]);     // 709 => [2058]
            map.insert(1015, &[4106]);     // 1015 => [4106]
            map.insert(908, &[65546]);     // 908 => [65546]
            map.insert(923, &[131082]);     // 923 => [131082]
            map.insert(55, &[262154]);     // 55 => [262154]
            map.insert(868, &[524298]);     // 868 => [524298]
            map.insert(176, &[1048586]);     // 176 => [1048586]
            map.insert(789, &[2097162]);     // 789 => [2097162]
            map.insert(1001, &[4194314]);     // 1001 => [4194314]
            map.insert(50, &[50]);     // 50 => [50]
            map.insert(82, &[82]);     // 82 => [82]
            map.insert(274, &[274]);     // 274 => [274]
            map.insert(362, &[530]);     // 362 => [530]
            map.insert(530, &[1042]);     // 530 => [1042]
            map.insert(733, &[2066]);     // 733 => [2066]
            map.insert(357, &[32786]);     // 357 => [32786]
            map.insert(47, &[262162]);     // 47 => [262162]
            map.insert(168, &[1048594]);     // 168 => [1048594]
            map.insert(781, &[2097170]);     // 781 => [2097170]
            map.insert(1009, &[4194322]);     // 1009 => [4194322]
            map.insert(98, &[98]);     // 98 => [98]
            map.insert(162, &[162]);     // 162 => [162]
            map.insert(290, &[290]);     // 290 => [290]
            map.insert(346, &[546]);     // 346 => [546]
            map.insert(546, &[1058]);     // 546 => [1058]
            map.insert(749, &[2082]);     // 749 => [2082]
            map.insert(397, &[8226]);     // 397 => [8226]
            map.insert(406, &[16418]);     // 406 => [16418]
            map.insert(341, &[32802]);     // 341 => [32802]
            map.insert(947, &[131106]);     // 947 => [131106]
            map.insert(844, &[524322]);     // 844 => [524322]
            map.insert(322, &[322]);     // 322 => [322]
            map.insert(314, &[578]);     // 314 => [578]
            map.insert(578, &[1090]);     // 578 => [1090]
            map.insert(653, &[2114]);     // 653 => [2114]
            map.insert(959, &[4162]);     // 959 => [4162]
            map.insert(493, &[8258]);     // 493 => [8258]
            map.insert(964, &[65602]);     // 964 => [65602]
            map.insert(979, &[131138]);     // 979 => [131138]
            map.insert(127, &[262210]);     // 127 => [262210]
            map.insert(812, &[524354]);     // 812 => [524354]
            map.insert(248, &[1048642]);     // 248 => [1048642]
            map.insert(861, &[2097218]);     // 861 => [2097218]
            map.insert(929, &[4194370]);     // 929 => [4194370]
            map.insert(386, &[386]);     // 386 => [386]
            map.insert(506, &[642]);     // 506 => [642]
            map.insert(642, &[1154]);     // 642 => [1154]
            map.insert(772, &[65666]);     // 772 => [65666]
            map.insert(787, &[131202]);     // 787 => [131202]
            map.insert(925, &[2097282]);     // 925 => [2097282]
            map.insert(770, &[1282]);     // 770 => [1282]
            map.insert(973, &[2306]);     // 973 => [2306]
            map.insert(173, &[8450]);     // 173 => [8450]
            map.insert(182, &[16642]);     // 182 => [16642]
            map.insert(117, &[33026]);     // 117 => [33026]
            map.insert(659, &[131330]);     // 659 => [131330]
            map.insert(319, &[262402]);     // 319 => [262402]
            map.insert(620, &[524546]);     // 620 => [524546]
            map.insert(440, &[1048834]);     // 440 => [1048834]
            map.insert(541, &[2097410]);     // 541 => [2097410]
            map.insert(737, &[4194562]);     // 737 => [4194562]
            map.insert(213, &[8706]);     // 213 => [8706]
            map.insert(747, &[131586]);     // 747 => [131586]
            map.insert(327, &[262658]);     // 327 => [262658]
            map.insert(532, &[524802]);     // 532 => [524802]
            map.insert(448, &[1049090]);     // 448 => [1049090]
            map.insert(613, &[2097666]);     // 613 => [2097666]
            map.insert(665, &[4194818]);     // 665 => [4194818]
            map.insert(511, &[5122]);     // 511 => [5122]
            map.insert(885, &[33794]);     // 885 => [33794]
            map.insert(388, &[66562]);     // 388 => [66562]
            map.insert(364, &[525314]);     // 364 => [525314]
            map.insert(696, &[1049602]);     // 696 => [1049602]
            map.insert(285, &[2098178]);     // 285 => [2098178]
            map.insert(481, &[4195330]);     // 481 => [4195330]
            map.insert(304, &[6146]);     // 304 => [6146]
            map.insert(348, &[133122]);     // 348 => [133122]
            map.insert(419, &[526338]);     // 419 => [526338]
            map.insert(631, &[1050626]);     // 631 => [1050626]
            map.insert(466, &[2099202]);     // 466 => [2099202]
            map.insert(592, &[12290]);     // 592 => [12290]
            map.insert(587, &[20482]);     // 587 => [20482]
            map.insert(648, &[36866]);     // 648 => [36866]
            map.insert(110, &[135170]);     // 110 => [135170]
            map.insert(837, &[1052674]);     // 837 => [1052674]
            map.insert(224, &[2101250]);     // 224 => [2101250]
            map.insert(218, &[40962]);     // 218 => [40962]
            map.insert(555, &[73730]);     // 555 => [73730]
            map.insert(707, &[532482]);     // 707 => [532482]
            map.insert(279, &[1056770]);     // 279 => [1056770]
            map.insert(690, &[2105346]);     // 690 => [2105346]
            map.insert(560, &[81922]);     // 560 => [81922]
            map.insert(551, &[147458]);     // 551 => [147458]
            map.insert(395, &[278530]);     // 395 => [278530]
            map.insert(728, &[540674]);     // 728 => [540674]
            map.insert(268, &[1064962]);     // 268 => [1064962]
            map.insert(681, &[2113538]);     // 681 => [2113538]
            map.insert(597, &[4210690]);     // 597 => [4210690]
            map.insert(740, &[163842]);     // 740 => [163842]
            map.insert(539, &[557058]);     // 539 => [557058]
            map.insert(463, &[1081346]);     // 463 => [1081346]
            map.insert(618, &[2129922]);     // 618 => [2129922]
            map.insert(662, &[4227074]);     // 662 => [4227074]
            map.insert(234, &[589826]);     // 234 => [589826]
            map.insert(103, &[4259842]);     // 103 => [4259842]
            map.insert(809, &[1179650]);     // 809 => [1179650]
            map.insert(849, &[786434]);     // 849 => [786434]
            map.insert(800, &[2359298]);     // 800 => [2359298]
            map.insert(982, &[1572866]);     // 982 => [1572866]
            map.insert(859, &[5242882]);     // 859 => [5242882]
            map.insert(76, &[76]);     // 76 => [76]
            map.insert(524, &[1036]);     // 524 => [1036]
            map.insert(906, &[65548]);     // 906 => [65548]
            map.insert(84, &[84]);     // 84 => [84]
            map.insert(148, &[148]);     // 148 => [148]
            map.insert(355, &[32788]);     // 355 => [32788]
            map.insert(779, &[2097172]);     // 779 => [2097172]
            map.insert(164, &[164]);     // 164 => [164]
            map.insert(292, &[292]);     // 292 => [292]
            map.insert(985, &[4132]);     // 985 => [4132]
            map.insert(339, &[32804]);     // 339 => [32804]
            map.insert(842, &[524324]);     // 842 => [524324]
            map.insert(158, &[1048612]);     // 158 => [1048612]
            map.insert(827, &[2097188]);     // 827 => [2097188]
            map.insert(196, &[196]);     // 196 => [196]
            map.insert(580, &[1092]);     // 580 => [1092]
            map.insert(491, &[8260]);     // 491 => [8260]
            map.insert(496, &[16452]);     // 496 => [16452]
            map.insert(299, &[8324]);     // 299 => [8324]
            map.insert(499, &[32900]);     // 499 => [32900]
            map.insert(971, &[2308]);     // 971 => [2308]
            map.insert(761, &[4356]);     // 761 => [4356]
            map.insert(211, &[8708]);     // 211 => [8708]
            map.insert(200, &[16900]);     // 200 => [16900]
            map.insert(762, &[66052]);     // 762 => [66052]
            map.insert(454, &[1049092]);     // 454 => [1049092]
            map.insert(611, &[2097668]);     // 611 => [2097668]
            map.insert(671, &[4194820]);     // 671 => [4194820]
            map.insert(203, &[3076]);     // 203 => [3076]
            map.insert(939, &[9220]);     // 939 => [9220]
            map.insert(883, &[33796]);     // 883 => [33796]
            map.insert(569, &[263172]);     // 569 => [263172]
            map.insert(702, &[1049604]);     // 702 => [1049604]
            map.insert(283, &[2098180]);     // 283 => [2098180]
            map.insert(487, &[4195332]);     // 487 => [4195332]
            map.insert(333, &[67588]);     // 333 => [67588]
            map.insert(758, &[264196]);     // 758 => [264196]
            map.insert(625, &[1050628]);     // 625 => [1050628]
            map.insert(468, &[2099204]);     // 468 => [2099204]
            map.insert(296, &[4196356]);     // 296 => [4196356]
            map.insert(104, &[135172]);     // 104 => [135172]
            map.insert(151, &[528388]);     // 151 => [528388]
            map.insert(835, &[1052676]);     // 835 => [1052676]
            map.insert(230, &[2101252]);     // 230 => [2101252]
            map.insert(220, &[40964]);     // 220 => [40964]
            map.insert(557, &[73732]);     // 557 => [73732]
            map.insert(570, &[139268]);     // 570 => [139268]
            map.insert(692, &[2105348]);     // 692 => [2105348]
            map.insert(199, &[49156]);     // 199 => [49156]
            map.insert(566, &[81924]);     // 566 => [81924]
            map.insert(687, &[2113540]);     // 687 => [2113540]
            map.insert(757, &[98308]);     // 757 => [98308]
            map.insert(334, &[294916]);     // 334 => [294916]
            map.insert(457, &[1081348]);     // 457 => [1081348]
            map.insert(236, &[589828]);     // 236 => [589828]
            map.insert(824, &[1114116]);     // 824 => [1114116]
            map.insert(157, &[2162692]);     // 157 => [2162692]
            map.insert(936, &[393220]);     // 936 => [393220]
            map.insert(855, &[786436]);     // 855 => [786436]
            map.insert(806, &[2359300]);     // 806 => [2359300]
            map.insert(986, &[4456452]);     // 986 => [4456452]
            map.insert(88, &[88]);     // 88 => [88]
            map.insert(280, &[280]);     // 280 => [280]
            map.insert(352, &[536]);     // 352 => [536]
            map.insert(727, &[2072]);     // 727 => [2072]
            map.insert(905, &[131096]);     // 905 => [131096]
            map.insert(336, &[552]);     // 336 => [552]
            map.insert(412, &[16424]);     // 412 => [16424]
            map.insert(823, &[2097192]);     // 823 => [2097192]
            map.insert(242, &[1048648]);     // 242 => [1048648]
            map.insert(583, &[2184]);     // 583 => [2184]
            map.insert(295, &[8328]);     // 295 => [8328]
            map.insert(776, &[1288]);     // 776 => [1288]
            map.insert(167, &[8456]);     // 167 => [8456]
            map.insert(880, &[1544]);     // 880 => [1544]
            map.insert(223, &[8712]);     // 223 => [8712]
            map.insert(458, &[1049096]);     // 458 => [1049096]
            map.insert(409, &[132104]);     // 409 => [132104]
            map.insert(565, &[263176]);     // 565 => [263176]
            map.insert(637, &[1050632]);     // 637 => [1050632]
            map.insert(472, &[2099208]);     // 472 => [2099208]
            map.insert(602, &[12296]);     // 602 => [12296]
            map.insert(968, &[266248]);     // 968 => [266248]
            map.insert(208, &[40968]);     // 208 => [40968]
            map.insert(410, &[270344]);     // 410 => [270344]
            map.insert(722, &[540680]);     // 722 => [540680]
            map.insert(675, &[2113544]);     // 675 => [2113544]
            map.insert(607, &[4210696]);     // 607 => [4210696]
            map.insert(453, &[1081352]);     // 453 => [1081352]
            map.insert(608, &[2129928]);     // 608 => [2129928]
            map.insert(668, &[4227080]);     // 668 => [4227080]
            map.insert(820, &[1114120]);     // 820 => [1114120]
            map.insert(247, &[655368]);     // 247 => [655368]
            map.insert(244, &[6291464]);     // 244 => [6291464]
            map.insert(415, &[8240]);     // 415 => [8240]
            map.insert(484, &[16464]);     // 484 => [16464]
            map.insert(488, &[656]);     // 488 => [656]
            map.insert(638, &[524560]);     // 638 => [524560]
            map.insert(527, &[2097424]);     // 527 => [2097424]
            map.insert(601, &[20496]);     // 601 => [20496]
            map.insert(107, &[69648]);     // 107 => [69648]
            map.insert(558, &[139280]);     // 558 => [139280]
            map.insert(721, &[532496]);     // 721 => [532496]
            map.insert(672, &[2105360]);     // 672 => [2105360]
            map.insert(604, &[4202512]);     // 604 => [4202512]
            map.insert(477, &[1081360]);     // 477 => [1081360]
            map.insert(632, &[2129936]);     // 632 => [2129936]
            map.insert(239, &[655376]);     // 239 => [655376]
            map.insert(818, &[2359312]);     // 818 => [2359312]
            map.insert(841, &[5242896]);     // 841 => [5242896]
            map.insert(93, &[262240]);     // 93 => [262240]
            map.insert(471, &[32928]);     // 471 => [32928]
            map.insert(817, &[131232]);     // 817 => [131232]
            map.insert(87, &[33056]);     // 87 => [33056]
            map.insert(678, &[65824]);     // 678 => [65824]
            map.insert(677, &[4640]);     // 677 => [4640]
            map.insert(832, &[10272]);     // 832 => [10272]
            map.insert(626, &[12320]);     // 626 => [12320]
            map.insert(91, &[69664]);     // 91 => [69664]
            map.insert(701, &[4416]);     // 701 => [4416]
            map.insert(79, &[33344]);     // 79 => [33344]
            map.insert(94, &[4198464]);     // 94 => [4198464]
            map.insert(724, &[4227136]);     // 724 => [4227136]
            map.insert(478, &[133248]);     // 478 => [133248]
            map.insert(229, &[4259968]);     // 229 => [4259968]
            map.insert(852, &[1572992]);     // 852 => [1572992]
            map.insert(241, &[2621568]);     // 241 => [2621568]
            map.insert(805, &[3145856]);     // 805 => [3145856]
            map.insert(695, &[2816]);     // 695 => [2816]
            map.insert(635, &[18688]);     // 635 => [18688]
            map.insert(684, &[393472]);     // 684 => [393472]
            map.insert(39, &[39]);     // 39 => [39]
            map.insert(71, &[71]);     // 71 => [71]
            map.insert(263, &[263]);     // 263 => [263]
            map.insert(519, &[1031]);     // 519 => [1031]
            map.insert(712, &[2055]);     // 712 => [2055]
            map.insert(1018, &[4103]);     // 1018 => [4103]
            map.insert(424, &[8199]);     // 424 => [8199]
            map.insert(435, &[16391]);     // 435 => [16391]
            map.insert(873, &[524295]);     // 873 => [524295]
            map.insert(792, &[2097159]);     // 792 => [2097159]
            map.insert(996, &[4194311]);     // 996 => [4194311]
            map.insert(43, &[43]);     // 43 => [43]
            map.insert(75, &[75]);     // 75 => [75]
            map.insert(139, &[139]);     // 139 => [139]
            map.insert(267, &[267]);     // 267 => [267]
            map.insert(523, &[1035]);     // 523 => [1035]
            map.insert(708, &[2059]);     // 708 => [2059]
            map.insert(1014, &[4107]);     // 1014 => [4107]
            map.insert(909, &[65547]);     // 909 => [65547]
            map.insert(922, &[131083]);     // 922 => [131083]
            map.insert(54, &[262155]);     // 54 => [262155]
            map.insert(869, &[524299]);     // 869 => [524299]
            map.insert(177, &[1048587]);     // 177 => [1048587]
            map.insert(788, &[2097163]);     // 788 => [2097163]
            map.insert(1000, &[4194315]);     // 1000 => [4194315]
            map.insert(51, &[51]);     // 51 => [51]
            map.insert(83, &[83]);     // 83 => [83]
            map.insert(275, &[275]);     // 275 => [275]
            map.insert(363, &[531]);     // 363 => [531]
            map.insert(531, &[1043]);     // 531 => [1043]
            map.insert(732, &[2067]);     // 732 => [2067]
            map.insert(356, &[32787]);     // 356 => [32787]
            map.insert(46, &[262163]);     // 46 => [262163]
            map.insert(169, &[1048595]);     // 169 => [1048595]
            map.insert(780, &[2097171]);     // 780 => [2097171]
            map.insert(1008, &[4194323]);     // 1008 => [4194323]
            map.insert(99, &[99]);     // 99 => [99]
            map.insert(163, &[163]);     // 163 => [163]
            map.insert(291, &[291]);     // 291 => [291]
            map.insert(347, &[547]);     // 347 => [547]
            map.insert(547, &[1059]);     // 547 => [1059]
            map.insert(748, &[2083]);     // 748 => [2083]
            map.insert(396, &[8227]);     // 396 => [8227]
            map.insert(407, &[16419]);     // 407 => [16419]
            map.insert(340, &[32803]);     // 340 => [32803]
            map.insert(946, &[131107]);     // 946 => [131107]
            map.insert(845, &[524323]);     // 845 => [524323]
            map.insert(323, &[323]);     // 323 => [323]
            map.insert(315, &[579]);     // 315 => [579]
            map.insert(579, &[1091]);     // 579 => [1091]
            map.insert(652, &[2115]);     // 652 => [2115]
            map.insert(958, &[4163]);     // 958 => [4163]
            map.insert(492, &[8259]);     // 492 => [8259]
            map.insert(965, &[65603]);     // 965 => [65603]
            map.insert(978, &[131139]);     // 978 => [131139]
            map.insert(126, &[262211]);     // 126 => [262211]
            map.insert(813, &[524355]);     // 813 => [524355]
            map.insert(249, &[1048643]);     // 249 => [1048643]
            map.insert(860, &[2097219]);     // 860 => [2097219]
            map.insert(928, &[4194371]);     // 928 => [4194371]
            map.insert(387, &[387]);     // 387 => [387]
            map.insert(507, &[643]);     // 507 => [643]
            map.insert(643, &[1155]);     // 643 => [1155]
            map.insert(773, &[65667]);     // 773 => [65667]
            map.insert(786, &[131203]);     // 786 => [131203]
            map.insert(924, &[2097283]);     // 924 => [2097283]
            map.insert(771, &[1283]);     // 771 => [1283]
            map.insert(972, &[2307]);     // 972 => [2307]
            map.insert(172, &[8451]);     // 172 => [8451]
            map.insert(183, &[16643]);     // 183 => [16643]
            map.insert(116, &[33027]);     // 116 => [33027]
            map.insert(658, &[131331]);     // 658 => [131331]
            map.insert(318, &[262403]);     // 318 => [262403]
            map.insert(621, &[524547]);     // 621 => [524547]
            map.insert(441, &[1048835]);     // 441 => [1048835]
            map.insert(540, &[2097411]);     // 540 => [2097411]
            map.insert(736, &[4194563]);     // 736 => [4194563]
            map.insert(212, &[8707]);     // 212 => [8707]
            map.insert(746, &[131587]);     // 746 => [131587]
            map.insert(326, &[262659]);     // 326 => [262659]
            map.insert(533, &[524803]);     // 533 => [524803]
            map.insert(449, &[1049091]);     // 449 => [1049091]
            map.insert(612, &[2097667]);     // 612 => [2097667]
            map.insert(664, &[4194819]);     // 664 => [4194819]
            map.insert(510, &[5123]);     // 510 => [5123]
            map.insert(884, &[33795]);     // 884 => [33795]
            map.insert(389, &[66563]);     // 389 => [66563]
            map.insert(365, &[525315]);     // 365 => [525315]
            map.insert(697, &[1049603]);     // 697 => [1049603]
            map.insert(284, &[2098179]);     // 284 => [2098179]
            map.insert(480, &[4195331]);     // 480 => [4195331]
            map.insert(305, &[6147]);     // 305 => [6147]
            map.insert(349, &[133123]);     // 349 => [133123]
            map.insert(418, &[526339]);     // 418 => [526339]
            map.insert(630, &[1050627]);     // 630 => [1050627]
            map.insert(467, &[2099203]);     // 467 => [2099203]
            map.insert(593, &[12291]);     // 593 => [12291]
            map.insert(586, &[20483]);     // 586 => [20483]
            map.insert(649, &[36867]);     // 649 => [36867]
            map.insert(111, &[135171]);     // 111 => [135171]
            map.insert(836, &[1052675]);     // 836 => [1052675]
            map.insert(225, &[2101251]);     // 225 => [2101251]
            map.insert(219, &[40963]);     // 219 => [40963]
            map.insert(554, &[73731]);     // 554 => [73731]
            map.insert(706, &[532483]);     // 706 => [532483]
            map.insert(278, &[1056771]);     // 278 => [1056771]
            map.insert(691, &[2105347]);     // 691 => [2105347]
            map.insert(561, &[81923]);     // 561 => [81923]
            map.insert(550, &[147459]);     // 550 => [147459]
            map.insert(394, &[278531]);     // 394 => [278531]
            map.insert(729, &[540675]);     // 729 => [540675]
            map.insert(269, &[1064963]);     // 269 => [1064963]
            map.insert(680, &[2113539]);     // 680 => [2113539]
            map.insert(596, &[4210691]);     // 596 => [4210691]
            map.insert(741, &[163843]);     // 741 => [163843]
            map.insert(538, &[557059]);     // 538 => [557059]
            map.insert(462, &[1081347]);     // 462 => [1081347]
            map.insert(619, &[2129923]);     // 619 => [2129923]
            map.insert(663, &[4227075]);     // 663 => [4227075]
            map.insert(235, &[589827]);     // 235 => [589827]
            map.insert(102, &[4259843]);     // 102 => [4259843]
            map.insert(808, &[1179651]);     // 808 => [1179651]
            map.insert(848, &[786435]);     // 848 => [786435]
            map.insert(801, &[2359299]);     // 801 => [2359299]
            map.insert(983, &[1572867]);     // 983 => [1572867]
            map.insert(858, &[5242883]);     // 858 => [5242883]
            map.insert(77, &[77]);     // 77 => [77]
            map.insert(525, &[1037]);     // 525 => [1037]
            map.insert(907, &[65549]);     // 907 => [65549]
            map.insert(85, &[85]);     // 85 => [85]
            map.insert(149, &[149]);     // 149 => [149]
            map.insert(354, &[32789]);     // 354 => [32789]
            map.insert(778, &[2097173]);     // 778 => [2097173]
            map.insert(165, &[165]);     // 165 => [165]
            map.insert(293, &[293]);     // 293 => [293]
            map.insert(984, &[4133]);     // 984 => [4133]
            map.insert(338, &[32805]);     // 338 => [32805]
            map.insert(843, &[524325]);     // 843 => [524325]
            map.insert(159, &[1048613]);     // 159 => [1048613]
            map.insert(826, &[2097189]);     // 826 => [2097189]
            map.insert(197, &[197]);     // 197 => [197]
            map.insert(581, &[1093]);     // 581 => [1093]
            map.insert(490, &[8261]);     // 490 => [8261]
            map.insert(497, &[16453]);     // 497 => [16453]
            map.insert(298, &[8325]);     // 298 => [8325]
            map.insert(498, &[32901]);     // 498 => [32901]
            map.insert(970, &[2309]);     // 970 => [2309]
            map.insert(760, &[4357]);     // 760 => [4357]
            map.insert(210, &[8709]);     // 210 => [8709]
            map.insert(201, &[16901]);     // 201 => [16901]
            map.insert(763, &[66053]);     // 763 => [66053]
            map.insert(455, &[1049093]);     // 455 => [1049093]
            map.insert(610, &[2097669]);     // 610 => [2097669]
            map.insert(670, &[4194821]);     // 670 => [4194821]
            map.insert(202, &[3077]);     // 202 => [3077]
            map.insert(938, &[9221]);     // 938 => [9221]
            map.insert(882, &[33797]);     // 882 => [33797]
            map.insert(568, &[263173]);     // 568 => [263173]
            map.insert(703, &[1049605]);     // 703 => [1049605]
            map.insert(282, &[2098181]);     // 282 => [2098181]
            map.insert(486, &[4195333]);     // 486 => [4195333]
            map.insert(332, &[67589]);     // 332 => [67589]
            map.insert(759, &[264197]);     // 759 => [264197]
            map.insert(624, &[1050629]);     // 624 => [1050629]
            map.insert(469, &[2099205]);     // 469 => [2099205]
            map.insert(297, &[4196357]);     // 297 => [4196357]
            map.insert(105, &[135173]);     // 105 => [135173]
            map.insert(150, &[528389]);     // 150 => [528389]
            map.insert(834, &[1052677]);     // 834 => [1052677]
            map.insert(231, &[2101253]);     // 231 => [2101253]
            map.insert(221, &[40965]);     // 221 => [40965]
            map.insert(556, &[73733]);     // 556 => [73733]
            map.insert(571, &[139269]);     // 571 => [139269]
            map.insert(693, &[2105349]);     // 693 => [2105349]
            map.insert(198, &[49157]);     // 198 => [49157]
            map.insert(567, &[81925]);     // 567 => [81925]
            map.insert(686, &[2113541]);     // 686 => [2113541]
            map.insert(756, &[98309]);     // 756 => [98309]
            map.insert(335, &[294917]);     // 335 => [294917]
            map.insert(456, &[1081349]);     // 456 => [1081349]
            map.insert(237, &[589829]);     // 237 => [589829]
            map.insert(825, &[1114117]);     // 825 => [1114117]
            map.insert(156, &[2162693]);     // 156 => [2162693]
            map.insert(937, &[393221]);     // 937 => [393221]
            map.insert(854, &[786437]);     // 854 => [786437]
            map.insert(807, &[2359301]);     // 807 => [2359301]
            map.insert(987, &[4456453]);     // 987 => [4456453]
            map.insert(89, &[89]);     // 89 => [89]
            map.insert(281, &[281]);     // 281 => [281]
            map.insert(353, &[537]);     // 353 => [537]
            map.insert(726, &[2073]);     // 726 => [2073]
            map.insert(904, &[131097]);     // 904 => [131097]
            map.insert(337, &[553]);     // 337 => [553]
            map.insert(413, &[16425]);     // 413 => [16425]
            map.insert(822, &[2097193]);     // 822 => [2097193]
            map.insert(243, &[1048649]);     // 243 => [1048649]
            map.insert(582, &[2185]);     // 582 => [2185]
            map.insert(294, &[8329]);     // 294 => [8329]
            map.insert(777, &[1289]);     // 777 => [1289]
            map.insert(166, &[8457]);     // 166 => [8457]
            map.insert(881, &[1545]);     // 881 => [1545]
            map.insert(222, &[8713]);     // 222 => [8713]
            map.insert(459, &[1049097]);     // 459 => [1049097]
            map.insert(408, &[132105]);     // 408 => [132105]
            map.insert(564, &[263177]);     // 564 => [263177]
            map.insert(636, &[1050633]);     // 636 => [1050633]
            map.insert(473, &[2099209]);     // 473 => [2099209]
            map.insert(603, &[12297]);     // 603 => [12297]
            map.insert(969, &[266249]);     // 969 => [266249]
            map.insert(209, &[40969]);     // 209 => [40969]
            map.insert(411, &[270345]);     // 411 => [270345]
            map.insert(723, &[540681]);     // 723 => [540681]
            map.insert(674, &[2113545]);     // 674 => [2113545]
            map.insert(606, &[4210697]);     // 606 => [4210697]
            map.insert(452, &[1081353]);     // 452 => [1081353]
            map.insert(609, &[2129929]);     // 609 => [2129929]
            map.insert(669, &[4227081]);     // 669 => [4227081]
            map.insert(821, &[1114121]);     // 821 => [1114121]
            map.insert(246, &[655369]);     // 246 => [655369]
            map.insert(245, &[6291465]);     // 245 => [6291465]
            map.insert(414, &[8241]);     // 414 => [8241]
            map.insert(485, &[16465]);     // 485 => [16465]
            map.insert(489, &[657]);     // 489 => [657]
            map.insert(639, &[524561]);     // 639 => [524561]
            map.insert(526, &[2097425]);     // 526 => [2097425]
            map.insert(600, &[20497]);     // 600 => [20497]
            map.insert(106, &[69649]);     // 106 => [69649]
            map.insert(559, &[139281]);     // 559 => [139281]
            map.insert(720, &[532497]);     // 720 => [532497]
            map.insert(673, &[2105361]);     // 673 => [2105361]
            map.insert(605, &[4202513]);     // 605 => [4202513]
            map.insert(476, &[1081361]);     // 476 => [1081361]
            map.insert(633, &[2129937]);     // 633 => [2129937]
            map.insert(238, &[655377]);     // 238 => [655377]
            map.insert(819, &[2359313]);     // 819 => [2359313]
            map.insert(840, &[5242897]);     // 840 => [5242897]
            map.insert(92, &[262241]);     // 92 => [262241]
            map.insert(470, &[32929]);     // 470 => [32929]
            map.insert(816, &[131233]);     // 816 => [131233]
            map.insert(86, &[33057]);     // 86 => [33057]
            map.insert(679, &[65825]);     // 679 => [65825]
            map.insert(676, &[4641]);     // 676 => [4641]
            map.insert(833, &[10273]);     // 833 => [10273]
            map.insert(627, &[12321]);     // 627 => [12321]
            map.insert(90, &[69665]);     // 90 => [69665]
            map.insert(700, &[4417]);     // 700 => [4417]
            map.insert(78, &[33345]);     // 78 => [33345]
            map.insert(95, &[4198465]);     // 95 => [4198465]
            map.insert(725, &[4227137]);     // 725 => [4227137]
            map.insert(479, &[133249]);     // 479 => [133249]
            map.insert(228, &[4259969]);     // 228 => [4259969]
            map.insert(853, &[1572993]);     // 853 => [1572993]
            map.insert(240, &[2621569]);     // 240 => [2621569]
            map.insert(804, &[3145857]);     // 804 => [3145857]
            map.insert(694, &[2817]);     // 694 => [2817]
            map.insert(634, &[18689]);     // 634 => [18689]
            map.insert(685, &[393473]);     // 685 => [393473]
            map.insert(474, &[2099210]);     // 474 => [2099210]
            map.insert(475, &[2099211]);     // 475 => [2099211]
            
            SYNDROME_MAP = Box::into_raw(map);
        }
    });
}

impl GuavaCode23_13 {
    fn parity_check_matrix_transposed(&self) -> &BinMatrix {
        init();
        unsafe {
            PARITY_MATRIX_T.as_ref().unwrap()
        }
    }
}

impl BinaryCode for GuavaCode23_13 {
    fn name(&self) -> String {
        "[23, 13] Guava code".to_owned()
    }

    fn length(&self) -> usize {
        23
    }

    fn dimension(&self) -> usize {
        13
    }

    fn generator_matrix(&self) -> &BinMatrix {
        init();
        unsafe {
            GENERATOR_MATRIX.as_ref().unwrap()
        }
    }

    fn parity_check_matrix(&self) -> &BinMatrix {
        init();
        unsafe {
            PARITY_MATRIX.as_ref().unwrap()
        }
    }

    fn decode_to_code(&self, c: &BinVector) -> Result<BinVector, &str> {
        init();
        let map = unsafe {
            SYNDROME_MAP.as_ref().unwrap()
        };
        debug_assert_eq!(c.len(), self.length(), "the length doesn't match the expected length (length of the code)");
        let he = c * self.parity_check_matrix_transposed();
        let mut error = BinVector::with_capacity(23);
        let stor = unsafe { error.get_storage_mut() };
        let errbytes = map[&he.as_u64()];
        debug_assert_eq!(errbytes.len(), 23 / 64 + if 23 % 64 != 0 { 1 } else { 0 });
        stor.clear();
        stor.extend_from_slice(&errbytes[..]);
        unsafe { error.set_len(23) };
        debug_assert_eq!(error.len(), self.length(), "internal: the error vector is of the wrong length");
        let result = c + &error;
        debug_assert_eq!(result.len(), self.length(), "internal: the result vector is of the wrong length");
        debug_assert_eq!((&result * self.parity_check_matrix_transposed()).count_ones(), 0);
        Ok(result)
    }

    fn decode_to_message(&self, c: &BinVector) -> Result<BinVector, &str> {
        
        let mut codeword = self.decode_to_code(c)?;
        codeword.truncate(13);
        Ok(codeword)
        
    }

    fn decode_slice(&self, c: &mut [u64]) {
        init();
        
        debug_assert_eq!(c[23 / 64] & !((1 << 23) - 1), 0, "this message has excess bits");

        let map = unsafe {
            SYNDROME_MAP.as_ref().unwrap()
        };
        let he = &BinMatrix::from_slices(&[&c[..]], self.length()) * self.parity_check_matrix_transposed();
        let error = map[unsafe { &he.get_word_unchecked(0, 0) }];
        c.iter_mut().zip(error.iter().copied()).for_each(|(sample, error)| *sample ^= error as u64);
    }

    
}

#[cfg(test)]
mod tests {
    use super::*;
    use m4ri_rust::friendly::BinVector;
    use crate::oracle::Sample;

    #[test]
    fn size() {
        let code = GuavaCode23_13.generator_matrix();
        assert_eq!(code.ncols(), 23);
        assert_eq!(code.nrows(), 13);
    }

    #[test]
    fn test_decode_sample() {
        let code = GuavaCode23_13;
        for _ in 0..1000 {
            // setup
            let vec = BinVector::random(code.length());
            let mut sample_a = Sample::from_binvector(&vec, false);
            let mut sample_b = Sample::from_binvector(&vec, true);
            
            let decoded_vec = code.decode_to_message(&vec).unwrap();
            println!("decoded_vec: {:?}", decoded_vec);

            // test vectors
            let decoded_vec_sample_a = Sample::from_binvector(&decoded_vec, false);
            let decoded_vec_sample_b = Sample::from_binvector(&decoded_vec, true);

            code.decode_sample(&mut sample_a);
            code.decode_sample(&mut sample_b);
            assert_eq!(sample_a.get_product(), false);
            assert_eq!(sample_b.get_product(), true);
            assert_eq!(sample_a, decoded_vec_sample_a);
            assert_eq!(sample_b, decoded_vec_sample_b);
        }
    }

    #[test]
    fn random_decode_tests() {

        
        {
            let code = GuavaCode23_13;
            let randvec = BinVector::from_bools(&[true, false, false, true, true, true, false, false, false, true, true, false, true, false, false, true, true, false, false, true, false, false, false]);
            let codeword = BinVector::from_bools(&[false, true, false, true, true, false, false, false, true, true, true, false, true, false, false, true, true, false, false, true, false, false, false]);
            assert_eq!(code.decode_to_code(&randvec), Ok(codeword));
        }
        
        {
            let code = GuavaCode23_13;
            let randvec = BinVector::from_bools(&[true, false, true, false, false, false, true, false, true, false, false, true, false, false, false, true, true, true, false, false, false, true, true]);
            let codeword = BinVector::from_bools(&[true, false, true, false, false, false, true, false, true, true, false, true, false, false, false, true, true, true, false, true, false, true, true]);
            assert_eq!(code.decode_to_code(&randvec), Ok(codeword));
        }
        
        {
            let code = GuavaCode23_13;
            let randvec = BinVector::from_bools(&[true, true, true, true, false, true, false, false, false, true, false, false, true, true, false, true, false, false, true, false, false, true, false]);
            let codeword = BinVector::from_bools(&[true, true, true, false, false, false, false, false, false, false, false, false, true, true, false, true, false, false, true, false, false, true, false]);
            assert_eq!(code.decode_to_code(&randvec), Ok(codeword));
        }
        
        {
            let code = GuavaCode23_13;
            let randvec = BinVector::from_bools(&[false, false, false, false, true, true, false, false, true, false, true, true, false, true, true, true, true, false, false, false, true, false, false]);
            let codeword = BinVector::from_bools(&[false, false, false, false, true, true, false, false, true, false, false, true, false, false, true, true, true, false, false, false, true, false, false]);
            assert_eq!(code.decode_to_code(&randvec), Ok(codeword));
        }
        
        {
            let code = GuavaCode23_13;
            let randvec = BinVector::from_bools(&[true, false, true, false, true, true, true, true, false, false, false, true, true, false, false, true, true, false, true, true, false, true, false]);
            let codeword = BinVector::from_bools(&[false, false, true, false, true, true, true, true, false, false, false, false, true, false, true, true, true, false, true, true, false, true, false]);
            assert_eq!(code.decode_to_code(&randvec), Ok(codeword));
        }
        
        {
            let code = GuavaCode23_13;
            let randvec = BinVector::from_bools(&[true, true, true, true, true, false, false, false, false, true, false, true, true, false, false, false, true, false, false, false, true, true, true]);
            let codeword = BinVector::from_bools(&[true, true, false, true, true, false, false, false, false, true, false, true, true, false, false, false, true, true, false, false, true, true, true]);
            assert_eq!(code.decode_to_code(&randvec), Ok(codeword));
        }
        
        {
            let code = GuavaCode23_13;
            let randvec = BinVector::from_bools(&[true, true, false, false, true, true, false, false, false, true, false, true, true, true, false, false, false, true, false, true, true, true, true]);
            let codeword = BinVector::from_bools(&[false, true, false, false, true, true, false, false, false, true, true, true, true, true, false, false, false, true, false, false, true, true, true]);
            assert_eq!(code.decode_to_code(&randvec), Ok(codeword));
        }
        
        {
            let code = GuavaCode23_13;
            let randvec = BinVector::from_bools(&[true, false, false, true, true, false, true, false, false, false, true, false, false, false, true, false, true, false, true, true, true, false, false]);
            let codeword = BinVector::from_bools(&[true, false, true, true, true, false, true, false, false, false, true, false, false, false, true, false, false, false, true, true, true, false, false]);
            assert_eq!(code.decode_to_code(&randvec), Ok(codeword));
        }
        
        {
            let code = GuavaCode23_13;
            let randvec = BinVector::from_bools(&[true, true, false, true, false, true, true, true, false, false, false, false, false, false, false, false, false, false, true, true, false, false, false]);
            let codeword = BinVector::from_bools(&[true, true, false, true, false, true, true, true, false, false, false, true, false, false, false, true, false, false, true, true, false, false, false]);
            assert_eq!(code.decode_to_code(&randvec), Ok(codeword));
        }
        
        {
            let code = GuavaCode23_13;
            let randvec = BinVector::from_bools(&[false, false, false, true, false, false, false, false, true, false, false, false, true, true, false, false, true, true, false, false, true, false, true]);
            let codeword = BinVector::from_bools(&[false, false, true, true, true, false, false, false, true, false, false, false, true, true, false, false, true, true, false, false, true, false, true]);
            assert_eq!(code.decode_to_code(&randvec), Ok(codeword));
        }
        
        {
            let code = GuavaCode23_13;
            let randvec = BinVector::from_bools(&[true, true, true, true, false, true, true, true, false, false, true, false, false, true, false, true, false, true, true, false, false, true, false]);
            let codeword = BinVector::from_bools(&[false, true, true, true, false, true, true, true, false, true, true, false, true, true, false, true, false, true, true, false, false, true, false]);
            assert_eq!(code.decode_to_code(&randvec), Ok(codeword));
        }
        
        {
            let code = GuavaCode23_13;
            let randvec = BinVector::from_bools(&[false, true, true, true, false, false, true, true, false, true, false, false, false, true, true, true, false, true, true, true, true, false, false]);
            let codeword = BinVector::from_bools(&[false, false, true, true, false, true, true, false, false, true, false, false, false, true, true, true, false, true, true, true, true, false, false]);
            assert_eq!(code.decode_to_code(&randvec), Ok(codeword));
        }
        
        {
            let code = GuavaCode23_13;
            let randvec = BinVector::from_bools(&[false, false, false, false, false, false, false, false, true, false, true, false, false, false, true, false, false, false, true, true, true, false, false]);
            let codeword = BinVector::from_bools(&[true, true, false, false, false, false, false, false, true, false, true, true, false, false, true, false, false, true, true, true, true, false, false]);
            assert_eq!(code.decode_to_code(&randvec), Ok(codeword));
        }
        
        {
            let code = GuavaCode23_13;
            let randvec = BinVector::from_bools(&[true, true, false, true, false, true, true, true, true, false, true, true, false, true, false, false, false, false, false, true, false, false, false]);
            let codeword = BinVector::from_bools(&[true, false, true, true, false, true, true, true, true, false, true, true, false, true, false, false, false, false, false, true, false, false, true]);
            assert_eq!(code.decode_to_code(&randvec), Ok(codeword));
        }
        
        {
            let code = GuavaCode23_13;
            let randvec = BinVector::from_bools(&[false, false, true, true, true, true, false, true, false, false, false, false, true, true, false, true, true, false, false, true, false, false, false]);
            let codeword = BinVector::from_bools(&[true, false, true, false, true, true, false, true, false, true, true, false, true, true, false, true, true, false, false, true, false, false, false]);
            assert_eq!(code.decode_to_code(&randvec), Ok(codeword));
        }
        
        {
            let code = GuavaCode23_13;
            let randvec = BinVector::from_bools(&[false, false, true, true, false, true, false, true, true, true, false, false, true, false, true, true, true, true, true, true, false, true, true]);
            let codeword = BinVector::from_bools(&[false, true, true, true, true, true, true, true, true, true, false, false, true, false, true, true, true, true, true, true, false, true, true]);
            assert_eq!(code.decode_to_code(&randvec), Ok(codeword));
        }
        
        {
            let code = GuavaCode23_13;
            let randvec = BinVector::from_bools(&[true, false, true, true, true, false, true, true, true, false, false, true, true, false, false, false, false, true, true, true, false, true, false]);
            let codeword = BinVector::from_bools(&[true, false, true, true, false, false, true, true, true, false, false, true, true, false, false, false, false, true, false, true, false, false, false]);
            assert_eq!(code.decode_to_code(&randvec), Ok(codeword));
        }
        
        {
            let code = GuavaCode23_13;
            let randvec = BinVector::from_bools(&[true, false, true, false, true, true, false, true, true, false, false, false, true, true, false, false, false, true, false, true, true, true, true]);
            let codeword = BinVector::from_bools(&[false, false, true, false, true, true, true, true, true, false, false, false, true, true, false, false, false, true, false, true, true, false, true]);
            assert_eq!(code.decode_to_code(&randvec), Ok(codeword));
        }
        
        {
            let code = GuavaCode23_13;
            let randvec = BinVector::from_bools(&[false, false, true, true, false, false, false, false, true, false, false, true, false, false, true, false, false, true, false, true, true, true, false]);
            let codeword = BinVector::from_bools(&[true, false, true, true, false, false, false, false, true, false, false, false, false, false, true, false, false, true, false, true, true, true, true]);
            assert_eq!(code.decode_to_code(&randvec), Ok(codeword));
        }
        
        {
            let code = GuavaCode23_13;
            let randvec = BinVector::from_bools(&[false, false, true, false, true, false, false, true, false, false, false, false, false, true, true, false, false, true, false, true, false, false, true]);
            let codeword = BinVector::from_bools(&[false, true, true, false, true, false, false, true, false, false, false, false, false, true, true, false, false, false, false, true, false, false, true]);
            assert_eq!(code.decode_to_code(&randvec), Ok(codeword));
        }
        
    }

    #[test]
    fn test_generator_representation() {
        init();
        let generator_matrix = unsafe { GENERATOR_MATRIX.as_ref().unwrap() };
        let first_row = generator_matrix.get_window(0, 0, 1, generator_matrix.ncols());
        let vector = BinVector::from_bools(&[ true, false, false, false, false, false, false, false, false, false, false, false, false, false, true, true, false, true, true, true, false, false, false ]);
        assert_eq!(vector, first_row.as_vector());
    }

}