Skip to content

Instantly share code, notes, and snippets.

@gboncoffee
Created April 4, 2024 03:26
Show Gist options
  • Save gboncoffee/861039050d0f32d6cddfa565e6fd248f to your computer and use it in GitHub Desktop.
Save gboncoffee/861039050d0f32d6cddfa565e6fd248f to your computer and use it in GitHub Desktop.
Rule 110 in Odin
package main
import "core:fmt"
import "core:os"
import "core:strconv"
import "core:strings"
panic_read :: proc() {
fmt.eprintln("cannot read from stdin")
os.exit(1)
}
rule110 :: proc(a, b, c: u8) -> u8 {
arr := [3]u8{a, b, c}
switch arr {
case {'0', '0', '0'}:
return '0'
case {'0', '0', '1'}:
return '1'
case {'0', '1', '0'}:
return '1'
case {'0', '1', '1'}:
return '1'
case {'1', '0', '0'}:
return '0'
case {'1', '0', '1'}:
return '1'
case {'1', '1', '0'}:
return '1'
case {'1', '1', '1'}:
return '0'
}
return '0'
}
apply_rule_110 :: proc(s, o: []u8) {
s := s
o := o
o[0] = rule110('0', s[0], s[1])
for c, i in s[1:(len(s)-1)] {
o[i+1] = rule110(s[i], s[i+1], s[i+2])
}
o[len(s)-1] = rule110(s[len(s)-2], s[len(s)-1], '0')
for c, i in o do s[i] = c
}
ensure_binary_string_or_panic :: proc(s: []u8) {
for c in s {
if (c != '0' && c != '1') {
fmt.eprintln("input is not only 0 and 1")
os.exit(1)
}
}
}
run_rule110 :: proc(input: []u8, times: int) {
ensure_binary_string_or_panic(input)
other: []u8 = make([]u8, len(input))
defer delete(other)
for _ in 1..=times {
apply_rule_110(input, other)
for c in string(input) {
if c == '1' do fmt.print(1)
else do fmt.print(' ')
}
fmt.println("")
}
}
main :: proc() {
buf: [256]byte
n, err := os.read(os.stdin, buf[:])
if err < 0 do panic_read()
it, ok := strconv.parse_int(string(buf[:(n-1)]))
if !ok {
fmt.eprintln("cannot parse input as int")
os.exit(1)
}
n, err = os.read(os.stdin, buf[:])
if err < 0 do panic_read()
run_rule110(buf[:(n-1)], it)
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment