[Back to the 30 Days of Programming Overview Page]
Insertion Sort in INTERCAL
Oh dear god, INTERCAL. This language is insane. This actually took me three
days. I managed to figure out how to do comparison, branching, and looping,
though, and once I got those down, things got a lot easier. That's not saying
much, though. Anyway, below is the INTERCAL code (with the PLEASE
s removed
because, while they are a hilarious part of the spec, they aren't terribly
interesting as part of the code), and then below that is roughly directly
translated Python code, to give a slightly better idea of what's going on.
You can download everything (the code, the translated Python code, a Makefile,
and a Python script to add PLEASE
s) in a zip file (02.zip).
INTERCAL (insertion.i)
DO NOTE: vim: set ft=intercal :
DO NOTE: Array length less than 2 is not checked but is an error
DO NOTE: Variables:
DO NOTE: ,1: Array
DO NOTE: .1: Increment scratch
DO NOTE: .2: Operand scratch
DO NOTE: .3: Result scratch
DO NOTE: .4: Overflow scratch
DO NOTE: .5: Array length
DO NOTE: .6: Iteration variable
DO NOTE: .7: Current array element
DO NOTE: .8: Another iteration variable
DO NOTE: .9: Another array element
DO NOTE: First, we read the length of the array
DO WRITE IN .5
DO ,1 <- .5
DO NOTE: Now we need to read in the values of the array
DO .6 <- #1
(1) DO FORGET #1
DO READ OUT .6
DO WRITE IN ,1 SUB .6
DO NOTE: Checking and Increment
DO (101) NEXT
DO (110) NEXT
DO NOTE: Branching
DO (2) NEXT
DO NOTE: Only get here if Length > Index we just read into
DO (1) NEXT
(2) DO (3) NEXT
DO NOTE: Only get here if Length <= Index we just read into
DO (4) NEXT
(3) DO RESUME .4
(4) DO FORGET #2
DO NOTE: Now we can start the insertion sort
DO .6 <- #2
(5) DO FORGET #1
DO .7 <- ,1 SUB .6
DO .8 <- .6
DO (120) NEXT
DO NOTE: Nested loop
(6) DO FORGET #1
DO .9 <- ,1 SUB .8
DO NOTE: Check if .9 > .7
DO (102) NEXT
DO (12) NEXT
DO NOTE: Only get here if .9 > .7: Do loop body
DO (7) NEXT
(12) DO (13) NEXT
DO NOTE: Only get here if .9 <= .7: Break
DO (8) NEXT
(13) DO RESUME .4
(7) DO FORGET #1
DO .1 <- .8
DO (1020) NEXT
DO ,1 SUB .1 <- ,1 SUB .8
DO (120) NEXT
DO NOTE: Check if .8 > 0
DO .1 <- .8
DO .2 <- #65535
DO (1009) NEXT
DO NOTE: Now .4 <- #2 if .8 > 0 else #1
DO (22) NEXT
DO NOTE: Only get here if .8 > 0
DO (6) NEXT
(22) DO (23) NEXT
DO NOTE: Only get here if .8 == 0
DO (8) NEXT
(23) DO RESUME .4
DO NOTE: End of nested loop
(8) DO FORGET #2
DO NOTE: Place current element
DO .1 <- .8
DO (1020) NEXT
DO ,1 SUB .1 <- .7
DO NOTE: Checking and Increment
DO (101) NEXT
DO (110) NEXT
DO NOTE: Branching
DO (32) NEXT
DO NOTE: Only get here if Length > Index we just processed
DO (5) NEXT
(32) DO (33) NEXT
DO NOTE: Only get here if Length <= Index we just processed
DO (34) NEXT
(33) DO RESUME .4
(34) DO FORGET #2
DO NOTE: Now we can output the result array
DO .6 <- #1
(41) DO FORGET #1
DO READ OUT ,1 SUB .6
DO NOTE: Checking and Increment
DO (101) NEXT
DO (110) NEXT
DO NOTE: Branching
DO (42) NEXT
DO NOTE: Only get here if Length > Index we just wrote out of
DO (41) NEXT
(42) DO (43) NEXT
DO NOTE: Only get here if Length <= Index we just wrote out of
DO GIVE UP
(43) DO RESUME .4
DO NOTE: The remainder of the file is subroutines
DO NOTE: Subroutine: .4 <- #2 if .2 > .1 else #1 (Writes .1 through .4)
DO NOTE: Underflow subtraction and then detect overflow on addition
(100) DO (1010) NEXT
DO .1 <- .3
DO (1009) NEXT
DO RESUME #1
DO NOTE: Subroutine: .4 <- #2 if .5 > .6 else #1 (Writes .1 through .4)
(101) DO .1 <- .6
DO .2 <- .5
DO (100) NEXT
DO RESUME #1
DO NOTE: Subroutine: .4 <- #2 if .9 > .7 else #1 (Writes .1 through .4)
(102) DO .1 <- .7
DO .2 <- .9
DO (100) NEXT
DO RESUME #1
DO NOTE: Subroutine: Increment .6 (Writes .1)
(110) DO .1 <- .6
DO (1020) NEXT
DO .6 <- .1
DO RESUME #1
DO NOTE: Subroutine: Decrement .8 (Writes .1 through .3)
(120) DO .1 <- .8
DO .2 <- #1
DO (1010) NEXT
DO .8 <- .3
DO RESUME #1
Python (insertion.py)
#!/usr/bin/env python3
# Array length less than 2 is not checked but is an error
# First, we read the length of the array
length = int(input()) # WRITE IN .5
# INTERCAL arrays are 1-indexed: simulating that with None at index 0
arr = [None] + [None] * length # ,1 <- .5
# Now we need to read in the values of the array
i = 1 # .6 <- #1
while True: # label (1)
print('\n{}'.format(i)) # READ OUT .6
arr[i] = int(input()) # WRITE IN ,1 SUB .6
# Checking and Increment
gt = (length > i) # (101) NEXT
i += 1 # (110) NEXT
# Branching
if gt:
# Only get here if Length > Index we just read into
continue # (1) NEXT
else:
# Only get here if Length <= Index we just read into
break # (4) NEXT
# Now we can start the insertion sort
i = 2 # .6 <- #2
while True: # label (5)
x = arr[i] # .7 <- ,1 SUB .6
j = i - 1 # .8 <- .6; (120) NEXT
# Nested loop
while True: # label (6)
y = arr[j] # .9 <- ,1 SUB .8
# Check if y > x
gt = (y > x) # (102) NEXT
if gt:
# Only get here if y > x: Do loop body
pass # (7) NEXT
else:
# Only get here if x <= y: Break
break # (8) NEXT
arr[j + 1] = arr[j] # .1 <- .8; (1020) NEXT; ,1 SUB .1 <- ,1 SUB .8
j -= 1 # (120) NEXT
# Check if j > 0
gt = (j > 0) # .1 <- .8; .2 <- #65535; (1009) NEXT
# Now gt = True if j > 0 else False
if gt:
# Only get here if j > 0
continue # (6) NEXT
else:
# Only get here if j == 0
break # (8) NEXT
# End of nested loop
# Place current element
arr[j + 1] = x # .1 <- .8; (1020) NEXT; ,1 SUB .1 <- .7
# Checking and Increment
gt = (length > i) # (101) NEXT
i += 1 # (110) NEXT
# Branching
if gt:
# Only get here if Length > Index we just processed
continue # (5) NEXT
else:
# Only get here if Length <= Index we just processed
break # (34) NEXT
i = 1 # .6 <- #1
while True: # label (41)
print('\n{}'.format(arr[i])) # READ OUT ,1 SUB .6
# Checking and Increment
gt = (length > i) # (101) NEXT
i += 1 # (110) NEXT
# Branching
if gt:
# Only get here if Length > Index we just wrote out of
continue # (41) NEXT
else:
# Only get here if Length <= Index we just wrote out of
raise SystemExit(0) # GIVE UP