about summary refs log tree commit diff stats
diff options
context:
space:
mode:
authorelioat <elioat@tilde.institute>2024-06-23 13:19:41 -0400
committerelioat <elioat@tilde.institute>2024-06-23 13:19:41 -0400
commitdff45625c50d2314c66199fc9df6071409ca4afe (patch)
treecc457ca09beea94d99c7b504b64445c64d7626e7
parent20b3050a18b0902d8620f3dbd82d9fc4c7a61cbd (diff)
downloadtour-dff45625c50d2314c66199fc9df6071409ca4afe.tar.gz
*
-rw-r--r--js/fsa-tokenizer.js74
-rw-r--r--js/life.js14
2 files changed, 88 insertions, 0 deletions
diff --git a/js/fsa-tokenizer.js b/js/fsa-tokenizer.js
new file mode 100644
index 0000000..601583c
--- /dev/null
+++ b/js/fsa-tokenizer.js
@@ -0,0 +1,74 @@
+const TokenizerFSA = (() => {
+  // Define the states
+  const states = {
+    START: 'START',
+    IN_WORD: 'IN_WORD',
+    IN_NUMBER: 'IN_NUMBER',
+    IN_SYMBOL: 'IN_SYMBOL'
+  };
+
+  // Utility functions to check character types
+  const isLetter = char => /[a-zA-Z]/.test(char);
+  const isDigit = char => /\d/.test(char);
+  const isSymbol = char => /\W/.test(char) && !/\s/.test(char);
+
+  // Add a token to the list if it's not empty
+  const addToken = (token, tokens) => {
+    if (token) tokens.push(token);
+  };
+
+  // Process a single character and update the state and token accordingly
+  const processChar = (state, char, token, tokens) => {
+    switch (state) {
+      case states.START:
+        if (isLetter(char)) return { state: states.IN_WORD, token: char };
+        if (isDigit(char)) return { state: states.IN_NUMBER, token: char };
+        if (isSymbol(char)) return { state: states.IN_SYMBOL, token: char };
+        break;
+
+      case states.IN_WORD:
+        if (isLetter(char)) return { state, token: token + char };
+        addToken(token, tokens);
+        return { state: states.START, token: '' };
+
+      case states.IN_NUMBER:
+        if (isDigit(char)) return { state, token: token + char };
+        addToken(token, tokens);
+        return { state: states.START, token: '' };
+
+      case states.IN_SYMBOL:
+        if (isSymbol(char)) return { state, token: token + char };
+        addToken(token, tokens);
+        return { state: states.START, token: '' };
+
+      default:
+        return { state: states.START, token: '' };
+    }
+  };
+
+  // Tokenize the entire input text
+  const tokenize = text => {
+    let state = states.START;
+    let token = '';
+    const tokens = [];
+
+    for (const char of text) {
+      const result = processChar(state, char, token, tokens);
+      state = result.state;
+      token = result.token;
+    }
+
+    // Add the last token if any
+    addToken(token, tokens);
+
+    return tokens;
+  };
+
+  // Expose the tokenize function as a public method
+  return { tokenize };
+})();
+
+// Example usage
+const text = "Hello, world! 123";
+const tokens = TokenizerFSA.tokenize(text);
+console.log(tokens);  // Output: ['Hello', ',', 'world', '!', '123']
diff --git a/js/life.js b/js/life.js
index b6fe9de..e28e1f3 100644
--- a/js/life.js
+++ b/js/life.js
@@ -1,24 +1,38 @@
 function countNeighbors(grid, x, y) {
+  // Define the offsets for the neighboring cells
   const neighborOffsets = [
       [-1, -1], [-1, 0], [-1, 1],
       [0, -1],           [0, 1],
       [1, -1],  [1, 0],  [1, 1]
   ];
 
+  // Use reduce to iterate over the neighborOffsets and count the number of live neighbors
   return neighborOffsets.reduce((count, [dx, dy]) => {
+      // Calculate the coordinates of the neighboring cell
       const nx = x + dx;
       const ny = y + dy;
+
+      // Check if the neighboring cell is within the grid boundaries and if it is alive
       if (nx >= 0 && ny >= 0 && nx < grid.length && ny < grid[0].length && grid[nx][ny]) {
+          // If the neighboring cell is alive, increment the count
           return count + 1;
       }
+
+      // If the neighboring cell is not alive or is outside the grid boundaries, return the current count
       return count;
   }, 0);
 }
 
 function step(grid) {
+  // Use map to iterate over each cell in the grid and calculate the next state based on the rules of the game
   return grid.map((row, x) =>
       row.map((cell, y) => {
+          // Count the number of live neighbors for the current cell
           const neighbors = countNeighbors(grid, x, y);
+
+          // Apply the rules of the game to determine the next state of the cell
+          // If the cell has 3 live neighbors or has 2 live neighbors and is already alive, it stays alive
+          // Otherwise, it becomes dead
           return neighbors === 3 || (neighbors === 2 && cell) ? 1 : 0;
       })
   );