Skip to content

Instantly share code, notes, and snippets.

@paigeadelethompson
Last active June 11, 2026 03:37
Show Gist options
  • Select an option

  • Save paigeadelethompson/0253c1809b50fc1cbbd28c695a6cbb55 to your computer and use it in GitHub Desktop.

Select an option

Save paigeadelethompson/0253c1809b50fc1cbbd28c695a6cbb55 to your computer and use it in GitHub Desktop.
static int ROWS = 20;
static int COLS = 40;
void initializeBoard(int *board) {
int i, j;
for (i = 0; i < ROWS; i++) {
for (j = 0; j < COLS; j++) {
*(board + i * COLS + j) = 0;
}
}
/* Glider pattern coordinates */
*(board + 0 * COLS + 1) = 1;
*(board + 1 * COLS + 2) = 1;
*(board + 2 * COLS + 0) = 1;
*(board + 2 * COLS + 1) = 1;
*(board + 2 * COLS + 2) = 1;
}
void printBoard(int *board) {
int i, j;
printf("\033[H\033[J"); /* Clear terminal screen */
for (i = 0; i < ROWS; i++) {
for (j = 0; j < COLS; j++) {
if (*(board + i * COLS + j) == 1) {
printf("O");
} else {
printf(".");
}
}
printf("\n");
}
}
int countNeighbors(int *board, int row, int col) {
int count = 0;
int i, j;
for (i = -1; i <= 1; i++) {
for (j = -1; j <= 1; j++) {
int newRow, newCol;
if (i == 0 && j == 0) continue;
newRow = row + i;
newCol = col + j;
/* Wrap around the board edges (Toroidal grid) */
if (newRow < 0) newRow = ROWS - 1;
else if (newRow >= ROWS) newRow = 0;
if (newCol < 0) newCol = COLS - 1;
else if (newCol >= COLS) newCol = 0;
count += *(board + newRow * COLS + newCol);
}
}
return count;
}
void updateBoard(int *board, int *nextBoard) {
int i, j;
for (i = 0; i < ROWS; i++) {
for (j = 0; j < COLS; j++) {
int liveNeighbors = countNeighbors(board, i, j);
int isAlive = *(board + i * COLS + j);
int *target = nextBoard + i * COLS + j;
if (isAlive && (liveNeighbors < 2 || liveNeighbors > 3)) {
*target = 0;
} else if (!isAlive && liveNeighbors == 3) {
*target = 1;
} else {
*target = isAlive;
}
}
}
}
void copyBoard(int *board, int *nextBoard) {
int i, j;
for (i = 0; i < ROWS; i++) {
for (j = 0; j < COLS; j++) {
*(board + i * COLS + j) = *(nextBoard + i * COLS + j);
}
}
}
int main() {
/* Reference types allocated on the heap to avoid local value errors */
int *board = (int *)malloc(20 * 40 * sizeof(int));
int *nextBoard = (int *)malloc(20 * 40 * sizeof(int));
/* Basic safety check for heap allocation */
if (board == NULL || nextBoard == NULL) {
return 1;
}
initializeBoard(board);
while (1) {
printBoard(board);
updateBoard(board, nextBoard);
copyBoard(board, nextBoard);
usleep(100000); /* Delay 100 milliseconds */
}
/* Free memory (unreachable in infinite loop but good practice) */
free(board);
free(nextBoard);
return 0;
}
#!/bin/sh
set -e -u -f
LC_ALL=C
# static int ROWS = 20;
_ROWS=20
# static int COLS = 40;
_COLS=40
# void initializeBoard(int *board) {
# int i, j;
# for (i = 0; i < ROWS; i++) {
# for (j = 0; j < COLS; j++) {
# *(board + i * COLS + j) = 0;
# }
# }
#
# /* Glider pattern coordinates */
# *(board + 0 * COLS + 1) = 1;
# *(board + 1 * COLS + 2) = 1;
# *(board + 2 * COLS + 0) = 1;
# *(board + 2 * COLS + 1) = 1;
# *(board + 2 * COLS + 2) = 1;
# }
: $((j = i = board = 0))
_initializeBoard() { let board $2
let i; let j
i=0
while [ $i -lt $_ROWS ]; do
j=0
while [ $j -lt $_COLS ]; do
: $((_$((board + (i * _COLS) + j)) = 0))
: $(((j += 1) - 1))
done
: $(((i += 1) - 1))
done
: $((_$((board + (0 * _COLS) + 1)) = 1))
: $((_$((board + (1 * _COLS) + 2)) = 1))
: $((_$((board + (2 * _COLS) + 0)) = 1))
: $((_$((board + (2 * _COLS) + 1)) = 1))
: $((_$((board + (2 * _COLS) + 2)) = 1))
endlet $1 j i board
}
# void printBoard(int *board) {
# int i, j;
# printf("\033[H\033[J"); /* Clear terminal screen */
# for (i = 0; i < ROWS; i++) {
# for (j = 0; j < COLS; j++) {
# if (*(board + i * COLS + j) == 1) {
# printf("O");
# } else {
# printf(".");
# }
# }
# printf("\n");
# }
# }
: $((j = i = board = 0))
_printBoard() { let board $2
let i; let j
printf ""
i=0
while [ $i -lt $_ROWS ]; do
j=0
while [ $j -lt $_COLS ]; do
if [ $((_$((board + (i * _COLS) + j)))) = 1 ] ; then
printf "O"
else
printf "."
fi
: $(((j += 1) - 1))
done
printf "\n"
: $(((i += 1) - 1))
done
endlet $1 j i board
}
# int countNeighbors(int *board, int row, int col) {
# int count = 0;
# int i, j;
# for (i = -1; i <= 1; i++) {
# for (j = -1; j <= 1; j++) {
# int newRow, newCol;
# if (i == 0 && j == 0) continue;
#
# newRow = row + i;
# newCol = col + j;
#
# /* Wrap around the board edges (Toroidal grid) */
# if (newRow < 0) newRow = ROWS - 1;
# else if (newRow >= ROWS) newRow = 0;
#
# if (newCol < 0) newCol = COLS - 1;
# else if (newCol >= COLS) newCol = 0;
#
# count += *(board + newRow * COLS + newCol);
# }
# }
# return count;
# }
: $((newCol = newRow = j = i = count = col = row = board = 0))
_countNeighbors() { let board $2; let row $3; let col $4
let count; let i; let j; let newRow; let newCol
count=0
i=-1
while [ $i -le 1 ]; do
j=-1
while [ $j -le 1 ]; do
if [ $i = 0 ] && [ $j = 0 ] ; then
: $(((j += 1) - 1))
continue
fi
newRow=$((row + i))
newCol=$((col + j))
if [ $newRow -lt 0 ] ; then
newRow=$((_ROWS - 1))
elif [ $newRow -ge $_ROWS ] ; then
newRow=0
fi
if [ $newCol -lt 0 ] ; then
newCol=$((_COLS - 1))
elif [ $newCol -ge $_COLS ] ; then
newCol=0
fi
: $((count += _$((board + (newRow * _COLS) + newCol))))
: $(((j += 1) - 1))
done
: $(((i += 1) - 1))
done
: $(($1 = count))
endlet $1 newCol newRow j i count col row board
}
# void updateBoard(int *board, int *nextBoard) {
# int i, j;
# for (i = 0; i < ROWS; i++) {
# for (j = 0; j < COLS; j++) {
# int liveNeighbors = countNeighbors(board, i, j);
# int isAlive = *(board + i * COLS + j);
# int *target = nextBoard + i * COLS + j;
#
# if (isAlive && (liveNeighbors < 2 || liveNeighbors > 3)) {
# *target = 0;
# } else if (!isAlive && liveNeighbors == 3) {
# *target = 1;
# } else {
# *target = isAlive;
# }
# }
# }
# }
: $((target = isAlive = liveNeighbors = j = i = nextBoard = board = 0))
_updateBoard() { let board $2; let nextBoard $3
let i; let j; let liveNeighbors; let isAlive; let target
i=0
while [ $i -lt $_ROWS ]; do
j=0
while [ $j -lt $_COLS ]; do
_countNeighbors liveNeighbors $board $i $j
isAlive=$((_$((board + (i * _COLS) + j))))
target=$((nextBoard + (i * _COLS) + j))
if [ $isAlive != 0 ] && { [ $liveNeighbors -lt 2 ] || [ $liveNeighbors -gt 3 ]; } ; then
: $((_$target = 0))
elif [ $((! isAlive)) != 0 ] && [ $liveNeighbors = 3 ] ; then
: $((_$target = 1))
else
: $((_$target = isAlive))
fi
: $(((j += 1) - 1))
done
: $(((i += 1) - 1))
done
endlet $1 target isAlive liveNeighbors j i nextBoard board
}
# void copyBoard(int *board, int *nextBoard) {
# int i, j;
# for (i = 0; i < ROWS; i++) {
# for (j = 0; j < COLS; j++) {
# *(board + i * COLS + j) = *(nextBoard + i * COLS + j);
# }
# }
# }
: $((j = i = nextBoard = board = 0))
_copyBoard() { let board $2; let nextBoard $3
let i; let j
i=0
while [ $i -lt $_ROWS ]; do
j=0
while [ $j -lt $_COLS ]; do
: $((_$((board + (i * _COLS) + j)) = _$((nextBoard + (i * _COLS) + j))))
: $(((j += 1) - 1))
done
: $(((i += 1) - 1))
done
endlet $1 j i nextBoard board
}
# int main() {
# /* Reference types allocated on the heap to avoid local value errors */
# int *board = (int *)malloc(20 * 40 * sizeof(int));
# int *nextBoard = (int *)malloc(20 * 40 * sizeof(int));
#
# /* Basic safety check for heap allocation */
# if (board == NULL || nextBoard == NULL) {
# return 1;
# }
#
# initializeBoard(board);
#
# while (1) {
# printBoard(board);
# updateBoard(board, nextBoard);
# copyBoard(board, nextBoard);
# usleep(100000); /* Delay 100 milliseconds */
# }
#
# /* Free memory (unreachable in infinite loop but good practice) */
# free(board);
# free(nextBoard);
#
# return 0;
# }
: $((__t1 = nextBoard = board = 0))
_main() {
let board; let nextBoard; let __t1
_malloc __t1 $((20 * 40 * 1))
board=$__t1
_malloc __t1 $((20 * 40 * 1))
nextBoard=$__t1
if [ $board = $_NULL ] || [ $nextBoard = $_NULL ] ; then
: $(($1 = 1))
endlet $1 __t1 nextBoard board
return
fi
_initializeBoard __ $board
while [ 1 != 0 ]; do
_printBoard __ $board
_updateBoard __ $board $nextBoard
_copyBoard __ $board $nextBoard
_usleep __ 100000
done
_free __ $board
_free __ $nextBoard
: $(($1 = 0))
endlet $1 __t1 nextBoard board
}
#_ Runtime library
__ALLOC=1 # Starting heap at 1 because 0 is the null pointer.
_malloc() { # $2 = object size
: $((_$__ALLOC = $2)) # Track object size
: $(($1 = $__ALLOC + 1))
: $((__ALLOC += $2 + 1))
}
_free() { # $2 = object to free
__ptr=$(($2 - 1)) # Start of object
__end=$((__ptr + _$__ptr)) # End of object
while [ $__ptr -lt $__end ]; do
unset "_$__ptr"
: $((__ptr += 1))
done
: $(($1 = 0)) # Return 0
}
#_ Local variables
__=0
__SP=0
let() { # $1: variable name, $2: value (optional)
: $((__$((__SP += 1))=$1)) # Push
: $(($1=${2-0})) # Init
}
endlet() { # $1: return variable
# $2...: function local variables
__ret=$1 # Don't overwrite return value
: $((__tmp = $__ret))
while [ $# -ge 2 ]; do
: $(($2 = __$(((__SP -= 1) + 1)))) # Pop
shift;
done
: $(($__ret=__tmp)) # Restore return value
}
__code=0; # Exit code
_main __code
exit $__code
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment