/** * ARC Puzzle Renderer for Retool - INLINE VERSION * * USAGE IN RETOOL HTML COMPONENT: * Paste this entire code block wrapped in {{ ... }} in your HTML component * * Example for database query: * {{ * (function() { * // ... paste this entire file content here ... * })() * }} */ (function() { // ============================================= // GET DATA FROM RETOOL QUERY // ============================================= // ADJUST THESE LINES based on your Retool setup: const selectedPuzzle = problem_select.value; // Your selector name // Handle empty selection if (!selectedPuzzle) { return '
No puzzle data available. Please select a problem.
'; } // Use the selected row directly const row = selectedPuzzle; // Parse JSON if it's stored as text, otherwise use as-is let puzzleData; try { puzzleData = typeof row.json === 'string' ? JSON.parse(row.json) : row.json; } catch (e) { return '
Error parsing JSON: ' + e.message + '
'; } // ============================================= // ARC RENDERER CODE // ============================================= // Color mapping for ARC puzzles (0-9) const ARC_COLORS = { 0: '#000000', // black 1: '#0074D9', // blue 2: '#FF4136', // red 3: '#2ECC40', // green 4: '#FFDC00', // yellow 5: '#AAAAAA', // grey 6: '#F012BE', // magenta 7: '#FF851B', // orange 8: '#7FDBFF', // light blue 9: '#85144b' // dark red }; /** * Renders a single grid as HTML */ function renderGrid(grid, label) { if (!grid || grid.length === 0) { return '
Invalid grid data
'; } const rows = grid.length; const cols = grid[0].length; const cellSize = 20; // Fixed 20px per cell let html = '
'; // Add dimension label if (label) { html += `
${label}
`; } // Grid container with black border html += `
`; // Render each row for (let r = 0; r < rows; r++) { html += '
'; // Render each cell in the row for (let c = 0; c < cols; c++) { const cellValue = grid[r][c]; const color = ARC_COLORS[cellValue] || '#FFFFFF'; html += `
`; } html += '
'; // Close row } html += '
'; // Close grid container html += '
'; // Close inline-block wrapper return html; } /** * Renders a training or test pair (input and output side-by-side) */ function renderPair(inputGrid, outputGrid, exampleIndex) { let html = ''; // Add spacing between examples (except for the first one) if (exampleIndex > 0) { html += '
'; } html += '
'; // Render input grid const inputRows = inputGrid.length; const inputCols = inputGrid[0].length; html += renderGrid(inputGrid, `${inputCols}×${inputRows}`); // Add spacing between input and output (2 cells worth = 40px) html += '
'; // Render output grid if provided if (outputGrid) { const outputRows = outputGrid.length; const outputCols = outputGrid[0].length; html += renderGrid(outputGrid, `${outputCols}×${outputRows}`); } html += '
'; // Close pair container return html; } /** * Main rendering function */ function renderArcPuzzle(data) { // Validate data structure if (!data || !data.train || !data.test) { return '
Error: JSON must contain "train" and "test" properties
'; } let html = '
'; // === TRAINING SECTION === html += '
'; html += '

Training Examples

'; data.train.forEach((example, index) => { html += renderPair(example.input, example.output, index); }); html += '
'; // Close training section // === TEST SECTION === html += '
'; html += '

Test

'; data.test.forEach((example, index) => { // Render both test input and output html += renderPair(example.input, example.output, index); }); html += '
'; // Close test section html += '
'; // Close main container return html; } // ============================================= // RENDER AND RETURN // ============================================= return renderArcPuzzle(puzzleData); })()