11package org.operatorfoundation.codex
22
3+ import org.operatorfoundation.codex.symbols.Power
4+ import org.operatorfoundation.codex.symbols.Binary
35import org.operatorfoundation.codex.symbols.Symbol
46
57/* *
6- * Decoder class that converts encoded symbols back to their original numeric value .
8+ * Decoder class that converts a list of encoded values back to an integer .
79 *
8- * The decoder uses a list of symbols to interpret encoded data. Each symbol in the
9- * list represents a different position in the encoding, with different value ranges.
10- * The decoder calculates the total numeric value by considering each symbol's
11- * contribution based on its position and the sizes of subsequent symbols.
10+ * The decoder uses a list of symbols to interpret encoded data. Each position
11+ * in the input list corresponds to one symbol, and the decoder calculates
12+ * the total numeric value using a mixed-radix number system.
1213 *
1314 * @param symbols List of Symbol objects used for decoding
1415 */
15- class Decoder (private val symbols : List <Symbol >) {
16+ class Decoder (private val symbols : List <Symbol >)
17+ {
1618
1719 /* *
1820 * Creates an Encoder instance with the same symbol list.
19- * Useful for round-trip encoding/decoding operations.
2021 */
2122 fun encoder (): Encoder {
2223 return Encoder (symbols)
2324 }
2425
2526 /* *
26- * Decodes a list of encoded values back to the original integer.
27+ * Decodes a list of ByteArrays back to the original integer.
28+ * Each ByteArray in the list corresponds to one symbol at the same index.
2729 *
28- * The decoding process works by treating the symbols as a mixed-radix number system.
29- * Each symbol position contributes to the final value based on the product of all
30- * subsequent symbol sizes.
31- *
32- * @param encodedValues Can be String (for character data), ByteArray, or List<String>
30+ * @param encodedValues List of ByteArrays, one for each symbol
3331 * @return The decoded integer value
3432 */
35- fun decode (encodedValues : Any ): Int {
36- val decodedResults = mutableListOf<Int >()
37-
38- // Convert input to a list of strings we can iterate over
39- val encodedList: List <String > = when (encodedValues) {
40- is String -> encodedValues.map { it.toString() } // Convert each char to string
41- is ByteArray -> encodedValues.map { it.toInt().toString() } // Convert bytes to string ints
42- is List <* > -> encodedValues.map { it.toString() } // Convert each element to string
43- else -> throw IllegalArgumentException (" Unsupported input type: ${encodedValues::class } " )
44- }
33+ fun decode (encodedValues : List <ByteArray >): Int {
34+ val results = mutableListOf<Int >()
4535
4636 // Process each symbol with its corresponding encoded value
47- symbols.forEachIndexed { symbolIndex , symbol ->
48- val encodedValue = encodedList[symbolIndex ]
49- val decodedValue = decodeStep(encodedValue, symbol, symbolIndex )
50- decodedResults .add(decodedValue )
37+ symbols.forEachIndexed { index , symbol ->
38+ val encodedValue = encodedValues[index ]
39+ val result = decodeStep(encodedValue, symbol, index )
40+ results .add(result )
5141 }
5242
53- // Sum all decoded values to get the final result
54- return decodedResults.sum()
43+ return results.sum()
5544 }
5645
5746 /* *
5847 * Performs a single decode step for one symbol position.
5948 *
60- * The contribution of each symbol to the final value depends on:
61- * - Its decoded value (from the symbol's decode method)
62- * - Its position in the symbol list
63- * - The sizes of all symbols that come after it
64- *
65- * @param encodedValue The encoded string value to decode
49+ * @param encodedValue The ByteArray to decode for this symbol
6650 * @param symbol The symbol to use for decoding
67- * @param symbolIndex The position of this symbol in the list
51+ * @param index The position of this symbol in the list
6852 * @return The numeric contribution of this symbol to the total
6953 */
70- private fun decodeStep (encodedValue : String , symbol : Symbol , symbolIndex : Int ): Int {
71- // Symbols with size 1 (like Required) don't contribute to the numeric value
72- // They're used for validation only
54+ private fun decodeStep (encodedValue : ByteArray , symbol : Symbol , index : Int ): Int
55+ {
7356 return if (symbol.size() == 1 ) {
74- println (" decode_step($encodedValue , $symbol , $symbolIndex )" )
57+ // Symbols with size 1 don't contribute to the numeric value
58+ println (" decode_step(${encodedValue.decodeToString()} , $symbol , $index )" )
7559 0
76- } else {
77- println (" decode_step($encodedValue , $symbol , $symbolIndex )" )
60+ }
61+ else
62+ {
63+ println (" decode_step(${encodedValue.decodeToString()} , $symbol , $index )" )
7864
79- if (symbolIndex == symbols.size - 1 ) {
80- // Last symbol: its contribution is just its decoded value
65+ if (index == symbols.size - 1 )
66+ {
67+ // Last symbol: just return its decoded value
8168 symbol.decode(encodedValue)
82- } else {
83- // Calculate the multiplier based on remaining symbols
84- // This implements a mixed-radix number system
85- val remainingSymbols = symbols.subList(symbolIndex + 1 , symbols.size)
86- val remainingSizes = remainingSymbols.map { it.size() }
87-
88- // Product of all remaining symbol sizes determines this position's weight
89- val positionMultiplier = remainingSizes.fold(1 ) { acc, size -> acc * size }
69+ }
70+ else
71+ {
72+ // Calculate product of remaining symbol sizes
73+ val history = symbols.subList(index + 1 , symbols.size)
74+ val lens = history.map { it.size() }
75+ val p = lens.fold(1 ) { acc, size -> acc * size }
9076
91- println (" history: $remainingSizes , p: $positionMultiplier " )
77+ println (" history: $lens , p: $p " )
9278
93- // This symbol's contribution = decoded value * position weight
94- val contribution = symbol.decode(encodedValue) * positionMultiplier
95- println (" result: $contribution " )
79+ // Multiply decoded value by position weight
80+ val result = symbol.decode(encodedValue) * p
81+ println (" result: $result " )
9682
97- contribution
83+ result
9884 }
9985 }
10086 }
101- }
87+ }
0 commit comments