Skip to content

Instantly share code, notes, and snippets.

@gboncoffee
Last active August 5, 2023 03:59
Show Gist options
  • Save gboncoffee/c8e75f5524bab091499da608d13b3525 to your computer and use it in GitHub Desktop.
Save gboncoffee/c8e75f5524bab091499da608d13b3525 to your computer and use it in GitHub Desktop.
Rule 110 in OCaml
open List;;
(*
* 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.
*)
type cell = I | O;;
let rule110 a b c =
match (a, b, c) with
| (I, I, I) -> O
| (I, I, O) -> I
| (I, O, I) -> I
| (I, O, O) -> O
| (O, I, I) -> I
| (O, I, O) -> I
| (O, O, I) -> I
| (O, O, O) -> O;;
let rec apply_rule110' a l =
match (a, l) with
| (x, []) -> [x]
| (x, [y]) -> [rule110 x y O]
| (x, y :: r) -> rule110 x y (hd r) :: apply_rule110' y r;;
let apply_rule110 l = apply_rule110' O l;;
(* type handling *)
let print_cell = function
| I -> print_string "1"
| O -> print_string " ";;
let rec print_cells = function
| [] -> print_newline ()
| c :: r -> print_cell c; print_cells r;;
let rec cell_of_char = function
| '1' -> I
| '0' -> O
| c -> O;; (* unecessary as we garantee the strings to be just 0 and 1 *)
let rec cells_of_char_list = function
| [] -> []
| c :: r -> cell_of_char c :: cells_of_char_list r;;
let list_of_string s = init (String.length s) (String.get s);;
let cells_of_string s = cells_of_char_list @@ list_of_string s;;
let rec is_binary' = function
| [] -> true
| '1' :: r
| '0' :: r -> is_binary' r
| a :: r -> false;;
let is_binary s = is_binary' @@ list_of_string s;;
(* now the program starts to look ugly *)
let rec get_binary prompt =
print_string prompt;
let s = read_line () in
if is_binary s then s else get_binary "Only enter 0s and 1s!: ";;
let get_int prompt =
print_string prompt;
int_of_string @@ read_line ();;
let main_loop =
let n = get_int "Enter number of iterations: " in
let s = ref @@ cells_of_string @@ get_binary "Enter the initial state: " in
for i = 1 to n do
s := apply_rule110 !s;
print_cells !s;
done
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment