Skip to content

Commit 11592e5

Browse files
committed
Update Encoder.kt
1 parent 45b09b0 commit 11592e5

File tree

1 file changed

+76
-69
lines changed
  • Codex/src/main/java/org/operatorfoundation/codex

1 file changed

+76
-69
lines changed

Codex/src/main/java/org/operatorfoundation/codex/Encoder.kt

Lines changed: 76 additions & 69 deletions
Original file line numberDiff line numberDiff line change
@@ -4,116 +4,123 @@ import org.operatorfoundation.codex.symbols.Symbol
44
import kotlin.math.min
55

66
/**
7-
* Encoder class that converts an integer to a list of encoded symbols.
7+
* Encoder class that converts an integer to a list of encoded values.
88
*
9-
* The encoder uses a list of symbols to represent different parts of the integer.
10-
* It works like converting to a mixed-radix number system, where each position
11-
* can have a different base (determined by the symbol's size).
9+
* The encoder divides the integer into parts using a mixed-radix system,
10+
* where each symbol encodes a portion based on its size and position.
1211
*
1312
* @param symbols List of Symbol objects used for encoding
1413
*/
15-
class Encoder(private val symbols: List<Symbol>) {
16-
14+
class Encoder(private val symbols: List<Symbol>)
15+
{
1716
/**
1817
* Creates a Decoder instance with the same symbol list.
19-
* Useful for round-trip encoding/decoding operations.
2018
*/
2119
fun decoder(): Decoder {
2220
return Decoder(symbols)
2321
}
2422

2523
/**
26-
* Encodes an integer value into a list of symbol representations.
27-
*
28-
* The encoding process divides the input number into parts, with each symbol
29-
* encoding a portion based on its size and position. This is similar to
30-
* converting a decimal number to a mixed-radix representation.
24+
* Encodes an integer value into a list of ByteArrays.
25+
* Each ByteArray in the result corresponds to one symbol.
3126
*
32-
* @param valueToEncode The integer value to encode
33-
* @return List of encoded values, one for each symbol
34-
* @throws Exception if the value is too large to encode with the given symbols
27+
* @param integerToEncode The integer value to encode
28+
* @return List of ByteArrays, one for each symbol
29+
* @throws Exception if the value is too large to encode
3530
*/
36-
fun encode(valueToEncode: Int): List<Any> {
37-
val encodedResults = mutableListOf<Any>()
38-
var remainingValue = valueToEncode
31+
fun encode(integerToEncode: Int): List<ByteArray>
32+
{
33+
val results = mutableListOf<ByteArray>()
34+
var remainingValue = integerToEncode
3935

4036
// Process each symbol in sequence
41-
symbols.forEachIndexed { symbolIndex, symbol ->
42-
val (encodedPart, leftoverValue) = encodeStep(remainingValue, symbol, symbolIndex)
43-
encodedResults.add(encodedPart)
37+
symbols.forEachIndexed { index, symbol ->
38+
val (encodedBytes, leftoverValue) = encodeStep(remainingValue, symbol, index)
39+
results.add(encodedBytes)
4440
remainingValue = leftoverValue
4541
}
4642

47-
// If there's a leftover value, the input was too large for our symbol set
4843
if (remainingValue != 0) {
49-
throw Exception("Encoder error, results: $encodedResults, leftover: $remainingValue")
44+
throw Exception("Encoder error, results: ${results.map { it.decodeToString() }}, leftover: $remainingValue")
5045
}
5146

52-
return encodedResults
47+
return results
5348
}
5449

5550
/**
5651
* Performs a single encode step for one symbol position.
5752
*
58-
* For symbols with size > 1:
59-
* - Determines how much of the remaining value this symbol should encode
60-
* - Uses division and modulo based on the product of remaining symbol sizes
61-
*
62-
* For symbols with size = 1:
63-
* - These are fixed values (like Required symbols) that don't encode data
64-
*
65-
* @param remainingValue The value left to encode
53+
* @param currentValue The value left to encode
6654
* @param symbol The symbol to use for encoding
67-
* @param symbolIndex The position of this symbol in the list
68-
* @return Pair of (encoded result for this symbol, remaining value for next symbols)
55+
* @param index The position of this symbol in the list
56+
* @return Pair of (encoded ByteArray for this symbol, remaining value)
6957
*/
70-
private fun encodeStep(remainingValue: Int, symbol: Symbol, symbolIndex: Int): Pair<Any, Int> {
71-
return if (symbol.size() == 1) {
58+
private fun encodeStep(currentValue: Int, symbol: Symbol, index: Int): Pair<ByteArray, Int>
59+
{
60+
if (symbol.size() == 1)
61+
{
7262
// Fixed symbols (size = 1) don't consume any of the value
73-
println("encode_step($remainingValue, $symbol, $symbolIndex)")
63+
println("encode_step($currentValue, $symbol, $index)")
7464

75-
// Calculate product of all symbols up to this point (for debugging)
76-
val relevantSymbols = if (symbolIndex == 0) {
65+
// For debugging: show symbol capacity up to this point
66+
val symbolsUpToHere = if (index == 0)
67+
{
7768
symbols
78-
} else {
79-
symbols.subList(0, symbols.size - symbolIndex)
8069
}
81-
val symbolSizes = relevantSymbols.map { it.size() }
82-
val product = symbolSizes.fold(1) { acc, size -> acc * size }
70+
else
71+
{
72+
symbols.subList(0, symbols.size - index)
73+
}
74+
75+
val symbolSizes = symbolsUpToHere.map { it.size() }
76+
val totalCapacity = symbolSizes.fold(1) { acc, size -> acc * size }
8377

84-
println("history: $symbolSizes, p: $product")
78+
println("history: $symbolSizes, p: $totalCapacity")
8579

86-
val result = Pair(symbol.encode(remainingValue), remainingValue)
87-
println("result: $result")
88-
result
89-
} else {
90-
println("encode_step($remainingValue, $symbol, $symbolIndex)")
80+
// Symbol with size 1 encodes its fixed value and passes through the current value
81+
val encodedBytes = symbol.encode(currentValue)
82+
val result = Pair(encodedBytes, currentValue)
83+
println("result: (${encodedBytes.decodeToString()}, $currentValue)")
9184

92-
if (symbolIndex == symbols.size - 1) {
85+
return result
86+
}
87+
else
88+
{
89+
println("encode_step($currentValue, $symbol, $index)")
90+
91+
if (index == symbols.size - 1)
92+
{
9393
// Last symbol: encode all remaining value
94-
val result = Pair(symbol.encode(remainingValue), 0)
95-
println("result: $result")
96-
result
97-
} else {
98-
// Calculate how much this symbol should encode based on remaining symbols
99-
val remainingSymbols = symbols.subList(symbolIndex + 1, symbols.size)
100-
val remainingSizes = remainingSymbols.map { it.size() }
101-
val remainingCapacity = remainingSizes.fold(1) { acc, size -> acc * size }
102-
103-
println("history: $remainingSizes, p: $remainingCapacity")
104-
105-
// Determine the value for this symbol position
106-
// Use min to ensure we don't exceed the symbol's capacity
107-
val symbolValue = min(remainingValue / remainingCapacity, symbol.size() - 1)
94+
val encodedBytes = symbol.encode(currentValue)
95+
val result = Pair(encodedBytes, 0)
96+
println("result: (${encodedBytes.decodeToString()}, 0)")
97+
98+
return result
99+
}
100+
else
101+
{
102+
// Calculate capacity of remaining symbols
103+
val remainingSymbols = symbols.subList(index + 1, symbols.size)
104+
val remainingSymbolSizes = remainingSymbols.map { it.size() }
105+
val remainingCapacity = remainingSymbolSizes.fold(1) { acc, size -> acc * size }
106+
107+
println("history: $remainingSymbolSizes, p: $remainingCapacity")
108+
109+
// Determine value for this symbol position
110+
// Division gives us how many "chunks" of remaining capacity we have
111+
val symbolValue = min(currentValue / remainingCapacity, symbol.size() - 1)
108112
println("n: $symbolValue")
109113

110-
// Calculate what's left for the remaining symbols
111-
val leftoverValue = remainingValue % remainingCapacity
114+
// Modulo gives us what's left for the remaining symbols
115+
val leftoverValue = currentValue % remainingCapacity
112116
println("m: $leftoverValue")
113117

114-
val result = Pair(symbol.encode(symbolValue), leftoverValue)
115-
println("result: $result")
116-
result
118+
// Encode this symbol's portion
119+
val encodedBytes = symbol.encode(symbolValue)
120+
val result = Pair(encodedBytes, leftoverValue)
121+
println("result: (${encodedBytes.decodeToString()}, $leftoverValue)")
122+
123+
return result
117124
}
118125
}
119126
}

0 commit comments

Comments
 (0)