/* * Hortensius - Tim Tyler 2000. * * A generator of Hortensius CA RNGs. * * This code has been placed in the public domain. * This means that you can do what you like with it. * Please note that this code comes with no warranty. * */ /* * To Do: * */ import java.lang.Object; public class Hortensius extends Object { public static int size; public static int sizemo; public static int sizeo2; public static int i, j; public static int ret_val; public static int temp; public static int total_number; public static int iterations; public static int generation; public static int count; public static int number; public static int numbermo; public static int numbero2; public static int total_found; public static int cx; public static int hside; public static int hsidemo; public static int mask; public static int period; public static int reversibility; public static int total; public static Executor executor; static int[] in_grid; static int[] out_grid; static int[] tmp_grid; static int[] results; static String output_string; public static void set_size(int h) { hside = h; hsidemo = h - 1; number = 1 << (h - 2); numbermo = number - 1; numbero2 = number >>> 1; in_grid = new int[h]; out_grid = new int[h]; results = new int[number]; } public static void setUpGrid(int n) { for (cx = 1; cx < hsidemo; cx++) { mask = (n >>> (cx - 1)) & 1; if (mask != 0) { in_grid[cx] = 150 << 24; // 150 / 145 } else { in_grid[cx] = 90 << 24; // 90 / 105 } } in_grid[0] = 0; in_grid[hsidemo] = 0; } public static void setUpResults() { for (cx = 0; cx < number; cx++) { results[cx] = 0; } } public static void setUpCells() { in_grid[1] |= 1; } public static void setUpCells(int k) { for (cx = 1; cx < hsidemo; cx++) { if (((k >> (cx - 1)) & 1) != 0) { in_grid[cx] |= 1; } else { in_grid[cx] &= 0xffffff00; } } } public static void update() { // in_grid[0] = (in_grid[0] & 0xffffff00) | (in_grid[hsidemo - 1] & 1); // out_grid[hsidemo - 1]; // in_grid[hsidemo] = (in_grid[hsidemo] & 0xffffff00) | (in_grid[1] & 1); for (cx = 1; cx < hsidemo; cx++) { temp = (in_grid[cx + 1] & 1) | ((in_grid[cx] & 1) << 1) | ((in_grid[cx - 1] & 1) << 2); out_grid[cx] = (in_grid[cx] & -256) | ((in_grid[cx] >>> 24) >>> temp); } // out_grid[0] = 0; // out_grid[hsidemo] = 0; swap_grids(); generation++; } final static void swap_grids() { // swap them... tmp_grid = in_grid; in_grid = out_grid; out_grid = tmp_grid; } public static void report(int n) { resetPrinting(); setUpGrid(n); setUpCells(); generation = 0; R1D_Period.setSearch(in_grid,1); period = 0; do { update(); if ((period == 0) && (R1D_Period.periodFound(in_grid))) { period = generation; } } while (generation < number); // !R1D_Period.periodFound(in_grid)); if (period != 0) { if (period == numbermo) { printOut(); } } executor.execute(); } // Test for reversibility by exhaustively ensuring the automata is bijective public static void reversibilityReport(int n) { resetPrinting(); setUpGrid(n); setUpResults(); generation = 0; for (int wibble = 0; wibble < number; wibble++) { setUpCells(wibble); update(); total = 0; for (cx = hsidemo; cx-- > 1; ) { total = (total << 1) | (in_grid[cx] & 1); } results[total] = 1; } reversibility = 1; for (cx = 0; cx < number; cx++) { // print("" + results[cx]); if (results[cx] == 0) { reversibility = 0; } } if (reversibility != 0) printReversibility(); executor.execute(); } // Test for reversibility by only checking four consecutive states for possible precursors. public static void quickReversibilityReport(int n) { resetPrinting(); setUpGrid(n); reversibility = 0; if ((hasAPrecursor(0)) && (hasAPrecursor(1)) && (hasAPrecursor(2)) && (hasAPrecursor(3))) { reversibility = 1; } if (reversibility != 0) printReversibility(); executor.execute(); } public static boolean hasAPrecursor(int to_check) { for (int wibble = 0; wibble < number; wibble++) { setUpCells(wibble); update(); total = 0; for (cx = hsidemo; cx-- > 1; ) { total = (total << 1) | (in_grid[cx] & 1); } if (total == to_check) return true; } return false; } public static void resetPrinting() { output_string = ""; } public static void printOut() { print("" + count + " - "); for (cx = hsidemo; cx-- > 1; ) { mask = (count >>> (cx - 1)) & 1; if (mask != 0) { print("1"); } else { print("0"); } } print(" - Period: " + period + "\n"); total_found++; } public static void printReversibility() { print("" + count + " - "); for (cx = hsidemo; cx-- > 1; ) { mask = (count >>> (cx - 1)) & 1; if (mask != 0) { print("1"); } else { print("0"); } } print(" - a reversible rule.\n"); total_found++; } public static void print(String x) { output_string += x; } public static void main(String args[]) { executor = new Executor() { public void execute() { System.out.println(output_string); } }; total_number = 6; do { test(total_number); total_number++; } while (true); } public static void test(int total_number) { set_size(total_number); total_found = 0; for (count = 0; count < number; count++) { report(count); } resetPrinting(); print("Total maximal period automata found: " + total_found + ".\n"); executor.execute(); } public static void testReversibility(int total_number) { set_size(total_number); total_found = 0; for (count = 0; count < number; count++) { // reversibilityReport(count); quickReversibilityReport(count); } resetPrinting(); print("Number of reversible rules found: " + total_found + ".\n"); executor.execute(); } }