From 05a422b438375d55eb58c42e12c3f435c3889a56 Mon Sep 17 00:00:00 2001 From: Luxferre Date: Fri, 29 May 2026 09:21:49 +0300 Subject: [PATCH] added elem --- README.md | 1 + elem | 38 ++++++++++++++++++++++++++++++++++++++ 2 files changed, 39 insertions(+) create mode 100755 elem diff --git a/README.md b/README.md index b337163..2c3dd45 100644 --- a/README.md +++ b/README.md @@ -8,4 +8,5 @@ For POSIX shell compatible scripts, see the [sh-goodies](https://codeberg.org/lu * [YouStore](./ys): a way to securely store any set of files/directories inside a video * [1DLife](./1dlife): Jon Millen's 1D Game of Life in pure Bash +* [Elem](./elem): Stephen Wolfram's elementary cellular automatons in pure Bash * [bmux](./bmux): a simple, dmux-like session manager in Bash on top of just dtach diff --git a/elem b/elem new file mode 100755 index 0000000..da8b7bd --- /dev/null +++ b/elem @@ -0,0 +1,38 @@ +#!/usr/bin/env bash +# Elementary cellular automatons (rule X) in pure Bash (zero dependencies) +# Usage: echo 'state' | elem rule# [iterations] +# Created by Luxferre in 2026, released into public domain + +D2B=({0..1}{0..1}{0..1}{0..1}{0..1}{0..1}{0..1}{0..1}) +RULENO="$1" +if ((RULENO > 255 || RULENO < 0)); then + echo "Invalid rule number!" + exit 1 +fi +rule="${D2B[RULENO]}" + +ITERS="$2" +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 +[[ -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 + +for ((i=0; i