В этой заметке привожу результаты тестов 3-х языковых моделей AI (ИИ). AI предложено проанализировать не оптимизированный алгоритм поиска простых чисел.

В тестах участвовали следующие модели:

ollama show llama3
  Model
    architecture        llama    
    parameters          8.0B     
    context length      8192     
    embedding length    4096     
    quantization        Q4_0     

  Parameters
    num_keep    24                       
    stop        "<|start_header_id|>"    
    stop        "<|end_header_id|>"      
    stop        "<|eot_id|>"             

  License
    META LLAMA 3 COMMUNITY LICENSE AGREEMENT             
    Meta Llama 3 Version Release Date: April 18, 2024

Llama 3

ollama show llama3.1
  Model
    architecture        llama     
    parameters          8.0B      
    context length      131072    
    embedding length    4096      
    quantization        Q4_0      

  Parameters
    stop    "<|start_header_id|>"    
    stop    "<|end_header_id|>"      
    stop    "<|eot_id|>"             

  License
    LLAMA 3.1 COMMUNITY LICENSE AGREEMENT            
    Llama 3.1 Version Release Date: July 23, 2024

Llama 3.1

ollama show llama3.2
  Model
    architecture        llama     
    parameters          3.2B      
    context length      131072    
    embedding length    3072      
    quantization        Q4_K_M    

  Parameters
    stop    "<|start_header_id|>"    
    stop    "<|end_header_id|>"      
    stop    "<|eot_id|>"             

  License
    LLAMA 3.2 COMMUNITY LICENSE AGREEMENT                 
    Llama 3.2 Version Release Date: September 25, 2024

Llama 3.2

ollama run llama3
>>>как в следующей программе работает функция prime_numbers, отвечай на русском языке: # Импортируем функцию timeit из модуля timeit для измерения времени выполнения код
... а
... from timeit import timeit
... 
... # Напишем функцию поиска простых чисел из числовой последовательности от 2 до n
... n = 1000
... 
... 
... def prime_numbers(n):
...     """
...     Реализация алгоритма "Решето Эратосфена" (Sieve of Eratosthenes)
...     для нахождения простых чисел в диапазоне от 2 до n.
... 
...     Args:
...         n Максимальное натуральное число, до которого продолжается поиск.
...     Returns:
...         sieve Список из n элементов, где значением True отмечен элемент с простым индексом.
...     """
...     # Создадим список sieve длинной n+1 с инициализацией флагами True и False.
...     # Это необходимо для работы алгоритма "Решето Эратосфена".
...     
...     sieve = [False] * 2 + [True] * (n - 1)  # Флаг True, предположительно простое число.
...     for i in range(2, n):                   # Переберем числа от 2 до n включительно.
...         for j in range(i + 1, n + 1):       # Переберем числа от i+1 до n+1.
...             if j % i == 0:                  # Если j делится без остатка на i:
...                 sieve[j] = False            # установим флаг в False для элемента sieve[j].
...     return sieve
... 
... 
... se = prime_numbers(n)           # Вызовем функцию prime_numbers с параметром n для получения
...                                 # решета Эратосфена с отмеченными простми числами.
...                                 # Выводим простые числа:
... for i, val in enumerate(se):    # Переберем элементы списка se
...     if val:                     # Если флаг элемента se[i] из списка se равен True:
...         print(i, end=' ')       # Выведем число i и разделитель (пробел)
... 
... print('\nRun 1000 tests...')    # Выводим сообщение о начале тестов.
... 
... # Вызываем функцию timeit 1000 раз для точного измерения времени выполнения функции sieve
... print(timeit(globals=globals(), stmt='prime_numbers(n)', number=1000),
...       'мс на одно выполнение функции при n = {}'.format(n))
... 
В этой программе функция `prime_numbers` реализует алгоритм "Решето Эратосфена" для поиска простых чисел в диапазоне от 2 до `n`.

Алгоритм работает следующим образом:

1. Создается список `sieve` длиной `n+1`, инициализованный флагами `True` и `False`. Это необходимо для работы алгоритма "Решето Эратосфена".

2. Затем iterate over the range `[2, n)`, где `n` - это максимальное натуральное число, до которого продолжается поиск.

3. Для каждого числа `i` в этом диапазоне:

   * Iterate over the range `[i+1, n+1)` (exclusive), что соответствует множителям `i`.

   * Если находим множитель `j`, который делится без остатка на `i`, то устанавливаем флаг в `False` для элемента `sieve[j]`. Это означает, что `j` не является 
простым числом.

4. В конце функция возвращает список `sieve`, где значением `True` отмечен элемент с простым индексом.

В программе также измеряется время выполнения функции `prime_numbers` 1000 раз для оценки ее эффективности.

Лист. 1. Llama3.

ollama run llama3.1
>>> как в следующей программе работает функция prime_numbers, отвечай на русском языке: # Импортируем функцию timeit из модуля timeit для измерения времени выполнения 
... кода
... from timeit import timeit
... 
... # Напишем функцию поиска простых чисел из числовой последовательности от 2 до n
... n = 1000
... 
... 
... def prime_numbers(n):
...     """
...     Реализация алгоритма "Решето Эратосфена" (Sieve of Eratosthenes)
...     для нахождения простых чисел в диапазоне от 2 до n.
... 
...     Args:
...         n Максимальное натуральное число, до которого продолжается поиск.
...     Returns:
...         sieve Список из n элементов, где значением True отмечен элемент с простым индексом.
...     """
...     # Создадим список sieve длинной n+1 с инициализацией флагами True и False.
...     # Это необходимо для работы алгоритма "Решето Эратосфена".
...     
...     sieve = [False] * 2 + [True] * (n - 1)  # Флаг True, предположительно простое число.
...     for i in range(2, n):                   # Переберем числа от 2 до n включительно.
...         for j in range(i + 1, n + 1):       # Переберем числа от i+1 до n+1.
...             if j % i == 0:                  # Если j делится без остатка на i:
...                 sieve[j] = False            # установим флаг в False для элемента sieve[j].
...     return sieve
... 
... 
... se = prime_numbers(n)           # Вызовем функцию prime_numbers с параметром n для получения
...                                 # решета Эратосфена с отмеченными простми числами.
...                                 # Выводим простые числа:
... for i, val in enumerate(se):    # Переберем элементы списка se
...     if val:                     # Если флаг элемента se[i] из списка se равен True:
...         print(i, end=' ')       # Выведем число i и разделитель (пробел)
... 
... print('\nRun 1000 tests...')    # Выводим сообщение о начале тестов.
... 
... # Вызываем функцию timeit 1000 раз для точного измерения времени выполнения функции sieve
... print(timeit(globals=globals(), stmt='prime_numbers(n)', number=1000),
...       'мс на одно выполнение функции при n = {}'.format(n))
... 
Отличная реализация алгоритма "Решето Эратосфена"!

Давайте разберем работу функции `prime_numbers`:

**Функция принимает аргумент**: `n`, максимальное натуральное число, до которого продолжается поиск простых чисел.

**Внутри функции создается список**: `sieve`, длиной `n+1`. Это список из флагов (`True` или `False`) для каждого числа от 2 до `n`.

**Алгоритм работы:**

1. Инициализация списка `sieve`: первый элемент (`sieve[0]`) всегда равен `False`, а все остальные элементы (`sieve[i]`, где `i` от 1 до `n`) инициализируются 
как `True`.
2. Два внешних цикла (`for i in range(2, n): ...` и `for j in range(i + 1, n + 1): ...`) обрабатывают числа от 2 до `n`.
3. Внутренний цикл (`for j in range(i + 1, n + 1): ...`) проверяет, делится ли число `j` на `i`. Если да, то:
	* Установка флага в `False` для элемента `sieve[j]`, что означает, что `j` не является простым числом.
4. После внутреннего цикла завершения вышедшее значение `sieve[i]` уже известно и равно `True`.

**Результат**: функция `prime_numbers` возвращает список `sieve` с отмеченными простыми числами (в значении `True`) от 2 до `n`.

Например, если `n = 10`, то результатом будет список: `[False, False, True, True, True, False, True, True, True, False]`. В этом списке `3`, `5` и `7` являются 
простыми числами.

Понятно?

Лист. 2. Llama3.1

ollama run llama3.2
>>> как в следующей программе работает функция prime_numbers, отвечай на русском языке: # Импортируем функцию timeit из модуля timeit для измерения времени выпол
... нения кода
... from timeit import timeit
... 
... # Напишем функцию поиска простых чисел из числовой последовательности от 2 до n
... n = 1000
... 
... 
... def prime_numbers(n):
...     """
...     Реализация алгоритма "Решето Эратосфена" (Sieve of Eratosthenes)
...     для нахождения простых чисел в диапазоне от 2 до n.
... 
...     Args:
...         n Максимальное натуральное число, до которого продолжается поиск.
...     Returns:
...         sieve Список из n элементов, где значением True отмечен элемент с простым индексом.
...     """
...     # Создадим список sieve длинной n+1 с инициализацией флагами True и False.
...     # Это необходимо для работы алгоритма "Решето Эратосфена".
...     
...     sieve = [False] * 2 + [True] * (n - 1)  # Флаг True, предположительно простое число.
...     for i in range(2, n):                   # Переберем числа от 2 до n включительно.
...         for j in range(i + 1, n + 1):       # Переберем числа от i+1 до n+1.
...             if j % i == 0:                  # Если j делится без остатка на i:
...                 sieve[j] = False            # установим флаг в False для элемента sieve[j].
...     return sieve
... 
... 
... se = prime_numbers(n)           # Вызовем функцию prime_numbers с параметром n для получения
...                                 # решета Эратосфена с отмеченными простми числами.
...                                 # Выводим простые числа:
... for i, val in enumerate(se):    # Переберем элементы списка se
...     if val:                     # Если флаг элемента se[i] из списка se равен True:
...         print(i, end=' ')       # Выведем число i и разделитель (пробел)
... 
... print('\nRun 1000 tests...')    # Выводим сообщение о начале тестов.
... 
... # Вызываем функцию timeit 1000 раз для точного измерения времени выполнения функции sieve
... print(timeit(globals=globals(), stmt='prime_numbers(n)', number=1000),
...       'мс на одно выполнение функции при n = {}'.format(n))
... 
Функция `prime_numbers` в этой программе использует алгоритм "Решето Эратосфена" (Sieve of Eratosthenes) для поиска простых чисел в диапазоне от 2 до `n`. 
Эта функция создает список `sieve` длиной `n+1`, где каждый элемент представляет собой флаг: `True` для простого числа, а `False` для composite числа.

Этапы работы функции:

1. Функция создает список `sieve` длиной `n+1` с инициализацией флагов `True` и `False`.
2. Для каждого простого числа `i` от 2 до `n`, она итерирует через число `j` от `i+1` до `n+1`, проверяя, делится ли `j` на `i`. Если это так, то она 
устанавливает флаг элемента `sieve[j]` в `False`.
3. В качестве результата функция возвращает список `sieve`.

Примечание: в данной программе используется алгоритм "Решето Эратосфена" с некоторыми ограничениями, поскольку он не works для всех значений `n`. Например, 
при `n` больше 2, в функции будет ошибка, так как функция будет использовать `i+1` в качестве начального значения цикла. 

В этом случае, для `n > 2`, функция создает список `sieve` длиной `n+1` с инициализацией флагов `True` и `False`. Поскольку при `i = 2` значение `j` равно 
`3`, то в функции будет ошибка. 

Чтобы исправить эту проблему, можно использовать алгоритм "Решето Эратосфена" с начальным значением `i=2`, а затем продолжать поиск простых чисел до 
значения `n`.

Лист. 3. Llama3.2