Spaces:
Sleeping
Sleeping
| import gradio as gr | |
| import plotly.graph_objects as go | |
| import plotly.express as px | |
| from plotly.subplots import make_subplots | |
| import numpy as np | |
| from collections import Counter | |
| import math | |
| # Historical researchers of perfect numbers - Enhanced HTML version | |
| MATHEMATICIANS = """ | |
| <div style='background: linear-gradient(135deg, #667eea 0%, #764ba2 100%); padding: 25px; border-radius: 15px; box-shadow: 0 8px 16px rgba(0,0,0,0.2); color: white; font-family: Arial, sans-serif;'> | |
| <h2 style='text-align: center; margin-top: 0; font-size: 24px; text-shadow: 2px 2px 4px rgba(0,0,0,0.3);'>๐ Notable Mathematicians & Their Contributions</h2> | |
| <div style='background: rgba(255,255,255,0.15); padding: 15px; border-radius: 10px; margin: 15px 0; border-left: 5px solid #ffd700;'> | |
| <strong style='font-size: 16px; color: #ffd700;'>โญ Euclid</strong> <em style='color: #e0e0e0;'>(c. 300 BCE)</em><br/> | |
| <span style='margin-left: 20px; line-height: 1.6;'>Proved that 2<sup>(p-1)</sup> ร (2<sup>p</sup> - 1) generates perfect numbers when 2<sup>p</sup> - 1 is prime</span> | |
| </div> | |
| <div style='background: rgba(255,255,255,0.15); padding: 15px; border-radius: 10px; margin: 15px 0; border-left: 5px solid #ff6b6b;'> | |
| <strong style='font-size: 16px; color: #ff6b6b;'>โญ Leonhard Euler</strong> <em style='color: #e0e0e0;'>(1707-1783)</em><br/> | |
| <span style='margin-left: 20px; line-height: 1.6;'>Proved all even perfect numbers follow Euclid's formula</span> | |
| </div> | |
| <div style='background: rgba(255,255,255,0.15); padding: 15px; border-radius: 10px; margin: 15px 0; border-left: 5px solid #4ecdc4;'> | |
| <strong style='font-size: 16px; color: #4ecdc4;'>โญ Marin Mersenne</strong> <em style='color: #e0e0e0;'>(1588-1648)</em><br/> | |
| <span style='margin-left: 20px; line-height: 1.6;'>Studied primes of form 2<sup>p</sup> - 1 (Mersenne primes), linked to perfect numbers</span> | |
| </div> | |
| <div style='background: rgba(255,255,255,0.15); padding: 15px; border-radius: 10px; margin: 15px 0; border-left: 5px solid #95e1d3;'> | |
| <strong style='font-size: 16px; color: #95e1d3;'>โญ Niccolรฒ Paganini</strong><br/> | |
| <span style='margin-left: 20px; line-height: 1.6;'>Not the violinist! Ancient Greek mathematician who studied perfect numbers</span> | |
| </div> | |
| <div style='background: rgba(255,255,255,0.15); padding: 15px; border-radius: 10px; margin: 15px 0; border-left: 5px solid #f38181;'> | |
| <strong style='font-size: 16px; color: #f38181;'>โญ Renรฉ Descartes</strong> <em style='color: #e0e0e0;'>(1596-1650)</em><br/> | |
| <span style='margin-left: 20px; line-height: 1.6;'>Conjectured properties about odd perfect numbers</span> | |
| </div> | |
| <div style='background: rgba(255,255,255,0.15); padding: 15px; border-radius: 10px; margin: 15px 0; border-left: 5px solid #aa96da;'> | |
| <strong style='font-size: 16px; color: #aa96da;'>โญ Pierre de Fermat</strong> <em style='color: #e0e0e0;'>(1607-1665)</em><br/> | |
| <span style='margin-left: 20px; line-height: 1.6;'>Contributed to number theory including perfect number properties</span> | |
| </div> | |
| <div style='background: rgba(255,255,255,0.15); padding: 15px; border-radius: 10px; margin: 15px 0; border-left: 5px solid #fcbad3;'> | |
| <strong style='font-size: 16px; color: #fcbad3;'>โญ Pythagoras</strong> <em style='color: #e0e0e0;'>(c. 570-495 BCE)</em><br/> | |
| <span style='margin-left: 20px; line-height: 1.6;'>Ancient Greek philosopher who ascribed mystical properties to perfect numbers</span> | |
| </div> | |
| <div style='background: linear-gradient(135deg, #f093fb 0%, #f5576c 100%); padding: 20px; border-radius: 10px; margin-top: 25px; text-align: center; box-shadow: 0 4px 8px rgba(0,0,0,0.2);'> | |
| <h3 style='margin: 0 0 10px 0; font-size: 20px; color: white; text-shadow: 2px 2px 4px rgba(0,0,0,0.3);'>๐ Known Perfect Numbers</h3> | |
| <p style='margin: 10px 0; font-size: 16px; line-height: 1.6;'>Only <strong style='font-size: 22px; color: #ffd700;'>51</strong> perfect numbers have been discovered (as of 2024)</p> | |
| <p style='margin: 10px 0; font-size: 14px;'>The first few:</p> | |
| <p style='font-size: 18px; font-weight: bold; color: #ffd700; text-shadow: 1px 1px 2px rgba(0,0,0,0.3);'>6, 28, 496, 8128, 33550336...</p> | |
| </div> | |
| </div> | |
| """ | |
| def prime_factorization(n): | |
| """Get prime factorization of n""" | |
| factors = [] | |
| d = 2 | |
| temp = n | |
| while d * d <= temp: | |
| while temp % d == 0: | |
| factors.append(d) | |
| temp //= d | |
| d += 1 | |
| if temp > 1: | |
| factors.append(temp) | |
| return factors | |
| def divisors(n): | |
| """Find all divisors of n efficiently""" | |
| if n == 1: | |
| return [1] | |
| divs = set() | |
| sqrt_n = int(math.isqrt(n)) | |
| for i in range(1, sqrt_n + 1): | |
| if n % i == 0: | |
| divs.add(i) | |
| divs.add(n // i) | |
| return sorted(divs) | |
| def classify_number(n, proper_sum): | |
| """Classify number as perfect, abundant, or deficient""" | |
| if proper_sum == n: | |
| return "Perfect", "โ " | |
| elif proper_sum > n: | |
| return "Abundant", "๐" | |
| else: | |
| return "Deficient", "๐" | |
| def check_perfect(n): | |
| """Check if number is perfect and return detailed info""" | |
| if n <= 1: | |
| return False, [], 0, "Invalid", "" | |
| divs = divisors(n) | |
| proper_divs = [d for d in divs if d != n] | |
| proper_sum = sum(proper_divs) | |
| classification, emoji = classify_number(n, proper_sum) | |
| return proper_sum == n, divs, proper_sum, classification, emoji | |
| def create_enhanced_visualization(n): | |
| """Create comprehensive visualization with Plotly for any positive integer""" | |
| try: | |
| n = int(n) | |
| except (ValueError, TypeError): | |
| return "Please enter a valid positive integer.", None | |
| if n <= 0: | |
| return "Please enter a positive integer.", None | |
| is_perfect, divs, proper_sum, classification, emoji = check_perfect(n) | |
| proper_divs = [d for d in divs if d != n] | |
| # Create subplots with Plotly | |
| fig = make_subplots( | |
| rows=2, cols=3, | |
| subplot_titles=( | |
| f'Proper Divisors of {n}', | |
| 'Divisor Magnitudes', | |
| f'{classification} Number Analysis {emoji}', | |
| 'Divisor Pairs', | |
| f'Prime Factorization of {n}', | |
| 'Perfect Number Definition' | |
| ), | |
| specs=[ | |
| [{"type": "pie"}, {"type": "bar"}, {"type": "bar"}], | |
| [{"type": "table"}, {"type": "table"}, {"type": "table"}] | |
| ], | |
| vertical_spacing=0.1, | |
| horizontal_spacing=0.05 | |
| ) | |
| # Define color scheme | |
| if classification == "Perfect": | |
| main_color = '#2ecc71' | |
| colors = px.colors.sequential.Greens[2:8] | |
| elif classification == "Abundant": | |
| main_color = '#3498db' | |
| colors = px.colors.sequential.Blues[2:8] | |
| else: | |
| main_color = '#e74c3c' | |
| colors = px.colors.sequential.Reds[2:8] | |
| # 1. PIE CHART - Divisor Distribution | |
| if proper_divs: | |
| # Limit to top 20 divisors for readability | |
| display_divs = proper_divs[:20] if len(proper_divs) > 20 else proper_divs | |
| fig.add_trace( | |
| go.Pie( | |
| labels=[str(d) for d in display_divs], | |
| values=display_divs, | |
| textinfo='label+percent', | |
| insidetextorientation='radial', | |
| marker=dict(colors=colors * (len(display_divs) // len(colors) + 1)), | |
| textfont=dict(size=12), | |
| hovertemplate="Divisor: %{label}<br>Value: %{value}<extra></extra>" | |
| ), | |
| row=1, col=1 | |
| ) | |
| # 2. BAR CHART - Divisor Values | |
| if proper_divs: | |
| # Limit to top 20 divisors for readability | |
| display_divs = proper_divs[:20] if len(proper_divs) > 20 else proper_divs | |
| fig.add_trace( | |
| go.Bar( | |
| x=[str(d) for d in display_divs], | |
| y=display_divs, | |
| marker_color=main_color, | |
| text=display_divs, | |
| textposition='outside', | |
| hovertemplate="Divisor: %{x}<br>Value: %{y}<extra></extra>" | |
| ), | |
| row=1, col=2 | |
| ) | |
| fig.update_xaxes(tickangle=45, row=1, col=2) | |
| # 3. COMPARISON BAR - Sum vs Number | |
| comparison = [proper_sum, n] | |
| labels = [f'Sum of Divisors<br>({proper_sum})', f'Number<br>({n})'] | |
| fig.add_trace( | |
| go.Bar( | |
| x=labels, | |
| y=comparison, | |
| marker_color=[main_color, '#95a5a6'], | |
| text=comparison, | |
| textposition='outside', | |
| hovertemplate="%{x}<br>Value: %{y}<extra></extra>" | |
| ), | |
| row=1, col=3 | |
| ) | |
| # Add difference annotation | |
| diff = abs(proper_sum - n) | |
| diff_pct = (diff / n) * 100 if n != 0 else 0 | |
| fig.add_annotation( | |
| x=0.5, y=max(comparison) * 0.5, | |
| text=f"Difference: {diff}<br>({diff_pct:.1f}%)", | |
| showarrow=False, | |
| bgcolor="wheat", | |
| bordercolor="black", | |
| font=dict(size=12, color="black"), | |
| row=1, col=3 | |
| ) | |
| # 4. DIVISOR PAIRS VISUALIZATION | |
| sqrt_n = int(math.isqrt(n)) | |
| pairs = [] | |
| for d in proper_divs: | |
| if d <= sqrt_n and d != n // d: | |
| pairs.append((d, n // d)) | |
| if pairs: | |
| pair_labels = [f"{d1} ร {d2}" for d1, d2 in pairs] | |
| pair_values = [n] * len(pairs) | |
| fig.add_trace( | |
| go.Table( | |
| header=dict(values=["Divisor Pairs", "Product"]), | |
| cells=dict(values=[pair_labels, pair_values]), | |
| columnwidth=[100, 50] | |
| ), | |
| row=2, col=1 | |
| ) | |
| else: | |
| fig.add_trace( | |
| go.Table( | |
| header=dict(values=["Divisor Pairs"]), | |
| cells=dict(values=[["No pairs found"]]) | |
| ), | |
| row=2, col=1 | |
| ) | |
| # 5. PRIME FACTORIZATION | |
| prime_factors = prime_factorization(n) | |
| if prime_factors: | |
| factor_counts = Counter(prime_factors) | |
| factor_parts = [] | |
| for prime in sorted(factor_counts.keys()): | |
| count = factor_counts[prime] | |
| if count == 1: | |
| factor_parts.append(f"{prime}") | |
| else: | |
| factor_parts.append(f"{prime}^{count}") | |
| factorization = " ร ".join(factor_parts) | |
| else: | |
| factorization = "1 (unity)" | |
| properties = [ | |
| f"Total divisors: {len(divs)}", | |
| f"Proper divisors: {len(proper_divs)}", | |
| f"Sum of all divisors: {sum(divs)}", | |
| f"Classification: {classification} {emoji}" | |
| ] | |
| fig.add_trace( | |
| go.Table( | |
| header=dict(values=["Prime Factorization", "Number Properties"]), | |
| cells=dict(values=[[factorization], ["<br>".join(properties)]]) | |
| ), | |
| row=2, col=2 | |
| ) | |
| # 6. MATHEMATICAL FORMULA | |
| if proper_divs: | |
| sum_parts = " + ".join([str(d) for d in proper_divs[:10]]) # Limit to first 10 | |
| if len(proper_divs) > 10: | |
| sum_parts += " + ..." | |
| formula = f"{sum_parts} = {proper_sum}" | |
| else: | |
| formula = "No proper divisors" | |
| result = f"{'โ ' if is_perfect else 'โ'} {proper_sum} {'=' if is_perfect else 'โ '} {n}" | |
| if is_perfect: | |
| conclusion = "PERFECT NUMBER! ๐" | |
| elif classification == "Abundant": | |
| conclusion = f"Abundant (Excess: {proper_sum - n})" | |
| else: | |
| conclusion = f"Deficient (Deficiency: {n - proper_sum})" | |
| fig.add_trace( | |
| go.Table( | |
| header=dict(values=["Perfect Number Definition"]), | |
| cells=dict(values=[[formula, result, conclusion]]) | |
| ), | |
| row=2, col=3 | |
| ) | |
| # Update layout | |
| fig.update_layout( | |
| height=800, | |
| showlegend=False, | |
| title_text=f"Comprehensive Analysis of {n}", | |
| title_x=0.5, | |
| title_font_size=24, | |
| plot_bgcolor='rgba(0,0,0,0)', | |
| paper_bgcolor='rgba(0,0,0,0)' | |
| ) | |
| # Generate detailed message with HTML formatting | |
| msg = f""" | |
| <div style='font-family: Arial, sans-serif; background: linear-gradient(to right, #e0f7fa, #e1bee7); padding: 25px; border-radius: 15px; box-shadow: 0 4px 12px rgba(0,0,0,0.15);'> | |
| <div style='background: linear-gradient(135deg, #1e3c72 0%, #2a5298 100%); color: white; padding: 20px; border-radius: 10px; margin-bottom: 20px; text-align: center; box-shadow: 0 4px 8px rgba(0,0,0,0.2);'> | |
| <h1 style='margin: 0; font-size: 28px; text-shadow: 2px 2px 4px rgba(0,0,0,0.3);'>๐ ANALYSIS OF NUMBER: {n}</h1> | |
| </div> | |
| <div style='background: {"linear-gradient(135deg, #11998e 0%, #38ef7d 100%)" if is_perfect else "linear-gradient(135deg, #ee0979 0%, #ff6a00 100%)" if classification == "Abundant" else "linear-gradient(135deg, #fc4a1a 0%, #f7b733 100%)"}; padding: 20px; border-radius: 10px; margin-bottom: 20px; box-shadow: 0 4px 8px rgba(0,0,0,0.2);'> | |
| <h2 style='color: white; margin-top: 0; font-size: 22px; text-shadow: 2px 2px 4px rgba(0,0,0,0.3);'>๐ Classification: {classification} Number {emoji}</h2> | |
| </div> | |
| <div style='background: white; padding: 20px; border-radius: 10px; margin-bottom: 20px; box-shadow: 0 2px 6px rgba(0,0,0,0.1); border-left: 6px solid #2196F3;'> | |
| <h3 style='color: #1976D2; margin-top: 0;'>๐ Divisor Information</h3> | |
| <p style='font-size: 16px; line-height: 1.8; color: #000;'><strong style='color: #000;'>All Divisors:</strong> <span style='color: #0D47A1; font-weight: bold;'>{divs[:20]}{"..." if len(divs) > 20 else ""}</span></p> | |
| <p style='font-size: 16px; line-height: 1.8; color: #000;'><strong style='color: #000;'>Proper Divisors (excluding {n}):</strong> <span style='color: #0D47A1; font-weight: bold;'>{proper_divs[:20]}{"..." if len(proper_divs) > 20 else ""}</span></p> | |
| </div> | |
| <div style='background: white; padding: 20px; border-radius: 10px; margin-bottom: 20px; box-shadow: 0 2px 6px rgba(0,0,0,0.1); border-left: 6px solid #FF9800;'> | |
| <h3 style='color: #F57C00; margin-top: 0;'>๐งฎ Sum Calculation</h3> | |
| <p style='font-size: 18px; line-height: 1.8; font-weight: bold;'> | |
| {' + '.join([f"<span style='background: #FFE0B2; color: #BF360C; padding: 3px 8px; border-radius: 5px; margin: 2px; display: inline-block;'>{d}</span>" for d in proper_divs[:10]])}{" + ..." if len(proper_divs) > 10 else ""} = <span style='background: #FF6F00; color: white; padding: 5px 12px; border-radius: 5px;'>{proper_sum}</span> | |
| </p> | |
| </div> | |
| <div style='background: {"linear-gradient(135deg, #00b09b 0%, #96c93d 100%)" if is_perfect else "linear-gradient(135deg, #eb3349 0%, #f45c43 100%)"}; padding: 25px; border-radius: 10px; box-shadow: 0 4px 8px rgba(0,0,0,0.2);'> | |
| <h3 style='color: white; margin-top: 0; font-size: 20px; text-shadow: 2px 2px 4px rgba(0,0,0,0.3);'>โจ Result</h3> | |
| <p style='font-size: 24px; line-height: 1.8; color: white; font-weight: bold; text-shadow: 1px 1px 2px rgba(0,0,0,0.5);'> | |
| {"โ " if is_perfect else "โ"} <span style='background: rgba(0,0,0,0.3); padding: 5px 10px; border-radius: 5px;'>{proper_sum}</span> {"=" if is_perfect else "โ "} <span style='background: rgba(0,0,0,0.3); padding: 5px 10px; border-radius: 5px;'>{n}</span> | |
| </p> | |
| <p style='font-size: 18px; color: white; line-height: 1.6; text-shadow: 1px 1px 2px rgba(0,0,0,0.5);'> | |
| {"๐ <strong>PERFECT NUMBER!</strong> This is one of the rare perfect numbers!" if is_perfect else f"<strong>NOT PERFECT</strong><br/>{'The sum (<strong>' + str(proper_sum) + '</strong>) is greater than the number (<strong>' + str(n) + '</strong>)<br/>Excess: <strong>' + str(proper_sum - n) + '</strong>' if classification == 'Abundant' else 'The sum (<strong>' + str(proper_sum) + '</strong>) is less than the number (<strong>' + str(n) + '</strong>)<br/>Deficiency: <strong>' + str(n - proper_sum) + '</strong>'}"} | |
| </p> | |
| </div> | |
| <div style='margin-top: 30px;'> | |
| {MATHEMATICIANS} | |
| </div> | |
| </div> | |
| """ | |
| return msg, fig | |
| # Create Gradio interface | |
| with gr.Blocks(theme=gr.themes.Soft(), title="Perfect Number Explorer") as demo: | |
| gr.Markdown(""" | |
| # ๐ข Perfect Number Visualizer & Explorer (Unlimited Range!) | |
| ### What are Perfect Numbers? | |
| A **perfect number** is a positive integer that equals the sum of its proper divisors (divisors excluding the number itself). | |
| **Example:** 6 is perfect because 1 + 2 + 3 = 6 | |
| ### Try these perfect numbers: 6, 28, 496, 8128, 33550336 | |
| ### Or try very large numbers like 2^31-1 (2147483647) or even larger! | |
| """) | |
| with gr.Row(): | |
| with gr.Column(scale=1): | |
| number_input = gr.Number( | |
| label="Enter ANY Positive Integer", | |
| value=6, | |
| precision=0 | |
| ) | |
| analyze_btn = gr.Button("๐ Analyze Number", variant="primary", size="lg") | |
| gr.Markdown(""" | |
| ### Key Features: | |
| - **Unlimited Range**: Analyze ANY positive integer (no upper limit!) | |
| - **Optimized Algorithms**: Efficiently handles very large numbers | |
| - **Interactive Visualizations**: Zoom, pan, and hover for details | |
| - **Comprehensive Analysis**: Divisors, factorization, and classification | |
| """) | |
| with gr.Row(): | |
| result_text = gr.HTML( | |
| label="๐ Detailed Analysis" | |
| ) | |
| with gr.Row(): | |
| plot_output = gr.Plot(label="๐ Interactive Visual Analysis") | |
| analyze_btn.click( | |
| fn=create_enhanced_visualization, | |
| inputs=number_input, | |
| outputs=[result_text, plot_output] | |
| ) | |
| # Auto-analyze on load | |
| demo.load( | |
| fn=create_enhanced_visualization, | |
| inputs=number_input, | |
| outputs=[result_text, plot_output] | |
| ) | |
| if __name__ == "__main__": | |
| demo.launch() |