We are currently working on new rules for what content should and shouldn't be allowed on this website, and are looking for feedback! See Esolang:2026 topicality proposal to view and give feedback on the current draft.
Kontakion-machine
Jump to navigation
Jump to search
A Kontakion-machine uses heptavtinimal terscii encoding and generates a Kontakion.
It can evaluate a word or a set of words and operates by producing a jump-address in the case of a collision between two words.
machine
# -----------------------------
# TERSCII ENCODING
# -----------------------------
_CHAR_TO_TERSCII_CODE = {}
# Mapping for the Basic Roman Block (00-88)
terscii_roman_block_map = [
# Col 0 Col 1 Col 2 Col 3 Col 4 Col 5 Col 6 Col 7 Col 8
["ES", "SP", "0", "9", "I", "R", "_", "i", "r"], # Row 0
["EL", "-", "1", "A", "J", "S", "a", "j", "s"], # Row 1
["ET", "'", "2", "B", "K", "T", "b", "k", "t"], # Row 2
["LR", ",", "3", "C", "L", "U", "c", "l", "u"], # Row 3
["OP", ";", "4", "D", "M", "V", "d", "m", "v"], # Row 4
["RL", ":", "5", "E", "N", "W", "e", "n", "w"], # Row 5
["SU", ".", "6", "F", "O", "X", "f", "o", "x"], # Row 6
["HT", "!", "7", "G", "P", "Y", "g", "p", "y"], # Row 7
["SD", "?", "8", "H", "Q", "Z", "h", "q", "z"], # Row 8
]
for row_idx, row_chars in enumerate(terscii_roman_block_map):
for col_idx, char_code_str in enumerate(row_chars):
terscii_code = f"{row_idx}{col_idx}"
# Explicitly map known characters, prioritizing printable characters
if char_code_str == "SP":
_CHAR_TO_TERSCII_CODE[" "] = terscii_code
elif len(char_code_str) == 1: # Single character (digit, letter, punctuation)
_CHAR_TO_TERSCII_CODE[char_code_str] = terscii_code
# Control codes like ES, EL, ET, LR, OP, RL, SU, HT, SD are not direct printable chars
# that would appear in the 'word' for this context, so we don't map them here.
# Mapping for the Extended Block (Block 01)
terscii_extended_block_map = [
# Col 0 Col 1 Col 2 Col 3 Col 4 Col 5 Col 6 Col 7 Col 8
[None, '‘', None, None, None, None, None, None, None], # Row 0
[None, '*', None, None, None, None, None, None, None], # Row 1
[None, '’', None, None, None, None, None, None, None], # Row 2
[None, '/', None, None, None, None, None, None, None], # Row 3
[None, '|', None, None, None, None, None, None, None], # Row 4
[None, '\\', None, None, None, None, None, None, None], # Row 5
[None, '‹', None, None, None, None, None, None, None], # Row 6
[None, '◊', None, None, None, None, None, None, None], # Row 7
[None, '›', None, None, None, None, None, None, None], # Row 8
]
# Process Extended Block
for row_idx, row_chars in enumerate(terscii_extended_block_map):
for col_idx, char_code_str in enumerate(row_chars):
if char_code_str is not None: # Only map if character is present
terscii_code = f"1{row_idx}{col_idx}" # Block 1 prefix, e.g., '101' for '‘'
_CHAR_TO_TERSCII_CODE[char_code_str] = terscii_code
def word_to_terscii_string(word):
terscii_parts = []
for char in word:
terscii_code = _CHAR_TO_TERSCII_CODE.get(char)
if terscii_code is None:
terscii_parts.append("00") # Default to 'ES' (End of String) for unmapped characters
else:
terscii_parts.append(terscii_code)
return "".join(terscii_parts)
def convert_hex_string_to_terscii_codes(hex_str):
terscii_hex_parts = []
for char in hex_str.upper(): # Ensure uppercase for hex digits A-F
terscii_code = _CHAR_TO_TERSCII_CODE.get(char)
if terscii_code is None:
# For characters not explicitly in the TerSCII tables (e.g. if pad chars were not '0')
# Fallback to '00' (ES) as a general default.
terscii_hex_parts.append("00")
else:
terscii_hex_parts.append(terscii_code)
return "".join(terscii_hex_parts)
# -----------------------------
# COLLISION RESOLUTION AND ORCHESTRATION
# -----------------------------
def process_words_with_collision_resolution(words):
global_seen_addresses = set()
jump_register = {}
final_output = []
MAX_COLLISION_ATTEMPTS = 64 # Cap similar to internal octal doubling
print("\n--- Processing Words ---\n")
for word in words:
print(f"Analyzing WORD: {word}")
word_registry = analyze(word)
terscii_representation = word_to_terscii_string(word)
# Store current word's results temporarily to allow for jump register updates
current_word_processed_entries = []
for hept, original_full_addr, radix_val, seq_counter in word_registry:
current_seq_counter = seq_counter
current_full_addr = original_full_addr
attempts = 0
collision_detected_for_this_entry = False
# Extract base parts to rebuild address
pad_radix_part = original_full_addr[2:23] # '0'*15 + radix_hex
while current_full_addr in global_seen_addresses and attempts < MAX_COLLISION_ATTEMPTS:
if not collision_detected_for_this_entry: # Mark first collision for this entry
collision_detected_for_this_entry = True
# Only add to jump register if it's the first time this original address causes a collision
if original_full_addr not in jump_register:
jump_register[original_full_addr] = None # Placeholder, will be updated with final unique address
current_seq_counter += 1
# The current_seq_counter (0-63) directly maps to a TerSCII index (0-80).
# We format this index as a 3-digit hex string for the address.
new_seq_hex = format(current_seq_counter, '03X')
current_full_addr = f"0x{pad_radix_part}{new_seq_hex}"
attempts += 1
if collision_detected_for_this_entry:
jump_register[original_full_addr] = current_full_addr
if current_full_addr in global_seen_addresses:
print(f" WARNING: Collision for {word} at {current_full_addr} could not be resolved after {MAX_COLLISION_ATTEMPTS} attempts. Using potentially non-unique address: {current_full_addr}")
global_seen_addresses.add(current_full_addr)
current_word_processed_entries.append((word, hept, current_full_addr, terscii_representation))
final_output.extend(current_word_processed_entries)
# Sort the final output by hept_to_int value across all words
# Sorting key remains on the base hept value, not the appended terscii representation
final_output.sort(key=lambda x: hept_to_int(x[1]))
print("\n--- Final Registry Output ---\n")
for idx, (word, hept, full_addr, terscii_encoded_word) in enumerate(final_output):
last9 = full_addr[-9:]
terscii_encoded_last9_hex = convert_hex_string_to_terscii_codes(last9)
# The requested format: idx:HEPT_code<TERSCII_encoded_address_part>TERSCII_encoded_word
print(f"{idx}:{hept}<{terscii_encoded_last9_hex}>{terscii_encoded_word}")
# Removed printing of jump_register debugfs as requested.
# -----------------------------
# RUN IT WITH MULTIPLE WORDS
# -----------------------------
words_to_analyze = ["Hello, ", "World!"]
process_words_with_collision_resolution(words_to_analyze)
example
A + B problem
-- Processing Words --- Analyzing WORD: A Analyzing WORD: B --- Final Registry Output --- 0:0<020242335332020202>13 1:0<020222720253024212>23 2:A<020242335332020212>23 3:B<020242335322020212>23 4:D<020242335312020222>23 5:H<020242335302020232>23 6:P<020242334363020242>23 7:AE<020242334353020252>23 8:BJ<020242334343020262>23 9:DT<020242334333020272>23 10:IM<020242334323020282>23 11:RZ<020242334313020203>23 12:AJY<020242334303020213>23 13:BMP<020242333343021262>23 14:BST<020242331362023243>23 15:BUW<020242334382020223>23 16:BWT<020242332382022223>23 17:CEA<020242332363022242>23 18:E0E<020242333333021272>23 19:EFH<020242331313023203>23 20:EJN<020242331353023252>23 21:ELM<020242331352023253>23 22:EPS<020242334372020233>23 23:ETM<020242332372022233>23 24:FJB<020242332353022252>23 25:GJD<020242333363021242>23 26:HBQ<020242332302023232>23 27:HPA<020242334312021222>23 28:HXG<020242334332021202>23 29:J0J<020242333323021282>23 30:JLP<020242331303023213>23 31:JUA<020242331343023262>23 32:JXZ<020242331342023263>23 33:KCS<020242332332023202>23 34:KFK<020242334362020243>23 35:KMZ<020242332362022243>23 36:LTD<020242332343022262>23 37:LTK<020242333342021263>23 38:MAM<020242333303021213>23 39:NTH<020242333353021252>23 40:NWJ<020242331372023233>23 41:NYJ<020242332303022213>23 42:OBN<020242333302022232>23 43:PCD<020242331323023282>23 44:PEG<020242331363023242>23 45:QEB<020242334302021232>23 46:QNV<020242332312023222>23 47:QUN<020242334322021212>23 48:QYQ<020242334342020263>23 49:SAW<020242332342022263>23 50:SWS<020242333352021253>23 51:T0T<020242333313021203>23 52:TYE<020242331382023223>23 53:TZE<020242332313022203>23 54:UAG<020242333312022222>23 55:UOB<020242331333023272>23 56:UVY<020242331332024202>23 57:VGK<020242332322023212>23 58:VLV<020242334352020253>23 59:W0Y<020242332352022253>23 60:WKW<020242333362021243>23 61:WZP<020242332323022282>23 62:X0Q<020242333322022212>23 63:YEY<020242333372021233>23 64:YMH<020242332333022272>23 65:YMV<020242333332022202>23 66:ZBZ<020242333382021223>23