diff options
author | elioat <elioat@tilde.institute> | 2024-06-23 13:19:41 -0400 |
---|---|---|
committer | elioat <elioat@tilde.institute> | 2024-06-23 13:19:41 -0400 |
commit | dff45625c50d2314c66199fc9df6071409ca4afe (patch) | |
tree | cc457ca09beea94d99c7b504b64445c64d7626e7 | |
parent | 20b3050a18b0902d8620f3dbd82d9fc4c7a61cbd (diff) | |
download | tour-dff45625c50d2314c66199fc9df6071409ca4afe.tar.gz |
*
-rw-r--r-- | js/fsa-tokenizer.js | 74 | ||||
-rw-r--r-- | js/life.js | 14 |
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; }) ); |