2026-05-28 07:02:36 +03:00
|
|
|
#!/usr/bin/env bash
|
2026-05-28 09:48:15 +03:00
|
|
|
# Jon Millen's 1D Game of Life in pure Bash (zero dependencies)
|
2026-05-28 07:02:36 +03:00
|
|
|
# Usage: echo 'state' | 1dlife [iterations]
|
|
|
|
|
# Created by Luxferre in 2026, released into public domain
|
|
|
|
|
|
|
|
|
|
ITERS="$1"
|
2026-05-28 09:48:15 +03:00
|
|
|
if [[ -z "$ITERS" ]]; then # get the iteration count dynamically
|
|
|
|
|
shopt -s checkwinsize # enable checking the terminal size
|
|
|
|
|
:|: # trigger the WINCH signal to get the size
|
|
|
|
|
ITERS=$((LINES - 1)) # the row count is now in LINES
|
|
|
|
|
fi
|
2026-05-28 07:02:36 +03:00
|
|
|
[[ -z "$RENDER_CHAR" ]] && RENDER_CHAR='#'
|
|
|
|
|
|
|
|
|
|
# read and process the state
|
|
|
|
|
IFS= read -r state
|
|
|
|
|
state="${state//[[:space:]]/0}"
|
|
|
|
|
state="${state//[^0]/1}"
|
|
|
|
|
slen=$((${#state} - 1)) # length + 4 (temporary padding) - 5
|
|
|
|
|
|
|
|
|
|
# complete rule mapping
|
|
|
|
|
declare -A values=(
|
|
|
|
|
00000 0 00001 0 00010 0 00011 1
|
|
|
|
|
00100 0 00101 0 00110 0 00111 1
|
|
|
|
|
01000 0 01001 1 01010 1 01011 1
|
|
|
|
|
01100 0 01101 1 01110 1 01111 0
|
|
|
|
|
10000 0 10001 1 10010 1 10011 1
|
|
|
|
|
10100 0 10101 1 10110 1 10111 0
|
|
|
|
|
11000 1 11001 1 11010 1 11011 0
|
|
|
|
|
11100 1 11101 0 11110 0 11111 1)
|
|
|
|
|
|
|
|
|
|
for ((i=0; i<ITERS; ++i)); do
|
|
|
|
|
state="00${state}00" # pad the current state from both sides
|
|
|
|
|
newstate=''
|
|
|
|
|
for ((k=0; k<slen; ++k)); do
|
|
|
|
|
vidx="${state:k:5}"
|
|
|
|
|
newstate="${newstate}${values[$vidx]}"
|
|
|
|
|
done
|
|
|
|
|
state="$newstate"
|
|
|
|
|
newstate="${newstate//0/ }"
|
|
|
|
|
printf '%s\n' "${newstate//1/$RENDER_CHAR}"
|
|
|
|
|
done
|