UNPKG

minangscript

Version:

Modern programming language with Minangkabau philosophy. Features native arrays (kumpulan), objects (benda), web development support, and comprehensive algorithm examples. Ready for web applications, data structures, and algorithmic programming.

494 lines (418 loc) 15.5 kB
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Two Sum Solver - MinangScript</title> <style> * { box-sizing: border-box; margin: 0; padding: 0; } body { font-family: 'Monaco', 'Menlo', 'Ubuntu Mono', monospace; background: linear-gradient(135deg, #667eea 0%, #764ba2 100%); min-height: 100vh; padding: 20px; color: #333; } .container { max-width: 900px; margin: 0 auto; background: rgba(255, 255, 255, 0.95); border-radius: 15px; padding: 30px; box-shadow: 0 20px 40px rgba(0, 0, 0, 0.1); backdrop-filter: blur(10px); } h1 { text-align: center; color: #4a5568; margin-bottom: 10px; font-size: 2.5em; } .subtitle { text-align: center; color: #718096; margin-bottom: 30px; font-size: 1.1em; } .input-section { background: #f7fafc; padding: 20px; border-radius: 10px; margin-bottom: 20px; border: 2px solid #e2e8f0; } .input-group { margin-bottom: 15px; } label { display: block; margin-bottom: 5px; font-weight: bold; color: #4a5568; } input[type="text"] { width: 100%; padding: 12px; border: 2px solid #cbd5e0; border-radius: 8px; font-size: 16px; font-family: 'Monaco', monospace; transition: border-color 0.3s; } input[type="text"]:focus { outline: none; border-color: #667eea; box-shadow: 0 0 0 3px rgba(102, 126, 234, 0.1); } .solve-button { width: 100%; background: linear-gradient(135deg, #667eea 0%, #764ba2 100%); color: white; border: none; padding: 15px; border-radius: 8px; font-size: 18px; font-weight: bold; cursor: pointer; transition: transform 0.2s, box-shadow 0.2s; } .solve-button:hover { transform: translateY(-2px); box-shadow: 0 10px 25px rgba(102, 126, 234, 0.3); } .result { padding: 20px; border-radius: 10px; margin: 20px 0; font-size: 16px; border: 2px solid; } .result.success { background: #f0fff4; border-color: #38a169; color: #22543d; } .result.error { background: #fed7d7; border-color: #e53e3e; color: #742a2a; } .steps { background: #edf2f7; padding: 20px; border-radius: 10px; margin-top: 20px; } .step { background: white; padding: 15px; margin: 10px 0; border-radius: 8px; border-left: 4px solid #cbd5e0; font-family: 'Monaco', monospace; font-size: 14px; } .step.found { border-left-color: #38a169; background: #f0fff4; } .examples { margin: 20px 0; } .example-btn { background: #4299e1; color: white; border: none; padding: 10px 15px; margin: 5px; border-radius: 6px; cursor: pointer; font-size: 14px; transition: background 0.2s; } .example-btn:hover { background: #3182ce; } .algorithm-info { background: #ebf8ff; border: 2px solid #4299e1; border-radius: 10px; padding: 20px; margin-top: 20px; } .complexity { display: flex; justify-content: space-around; text-align: center; margin-top: 15px; } .complexity div { background: white; padding: 10px; border-radius: 8px; flex: 1; margin: 0 5px; } @media (max-width: 768px) { .container { padding: 20px; margin: 10px; } h1 { font-size: 2em; } .complexity { flex-direction: column; } .complexity div { margin: 5px 0; } } </style> </head> <body> <div class="container"> <h1>🎯 Two Sum Solver</h1> <p class="subtitle">LeetCode Problem #1 - Solved with MinangScript</p> <div class="input-section"> <div class="input-group"> <label for="arrayInput">📋 Array (format: [1,2,3,4]):</label> <input type="text" id="arrayInput" placeholder="[2,7,11,15]" value="[2,7,11,15]"> </div> <div class="input-group"> <label for="targetInput">🎯 Target:</label> <input type="text" id="targetInput" placeholder="9" value="9"> </div> <button id="solveBtn" class="solve-button">🚀 Solve Two Sum</button> </div> <div id="examples" class="examples"></div> <div id="result" class="result" style="display: none;"></div> <div id="steps" class="steps" style="display: none;"></div> <div class="algorithm-info"> <h3>🧠 Algorithm Information</h3> <p><strong>Hash Map Approach:</strong> We iterate through the array once, and for each element, we check if the complement (target - current) exists in our hash map. If it does, we found our answer. If not, we add the current element to the hash map.</p> <div class="complexity"> <div> <strong>⚡ Time Complexity</strong><br> O(n) </div> <div> <strong>💾 Space Complexity</strong><br> O(n) </div> <div> <strong>🎯 Optimal Solution</strong><br> Yes </div> </div> </div> </div> <!-- MinangScript Runtime (simplified for demo) --> <script> // Simplified MinangScript runtime for this demo class MinangRuntime { constructor() { this.variables = new Map(); this.functions = new Map(); this.initializeBuiltins(); } initializeBuiltins() { // piliah - querySelector this.functions.set('piliah', (selector) => { return document.querySelector(selector); }); // dengar - addEventListener this.functions.set('dengar', (element, event, callback) => { if (element && element.addEventListener) { element.addEventListener(event, callback); } }); // cetak - console.log this.functions.set('cetak', (...args) => { console.log(...args); }); // jsonKe - JSON.stringify this.functions.set('jsonKe', (obj) => { return JSON.stringify(obj); }); } } // Initialize runtime const runtime = new MinangRuntime(); // Make MinangScript functions available globally window.piliah = runtime.functions.get('piliah'); window.dengar = runtime.functions.get('dengar'); window.cetak = runtime.functions.get('cetak'); window.jsonKe = runtime.functions.get('jsonKe'); // DOM element shortcuts const arrayInput = document.querySelector('#arrayInput'); const targetInput = document.querySelector('#targetInput'); const solveBtn = document.querySelector('#solveBtn'); const resultDiv = document.querySelector('#result'); const stepsDiv = document.querySelector('#steps'); // Two Sum algorithm (translated from MinangScript) function twoSum(nums, target) { const map = {}; const steps = []; for (let i = 0; i < nums.length; i++) { const current = nums[i]; const complement = target - current; steps.push({ step: i + 1, current: current, complement: complement, mapState: {...map}, found: map[complement] !== undefined }); if (map[complement] !== undefined) { return { indices: [map[complement], i], values: [complement, current], steps: steps }; } map[current] = i; } return { indices: [], values: [], steps: steps }; } // Parse array input function parseArray(str) { try { const cleaned = str.replace(/[\[\]]/g, '').split(','); const result = []; for (const item of cleaned) { const num = parseInt(item.trim()); if (!isNaN(num)) { result.push(num); } } return result; } catch (error) { return []; } } // Display solution steps function displaySteps(steps, target) { let stepsHtml = "<h3>📋 Solution Steps:</h3>"; for (const step of steps) { const mapStr = JSON.stringify(step.mapState); stepsHtml += ` <div class="step ${step.found ? 'found' : ''}"> <strong>Step ${step.step}:</strong><br> Current: ${step.current}, Need: ${step.complement}<br> Map: ${mapStr}<br> ${step.found ? `✅ Found! ${step.complement} exists in map` : `❌ ${step.complement} not found, adding ${step.current} to map` } </div> `; } stepsDiv.innerHTML = stepsHtml; stepsDiv.style.display = 'block'; } // Handle solve button click function handleSolve() { const arrayStr = arrayInput.value; const targetStr = targetInput.value; if (!arrayStr || !targetStr) { resultDiv.innerHTML = "❌ Please enter both array and target"; resultDiv.className = "result error"; resultDiv.style.display = 'block'; return; } const nums = parseArray(arrayStr); const target = parseInt(targetStr); if (nums.length === 0) { resultDiv.innerHTML = "❌ Invalid array format. Use: [1,2,3,4]"; resultDiv.className = "result error"; resultDiv.style.display = 'block'; return; } if (isNaN(target)) { resultDiv.innerHTML = "❌ Invalid target number"; resultDiv.className = "result error"; resultDiv.style.display = 'block'; return; } console.log(`Solving Two Sum for array: ${JSON.stringify(nums)}, target: ${target}`); const solution = twoSum(nums, target); if (solution.indices.length > 0) { const [i, j] = solution.indices; const [val1, val2] = solution.values; resultDiv.innerHTML = ` <h3>✅ Solution Found!</h3> <p><strong>Indices:</strong> [${i}, ${j}]</p> <p><strong>Values:</strong> ${val1} + ${val2} = ${target}</p> <p><strong>Array[${i}] + Array[${j}] = ${nums[i]} + ${nums[j]} = ${target}</strong></p> `; resultDiv.className = "result success"; } else { resultDiv.innerHTML = ` <h3>❌ No Solution Found</h3> <p>No two numbers in the array add up to ${target}</p> `; resultDiv.className = "result error"; } resultDiv.style.display = 'block'; displaySteps(solution.steps, target); } // Load example test case function loadExample(nums, target) { arrayInput.value = JSON.stringify(nums); targetInput.value = target.toString(); handleSolve(); } // Setup example buttons function setupExamples() { const examplesDiv = document.querySelector('#examples'); if (!examplesDiv) return; const examples = [ { nums: [2, 7, 11, 15], target: 9, name: "Classic" }, { nums: [3, 2, 4], target: 6, name: "Middle" }, { nums: [3, 3], target: 6, name: "Duplicates" }, { nums: [1, 5, 3, 8, 2], target: 10, name: "Random" }, { nums: [-1, -2, -3, -4, -5], target: -8, name: "Negatives" } ]; let buttonsHtml = "<h3>🎯 Example Test Cases:</h3>"; for (const ex of examples) { buttonsHtml += ` <button onclick="loadExample(${JSON.stringify(ex.nums)}, ${ex.target})" class="example-btn"> ${ex.name}: ${JSON.stringify(ex.nums)}${ex.target} </button> `; } examplesDiv.innerHTML = buttonsHtml; } // Event listeners solveBtn.addEventListener('click', handleSolve); arrayInput.addEventListener('keypress', (e) => { if (e.key === "Enter") { handleSolve(); } }); targetInput.addEventListener('keypress', (e) => { if (e.key === "Enter") { handleSolve(); } }); // Initialize document.addEventListener('DOMContentLoaded', () => { setupExamples(); console.log("🚀 Two Sum Interactive Solver ready!"); // Load default example handleSolve(); }); // Make loadExample available globally for onclick handlers window.loadExample = loadExample; </script> </body> </html>