Last active
November 26, 2017 23:33
-
-
Save cipharius/5fc8f90de0e5a28b29d2bd4b062ae312 to your computer and use it in GitHub Desktop.
Algorithms to translate ASCII message to JoshScript code
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import algorithm | |
import strutils | |
proc splitChars(str: string): seq[char] = | |
result = @[] | |
for ch in str: | |
add result, ch | |
proc translateSimple(text: string): string = | |
## Translates ASCII to JoshScript | |
## | |
## This method uses simple algorithm, by calculating each letter's value | |
## Doesn't scale well for long messages | |
result = "" | |
var opStack: seq[bool] = @[] | |
for ch in text: | |
var current = ch.int | |
while current > 0: | |
if (current mod 2) == 0: | |
current = current shr 1 | |
add opStack, true | |
else: | |
dec current | |
add opStack, false | |
while opStack.len > 0: | |
let shiftLeft = opStack.pop | |
if shiftLeft: | |
add result, "Josh" | |
else: | |
add result, "JOSH" | |
# Print the result and clear cell | |
add result, "JOshjOsh" | |
proc translateDynamic(text: string): string = | |
## Translates ASCII to JoshScript | |
## | |
## This method simulates the JoshScript and tries to | |
## reuse cells. | |
var | |
text = text.splitChars | |
sorted = text.sorted(system.cmp[char]) | |
cells: seq[int] = @[] | |
cellPtr = 0 | |
# Fill [1] with 10, start loop and move to [2] for 0 padding | |
result = "JOSHJoshJoshJoshJOSHJOSHJoShjoSH" | |
for i, ch in sorted: | |
if (i == 0) or (ch.int - cells[^1] >= 10): | |
let closest = ch.int+5 - (ch.int+5).mod(10) | |
add cells, closest | |
# Generate the equivelent Josh OPs | |
add result, "joSH" | |
add result, "JOSH".repeat(int closest/10) | |
# Go back to [1], decrement, end loop, then move to first character | |
add result, "JoShjoShjOsHjoShjoshjOsHjoSHjoSH" | |
for ch in text: | |
var | |
mi = -1 | |
mv = -1 | |
# Find closest ASCII value in cells | |
for i, v in cells: | |
if (mi == -1) or (abs(ch.int - v) < abs(ch.int - mv)): | |
mi = i | |
mv = v | |
if mi - cellPtr > 0: | |
add result, "joSH".repeat(mi - cellPtr) | |
else: | |
add result, "joSh".repeat(cellPtr - mi) | |
cellPtr += mi - cellPtr | |
if ch.int - mv > 0: | |
add result, "JOSH".repeat(ch.int - mv) | |
else: | |
add result, "josh".repeat(mv - ch.int) | |
cells[cellPtr] = ch.int | |
add result, "JOsh" | |
proc translate(text: string): string = | |
## Translates ASCII to JoshScript | |
## | |
## Evaluates which algorithm gives shortest | |
## JoshScript and returns it. | |
let | |
simpleApprox = 4*11*text.len | |
dynamicTrans = translateDynamic text | |
if dynamicTrans.len < simpleApprox: | |
echo "Using dynamic translation" | |
return dynamicTrans | |
else: | |
echo "Using simple translation" | |
return translateSimple text | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment