22 Gennaio 2026
Algoritmo di Babbo Natale
A Natale l’Osservatorio vi regala l'algoritmo di Babbo Natale! Segue la notte, ottimizza il percorso e ci ricorda che anche la magia ha regole.

Il Natale è, per tradizione, il tempo della meraviglia. È il momento in cui accettiamo senza troppe domande che un uomo con la barba bianca possa consegnare milioni di regali in una sola notte, attraversando il mondo mentre tutti dormono.

Eppure, se osserviamo questa storia con gli occhi di chi si occupa di tecnologia, innovazione e regole, quella stessa magia assume un significato diverso, forse ancora più affascinante.

Da Presidente dell’Osservatorio Italiano sul Diritto delle Nuove Tecnologie, credo che il Natale sia anche l’occasione giusta per ricordare che dietro ogni fenomeno complesso – persino quelli che chiamiamo “magici” – esistono logiche, modelli e regole invisibili. È lo stesso principio che governa le reti digitali, gli algoritmi, l’intelligenza artificiale e, di conseguenza, le nuove sfide giuridiche che ogni giorno affrontiamo.

Prendiamo proprio l’esempio di Babbo Natale. Se lo liberiamo per un attimo dalla favola, ci troviamo davanti a un problema estremamente concreto: milioni di destinazioni, una finestra temporale rigidissima, la necessità di ridurre tempi e distanze, l’obbligo di non commettere errori. In termini tecnici, è un classico problema di ottimizzazione e di routing, molto simile a quelli affrontati quotidianamente dai grandi sistemi di distribuzione, dalle reti di comunicazione elettronica e dalle piattaforme digitali globali.

Ora per questo Natale ho deciso di fare un piccolo regalo a tutti voi, e svestendo per un attimo la toga di avvocato e ritornando nei panni vestiti sin dalla tenera età di 11 anni di programmatore informatico, ho deciso di cercare di trasformare questa intuizione in qualcosa di concreto.

Ho immaginato e sviluppato un algoritmo simbolico, capace di simulare il percorso di consegna dei regali seguendo una logica semplice ma potente. Il principio è quello del “follow the night”, e cioè partire da Est e seguire la mezzanotte che avanza, organizzando le consegne per fuso orario e ottimizzando il percorso scegliendo, di volta in volta, la destinazione più vicina. Una strategia che riduce gli sprechi, massimizza l’efficienza e dimostra come anche il caos apparente possa essere governato da regole razionali.

Strada facendo mi sono reso conto che questo esercizio non è un gioco fine a sé stesso, ma diventa un modo per ricordare che gli algoritmi non sono entità astratte o incomprensibili, ma strumenti costruiti da esseri umani, che riflettono scelte, priorità e valori. Ed è proprio qui che il diritto entra in gioco. Ogni algoritmo che incide sulla realtà, ogni sistema automatizzato che prende decisioni, pone questioni di responsabilità, trasparenza, equità e tutela dei diritti fondamentali. Anche quando tutto sembra funzionare “come per magia”.

Con questo breve post voglio quindi fare due auguri. Il primo è quello, più tradizionale, di un sereno Natale a chi ci segue, studia, lavora e riflette con noi sul rapporto tra diritto e nuove tecnologie. Il secondo è un augurio meno scontato, quello di continuare a coltivare uno sguardo critico e curioso sull’innovazione, capace di vedere oltre la superficie e di interrogarsi sulle regole che governano il mondo digitale in cui viviamo.

Perché, in fondo, anche nel diritto delle nuove tecnologie vale una grande lezione natalizia, la vera magia non è l’assenza di regole, ma la loro comprensione!

Buon Natale a tutti!

P.S.

Il codice seguente l’ho scritto in python, perdonate qualche errore!

# ============================================================
# Algoritmo di Babbo Natale
# Simulazione di consegna regali su mappa (lon/lat)
# - Follow-the-night: ordina per fuso orario da Est a Ovest
# - Routing locale: nearest neighbor
# - Miglioramento: 2-opt
# ============================================================

import numpy as np
import matplotlib.pyplot as plt
from math import hypot

# ----------------------------
# 1) Dati simulati (case nel mondo)
# ----------------------------
def genera_case(n=250, seed=42):
"""
Genera 'case' come punti su una pseudo-mappa:
- longitudine in [-180, 180]
- latitudine in [-90, 90]
- fuso_orario approssimato dalla longitudine (lon/15)
"""
rng = np.random.default_rng(seed)
lon = rng.uniform(-180, 180, n)
lat = rng.uniform(-60, 75, n) # limiti ragionevoli per un grafico leggibile
fuso = np.clip(np.round(lon / 15).astype(int), -12, 14)
return lon, lat, fuso

# ----------------------------
# 2) Distanze e utilità
# ----------------------------
def distanza(a, b):
"""Distanza euclidea su lon/lat (solo per simulazione/visualizzazione)."""
return hypot(a[0] - b[0], a[1] - b[1])

def lunghezza_percorso(punti, ordine):
"""Somma delle distanze lungo l'ordine indicato."""
tot = 0.0
for i in range(len(ordine) - 1):
tot += distanza(punti[ordine[i]], punti[ordine[i + 1]])
return tot

# ----------------------------
# 3) Euristiche di routing
# ----------------------------
def nearest_neighbor(punti, start_idx=0):
"""
Euristica: parti da start_idx e vai sempre al punto non visitato più vicino.
Restituisce un ordine (lista di indici) dei punti.
"""
n = len(punti)
non_visitati = set(range(n))
ordine = [start_idx]
non_visitati.remove(start_idx)

while non_visitati:
ultimo = ordine[-1]
prox = min(non_visitati, key=lambda j: distanza(punti[ultimo], punti[j]))
ordine.append(prox)
non_visitati.remove(prox)

return ordine

def two_opt(punti, ordine, max_iter=2000):
"""
Miglioramento 2-opt: prova a invertire segmenti del percorso se riduce la lunghezza.
"""
n = len(ordine)
migliorato = True
it = 0

while migliorato and it < max_iter:
migliorato = False
it += 1

for i in range(1, n - 2):
for k in range(i + 1, n - 1):
a, b = ordine[i - 1], ordine[i]
c, d = ordine[k], ordine[k + 1]

prima = distanza(punti[a], punti[b]) + distanza(punti[c], punti[d])
dopo = distanza(punti[a], punti[c]) + distanza(punti[b], punti[d])

if dopo + 1e-9 < prima:
# inversione del segmento [i : k]
ordine[i:k + 1] = reversed(ordine[i:k + 1])
migliorato = True

return ordine

# ----------------------------
# 4) Algoritmo di Babbo Natale (follow-the-night)
# ----------------------------
def algoritmo_di_babbo_natale(lon, lat, fuso):
"""
Strategia:
1) Ordina i fusi da Est a Ovest (valore fuso più alto -> più basso)
2) Per ogni fuso:
- calcola un percorso locale (nearest neighbor)
- ottimizza (2-opt)
3) Concatena i percorsi locali in un piano globale di consegna
"""
punti = np.column_stack([lon, lat])
piano = []

for t in sorted(np.unique(fuso), reverse=True): # Est -> Ovest
indici = np.where(fuso == t)[0]
if len(indici) == 0:
continue

sotto_punti = punti[indici]

ordine_locale = nearest_neighbor(sotto_punti, start_idx=0)
ordine_locale = two_opt(sotto_punti, ordine_locale)

# Trasforma indici locali in indici globali
piano.extend(indici[ordine_locale].tolist())

return punti, piano

# ----------------------------
# 5) Esecuzione + Grafico
# ----------------------------
def main():
lon, lat, fuso = genera_case(n=220, seed=42)
punti, piano = algoritmo_di_babbo_natale(lon, lat, fuso)

ordine_grezzo = list(range(len(punti)))
len_grezza = lunghezza_percorso(punti, ordine_grezzo)
len_babbo = lunghezza_percorso(punti, piano)

# Plot
fig = plt.figure(figsize=(12, 6))
ax = plt.gca()
ax.set_title("Algoritmo di Babbo Natale – Simulazione su mappa (lon/lat)\n"
"Follow-the-night (fusi orari) + nearest-neighbor + 2-opt")
ax.set_xlabel("Longitudine")
ax.set_ylabel("Latitudine")
ax.set_xlim(-180, 180)
ax.set_ylim(-90, 90)
ax.grid(True, alpha=0.3)

# bordo "mondo"
ax.plot([-180, 180, 180, -180, -180], [-90, -90, 90, 90, -90], linewidth=1)

# case colorate per fuso
sc = ax.scatter(lon, lat, c=fuso, s=18, alpha=0.85)
cbar = plt.colorbar(sc, ax=ax, pad=0.01)
cbar.set_label("Fuso orario (approx)")

# rotta
rotta = punti[piano]
ax.plot(rotta[:, 0], rotta[:, 1], linewidth=1)

# start/end
ax.scatter(rotta[0, 0], rotta[0, 1], s=120, marker="*", edgecolor="black")
ax.scatter(rotta[-1, 0], rotta[-1, 1], s=80, marker="X", edgecolor="black")

# box info
ax.text(-175, -83,
f"Punti: {len(punti)}\n"
f"Lunghezza (ordine grezzo): {len_grezza:.1f}\n"
f"Lunghezza (Algoritmo di Babbo Natale): {len_babbo:.1f}",
fontsize=10, va="bottom")

plt.show()

if __name__ == "__main__":
main()

Sull'autore