Created
December 4, 2018 03:19
-
-
Save mbehan/6cbca570e9b80713f0f4e900ac00733a to your computer and use it in GitHub Desktop.
Swift playground for outputting elementary cellular automata
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import Foundation | |
extension Bool { | |
init(_ char: Character) { | |
self = String(char).boolValue | |
} | |
} | |
extension String { | |
func character(at index: Int) -> Character { | |
return self[self.index(self.startIndex, offsetBy: index)] | |
} | |
} | |
extension String { | |
var boolValue: Bool { | |
return NSString(string: self).boolValue | |
} | |
} | |
extension Bool: ExpressibleByIntegerLiteral { | |
public typealias IntegerLiteralType = Int | |
public init(integerLiteral value: Int) { | |
if value > 0 { | |
self.init(true) | |
} else { | |
self.init(false) | |
} | |
} | |
} | |
struct InputState: Hashable, ExpressibleByStringLiteral { | |
let previous: Bool | |
let current: Bool | |
let next: Bool | |
init(stringLiteral: String) { | |
previous = Bool(stringLiteral.character(at: 0)) | |
current = Bool(stringLiteral.character(at: 1)) | |
next = Bool(stringLiteral.character(at: 2)) | |
} | |
init(previous: Bool, current: Bool, next: Bool) { | |
self.previous = previous | |
self.current = current | |
self.next = next | |
} | |
} | |
typealias Output = Bool | |
struct Generation: CustomStringConvertible { | |
let cells: [Bool] | |
let rules: [InputState: Output] | |
init(size: Int, rules: [InputState: Output]){ | |
var initialCells = Array(repeating: false, count: size) | |
initialCells[size / 2] = true | |
cells = initialCells | |
self.rules = rules | |
} | |
init(cells: [Bool], rules: [InputState: Output]){ | |
self.cells = cells | |
self.rules = rules | |
} | |
func nextGeneration() -> Generation{ | |
var newCells = [Bool]() | |
for (index,cell) in cells.enumerated(){ | |
let previous = index == 0 ? false : cells[index - 1] | |
let next = index == cells.count - 1 ? false : cells[index + 1] | |
let input = InputState(previous: previous, current: cell, next: next) | |
newCells.append(rules[input]!) | |
} | |
return Generation(cells: newCells, rules: rules) | |
} | |
var description: String { | |
var str = "" | |
for value in cells { | |
str += value ? "X" : " " | |
} | |
return str | |
} | |
} | |
var rule30 = [InputState: Output]() | |
rule30["111"] = 0 | |
rule30["110"] = 0 | |
rule30["101"] = 0 | |
rule30["100"] = 1 | |
rule30["011"] = 1 | |
rule30["010"] = 1 | |
rule30["001"] = 1 | |
rule30["000"] = 0 | |
var rule60 = [InputState: Output]() | |
rule60["111"] = 0 | |
rule60["110"] = 0 | |
rule60["101"] = 1 | |
rule60["100"] = 1 | |
rule60["011"] = 1 | |
rule60["010"] = 1 | |
rule60["001"] = 0 | |
rule60["000"] = 0 | |
let numGenerations = 64 | |
var generation = Generation(size: 512, rules: rule60) | |
for _ in 0 ..< numGenerations{ | |
print(generation) | |
generation = generation.nextGeneration() | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment