# ============================================================================
# LOTTO RANDOM COMBINATION GENERATOR & FILTER by tom e Qwen AI :)
# Genera combinazioni ibride fisse (90%) + random (10%) e filtra per condizioni teoricamente ottimali
# ============================================================================
import requests
import numpy as np
from typing import List, Dict, Tuple
import time
from tqdm import tqdm
import random
class RandomCombinationAnalyzer:
def __init__(self, archive_url: str):
self.archive_url = archive_url
self.draws_array = self._load_archive()
def _load_archive(self) -> np.ndarray:
print(f"📥 Download archivio da: {self.archive_url}")
response = requests.get(self.archive_url, timeout=120)
response.raise_for_status()
lines = response.text.strip().split('\n')
data = []
for line in lines:
parts = line.split('.')
if len(parts) == 5:
nums = [int(p) for p in parts if p.strip()]
if len(nums) == 5:
data.append(nums)
draws_array = np.array(data, dtype=np.int16)
print(f"✅ Caricate {len(draws_array)} estrazioni")
return draws_array
def _calculate_metrics(
self,
numbers: np.ndarray,
min_hits: int = 2
) -> Tuple[int, int, int]:
"""
Calcola le metriche per un set di numeri
Returns:
(total_hits, current_delay, max_historical_delay)
"""
# Trova tutte le estrazioni con almeno min_hits numeri
hits_matrix = np.isin(self.draws_array, numbers)
hits_per_draw = hits_matrix.sum(axis=1)
hit_indices = np.where(hits_per_draw >= min_hits)[0]
if len(hit_indices) == 0:
return 0, 999999, 999999
total_hits = len(hit_indices)
# Le estrazioni recenti sono in alto (indice 0)
# hit_indices[0] è l'ESTRAZIONE PIÙ RECENTE che ha fatto ambo
current_delay = int(hit_indices[0])
# Calcola il ritardo storico massimo (massimo intervallo tra ambi consecutivi)
if len(hit_indices) > 1:
delays = np.diff(hit_indices)
max_historical_delay = int(np.max(delays))
else:
max_historical_delay = current_delay
return total_hits, current_delay, max_historical_delay
def analyze_random_combinations(
self,
fixed_numbers: List[int],
pool_numbers: List[int],
num_dynamic: int,
num_combinations: int,
target_sorte: str = "AMBO",
min_hits: int = 2,
max_diff: int = 10,
show_progress: bool = True
) -> Dict:
"""
Genera e analizza combinazioni random
Args:
fixed_numbers: Numeri fissi
pool_numbers: Pool da cui pescare i numeri dinamici
num_dynamic: Quanti numeri dinamici aggiungere
num_combinations: Quante combinazioni generare
target_sorte: Sorte da verificare
min_hits: Colpi minimi per la sorte
max_diff: Differenza massima accettabile (RS - RA)
show_progress: Mostra barra di progresso
Returns:
Dizionario con risultati filtrati
"""
start_time = time.time()
print(f"\n🔧 INIZIO ANALISI COMBINAZIONI RANDOM")
print(f" Fissi: {len(fixed_numbers)} numeri")
print(f" Pool disponibile: {len(pool_numbers)} numeri")
print(f" Dinamici per combinazione: {num_dynamic}")
print(f" Combinazioni da generare: {num_combinations}")
print(f" Filtro: diff <= {max_diff}")
print(f" Sorte: {target_sorte} (min {min_hits} colpi)")
# Calcola totale combinazioni possibili
from math import comb
total_possible = comb(len(pool_numbers), num_dynamic)
print(f" Combinazioni totali possibili: {total_possible:,}")
results = []
filtered_results = []
# Genera combinazioni random
print(f"\n🎲 Generazione e analisi combinazioni...")
iterator = range(num_combinations)
if show_progress:
iterator = tqdm(iterator, desc="Analisi combinazioni")
for i in iterator:
# Scegli num_dynamic numeri random dal pool
dynamic_numbers = random.sample(pool_numbers, num_dynamic)
# Combina fissi + dinamici
full_combo = np.array(sorted(fixed_numbers + dynamic_numbers), dtype=np.int16)
# Calcola metriche
total_hits, current_delay, max_hist_delay = self._calculate_metrics(
full_combo, min_hits
)
diff = max_hist_delay - current_delay
combo_data = {
'combination': full_combo.tolist(),
'fixed': sorted(fixed_numbers),
'dynamic': sorted(dynamic_numbers),
'total_hits': total_hits,
'current_delay': current_delay,
'max_historical_delay': max_hist_delay,
'diff': diff
}
results.append(combo_data)
# Applica filtro
if diff <= max_diff:
filtered_results.append(combo_data)
elapsed_time = time.time() - start_time
# Ordina risultati filtrati per diff (prima i migliori)
filtered_results.sort(key=lambda x: (x['diff'], x['current_delay']))
return {
'total_generated': len(results),
'filtered_count': len(filtered_results),
'filtered_results': filtered_results,
'elapsed_time': elapsed_time,
'parameters': {
'fixed_count': len(fixed_numbers),
'dynamic_count': num_dynamic,
'num_combinations': num_combinations,
'target_sorte': target_sorte,
'min_hits': min_hits,
'max_diff': max_diff
}
}
def print_results(self, result: Dict, top_n: int = 20):
print("\n" + "="*80)
print("📊 RISULTATI ANALISI COMBINAZIONI RANDOM")
print("="*80)
params = result['parameters']
print(f"\n⚙️ PARAMETRI:")
print(f" Numeri fissi: {params['fixed_count']}")
print(f" Numeri dinamici: {params['dynamic_count']}")
print(f" Combinazioni generate: {params['num_combinations']}")
print(f" Sorte target: {params['target_sorte']}")
print(f" Colpi minimi: {params['min_hits']}")
print(f" Filtro max diff: {params['max_diff']}")
print(f"\n📈 STATISTICHE:")
print(f" Totale generate: {result['total_generated']}")
print(f" Combinazioni filtrate: {result['filtered_count']}")
print(f" Percentuale filtrate: {result['filtered_count']/result['total_generated']*100:.2f}%")
print(f" Tempo elaborazione: {result['elapsed_time']:.2f} secondi")
if result['filtered_count'] > 0:
print(f"\n🏆 TOP {min(top_n, result['filtered_count'])} COMBINAZIONI MIGLIORI:")
for idx, combo in enumerate(result['filtered_results'][:top_n], 1):
print(f"\n #{idx}")
print(f" Combinazione completa: {combo['combination']}")
print(f" Fissi: {combo['fixed']}")
print(f" Dinamici: {combo['dynamic']}")
print(f" Totale ambi: {combo['total_hits']}")
print(f" Ritardo attuale (RA): {combo['current_delay']}")
print(f" Ritardo storico max (RS): {combo['max_historical_delay']}")
print(f" Diff (RS - RA): {combo['diff']}")
else:
print(f"\n⚠️ Nessuna combinazione rispetta il filtro")
print("\n" + "="*80)
# ============================================================================
# FUNZIONE PRINCIPALE - ESEMPIO DI UTILIZZO
# ============================================================================
def main():
# URL dell'archivio estrazioni
archive_url = "url estrazioni desiderato" # es. "https://huggingface.co/spaces/AI-tom/backtester-con-rilevamento-parametri-x-training/raw/main/LottoJarvis_Cloud/1_Data/archivi_estrazioni/estrazioni-VE.txt"
# Inizializza l'analizzatore
analyzer = RandomCombinationAnalyzer(archive_url)
# ========================================================================
# CONFIGURAZIONE - MODIFICA QUI I TUOI PARAMETRI
# ========================================================================
# I tuoi 29 numeri fissi (MODIFICA CON I TUOI NUMERI)
#fixed_numbers = list(range(1, 30)) # Esempio: numeri da 1 a 29
fixed_numbers = [1,2,3,4,5,6,7,8,9,10] # esempio di gruppo fisso fittizio
# Pool di numeri disponibili per i dinamici
pool_numbers = [n for n in range(1, 91) if n not in fixed_numbers]
# Parametri di configurazione
num_dynamic = 8 # Quanti numeri dinamici aggiungere
num_combinations = 10000 # Quante combinazioni "ibride" random generare
max_diff = 2 # Filtro: mostra solo combinazioni con diff <= 10
# ========================================================================
# ESECUZIONE ANALISI
# ========================================================================
result = analyzer.analyze_random_combinations(
fixed_numbers=fixed_numbers,
pool_numbers=pool_numbers,
num_dynamic=num_dynamic,
num_combinations=num_combinations,
target_sorte="AMBO",
min_hits=2,
max_diff=max_diff,
show_progress=True
)
# Stampa i risultati
analyzer.print_results(result, top_n=20)
return result
# Esegui l'analisi
if __name__ == "__main__":
result = main()
#fixed_numbers = [1, 5, 12, 23, ...] # I tuoi numeri fissi
#num_dynamic = 4 # Quanti numeri dinamici
#num_combinations = 1000 # Quante combinazioni generare
#max_diff = 10 # Filtro: diff <= 10