Skip to content

Instantly share code, notes, and snippets.

@gboncoffee
Last active August 5, 2023 03:59
Show Gist options
  • Save gboncoffee/199154d61a05bc928df110ba5f449e6e to your computer and use it in GitHub Desktop.
Save gboncoffee/199154d61a05bc928df110ba5f449e6e to your computer and use it in GitHub Desktop.
Rule 110 in Go
package main
import (
"bufio"
"fmt"
"os"
"strconv"
)
// Copyright (C) 2023 Gabriel de Brito
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.
func readline(prompt string) string {
fmt.Print(prompt)
stdin := bufio.NewScanner(os.Stdin)
stdin.Scan()
return stdin.Text()
}
func readint(prompt string) int {
for {
i, err := strconv.Atoi(readline(prompt))
if nil == err && 0 <= i {
return i
}
fmt.Println("please enter a valid positive integer!")
}
}
func is_binary(s string) bool {
for _, c := range s {
if '0' != c && '1' != c {
return false
}
}
return true
}
func readBinaryString(prompt string) string {
for {
s := readline(prompt)
if is_binary(s) {
return s
}
fmt.Println("please enter a string of only 1 and 0!")
}
}
func applyRule110_chars(bef byte, act byte, aft byte) string {
arr := [3]byte{bef, act, aft}
switch {
case [3]byte{'1', '1', '1'} == arr:
return "0"
case [3]byte{'1', '1', '0'} == arr:
return "1"
case [3]byte{'1', '0', '1'} == arr:
return "1"
case [3]byte{'1', '0', '0'} == arr:
return "0"
case [3]byte{'0', '1', '1'} == arr:
return "1"
case [3]byte{'0', '1', '0'} == arr:
return "1"
case [3]byte{'0', '0', '1'} == arr:
return "1"
case [3]byte{'0', '0', '0'} == arr:
return "0"
}
return "0"
}
func applyRule110(s string) string {
next := applyRule110_chars('0', s[0], s[1])
for i := 1; len(s)-1 > i; i++ {
next += applyRule110_chars(s[i-1], s[i], s[i+1])
}
next += applyRule110_chars(s[len(s)-2], s[len(s)-1], '0')
return next
}
func main() {
fmt.Printf("===\nRule 110\n===\n")
n := readint("number of iterations: ")
s := readBinaryString("initial state: ")
fmt.Println(s)
for n := n; 0 <= n; n-- {
s = applyRule110(s)
for _, c := range s {
if '0' == c {
fmt.Print(" ")
} else {
fmt.Print("1")
}
}
fmt.Println()
}
fmt.Println(s)
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment