Ottimizzazione di array non necessari in PHP

Supponiamo che un programmatore abbia il compito di trovare la somma dei numeri interi da 1 a 100000000.

Il nostro programmatore ha scritto una soluzione elegante per questo problema, in questo modo:

php<?php
  echo array_sum(range(1, 100000000));
?>

Una bella soluzione, non è vero? In una riga sola e tutto il resto. Ma non funziona! Provate ad eseguire questo codice e visualizzerà un errore che indica che è stata richiesta troppa memoria.

Mmh, 100000000 non sembra così tanto? O forse sì? Calcoliamo. La funzione range crea un array con 100000000 numeri. Supponiamo che PHP allochi 2 byte per numero - allora per memorizzare il nostro array serviranno 200000000 byte, cioè circa 200 megabyte di memoria RAM.

Ma in realtà servirà molta più memoria a causa degli alti costi generali in PHP per la memorizzazione degli array. Ad esempio, nel mio caso l'errore indica che sto tentando di allocare 4294967304 byte - circa 4 gigabyte!

Ora è chiaro perché si verifica l'errore - abbiamo superato di gran lunga il limite di memoria consentito.

Non è così difficile riscrivere il nostro script in un modo diverso, che consuma praticamente nessuna memoria:

php<?php
  $sum = 0;
  
  for ($i = 1; $i <= 100000000; $i++) {
    $sum += $i;
  }
  
  echo $sum;
?>

O ancora meglio, usiamo la soluzione matematica:

php<?php
  $n = 1000000;
  $sum = $n * ($n + 1) / 2;
  echo $sum;
?>
Задание 1

Un programmatore aveva il compito di trovare il fattoriale di un dato numero. Lo ha risolto nel modo seguente:

php<?php
  $n = 100;
  echo array_product(range(1, $n));
?>

Spiegate cosa non va in questo codice. Riscrivete il codice in modo più ottimale.

Задание 2

Un programmatore aveva il compito di trovare il numero di cifre necessarie per scrivere tutti i numeri interi da 1 a 1000000. Lo ha risolto nel modo seguente:

php<?php
  echo strlen(implode('', range(1, 1000000)));
?>

Spiegate cosa non va in questo codice. Riscrivete il codice in modo più ottimale.

Задание 3

Un programmatore aveva il compito di trovare il numero di numeri divisibili senza resto per 7, all'interno di un intervallo specificato. Lo ha risolto nel modo seguente:

php<?php
  $arr = [];
  
  for ($i = 0; $i <= 1000; $i++) {
    if ($i % 7 == 0) {
      $arr[] = $i;
    }
  }
  
  echo count($arr);
?>

Spiegate cosa non va in questo codice. Riscrivete il codice in modo più ottimale.

Задание 4

Un programmatore aveva il compito di trovare la somma dei divisori di un numero. Lo ha risolto nel modo seguente:

php<?php
  $num = 320;
  $divs = [];
  
  for ($i = 0; $i <= $num; $i++) {
    if ($num % $i == 0) {
      $divs[] = $i;
    }
  }
  
  echo array_sum($divs);
?>

Spiegate cosa non va in questo codice. Riscrivete il codice in modo più ottimale.