en
Feedback
C#Hive: Projects & Progress | Программирование

C#Hive: Projects & Progress | Программирование

Open in Telegram

Сообщество единомышленников C#: решаем задачи, учимся, развиваемся и общаемся вместе. Советы по работе на фрилансе, готовые проекты, код ревью, рекомендации и исследования. Вопросы/сотрудничество: @tel_phil9

Show more
1 780
Subscribers
No data24 hours
-17 days
-1030 days
Posts Archive
Решение задачи к посту.
void GnomeSort(int[] array)
{
    if (array == null || array.Length < 2) return;

    int i = 1;
    while (i < array.Length)
    {
        if (i == 0 || array[i - 1] <= array[i]) i++;
        else
        {
            int temp = array[i];
            array[i] = array[i - 1];
            array[i - 1] = temp;
            i--;
        }
    }
}
#Задача #Решение #Полезно

🖥 Задача: гномья сортировка (⭐️) Написать метод, который принимает массив целочисленного типа и сортирует его алгоритмом гномьей сортировки. Ниже приведены примеры.
int[] arr = { 21, -53, 75, -49, -80, 100, -48, 27, 38, -47, -42, -72 };
GnomeSort(arr);
👉 [-80, -72, -53, -49, -48, -47, -42, 21, 27, 38, 75, 100]
int[] arr = { 175, 136, 138, 300, 147, 252, 204, 91 };
GnomeSort(arr);
👉 [91, 136, 138, 147, 175, 204, 252, 300]
int[] arr = { 61, 45, 25, 31, 110, 48, 90, 114, 70, 60, 18, 112, 7, 82, 41, 39, 115, 84, 26, 29, 21, 57, 116, 65, 45 };
GnomeSort(arr);
👉 [7, 18, 21, 25, 26, 29, 31, 39, 41, 45, 45, 48, 57, 60, 61, 65, 70, 82, 84, 90, 110, 112, 114, 115, 116]
int[] arr = { 6, 18, -7, -9, -12, -16, 0, 8, 7, 3, -2, -10, 1, -9, 9, -6, 11, 4 };
GnomeSort(arr);
👉 [-16, -12, -10, -9, -9, -7, -6, -2, 0, 1, 3, 4, 6, 7, 8, 9, 11, 18]
int[] arr = { 8, 7, 6, 4, 3, 1 };
GnomeSort(arr);
👉 [1, 3, 4, 6, 7, 8] Пишите варианты в комментариях. Решение будет сегодня вечером новым постом в канале. #Задача #Lvl1

🖥 BenchmarkDotNet: измерение производительности Нередко возникает необходимость узнать некоторые аспекты производительности
🖥 BenchmarkDotNet: измерение производительности Нередко возникает необходимость узнать некоторые аспекты производительности программы: скорость выполнения, количество потребляемой памяти, сравнить производительность ряда альтернативных решений и выбрать из них наилучшее, и так далее. Для этих целей и принято использовать данную библиотеку. ➡️ Пример использования Рассмотрим базовое использование библиотеки. Для этого создадим новый проект консольного приложения и через Nuget добавим пакет BenchmarkDotNet. Рассмотрим примитивную программу, которая склеивает строки:
using System.Text;
using BenchmarkDotNet.Attributes;
using BenchmarkDotNet.Running;

BenchmarkRunner.Run<StringTest>();

public class StringTest
{
    public StringTest() { }

    private string[] numbers = { "one", "two", "three", "four", "five", "six", "seven", "eight", "nine", "ten" };

    [Benchmark]
    public string StringBuilder()
    {
        StringBuilder stringBuilder = new StringBuilder();

        foreach (string str in numbers)
        {
            stringBuilder.Append(str);
            stringBuilder.Append(' ');
        }

        return stringBuilder.ToString();
    }

    [Benchmark]
    public string Concatenation()
    {
        string result = "";

        foreach (string str in numbers) result = result + str + " ";

        return result;
    }

    [Benchmark]
    public string Interpolation()
    {
        string result = "";

        foreach (string str in numbers) result = $"{result}{str} ";

        return result;
    }
}
Мы определили класс StringTest, который определяет массив numbers из 10 строк и три метода. Методы используют разные техники, склеивая все эти строки в одну и возвращая её в качестве результата. Для тестирования все методы должны иметь модификатор public и к ним должны применяться атрибуты [Benchmark]. Сам класс, который содержит эти методы, тоже должен иметь модификатор public. Для запуска теста вызывается метод BenchmarkRunner.Run, который типизируется нашим классом:
BenchmarkRunner.Run<StringTest>();
Особенности запуска такого проекта: Следует запускать проект в Release конфигурации; Для большей точности рекомендуется выключить все остальные приложения, кроме текущего и стандартных процессов ОС; Если для тестирования используется ноутбук, то лучше его подключить к электросети и использовать наиболее производительный режим. По завершению теста консоль отобразит нам результаты. Нас интересует следующая таблица:
| Method        | Mean     | Error   | StdDev   |
|-------------- |---------:|--------:|---------:|
| StringBuilder | 313.5 ns | 6.31 ns | 17.49 ns |
| Concatenation | 427.0 ns | 8.51 ns |  7.96 ns |
| Interpolation | 428.7 ns | 5.10 ns |  4.26 ns |
Здесь столбец "Mean" представляет среднее время выполнения в наносекундах. Так, мы видим, что выполнение метода StringBuilder завершилось немногим быстрее, чем у других методов. Инструмент имеет множество различных настроек и возможностей конфигурации. Полная документация библиотеки. #Полезно #Benchmark

🖥 Из примера выше, что будет выведено на экран?
Anonymous voting

🖥 Фильтр Блума Представим, что мы крупный сайт — какой-нибудь маркетплейс — и нам нужно определять количество уникальных пос
🖥 Фильтр Блума Представим, что мы крупный сайт — какой-нибудь маркетплейс — и нам нужно определять количество уникальных посетителей. Как мы это сделаем? Вполне логичным решением будет сохранение нового IP-адреса из потока сетевого трафика в список, а общее количество элементов такого списка и будет сообщать нам количество уникальных посетителей. Вопреки такому решению, хранение всех этих данных (IP`шки) для нас может быть лишним. Мы не будем их использовать в дальнейшем, но каждый хранимый объект в памяти будет непременно "раздувать" его общее заполнение. В оптимизации такой задачи нам и поможет фильтр Блума, который мы сегодня рассмотрим на примере поставленной задачи. ➡️ Что это и как он работает Фильтр Блума проверяет принадлежность конкретного элемента к множеству данных без необходимости его хранения. Он использует массив битов (0 — false, 1 — true), а также несколько хеш-функций. Когда новый объект попадает в базу, его хеш-коды вычисляются, заполняя соответствующие биты массива в значении 1. Например, если хеш-функция возвращает число 50, то 50 бит (он же индекс) массива устанавливается в 1. Так происходит добавление IP-адреса в фильтр. Если при получении нового IP-адреса все нужные биты уже установлены в значение 1, то это значит, что он уже встречался ранее. Но важно помнить, что фильтр Блума не даёт 100% гарантии, что IP-адрес был уже замечен. Всегда есть небольшой риск ложноположительного результата. Эта вероятность зависит от размера массива битов, количества хеш-функций и количества уникальных IP-адресов. Фильтр Блума экономит память системы, особенно при работе с большими множествами, ускоряя операции добавления/проверки. Он подходит для задач проверки принадлежности, особенно когда требуется скорость при работе системы в условиях ограниченной памяти. Несмотря на небольшой процент ложноположительных результатов, он широко используется в разных приложениях. ➡️ Снижение вероятности коллизий Коллизии возникают, когда несколько различных элементов имеют одинаковые хеш-коды, что может привести к ложноположительным результатам при проверке. Стратегии снижения вероятности коллизий: Увеличение размера массива битов; Увеличение количества хеш-функций; Выбор качественных хеш-функций. ➡️ Простая реализация
public class BloomFilter<T>
{
    public BloomFilter(int capacity, int hashFunctionCount)
    {
        if (capacity < 1) throw new ArgumentOutOfRangeException(nameof(capacity), "Размер должен быть положительным");
        if (hashFunctionCount < 1) throw new ArgumentOutOfRangeException(nameof(hashFunctionCount), "Количество хеш-функций должно быть положительным");

        bitArray = new(capacity);
        hashCount = hashFunctionCount;
    }

    private readonly BitArray bitArray;
    private readonly int hashCount;

    public void Add(T item)
    {
        foreach (int hash in GetHashValues(item))
        {
            bitArray[hash] = true;
        }
    }

    public bool Contains(T item)
    {
        foreach (int hash in GetHashValues(item))
        {
            if (!bitArray[hash]) return false;
        }

        return true;
    }

    public void Clear() => bitArray.SetAll(false);

    private IEnumerable<int> GetHashValues(T item)
    {
        for (int i = 0; i < hashCount; i++)
        {
            int seed = i * 31;
            int hash = (item?.GetHashCode() ?? 0) ^ seed;
            yield return Math.Abs(hash) % bitArray.Length;
        }
    }
}
Проверим:
var filter = new BloomFilter<string>(1000, 5);
var apple = "apple";
var banana = "banana";

filter.Add(apple);
filter.Add(banana);
Check(apple);
Check(banana);
Check("date");
Check("grape");

filter.Clear();
Check(apple);
Check(banana);

void Check(string item) => Console.WriteLine(filter.Contains(item));
Вывод:
True
True
False
False
False
False
Отмечу, что реализация сильно простая. Рекомендую заменять GetHashCode на хеш-функцию MurmurHash2, MD5 или др. Ставьте реакции на пост, если хотите посмотреть на лучшую реализацию — напишу в комментариях. #Полезно #Хеширование #GetHashCode #Array

Решение задачи к посту.
double FastPow(double x, int n)
{
    if (n == 0) return 1;
    double count = 1;

    while (n != 0)
    {
        if (n % 2 == 0)
        {
            n /= 2;
            x *= x;
        }
        else
        {
            n--;
            count *= x;
        }
    }

    return count;
}
#Задача #Решение #Полезно

🖥 Задача: быстрое возведение в степень (⭐️) Написать метод, который принимает основание и показатель степени, реализует алгоритм быстрого возведения в степень и возвращает результат. Ниже приведены примеры.
double x = 3;
int n = 3;
double result = FastPow(x, n);
👉 27
double x = 3;
int n = 1;
double result = FastPow(x, n);
👉 1
double result = FastPow(2, 18);
👉 262144
FastPow(2, 51);
👉 2251799813685248
FastPow(3, 32);
👉 1853020188851841
FastPow(9, 13);
👉 2541865828329
FastPow(5, 16);
👉 152587890625 Пишите варианты в комментариях. Решение будет сегодня вечером новым постом в канале. #Задача #Lvl1

Веб-разработчика попросили покрасить яйца. #Юмор
Веб-разработчика попросили покрасить яйца. #Юмор

🖥 Из примера выше, что будет выведено на экран?
Anonymous voting

🖥 Асинхронные стримы: IAsyncEnumerable Асинхронные стримы упрощают работу с потоками данных в асинхронном режиме. Хотя «асин
🖥 Асинхронные стримы: IAsyncEnumerable Асинхронные стримы упрощают работу с потоками данных в асинхронном режиме. Хотя «асинхронность» существует уже довольно давно, асинхронные методы позволяли получать один объект, когда асинхронная операция была готова предоставить результат. Для возвращения нескольких значений могут применяться итераторы, но они имеют синхронную природу, блокируют вызывающий поток и не могут использоваться в асинхронном контексте. Асинхронные стримы обходят эту проблему, позволяя получать множество значений и возвращать их по мере готовности в асинхронном режиме. Асинхронный стрим представляет метод, который обладает тремя характеристиками: Метод имеет модификатор async; Метод возвращает объект IAsyncEnumerable<T>. Интерфейс IAsyncEnumerable определяет метод GetAsyncEnumerator, который возвращает IAsyncEnumerator; Метод содержит выражения yield return для последовательного получения элементов из асинхронного стрима. Фактически асинхронный стрим объединяет асинхронность и итераторы. Рассмотрим простейший пример:
await foreach (int number in GetNumbersAsync())
{
    Console.WriteLine(number);
}

async IAsyncEnumerable<int> GetNumbersAsync()
{
    for (int i = 0; i < 10; i++)
    {
        await Task.Delay(100);
        yield return i;
    }
}
Метод GetNumbersAsync() фактически и представляет асинхронный стрим. Этот метод является асинхронным, с возвращаемым типом IAsyncEnumerable<int>. Его суть сводится к тому, что он возвращает с помощью yield return каждые 100 миллисекунд некоторое число. Важно отметить, что цикл foreach отмечается оператором await. В итоге, каждый раз когда асинхронный стрим будет возвращать очередное число, цикл будет его получать и выводить на консоль. ➡️ Где можно применять асинхронные стримы? Асинхронные стримы могут применяться для получения данных из какого-нибудь внешнего хранилища: чтение больших файлов; обработка данных из БД; работа с API, возвращающими большие наборы данных. Например, пусть имеется следующий класс некоторого хранилища:
public class Repository
{
    private string[] data = { "Tom", "Sam", "Kate", "Alice", "Bob" };

    public async IAsyncEnumerable<string> GetDataAsync()
    {
        for (int i = 0; i < data.Length; i++)
        {
            Console.WriteLine($"Получаем {i + 1} элемент");
            await Task.Delay(500);
            yield return data[i];
        }
    }
}
Получим эти данные в программе:
Repository repo = new();
IAsyncEnumerable<string> data = repo.GetDataAsync();

await foreach (string name in data)
{
    Console.WriteLine(name);
}
Для упрощения примера данные здесь представлены в виде простого внутреннего массива строк. Для имитации задержки в получении применяется метод Task.Delay. #Полезно #Async #Await

Решение задачи к посту.
public class NumberToWordsConverter
{
    public int Number { get; init; }
    public string Words { get; init; }

    private NumberToWordsConverter(int number)
    {
        Number = number;
        if (number == 0)
        {
            Words = "ноль";
            return;
        }

        sb = new();
        int thousands = Number / 1000;

        if (thousands > 0) ParseHundreds(thousands, true);
        ParseHundreds(Number % 1000, false);

        Words = sb.ToString().Trim();
    }

    private static readonly string[] units = { null, "один ", "два ", "три ", "четыре ", "пять ", "шесть ", "семь ", "восемь ", "девять " };
    private static readonly string[] from10To19 = { "десять ", "одиннадцать ", "двенадцать ", "тринадцать ", "четырнадцать ", "пятнадцать ", "шестнадцать ", "семнадцать ", "восемнадцать ", "девятнадцать " };
    private static readonly string[] dozens = { null, null, "двадцать ", "тридцать ", "сорок ", "пятьдесят ", "шестьдесят ", "семьдесят ", "восемьдесят ", "девяносто " };
    private static readonly string[] hundreds = { null, "сто ", "двести ", "триста ", "четыреста ", "пятьсот ", "шестьсот ", "семьсот ", "восемьсот ", "девятьсот " };
    private readonly StringBuilder? sb;

    public static NumberToWordsConverter Read(int number)
    {
        if (number < 0 || number > 999999) throw new ArgumentOutOfRangeException(nameof(number), "Число должно быть между 0 и 999999");

        return new(number);
    }

    private void ParseHundreds(int number, bool isThousands)
    {
        int hundred = number / 100;
        int dozen = number % 100 / 10;
        int unit = number % 10;

        sb.Append(hundreds[hundred]);
        sb.Append(dozen == 1 ? from10To19[unit] : dozens[dozen]);
        if (dozen != 1) sb.Append(isThousands && unit == 1 ? "одна " : isThousands && unit == 2 ? "две " : units[unit]);

        if (isThousands && dozen == 1) sb.Append("тысяч ");
        else if (isThousands) sb.Append(unit == 1 ? "тысяча " : unit >= 2 && unit <= 4 ? "тысячи " : "тысяч ");
    }
}
#Задача #Решение #Полезно

🖥 Задача: преобразование числа в пропись (⭐️⭐️⭐️) Написать класс, который преобразует целочисленное число в словесное представление прописью. Допускаются предельные рамки числа от 0 до 999 999 (включительно). Ниже приведены примеры.
NumberToWordsConverter.Read(0).Words;
👉 ноль
NumberToWordsConverter number = NumberToWordsConverter.Read(1);
string words = number.Words;
👉 один
string words = NumberToWordsConverter.Read(12).Words;
👉 двенадцать
NumberToWordsConverter.Read(123).Words;
👉 сто двадцать три
NumberToWordsConverter.Read(111).Words;
👉 сто одиннадцать
NumberToWordsConverter.Read(51004).Words;
👉 пятьдесят одна тысяча четыре
NumberToWordsConverter.Read(1000).Words;
👉 одна тысяча
NumberToWordsConverter.Read(number: 2000).Words;
👉 две тысячи
NumberToWordsConverter.Read(5000).Words;
👉 пять тысяч
NumberToWordsConverter.Read(12345).Words;
👉 двенадцать тысяч триста сорок пять
NumberToWordsConverter.Read(100000).Words;
👉 сто тысяч
NumberToWordsConverter.Read(999999).Words;
👉 девятьсот девяносто девять тысяч девятьсот девяносто девять Пишите варианты в комментариях. Решение будет сегодня вечером новым постом в канале. #Задача #Lvl3

🖥 Selenium: отправка решённой Google reCAPTCHA v2 Когда я только начал фрилансить и узнал о Selenium, любая гугловская рекап
🖥 Selenium: отправка решённой Google reCAPTCHA v2 Когда я только начал фрилансить и узнал о Selenium, любая гугловская рекапча заставала меня врасплох. Я знал, что её решение возможно и даже знал «как», но я не понимал, что мне делать с этим токеном? Если мы отправляем его в запросе, то вопросов не возникало, а вот как решить задачу при эмуляции браузера — непонятно. Сегодня мы рассмотрим то, как правильно отправлять токен в форму рекапчи, чтобы продолжить сёрфинг. Прошу не путать с API интеграцией к сервисам ручного распознавания капч. Обсуждение поможет новичкам отправлять рекапчи, которые словил наш WebDriver. ➡️ Разбор на примере В качестве обзора, рассмотрим форму авторизации на сайте FL. Вариант довольно примитивный, так как нужно ввести логин, пароль, решить капчу и нажать кнопку. После быстрого анализа, определяем селекторы для логина, пароля и кнопки:
var usernameSelector = By.Name("username");
var passwordSelector = By.Name("password");
var submitSelector = By.Id("submit-button");
А также нам нужно найти селектор капчи. Его всегда можно найти по ID с именем "g-recaptcha-response":
var recaptchaSelector = By.Id("g-recaptcha-response");
Остаётся только корректно передать данные параметра "data-sitekey" в API сервиса, получить решённый токен и использовать его у себя. Как раз в этом и был у меня пробел в своё время, я не знал куда этот токен нужно ввести. А ввести его нужно просто в найденный нами селектор капчи, в качестве нового параметра "value", со значением нашего решённого токена. Отправим решённую капчу и успешно пройдём форму авторизации:
ChromeDriver driver = new ChromeDriver();
driver.Navigate().GoToUrl("https://www.fl.ru/account/login/");

// Вводим логин и пароль
driver.FindElement(usernameSelector).SendKeys("Мой_Логин");
driver.FindElement(passwordSelector).SendKeys("Мой_Пароль");

// Вводим токен капчи через JS
string token = "Решённый_Токен";
var elem = driver.FindElement(recaptchaSelector);
driver.ExecuteScript($"arguments[0].value = \"{token}\";", elem);

// Жмём кнопку "Войти"
driver.FindElement(submitSelector).Click();
Хочу поздравить — капча пройдена! Можешь позлорадствовать и продолжить свои "грязные делишки", ботовод. ➡️ Дополнительные советы Примеры могут быть разные, стоит это понимать. Нужно быть гибким, ибо каждый ресурс уникален. Капча может быть невидимой, может работать через функцию обратного вызова (callback), а может вообще быть иной версии. Для быстрого анализа данных рекапчи на целевом сайте, рекомендую использовать готовый JavaScript. Вставляем код в консоль браузера > запрашиваем функцию findRecaptchaClients() > получаем результат. Рекомендую более тщательно изучать документации сервисов ручного распознавания капч. Вы сэкономите время, улучшите качество своих проектов и увеличите продажи. #Полезно #Selenium #Капча

🖥 Из примера выше, что будет выведено на экран?
Anonymous voting

🖥 Имена объектов, если бы они были русскими Сегодня я предлагаю погрузиться в объекты языка (классы, структуры и т.д.) с русским колоритом. Если представить, что все объекты были бы исконно русскими и, соответственно, именованы на русском языке, то как бы они назывались? На вполне логичный вопрос "зачем это нужно?" отвечу кратко: это поможет лучше понять суть некоторых объектов, особенно новичкам без знания английского языка. Для более же опытных ребят — это будет просто развлечением и повторением давно понятных вещей, в комментариях предлагаю делиться своим мнением 😊 ➡️ Переименуем объекты Уточню, что все объекты перечисляться не будут, поскольку их безбожно много. Я постараюсь отметить только самые часто используемые объекты, которые могут иметь вопросы уже из-за своего имени. Описание же каждого класса сможете прочесть уже от Microsoft. Погнали! Класс Object aka «Объект». Класс Tuple aka «Кортеж». Структура DateTime aka «ДатаВремя». Структура TimeSpan aka «ИнтервалВремени». Структура Guid aka «Гуид» (аббр. Глобальный Уникальный Идентификатор). Структура KeyValuePair<TKey, TValue> aka «ПараКлючЗначение». ... Класс StringBuilder aka «СтроительСтроки». Класс Encoding aka «Кодировка». ... Класс Array aka «Массив». Класс List<T> aka «Список». Класс Dictionary<TKey, TValue> aka «Словарь». Класс Enumerable aka «Перечисляемый». ... Класс File aka «Файл». Класс Directory aka «Каталог». Класс Path aka «Путь». Класс Stream aka «ПотокБайтов». ... Класс Thread aka «Поток». Класс Task aka «Задача». Класс Mutex aka «Мьютекс». Структура CancellationToken aka «МаркерОтмены». ... Класс HttpClient aka «HttpКлиент». Класс HttpRequestMessage aka «HttpЗапросСообщения». Класс HttpListener aka «HttpПрослушиватель». ... Класс Type aka «Тип». Класс Assembly aka «Сборка». ... Класс GC aka «СборщикМусора». Класс Marshal aka «Маршалинг». Структура Span<T> aka «Промежуток». Структура ReadOnlySpan<T> aka «ТолькоЧтениеПромежутка». ... Класс Console aka «Консоль». Класс Convert aka «Преобразовать». Класс Random aka «Случайность». Класс Math aka «Математика». Класс AppDomain aka «ДоменПриложения». Класс Environment aka «Окружение». Класс Stopwatch aka «Секундомер». Класс Lazy<T> aka «Ленивый». ... Делегат Action aka «Действие». Делегат Func<T, TResult> aka «Функция». ... Атрибут [Obsolete] aka «Устарелый». Атрибут [Serializable] aka «Сериализуемый». ... Интерфейс IComparable aka «Сравниваемый». Интерфейс IDisposable aka «Утилизируемый». ➡️ Возможно ли это на практике? Да, мы можем даже на практике именовать как типы русским языком, так и функции с переменными:
public class Секундомер
{
    public ИнтервалВремени ПрошедшееВремя { get; }

    private int локальноеЗначение;

    public void Перезапуск()
    {
        локальноеЗначение = 0;
        // ...
        //
    }
}

public struct ИнтервалВремени
{

}
А можно даже совмещать:
public class HttpКлиент
{

}
Однако не стоит привыкать к такому подходу. Приучайте себя к общему формату и синтаксису. #Полезно

Решение задачи к посту.
void Eratosthenes(int n)
{
    if (n < 2) throw new ArgumentOutOfRangeException();

    var marked = Marking(n);
    var primeNumbers = PrimeNumbersFrom(marked, n);

    Console.WriteLine(string.Join(", ", primeNumbers));
}

bool[] Marking(int n)
{
    var marked = new bool[n + 1];
    for (int i = 2; i <= n; i++) marked[i] = true;

    for (int p = 2; p * p <= n; p++)
    {
        if (marked[p])
        {
            for (int i = p * p; i <= n; i += p)
                marked[i] = false;
        }
    }

    return marked;
}

List<int> PrimeNumbersFrom(bool[] marked, int n)
{
    List<int> nums = new();

    for (int i = 2; i <= n; i++)
        if (marked[i]) nums.Add(i);

    return nums;
}
#Задача #Решение #Полезно

🖥 Задача: решето Эратосфена (⭐️) Написать метод, принимающий некоторый диапазон чисел N (целочисленное значение), из которого необходимо получить все простые числа до N, используя реализацию решето Эратосфена и вывести результат на экран. Ниже приведены примеры.
Eratosthenes(25);
👉 2, 3, 5, 7, 11, 13, 17, 19, 23
Eratosthenes(59);
👉 2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41, 43, 47, 53, 59
Eratosthenes(101);
👉 2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41, 43, 47, 53, 59, 61, 67, 71, 73, 79, 83, 89, 97, 101
Eratosthenes(570);
👉 2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41, 43, 47, 53, 59, 61, 67, 71, 73, 79, 83, 89, 97, 101, 103, 107, 109, 113, 127, 131, 137, 139, 149, 151, 157, 163, 167, 173, 179, 181, 191, 193, 197, 199, 211, 223, 227, 229, 233, 239, 241, 251, 257, 263, 269, 271, 277, 281, 283, 293, 307, 311, 313, 317, 331, 337, 347, 349, 353, 359, 367, 373, 379, 383, 389, 397, 401, 409, 419, 421, 431, 433, 439, 443, 449, 457, 461, 463, 467, 479, 487, 491, 499, 503, 509, 521, 523, 541, 547, 557, 563, 569 Пишите варианты в комментариях. Решение будет сегодня вечером новым постом в канале. #Задача #Lvl1