import Database from 'bun:sqlite'; // Database path - adjust if your database is located elsewhere const dbPath = process.env.DATABASE_URL || './local.db'; console.log(`Connecting to database: ${dbPath}`); const db = new Database(dbPath); // Query all rows from daily_completions const query = db.query(` SELECT date, guess_count FROM daily_completions ORDER BY date `); const rows = query.all() as { date: string; guess_count: number }[]; if (rows.length === 0) { console.log('No completions found in the database.'); db.close(); process.exit(0); } // Group by date and calculate average guesses const dateStats = new Map(); for (const row of rows) { const existing = dateStats.get(row.date) || { total: 0, count: 0 }; existing.total += row.guess_count; existing.count += 1; dateStats.set(row.date, existing); } // Display results console.log('\n=== Average Guesses Per Day ===\n'); console.log('Date | Avg Guesses | Total Completions'); console.log('--------------|-------------|-------------------'); for (const [date, stats] of dateStats) { const avg = (stats.total / stats.count).toFixed(2); console.log(`${date.padEnd(14)}| ${avg.padStart(11)}| ${stats.count.toString().padStart(19)}`); } // Calculate overall average const totalGuesses = Array.from(dateStats.values()).reduce((sum, s) => sum + s.total, 0); const totalCompletions = Array.from(dateStats.values()).reduce((sum, s) => sum + s.count, 0); const overallAvg = (totalGuesses / totalCompletions).toFixed(2); console.log('--------------|-------------|-------------------'); console.log(`Overall Average: ${overallAvg} guesses across ${totalCompletions} completions`); // Calculate correlation between avg_guesses and completions function calculateCorrelation(data: { avgGuesses: number; completions: number }[]): number { const n = data.length; if (n < 2) return 0; const avgX = data.reduce((sum, d) => sum + d.avgGuesses, 0) / n; const avgY = data.reduce((sum, d) => sum + d.completions, 0) / n; let numerator = 0; let sumXSquared = 0; let sumYSquared = 0; for (const d of data) { const xDiff = d.avgGuesses - avgX; const yDiff = d.completions - avgY; numerator += xDiff * yDiff; sumXSquared += xDiff * xDiff; sumYSquared += yDiff * yDiff; } const denominator = Math.sqrt(sumXSquared * sumYSquared); return denominator === 0 ? 0 : numerator / denominator; } // Prepare data for correlation analysis const allData = Array.from(dateStats.entries()).map(([date, stats]) => ({ date, avgGuesses: stats.total / stats.count, completions: stats.count })); // Split into pre and post marketing periods const marketingStartDate = '2026-01-08'; const preMarketing = allData.filter(d => d.date < marketingStartDate); const postMarketing = allData.filter(d => d.date >= marketingStartDate); console.log('\n=== Correlation Analysis ===\n'); const allCorrelation = calculateCorrelation(allData); console.log(`Overall correlation (avg_guesses vs completions): ${allCorrelation.toFixed(3)}`); if (preMarketing.length >= 2) { const preCorrelation = calculateCorrelation(preMarketing); console.log(`Pre-marketing correlation (before ${marketingStartDate}): ${preCorrelation.toFixed(3)} (n=${preMarketing.length} days)`); } if (postMarketing.length >= 2) { const postCorrelation = calculateCorrelation(postMarketing); console.log(`Post-marketing correlation (${marketingStartDate} onward): ${postCorrelation.toFixed(3)} (n=${postMarketing.length} days)`); } console.log('\nInterpretation:'); console.log(' r close to -1: Strong negative correlation (easier verses → more completions)'); console.log(' r close to 0: No correlation'); console.log(' r close to +1: Strong positive correlation (harder verses → more completions)'); db.close();