fa
Feedback
PascalABC.NET официальный канал

PascalABC.NET официальный канал

رفتن به کانال در Telegram

Официальный канал языка и системы программирования PascalABC.NET

نمایش بیشتر
1 861
مشترکین
-624 ساعت
-57 روز
-2330 روز
آرشیو پست ها
🔧 Замена текста внутри квадратных скобок Если требуется заменить текст внутри [...], можно воспользоваться методами строк In
🔧 Замена текста внутри квадратных скобок Если требуется заменить текст внутри [...], можно воспользоваться методами строк IndexOf, Remove и Insert. Первую открывающую скобку ищем до цикла, а в самом цикле переходим к следующей уже со строки позиции конечной скобки.
begin
  var s := 'Клад зарыт на [юго-западе] под [пальмой]';
  var replaceStr := 'скрыто';
  
  var startPos := s.IndexOf('[');
  while startPos <> -1 do
  begin
    var endPos := s.IndexOf(']', startPos + 1);
    if endPos = -1 then break;
    
    s := s.Remove(startPos + 1, endPos - startPos - 1);
    s := s.Insert(startPos + 1, replaceStr);
    
    startPos := s.IndexOf('[', endPos); // безопасно в PascalABC.NET
  end;
  
  Println(s);
end.
Приём подходит для любой задачи, где нужно обработать фрагменты между парными символами.

Умножение матриц в стиле LINQ Для умножения матриц используем метод Zip и срезы матрицы по строке и столюцу function Dot(a1,
Умножение матриц в стиле LINQ Для умножения матриц используем метод Zip и срезы матрицы по строке и столюцу
function Dot(a1, a2: array of real): real := a1.Zip(a2,(x,y) -> x*y).Sum;

function Mult(a, b: array[,] of real): array[,] of real := 
  MatrGen(a.RowCount, b.ColCount, (i,j) -> Dot(a[i,:],b[:,j]));

begin
  var a := Matr([1.1,2,3],[4.3,5,6],[7.0,8,9],[5.7,2,8]);
  var b := Matr([4.0,5],[8.2,4],[3.0,9]);
  a.Print(7,1); Println;
  b.Print(7,1); Println;
  Mult(a,b).Print(7,1);
end.
Результат:
    1.1    2.0    3.0
    4.3    5.0    6.0
    7.0    8.0    9.0
    5.7    2.0    8.0

    4.0    5.0
    8.2    4.0
    3.0    9.0

   29.8   40.5
   76.2   95.5
  120.6  148.0
   63.2  108.5

Умножение матриц в стиле LINQ

Количество простых чисел Как вычислить количество простых чисел, меньших заданного n? Используем LINQ и функциональное програ
Количество простых чисел Как вычислить количество простых чисел, меньших заданного n? Используем LINQ и функциональное программирование. Два способа: обычный и с распараллеливанием.
##
function IsPrime(x: integer) := (2..x.Sqrt.Round).All(i -> x.NotDivs(i));

var n := 4000000;
(2..n).Where(IsPrime).Count.Println;
MillisecondsDelta.Println;

(2..n).AsParallel.Where(IsPrime).Count.Println;
MillisecondsDelta.Println;
Linq автоматически распараллеливает проверки для разных чисел на простоту по различным потокам. Скорость распараллеленной версии - примерно в 6 раз меньше - значит, процессор шестиядерный.

Массивы и списки - это последовательности В PascalABC.NET есть специальный тип-последовательность - набор элементов, которые можно перебрать один за другим циклом foreach. Если нужно написать некоторый алгоритм и перебрать элементы, то лучше использовать не конкретный тип - массив или список, а последовательность:
function SumSquares(s: sequence of integer): integer;
begin
  Result := 0;
  foreach var x in s do
    Result += x*x;
end;

begin
  SumSquares(Arr(1,2,3)).Print;
  SumSquares(Lst(2,3,4)).Print;
end.

Copy для массивов и матриц как метод расширения Для создания копии массивов и матриц пользуемся методом расширения Copy
Copy для массивов и матриц как метод расширения Для создания копии массивов и матриц пользуемся методом расширения Copy

🧠 ML: нормализация признаков в PascalABC.NET При подготовке данных для моделей машинного обучения часто требуется нормализов
🧠 ML: нормализация признаков в PascalABC.NET При подготовке данных для моделей машинного обучения часто требуется нормализовать каждый признак (столбец матрицы): вычесть среднее и поделить на стандартное отклонение. В PascalABC.NET это можно сделать компактно и полностью функционально.
function Normalize(a: array of real): array of real;
begin
  var mean := a.Average; 
  var std := Sqrt(a.ConvertAll(x -> (x-mean)**2).Average); 
  Result := a.ConvertAll(x -> (x-mean)/std);
end;

function NormalizeCols(a: array[,] of real): array[,] of real
  := MatrByCol(a.Cols.ConvertAll(col -> Normalize(col)));

begin
  var a := Matr([1.1,2,3],[4.3,5,6],[7.0,8,9],[5.7,2,8]);
  NormalizeCols(a).Print(7,1)
end.
Нормализация столбцов — стандартный шаг при работе с датасетами: она улучшает сходимость моделей, делает признаки сопоставимыми и устраняет влияние масштаба. Благодаря функциональному стилю PascalABC.NET такие операции можно выразить очень компактно.

Чему равен синус? Проверим. Для этого просто напечатаем синус 👀 А синус оказывается - это функция 🤔
Чему равен синус? Проверим. Для этого просто напечатаем синус 👀 А синус оказывается - это функция 🤔

Перегрузка операций - теперь без extensionmethod Теперь в PascalABC.NET для перегрузки операций не надо писать extensionmetho
Перегрузка операций - теперь без extensionmethod Теперь в PascalABC.NET для перегрузки операций не надо писать extensionmethod Операции перегружаются как обычные функции с именем operator@ где @ - значок операции #новое

Task / Task<integer> в PascalABC.NET — понятное объяснение Task — это задача, которая может выполняться параллельно с основной программой. Когда мы запускаем задачу через Task.Run, мы передаём внутрь лямбда-выражение без параметров, которое что-то вычисляет и в конце пишет:
Result := ...
В данном случае лямбда возвращает целое значение, и поэтому Task.Run создаёт объект класса Task<integer>. Что такое t1.Result t1.Result — это способ получить результат работы задачи. Если задача ещё не закончила работу — при обращении к t1.Result программа приостановится, подождёт завершения задачи и потом вернёт её результат. Если же к моменту вызова t1.Result задача закончила работу, то просто вернется результат как будто мы вызвали обычную функцию. То есть t1.Result одновременно: 🔹 ждёт завершения задачи 🔹 возвращает вычисленное значение Пример: две задачи считают параллельно
uses System.Threading.Tasks;

begin
  var t1 := Task.Run(()->
  begin
    var s := 0;
    for var i:=1 to 5_000_000 do
      s += i;
    Result := s // => t1 будет Task<integer>
  end);

  var t2 := Task.Run(()->
  begin
    var s := 0;
    for var i:=1 to 5_000_000 do
      s += i*i;
    Result := s // => t2 будет Task<integer>
  end);

  // Ожидание завершения + получение результата
  var r := t1.Result + t2.Result;
  Println(r);
end.
Что происходит 🔹 Создаются две независимые задачи 🔹 Каждая считает свою сумму 🔹 Они работают одновременно 🔹 Когда мы обращаемся к t1.Result и t2.Result, программа ждёт и получает результат 🔹 Затем выводим сумму двух результатов

Рост пользователей из Китая По данным mail.ru с июля 2025 года наблюдается стремительный рост пользователей PascalABC.NET из
Рост пользователей из Китая По данным mail.ru с июля 2025 года наблюдается стремительный рост пользователей PascalABC.NET из Китая

Градиентный спуск на PascalABC.NET Хотим предсказывать итоговую оценку студента по двум параметрам: x1 — часы подготовки x2 — часы сна Модель: линейная регрессия Учимся на реальных парах данных, минимизируем квадратичную ошибку методом градиентного спуска. Функция ошибки на одном наблюдении:
L = (w1*x1 + w2*x2 + b - y)**2
Частные производные:
dL/dw1 = 2*x1*(w1*x1 + w2*x2 + b - y)
dL/dw2 = 2*x2*(w1*x1 + w2*x2 + b - y)
dL/db  = 2*(w1*x1 + w2*x2 + b - y)
Используем средний градиент по всей выборке.
function Loss(x1, x2, w1, w2, b, y: real) := 
  (w1*x1 + w2*x2 + b - y)**2;

function dL_dw1(x1, x2, w1, w2, b, y: real) := 
  2 * x1 * (w1*x1 + w2*x2 + b - y);

function dL_dw2(x1, x2, w1, w2, b, y: real) := 
  2 * x2 * (w1*x1 + w2*x2 + b - y);

function dL_db(x1, x2, w1, w2, b, y: real) := 
  2 * (w1*x1 + w2*x2 + b - y);

begin
  var x: array of array of real := (
    (2,6),(4,5),(5,7),(1,4),(3,6),
    (6,5),(5,6),(7,8),(3,5),(4,7)
  );
  var y: array of real := (70,78,82,62,75,85,80,90,72,79);
  var n := x.Length;

  var w1 := 0.1; var w2 := 0.1; var b := 0.1;
// скорость обучения
  var lr := 0.002;
  var epochs := 20000;

  for var epoch := 0 to epochs-1 do
  begin
    var grad_w1 := 0.0; 
    var grad_w2 := 0.0; 
    var grad_b  := 0.0;
    var total_loss := 0.0;

    for var i := 0 to n-1 do
    begin
      var x1 := x[i][0]; 
      var x2 := x[i][1]; 
      var yi := y[i];
      total_loss += Loss(x1,x2,w1,w2,b,yi);
      grad_w1   += dL_dw1(x1,x2,w1,w2,b,yi);
      grad_w2   += dL_dw2(x1,x2,w1,w2,b,yi);
      grad_b    += dL_db (x1,x2,w1,w2,b,yi);
    end;

    w1 -= lr * grad_w1 / n;
    w2 -= lr * grad_w2 / n;
    b  -= lr * grad_b  / n;

    if (epoch+1) mod 5000 = 0 then
      Println($'Эпоха {epoch+1}: ошибка={total_loss/n:0.0000}; 
        w1={w1:0.000}; w2={w2:0.000}; b={b:0.000}');
  end;
end.
Это базовый пример градиентного спуска без библиотек.

Линейная модель + активация = простейший ИИ в PascalABC.NET Реализуем элементарный предсказатель на основе линейной комбинаци
Линейная модель + активация = простейший ИИ в PascalABC.NET Реализуем элементарный предсказатель на основе линейной комбинации признаков и функции активации. Такой принцип лежит в основе логистической регрессии и нейронных сетей.
function LinearCombination(x, w: array of real; b: real): real;
begin
  Result := b;
  for var i := 0 to x.Length - 1 do
    Result += x[i] * w[i];
end;
  
function Sigmoid(z: real) := 1 / (1 + Exp(-z));

function Predict(x, w: array of real; b: real; activation: real -> real) := 
  activation(LinearCombination(x, w, b));

begin
  var weights := [0.8, -0.3, 0.5, -0.2];
  var bias := 0.1;
  var x := [45.0, 120.0, 5.5, 24.5];

  var probability := Predict(x, weights, bias, Sigmoid);
  Println('Вероятность диабета:', probability);
end.
📌 В этом примере показано: * как считать линейную комбинацию x·w + b; * как применить сигмоиду — популярную функцию активации; * как через функциональные переменные передавать функцию в другую функцию; * как построить простейшую модель предсказания. 🧠 Это уже мини-модель машинного обучения — всё на чистом PascalABC.NET, без библиотек.

♟ Решение задачи о 8 ферзях в PascalABC.NET Классический алгоритм с рекурсией и проверкой конфликтов по столбцам и диагоналям. Каждое найденное расположение выводится на экран в виде массива: board[row] = column.
const N = 8;

var board := new integer[N]; // board[row] = столбец ферзя в этой строке

procedure Place(row: integer);
begin
  for var col := 0 to N-1 do
  begin
    // проверяем конфликты со всеми ранее поставленными ферзями
    var conflict := False;
    for var prevRow := 0 to row-1 do
      if (board[prevRow] = col) or                             // тот же столбец
         (abs(board[prevRow] - col) = abs(prevRow - row)) then // та же диагональ
      begin
        conflict := True;
        break;
      end;
    
    if not conflict then
    begin
      board[row] := col; // ставим ферзя
      
      if row = N-1 then
        board.Println // выводим решение
      else Place(row+1); // продолжаем рекурсию
    end
  end;
end;

begin
  Println('Все решения задачи о 8 ферзях:');
  Place(0);
end.
Один из самых коротких известных алгоритмов

Температура и цвет Здесь демонстрируется использование вложенной условной операции, а также метода расширения Between для цел
Температура и цвет Здесь демонстрируется использование вложенной условной операции, а также метода расширения Between для целых (по умолчанию он включает концы)
begin
  var t := ReadInteger; // температура
  
  var color := 
    if t.Between(-100, 0) then 'blue' else
    if t.Between(1, 15) then 'green' else
    if t.Between(16, 30) then 'yellow' else
    if t.Between(31, 100) then 'red' else
      'black';
  
  Println($'Temperature color: {color}');
end.

Чему равен корень из -1 А действительно - чему? Это зависит от типа. Если тип - real, то это не число. В смысле число, которо
Чему равен корень из -1 А действительно - чему? Это зависит от типа. Если тип - real, то это не число. В смысле число, которое называется NaN (Not a Number). Если тип - Complex - то вполне себе нормальное комплексное число, примерно равное i - комплексной единице.

Различия между модулями и библиотеками Данная таблица приводится в курсе Основы программирования в начале второго месяца обуч
Различия между модулями и библиотеками Данная таблица приводится в курсе Основы программирования в начале второго месяца обучения. Все весьма сложные концепции разбираются в этом курсе подробно, эффективно и на ранних этапах

Модуль TurtleABC Появился модуль TurtleABC для Linux uses TurtleABC; begin SetScale(4); SetOrigin(5,-35); SetColor(Color.Blue
Модуль TurtleABC Появился модуль TurtleABC для Linux
uses TurtleABC;

begin
  SetScale(4);
  SetOrigin(5,-35);
  SetColor(Color.Blue);
  Down;
  loop 4 do
  begin
    Forw(20);
    Turn(90);
  end;
  
  Up;
  MoveTo(-30, 30);
  Down;
  SetColor(Color.Red);
  loop 3 do
  begin
    Forw(15);
    Turn(120);
  end;
end.

Машинное 𝜀 Машинным 𝜀 называется минимальное вещественное значение, для которого для которого 1 + 𝜀 > 1. Для типа real оно находится между 1e-15 и 1e-16. Вот программа для вычисления машинного 𝜀
function MachineEpsilon: real;
begin
  var eps := 1.0;
  while 1.0 + eps > 1.0 do
    eps := eps / 2.0;
  Result := eps * 2.0;
end;

begin
  var eps := MachineEpsilon;
  Println('Машинный эпсилон =', eps);
  Println('1 + eps = 1?', 1 + eps = 1);
  Println('1 + eps/2 = 1?', 1 + eps/2 = 1);
end.

Особые значения вещественного типа Среди особых значений вещественного типа различают Бесконечность (положительную и отрицате
Особые значения вещественного типа Среди особых значений вещественного типа различают Бесконечность (положительную и отрицательную) и значение NaN - Not a Number (не число), которое возникает при некоторых некорректных операциях - например, при извлечении корня из отрицательного числа
##
// +∞: результат деления на 0 или константа PositiveInfinity
var posInf := real.PositiveInfinity;
var posInf2 := 1.0/0.0;
Println($'+∞: {posInf}  Проверка: {real.IsPositiveInfinity(posInf)}');
Println($'1/0 → {posInf2}');

// -∞: отрицательное деление на 0 или константа NegativeInfinity
var negInf := real.NegativeInfinity;
var negInf2 := -1.0/0.0;
Println($'-∞: {negInf}  Проверка: {real.IsNegativeInfinity(negInf)}');
Println($'-1/0 → {negInf2}');

// NaN: «не число» – результат недопустимых операций
var nanVal := real.NaN;
var nanVal2 := Sqrt(-1);
Println($'NaN: {nanVal}  Проверка: {real.IsNaN(nanVal)}');
Println($'Sqrt(-1) → {nanVal2}');