#include #include #include #include typedef uint8_t u8; typedef uint64_t usize; static void board_print(u8 *board); static void board_print_neighbors(u8 *board); static void board_tick(u8 *input, u8 *output); static u8 board_neighbors_at(u8 *board, usize x, usize y); static inline u8 next_cell_state(u8 cell_state, u8 neighbors); static void print_elapsed_time(struct timespec start, struct timespec end); #define BOARD_WIDTH 5L #define BOARD_LENGTH (BOARD_WIDTH * BOARD_WIDTH) #define BOARD_WIDTH_WITH_BOUNDS (BOARD_WIDTH + 2L) #define BOARD_LENGTH_WITH_BOUNDS (BOARD_WIDTH_WITH_BOUNDS * BOARD_WIDTH_WITH_BOUNDS) #define SWAP_BOARDS(BOARD, SWAP) do { u8 *TMP = BOARD; BOARD = SWAP; SWAP = TMP; } while (0); int main() { u8 *board1 = calloc(BOARD_LENGTH_WITH_BOUNDS, sizeof(u8)); u8 *board2 = calloc(BOARD_LENGTH_WITH_BOUNDS, sizeof(u8)); fprintf(stderr, "Memory: 2x %ld bytes (-> %.2f MB).\n", sizeof(board1) * BOARD_LENGTH_WITH_BOUNDS, (sizeof(board1) * BOARD_LENGTH_WITH_BOUNDS) / 1024.0 / 1024.0 * 2.0); fprintf(stderr, "Board: %ld x %ld (%ld)\n", (usize)BOARD_WIDTH, (usize)BOARD_WIDTH, (usize)BOARD_LENGTH); fprintf(stderr, "Befülle Board..."); struct timespec time_start; clock_gettime(CLOCK_MONOTONIC, &time_start); // Board aufsetzen srand(time(NULL)); for (usize i = 0; i < BOARD_LENGTH_WITH_BOUNDS; ++i) { board1[i] = rand() % 2; } for (usize i = 0; i < BOARD_WIDTH_WITH_BOUNDS; ++i) { board1[ i + 0 * BOARD_WIDTH_WITH_BOUNDS] = 0; board1[BOARD_WIDTH_WITH_BOUNDS + i * BOARD_WIDTH_WITH_BOUNDS] = 0; board1[ 0 + i * BOARD_WIDTH_WITH_BOUNDS] = 0; board1[BOARD_WIDTH_WITH_BOUNDS + i * BOARD_WIDTH_WITH_BOUNDS] = 0; } struct timespec time_board_done; clock_gettime(CLOCK_MONOTONIC, &time_board_done); print_elapsed_time(time_start, time_board_done); fprintf(stderr, "Starte tick... "); // Iterieren u8 *board = board1; u8 *swap = board2; fprintf(stderr, "\n"); board_print(board); for (usize i = 0; i < 3; ++i) { board_tick(board, swap); SWAP_BOARDS(board, swap); } struct timespec time_end; clock_gettime(CLOCK_MONOTONIC, &time_end); print_elapsed_time(time_board_done, time_end); board_print(board); free(board1); free(board2); return 0; } static void board_print(u8 *board) { for (usize i = 0; i < BOARD_LENGTH; ++i) { if (i > 0 && i % BOARD_WIDTH == 0) { putchar('\n'); } putchar(board[i] == 1 ? '#' : '.'); } putchar('\n'); } static void board_print_neighbors(u8 *board) { for (usize i = 0; i < BOARD_LENGTH; ++i) { if (i > 0 && i % BOARD_WIDTH == 0) { putchar('\n'); } putchar('0' + board_neighbors_at(board, i % BOARD_WIDTH, i / BOARD_WIDTH)); } putchar('\n'); } static void board_tick(u8 *input, u8 *output) { for (usize i = 0; i < BOARD_LENGTH; ++i) { u8 neighbors = board_neighbors_at(input, i % BOARD_WIDTH, i / BOARD_WIDTH); output[i] = next_cell_state(input[i], neighbors); } } static u8 board_neighbors_at(u8 *board, usize x, usize y) { u8 number_of_neighbors = 0; for (int y_offset = -1; y_offset <= 1; ++y_offset) { for (int x_offset = -1; x_offset <= 1; ++x_offset) { if ( (x_offset == 0 && y_offset == 0) || ((int)x + x_offset) < 0 || x + x_offset >= BOARD_WIDTH || ((int)y + y_offset) < 0 || y + y_offset >= BOARD_WIDTH) { continue; } usize i = (x + x_offset) + BOARD_WIDTH * (y + y_offset); number_of_neighbors += board[i]; } } return number_of_neighbors; } static inline u8 next_cell_state(u8 cell_state, u8 neighbors) { return (neighbors == 3 || (cell_state && neighbors == 2)) ? 1 : 0; } static void print_elapsed_time(struct timespec start, struct timespec end) { long seconds = end.tv_sec - start.tv_sec; long nanoseconds = end.tv_nsec - start.tv_nsec; double elapsed_ms = seconds * 1000.0 + nanoseconds / 1e6; fprintf(stderr, " %.3f ms\n", elapsed_ms); }