Skip to content

Instantly share code, notes, and snippets.

@cipharius
Last active November 26, 2017 23:33
Show Gist options
  • Save cipharius/5fc8f90de0e5a28b29d2bd4b062ae312 to your computer and use it in GitHub Desktop.
Save cipharius/5fc8f90de0e5a28b29d2bd4b062ae312 to your computer and use it in GitHub Desktop.
Algorithms to translate ASCII message to JoshScript code
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