1 #target WASI
3 Function noMoreFreeMemory() Which Returns Nothing Is External;
4 Function segmentationFault() Which Returns Nothing Is External;
5 Function
6 printString(PointerToCharacter string) Which Returns Nothing Is External;
7 Function clearScreen() Which Returns Nothing Is External;
8 Function getLengthOfTheInput() Which Returns Integer16 Is External;
9 Function
10 getCharacterOfTheInput(Integer16 index) Which Returns Character Is External;
11 Function setDiagramWidth(Integer32 width) Which Returns Nothing Is External;
12 Function setDiagramHeight(Integer32 height) Which Returns Nothing Is External;
13 Function drawLine(Integer32 x1, Integer32 y1, Integer32 x2,
14 Integer32 y2) Which Returns Nothing Is External;
15 Function drawRectangle(Integer32 x, Integer32 y, Integer32 width,
16 Integer32 height) Which Returns Nothing Is External;
17 Function drawText(Integer32 x, Integer32 y,
18 PointerToCharacter text) Which Returns Nothing Is External;
19
20 Integer32 NDEBUG := 1,
21 MAINTAIN_COMPATIBILITY_WITH_JAVASCRIPT_IMPLEMENTATION := 1;
22
25 Structure TreeNode Consists Of
26 Character character;
27 Integer16 frequencyOfCharacter;
28 PointerToTreeNode leftChild, rightChild;
29 Character code[16];
30 Integer32 x, y;
31 EndStructure
32
33 InstantiateStructure TreeNode treeNodes[64];
34 Integer16 isTreeNodeUsed[64];
35
36 Function isTreeNodeWithinBounds(
37 PointerToTreeNode treeNode) Which Returns Integer32 Does
38 Return AddressOf(treeNodes[0]) <= treeNode <= AddressOf(treeNodes[64 - 1]) and
39 mod(treeNode - AddressOf(treeNodes[0]), SizeOf(TreeNode)) =
40 0; EndFunction
43
44 Function
45 convertIntegerToString(PointerToCharacter string,
46 Integer32 integer) Which Returns Nothing Is Declared;
47 Function appendIntegerToString(PointerToCharacter string, Integer32 integer)
48 Which Returns Nothing Is Declared;
49 Function strcat(PointerToCharacter dest,
50 PointerToCharacter src) Which Returns Nothing Is Declared;
51 Function strlen(PointerToCharacter string) Which Returns Integer32 Is Declared;
52
53 Function newTreeNode() Which Returns PointerToTreeNode Does
54 Integer16 i := 0;
55 While i < 64 Loop
56 If not(isTreeNodeUsed[i]) Then
57 treeNodes[i].character := 0;
58 treeNodes[i].leftChild := treeNodes[i].rightChild
59 := PointerToTreeNode(0);
60 treeNodes[i].code[0] := 0;
61 treeNodes[i].frequencyOfCharacter := 0;
62 isTreeNodeUsed[i] := 1;
63 If NDEBUG = 0 Then
64 Character stringToBePrinted[64] := {0};
65 strcat(AddressOf(stringToBePrinted[0]),
66 "NDEBUG: Allocating the TreeNode #");
67 appendIntegerToString(AddressOf(stringToBePrinted[0]),
68 i);
69 strcat(AddressOf(stringToBePrinted[0]), "\n");
70 printString(AddressOf(stringToBePrinted[0]));
71 EndIf
72 Return AddressOf(treeNodes[i]);
73 EndIf
74 i += 1;
75 EndWhile
76 noMoreFreeMemory();
77 EndFunction
78
79 Function freeTreeNode(PointerToTreeNode treeNode) Which Returns Nothing Does
80 If not(isTreeNodeWithinBounds(treeNode)) Then
81 segmentationFault();
82 EndIf
83 If NDEBUG = 0 Then
84 Character stringToBePrinted[64] := {0};
85 strcat(AddressOf(stringToBePrinted[0]), "NDEBUG: Freeing the TreeNode #");
86 appendIntegerToString(AddressOf(stringToBePrinted[0]),
87 (treeNode - AddressOf(treeNodes[0])) /
88 SizeOf(TreeNode));
89 strcat(AddressOf(stringToBePrinted[0]), "\n");
90 printString(AddressOf(stringToBePrinted[0]));
91 EndIf
92 isTreeNodeUsed[(treeNode - AddressOf(treeNodes[0])) / SizeOf(TreeNode)] := 0;
93 EndFunction
94
95 Function getHeight(PointerToTreeNode node) Which Returns Integer32 Does
96 If not(node) Then
97 Return 0;
98 EndIf
99 Integer32 max := 0;
100 If getHeight(node->leftChild) > max Then
101 max := getHeight(node->leftChild);
102 EndIf
103 If getHeight(node->rightChild) > max Then
104 max := getHeight(node->rightChild);
105 EndIf
106 Return max + 1;
107 EndFunction
108
109 Function strlen(PointerToCharacter str) Which Returns Integer32 Does
110 If str = 0 Then
111 Return 0;
112 EndIf
113 Integer32 length := 0;
114 While ValueAt(str + length) Loop
115 length += 1;
116 EndWhile
117 Return length;
118 EndFunction
119
120 Function strncmp(PointerToCharacter first, PointerToCharacter second,
121 Integer32 n) Which Returns Integer32 Does
122 If first = 0 or second = 0 Then
123 Return 1;
124 EndIf
125 Integer32 iterator := 0;
126 While iterator < n Loop
127 If ValueAt(first + iterator) = ValueAt(second + iterator) Then
128 iterator += 1;
129 Else
130 Return ValueAt(first + iterator) - ValueAt(second + iterator);
131 EndIf
132 EndWhile
133 Return 0;
134 EndFunction
135
136 Function strcpy(PointerToCharacter dest,
137 PointerToCharacter src) Which Returns Nothing Does
138 While ValueAt(src) Loop
139 ValueAt(dest) := ValueAt(src);
140 dest += 1;
141 src += 1;
142 EndWhile
143 ValueAt(dest) := 0;
144 EndFunction
145
146 Function strcat(PointerToCharacter dest,
147 PointerToCharacter src) Which Returns Nothing Does
148 strcpy(dest + strlen(dest), src);
149 EndFunction
150
151 Function reverseString(PointerToCharacter string) Which Returns Nothing Does
152 PointerToCharacter pointerToLastCharacter := string + strlen(string) - 1;
153 While pointerToLastCharacter - string > 0 Loop
154 Character tmp := ValueAt(string);
155 ValueAt(string) := ValueAt(pointerToLastCharacter);
156 ValueAt(pointerToLastCharacter) := tmp;
157 string += 1;
158 pointerToLastCharacter -= 1;
159 EndWhile
160 EndFunction
161
162 Function convertIntegerToString(PointerToCharacter string,
163 Integer32 number) Which Returns Nothing Does
164 Integer32 isNumberNegative := 0;
165 If number < 0 Then
166 number *= -1;
167 isNumberNegative := 1;
168 EndIf
169 Integer32 i := 0;
170 While number >= 10 Loop
171 ValueAt(string + i) := '0' + mod(number, 10);
172 number /= 10;
173 i += 1;
174 EndWhile
175 ValueAt(string + i) := '0' + number;
176 i += 1;
177 If isNumberNegative Then
178 ValueAt(string + i) := '-';
179 i += 1;
180 EndIf
181 ValueAt(string + i) := 0;
182 reverseString(string);
183 EndFunction
184
185 Function appendIntegerToString(PointerToCharacter string,
186 Integer32 number) Which Returns Nothing Does
187 convertIntegerToString(string + strlen(string), number);
188 EndFunction
189
190 Function convertDecimalToString(PointerToCharacter string,
191 Decimal32 number) Which Returns Nothing Does
192 convertIntegerToString(string, number);
193 number -= Integer32(number);
194 If number < 0 Then
195 number *= -1;
196 EndIf
197 If number = 0 Then
198 Return;
199 EndIf
200 strcat(string, ".");
201 Integer16 numberOfDecimals := 0;
202 While numberOfDecimals < 3 and number > 0 Loop
203 numberOfDecimals += 1;
204 number *= 10;
205 Character stringWithTheNewDigit[2];
206 stringWithTheNewDigit[0] := stringWithTheNewDigit[1] := 0;
207 stringWithTheNewDigit[0] := '0' + number;
208 strcat(string, AddressOf(stringWithTheNewDigit[0]));
209 number -= Integer32(number);
210 EndWhile
211 EndFunction
212
213 PointerToCharacter mapOfCodes[256];
214
215 Function assignCode(PointerToCharacter currentCode,
216 PointerToTreeNode treeNode) Which Returns Nothing Does
217 If NDEBUG = 0 Then
218 Character stringToBePrinted[64] := {0};
219 strcat(AddressOf(stringToBePrinted[0]), "NDEBUG: Assigning the code \"");
220 strcat(AddressOf(stringToBePrinted[0]), currentCode);
221 strcat(AddressOf(stringToBePrinted[0]), "\" to the TreeNode #");
222 appendIntegerToString(AddressOf(stringToBePrinted[0]),
223 (treeNode - AddressOf(treeNodes[0])) /
224 SizeOf(TreeNode));
225 strcat(AddressOf(stringToBePrinted[0]), ".\n");
226 printString(AddressOf(stringToBePrinted[0]));
227
228 stringToBePrinted[0] := 0;
229 strcat(AddressOf(stringToBePrinted[0]),
230 "NDEBUG: Its left child is the TreeNode #");
231 If treeNode->leftChild Then
232 appendIntegerToString(AddressOf(stringToBePrinted[0]),
233 (treeNode->leftChild - AddressOf(treeNodes[0])) /
234 SizeOf(TreeNode));
235 Else
236 strcat(AddressOf(stringToBePrinted[0]), "null");
237 EndIf
238 strcat(AddressOf(stringToBePrinted[0]), ".\n");
239 printString(AddressOf(stringToBePrinted[0]));
240
241 stringToBePrinted[0] := 0;
242 strcat(AddressOf(stringToBePrinted[0]),
243 "NDEBUG: Its right child is the TreeNode #");
244 If treeNode->leftChild Then
245 appendIntegerToString(AddressOf(stringToBePrinted[0]),
246 (treeNode->rightChild - AddressOf(treeNodes[0])) /
247 SizeOf(TreeNode));
248 Else
249 strcat(AddressOf(stringToBePrinted[0]), "null");
250 EndIf
251 strcat(AddressOf(stringToBePrinted[0]), ".\n");
252 printString(AddressOf(stringToBePrinted[0]));
253 EndIf
254
255 If not(isTreeNodeWithinBounds(treeNode)) Then segmentationFault(); EndIf
256
257 strcpy(AddressOf(treeNode->code[0]), currentCode);
258
259 Character leftCode[16] := {0}, rightCode[16] := {0};
260
261 strcpy(AddressOf(leftCode[0]), currentCode);
262 strcat(AddressOf(leftCode[0]), "0");
263 strcpy(AddressOf(rightCode[0]), currentCode);
264 strcat(AddressOf(rightCode[0]), "1");
265
266 If treeNode->leftChild Then
267 assignCode(AddressOf(leftCode[0]), treeNode->leftChild);
268 EndIf
269 If treeNode->rightChild Then
270 assignCode(AddressOf(rightCode[0]), treeNode->rightChild);
271 EndIf
272
273 If treeNode->character Then
274 mapOfCodes[treeNode->character] := AddressOf(treeNode->code[0]);
275 Character codeToPrint[32] := {
276 '\'',
277 treeNode->character,
278 '\'',
279 '=',
280 '>',
281 0,
282 };
283 strcat(AddressOf(codeToPrint[0]), AddressOf(treeNode->code[0]));
284 strcat(AddressOf(codeToPrint[0]), "\n");
285 printString(AddressOf(codeToPrint[0]));
286 EndIf
287 EndFunction
288
289 Function freeUpTheTree(PointerToTreeNode tree) Which Returns Nothing Does
290 If tree->leftChild Then
291 freeUpTheTree(tree->leftChild); EndIf
294 If tree->rightChild Then
295 freeUpTheTree(tree->rightChild);
296 EndIf
297 freeTreeNode(tree);
298 EndFunction
299
300 Decimal32 PRECISION := 500;
301 Function ln(Decimal32 x) Which Returns Decimal32 Does
302 Decimal32 sum := 0, epsilon := (x - 1) / (5 * PRECISION), i := 1;
304 While epsilon > 0 and i < x or epsilon < 0 and i > x Loop
305 sum += epsilon / i;
306 i += epsilon;
307 EndWhile
308 Return sum;
309 EndFunction
310
311 Decimal32 ln2 := log(2);
313 Function log2(Decimal32 x) Which Returns Decimal32 Does
314 Return ln(x) / ln2;
315 EndFunction
316
317 Character input[64];
318 Character output[256];
319
320 Function getAddressOfTheOutput() Which Returns PointerToCharacter
321 Does Return AddressOf(output[0]);
327 EndFunction;
328
329 Function shl(Integer32 first_number,
330 Integer32 second_number) Which Returns Integer32 Does
331 Return asm_i32(R"WebAssembly(
332 (i32.shl
333 (i32.load %first_number)
334 (i32.load %second_number)
335 )
336 )WebAssembly");
337 EndFunction
338
339 Structure Maxima Consists Of
340 Integer32 minimumX, maximumX;
341 EndStructure
342 Integer32 minimumX, maximumX;
343
344 Function
345 findMinimumAndMaximumX(PointerToTreeNode node,
346 PointerToMaxima maxima) Which Returns Nothing Does
347 If node->x < maxima->minimumX Then
348 maxima->minimumX := node->x;
349 EndIf
350 If node->x > maxima->maximumX Then
351 maxima->maximumX := node->x;
352 EndIf
353
354 If node->rightChild Then
355 findMinimumAndMaximumX(node->rightChild, maxima);
356 EndIf
357 If node->leftChild Then
358 findMinimumAndMaximumX(node->leftChild, maxima);
359 EndIf
360 EndFunction
361
362 Function setCoordinates(PointerToTreeNode node, Integer32 x, Integer32 y,
363 Integer32 space) Which Returns Nothing Does
364 node->x := x;
365 node->y := y;
366 If node->leftChild Then
367 Integer32 newX := x - space - 10;
368 While 1 Loop
369 newX += 10;
370 setCoordinates(node->leftChild, newX, y + 75,
371 20 * shl(1, getHeight(node->leftChild) - 1));
372 InstantiateStructure Maxima localMaxima;
373 localMaxima.maximumX := localMaxima.minimumX := newX;
374 findMinimumAndMaximumX(node->leftChild, AddressOf(localMaxima));
375 If x - localMaxima.maximumX <= 60 Then
376 Break;
377 EndIf
378 EndWhile
379 EndIf
380 If node->rightChild Then
381 Integer32 newX := x + space + 10;
382 While 1 Loop
383 newX -= 10;
384 setCoordinates(node->rightChild, newX, y + 75,
385 20 * shl(1, getHeight(node->rightChild) - 1));
386 InstantiateStructure Maxima localMaxima;
387 localMaxima.maximumX := localMaxima.minimumX := newX;
388 findMinimumAndMaximumX(node->rightChild, AddressOf(localMaxima));
389 If localMaxima.minimumX - x <= 40 Then
390 Break;
391 EndIf
392 EndWhile
393 EndIf
394 EndFunction
395
396 Function drawTree(PointerToTreeNode node) Which Returns Nothing Does
397 drawRectangle(node->x - minimumX, node->y, 50, 50);
398 If node->character Then
399 Character output[4] := {'\'', node->character, '\'', 0};
400 drawText(node->x + 5 - minimumX, node->y + 20, AddressOf(output[0]));
401 EndIf
402 Character output[8];
403 output[0] := 0;
404 convertIntegerToString(AddressOf(output[0]), node->frequencyOfCharacter);
405 strcat(AddressOf(output[0]), "/");
406 appendIntegerToString(AddressOf(output[0]), getLengthOfTheInput());
407 drawText(node->x + 5 - minimumX, node->y + 40, AddressOf(output[0]));
408 If node->leftChild Then
409 drawText(node->x - minimumX - 10, node->y + 60, "0");
410 drawLine(
411 x1 := node->x + 25 - minimumX,
412 x2 := node->x + 25 - minimumX,
413 y1 := node->y + 50,
414 y2 := node->y + 50 + 13,
415 );
416 drawLine(
417 x1 := node->x + 25 - minimumX,
418 x2 := node->leftChild->x + 25 - minimumX,
419 y1 := node->y + 50 + 13,
420 y2 := node->y + 50 + 13,
421 );
422 drawLine(
423 x1 := node->leftChild->x + 25 - minimumX,
424 x2 := node->leftChild->x + 25 - minimumX,
425 y1 := node->y + 50 + 13,
426 y2 := node->leftChild->y,
427 );
428 drawTree(node->leftChild);
429 EndIf
430 If node->rightChild Then
431 drawText(node->x - minimumX + 50, node->y + 60, "1");
432 drawLine(x1 := node->x + 25 - minimumX,
433 y1 := node->y + 50,
434 x2 := node->x + 25 - minimumX,
435 y2 := node->y + 50 + 13);
436 drawLine(x1 := node->x + 25 - minimumX,
437 y1 := node->y + 50 + 13,
438 x2 := node->rightChild->x + 25 - minimumX,
439 y2 := node->y + 50 + 13);
440 drawLine(x1 := node->rightChild->x + 25 - minimumX,
441 y1 := node->y + 50 + 13,
442 x2 := node->rightChild->x + 25 - minimumX,
443 y2 := node->rightChild->y);
444 drawTree(node->rightChild);
445 EndIf
446 EndFunction
447
448 Function main() Which Returns Nothing Does
449 clearScreen();
450 Integer16 lengthOfInput := getLengthOfTheInput(), i := 0;
451 If NDEBUG = 0 Then
452 Character stringToBePrinted[64] := {0};
453 strcat(AddressOf(stringToBePrinted[0]),
454 "NDEBUG: The length of the input is: ");
455 appendIntegerToString(AddressOf(stringToBePrinted[0]),
456 lengthOfInput);
457 strcat(AddressOf(stringToBePrinted[0]), "\n");
458 printString(AddressOf(stringToBePrinted[0]));
459 EndIf
460 While i < lengthOfInput Loop
461 input[i] := getCharacterOfTheInput(i);
462 i += 1;
463 EndWhile
464 input[lengthOfInput] := 0;
465
466 If strlen(AddressOf(input[0])) = 0 Then
467 printString("The input is empty!\n");
468 Return;
469 EndIf
470
471 i := 0;
472 While i < 256 Loop
473 mapOfCodes[i] := PointerToCharacter(0);
474 i += 1;
475 EndWhile
476
477 PointerToTreeNode array[32];
478 Integer16 lengthOfTheArray := 0;
479 i := 0;
480 While i < lengthOfInput Loop
481 Integer16 j := 0, haveWeFoundTheCharacterInTheArray := 0;
482 While j < lengthOfTheArray Loop
483 If array[j]->character = input[i] Then
484 haveWeFoundTheCharacterInTheArray := 1;
485 array[j]->frequencyOfCharacter += 1;
486 EndIf
487 j += 1;
488 EndWhile
489 If not(haveWeFoundTheCharacterInTheArray) Then
490 array[lengthOfTheArray] := newTreeNode();
491 array[lengthOfTheArray]->character := input[i];
492 array[lengthOfTheArray]->frequencyOfCharacter := 1;
493 lengthOfTheArray += 1;
494 EndIf
495 i += 1;
496 EndWhile
497
498 i := 0;
499 While i < lengthOfTheArray Loop
500 Character stringToBePrinted[64] := {0};
501 strcat(AddressOf(stringToBePrinted[0]), "The character '");
502 Integer16 indexOfCharacter := strlen(AddressOf(stringToBePrinted[0]));
503 stringToBePrinted[indexOfCharacter] := array[i]->character;
504 stringToBePrinted[indexOfCharacter + 1] := 0;
505 strcat(AddressOf(stringToBePrinted[0]), "' has the frequency of ");
506 appendIntegerToString(AddressOf(stringToBePrinted[0]),
507 array[i]->frequencyOfCharacter);
508 strcat(AddressOf(stringToBePrinted[0]), ".\n");
509 printString(AddressOf(stringToBePrinted[0]));
510 i += 1;
511 EndWhile
512
513 Decimal32 ShannonEntropy := 0;
514 i := 0;
515 While i < lengthOfTheArray Loop
516 ShannonEntropy -=
517 (array[i]->frequencyOfCharacter / Decimal32(lengthOfInput)) *
518 log2(array[i]->frequencyOfCharacter / Decimal32(lengthOfInput));
519 i += 1;
520 EndWhile
521 output[0] := 0;
522 strcat(AddressOf(output[0]), "The Shannon Entropy of the input string is: ");
523 convertDecimalToString(AddressOf(output[0]) + strlen(AddressOf(output[0])),
524 ShannonEntropy);
525 strcat(AddressOf(output[0]), " bits/symbol.\n");
526 printString(AddressOf(output[0]));
527
528 While lengthOfTheArray > 1 Loop
529 Integer16 minimum := 0, secondMinimum := 0;
530
531 Integer16 i := 0;
532 If NDEBUG = 0 Then
533 Character stringToBePrinted[64] := {0};
534 strcat(AddressOf(stringToBePrinted[0]),
535 "NDEBUG: The length of the array is ");
536 appendIntegerToString(AddressOf(stringToBePrinted[0]),
537 lengthOfTheArray);
538 strcat(AddressOf(stringToBePrinted[0]), ".\n");
539 printString(AddressOf(stringToBePrinted[0]));
540 EndIf
541 While i < lengthOfTheArray Loop
542 If NDEBUG = 0 Then
543 Character stringToBePrinted[64] := {0};
544 strcat(AddressOf(stringToBePrinted[0]),
545 "NDEBUG: The tree at the index #");
546 appendIntegerToString(AddressOf(stringToBePrinted[0]),
547 i);
548 strcat(AddressOf(stringToBePrinted[0]), " is the TreeNode #");
549 appendIntegerToString(AddressOf(stringToBePrinted[0]),
550 (array[i] - AddressOf(treeNodes[0])) /
551 SizeOf(TreeNode));
552 strcat(AddressOf(stringToBePrinted[0]), ".\n");
553 printString(AddressOf(stringToBePrinted[0]));
554 EndIf
555 If not(isTreeNodeWithinBounds(array[i])) Then
556 segmentationFault();
557 asm("unreachable");
558 EndIf
559 i += 1;
560 EndWhile
561
562 i := 0;
563 While i < lengthOfTheArray Loop
564 If array[i]->frequencyOfCharacter <
565 array[minimum]->frequencyOfCharacter Then
566 minimum := i;
567 EndIf
568 i += 1;
569 EndWhile
570
571 i := minimum = 0 ? 1 : 0;
572 secondMinimum := i;
573 While i < lengthOfTheArray Loop
574 If array[i]->frequencyOfCharacter <
575 array[secondMinimum]->frequencyOfCharacter and
576 i != minimum Then
577 secondMinimum := i;
578 EndIf
579 i += 1;
580 EndWhile
581
582 If NDEBUG = 0 Then
583 Character stringToBePrinted[64] := {0};
584 strcat(AddressOf(stringToBePrinted[0]),
585 "NDEBUG: The minimum and the second minimum are ");
586 appendIntegerToString(AddressOf(stringToBePrinted[0]),
587 minimum);
588 strcat(AddressOf(stringToBePrinted[0]), " and ");
589 appendIntegerToString(AddressOf(stringToBePrinted[0]),
590 secondMinimum);
591 strcat(AddressOf(stringToBePrinted[0]), ".\n");
592 printString(AddressOf(stringToBePrinted[0]));
593 EndIf
594
595 If NDEBUG = 0 Then
596 Character stringToBePrinted[64] := {0};
597 strcat(AddressOf(stringToBePrinted[0]), "NDEBUG: Joining the TreeNode #");
598 appendIntegerToString(AddressOf(stringToBePrinted[0]),
599 (array[minimum] - AddressOf(treeNodes[0])) /
600 SizeOf(TreeNode));
601 strcat(AddressOf(stringToBePrinted[0]), " with the TreeNode #");
602 appendIntegerToString(AddressOf(stringToBePrinted[0]),
603 (array[secondMinimum] - AddressOf(treeNodes[0])) /
604 SizeOf(TreeNode));
605 strcat(AddressOf(stringToBePrinted[0]), ".\n");
606 printString(AddressOf(stringToBePrinted[0]));
607 EndIf
608
609 PointerToTreeNode sumOfTheTwoMostFrequent := newTreeNode();
610 sumOfTheTwoMostFrequent->frequencyOfCharacter
611 := array[minimum]->frequencyOfCharacter +
612 array[secondMinimum]->frequencyOfCharacter;
613 sumOfTheTwoMostFrequent->leftChild := array[minimum];
614 sumOfTheTwoMostFrequent->rightChild := array[secondMinimum];
615
616 If NDEBUG = 0 Then
617 Character stringToBePrinted[64] := {0};
618 strcat(AddressOf(stringToBePrinted[0]),
619 "NDEBUG: The new TreeNode has the frequency of: ");
620 appendIntegerToString(AddressOf(stringToBePrinted[0]),
621 sumOfTheTwoMostFrequent->frequencyOfCharacter);
622 strcat(AddressOf(stringToBePrinted[0]), ".\n");
623 printString(AddressOf(stringToBePrinted[0]));
624 EndIf
625
626 If not(MAINTAIN_COMPATIBILITY_WITH_JAVASCRIPT_IMPLEMENTATION) Then
627 array[minimum] := sumOfTheTwoMostFrequent;
628 EndIf
629
630 i := secondMinimum;
632 While i < lengthOfTheArray - 1 Loop
633 array[i] := array[i + 1];
634 i += 1;
635 EndWhile
636 lengthOfTheArray -= 1;
637 If not(MAINTAIN_COMPATIBILITY_WITH_JAVASCRIPT_IMPLEMENTATION) Then
638 Continue;
639 EndIf
640 If minimum >
642 secondMinimum Then minimum -= 1;
645 EndIf
646 i := minimum;
647 While i < lengthOfTheArray - 1 Loop
648 array[i] := array[i + 1];
649 i += 1;
650 EndWhile
651 array[lengthOfTheArray - 1] := sumOfTheTwoMostFrequent;
652 EndWhile
653
654 If NDEBUG = 0 Then
655 Character stringToBePrinted[128] := {0};
656 strcat(AddressOf(stringToBePrinted[0]),
657 "NDEBUG: The frequency of the root node is ");
658 appendIntegerToString(AddressOf(stringToBePrinted[0]),
659 array[0]->frequencyOfCharacter);
660 strcat(AddressOf(stringToBePrinted[0]),
661 ". If the algorithm is correctly implemented, it should be ");
662 appendIntegerToString(AddressOf(stringToBePrinted[0]),
663 lengthOfInput);
664 strcat(AddressOf(stringToBePrinted[0]), ".\n");
665 printString(AddressOf(stringToBePrinted[0]));
666 EndIf
667
668 printString("The tree has been constructed, let us assign Huffman codes to "
669 "characters:\n");
670 assignCode("", array[0]);
671
672 Integer16 lengthOfTheOutput := 0;
673 i := 0;
674 While i < lengthOfInput Loop
675 lengthOfTheOutput += strlen(mapOfCodes[input[i]]);
676 i += 1;
677 EndWhile
678 output[0] := 0;
679 strcat(AddressOf(output[0]), "The length of the encoded string is: ");
680 appendIntegerToString(AddressOf(output[0]), lengthOfTheOutput);
681 strcat(AddressOf(output[0]), " bits.\n");
682 printString(AddressOf(output[0]));
683
684 output[0] := 0;
685 strcat(AddressOf(output[0]),
686 "The average length of the symbol in the Huffman code is: ");
687 convertDecimalToString(AddressOf(output[0]) + strlen(AddressOf(output[0])),
688 Decimal32(lengthOfTheOutput) / lengthOfInput);
689 strcat(AddressOf(output[0]), " bits/symbol.\n");
690 printString(AddressOf(output[0]));
691
692 output[0] := 0;
693 i := 0;
694 While i < lengthOfInput Loop
695 strcat(AddressOf(output[0]), mapOfCodes[input[i]]);
696 i += 1;
697 EndWhile
698 strcat(AddressOf(output[0]), "\n");
699 printString("The Huffman code of the input is:\n");
700 printString(AddressOf(output[0]));
701
702 setCoordinates(array[0], 0, 0, 10 * shl(1, getHeight(array[0])));
703 InstantiateStructure Maxima globalMaxima;
704 globalMaxima.minimumX := globalMaxima.maximumX := 0;
705 findMinimumAndMaximumX(array[0], AddressOf(globalMaxima));
706 minimumX := globalMaxima.minimumX;
707 maximumX := globalMaxima.maximumX;
708 drawTree(array[0]);
709 setDiagramWidth(maximumX - minimumX + 55);
710 setDiagramHeight(getHeight(array[0]) * 75);
711
712 freeUpTheTree(array[0]);
713
714 Character stringToBePrinted[64] := {0};
715 strcat(AddressOf(stringToBePrinted[0]), "Decoding the output...\n");
716 printString(AddressOf(stringToBePrinted[0]));
717
718 Integer16 j := 0, k := 0;
719 While j < strlen(AddressOf(output[0])) - 1 Loop
720 i := 0;
721 If NDEBUG = 0 Then
722 printString(
723 "NDEBUG: We are entering the loop for decoding the output!\n");
724 EndIf
725 While (mapOfCodes[i] = 0 or strncmp(AddressOf(output[j]), mapOfCodes[i],
726 strlen(mapOfCodes[i]))) and
727 i < 256 Loop
728 If NDEBUG = 0 Then
729 If mapOfCodes[i] = 0 Then
730 printString("NDEBUG: Skipping the character because it's NULL.\n");
731 Else
732 printString(
733 "NDEBUG: Skipping the character because it doesn't match!\n");
734 EndIf
735 EndIf
736 i += 1;
737 EndWhile
738 If i = 256 Then
739 printString("ERROR: Cannot find the beginning of the current string in "
740 "the map of codes!\n");
741 Return;
742 EndIf
743 stringToBePrinted[0] := 0;
744 strcat(AddressOf(stringToBePrinted[0]), mapOfCodes[i]);
745 strcat(AddressOf(stringToBePrinted[0]), "=>");
746 Character stringToBeAdded[5] := {'\'', i, '\'', '\n', 0};
747 strcat(AddressOf(stringToBePrinted[0]), AddressOf(stringToBeAdded[0]));
748 printString(AddressOf(stringToBePrinted[0]));
749 j += strlen(mapOfCodes[i]);
750 If i != getCharacterOfTheInput(k) Then
751 printString("ERROR: The decoded output does not match the input!\n");
752 Break;
753 EndIf
754 k += 1;
755 EndWhile
756 EndFunction
757