Оптимизација непотребних низова у PHP

Нека је пред неким програмером задатак да пронађе суму целих бројева од 1 до 100000000.

Наш програмер је написао елегантно решење ове задате, овако:

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

Лепо решење, зар не? У једном реду и све то. Али оно не ради! Покушајте да покренете овај код и он ће приказати грешку да сте захтевали превише оперативне меморије.

Хм, 100000000 није некако много? Или јесте много? Хајде да израчунамо. Функција range ствара низ са 100000000 бројева. Нека PHP додели 2 бајта по броју - онда за чување нашег низа требаће 200000000 бајта, то јест нешто око 200 мегабајта оперативне меморије.

Али заправо оперативне меморије требаће много више због тога што PHP има веома велике режијске трошкове при чувању низа. На пример, у мом тексту грешке пише да покушавам да доделим 4294967304 бајта - нешто око 4 гигабајта!

Јасно је сада зашто се појављује грешка - далеко смо изашли из дозвољеног лимита меморије.

Није толико тешко преписати наш скрипт у други, који практично не троши оперативну меморију:

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

А још боље користимо математичко решење:

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

Пред неким програмером је био задатак да пронађе факторијел задатог броја. Решио га је на следећи начин:

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

Објасните шта није у реду са овим кодом. Прерадите код у оптималнији.

Задание 2

Пред неким програмером је био задатак да пронађе број цифара помоћу којих се могу записати сви цели бројеви од 1 до 1000000. Решио га је на следећи начин:

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

Објасните шта није у реду са овим кодом. Прерадите код у оптималнији.

Задание 3

Пред неким програмером је био задатак да пронађе број бројева који се деле без остатка са 7, а који се налазе у задатом интервалу. Решио га је на следећи начин:

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

Објасните шта није у реду са овим кодом. Прерадите код у оптималнији.

Задание 4

Пред неким програмером је био задатак да пронађе суму делилаца броја. Решио га је на следећи начин:

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

Објасните шта није у реду са овим кодом. Прерадите код у оптималнији.