PascalABC.NET официальный канал
Открыть в Telegram
Официальный канал языка и системы программирования PascalABC.NET
Больше1 860
Подписчики
-124 часа
-117 дней
-2630 дней
Архив постов
Комбинаторика на PascalABC.NET
В комбинаторике рассматриваются способы выбора и расположения элементов множества. Основные понятия:
1. Декартово произведение множеств (Cartesian product) — это множество всех возможных пар элементов, где первый элемент берётся из одного множества, а второй — из другого. В PascalABC.NET используется метод
Cartesian:
var a := [1, 2];
var b := ['A', 'B'];
a.Cartesian(b).Println;
Вывод:
(1, A) (1, B) (2, A) (2, B)2. Декартова степень множества (Cartesian power) — это декартово произведение множества само на себя n раз. В PascalABC.NET используется метод
CartesianPower, который возвращает последовательность массивов:
var a := [0, 1];
a.CartesianPower(3).Println;
Вывод:
[0, 0, 0] [0, 0, 1] [0, 1, 0] [0, 1, 1] [1, 0, 0] [1, 0, 1] [1, 1, 0] [1, 1, 1]3. Перестановки (permutations) — это все возможные способы упорядоченного расположения всех n элементов множества. Например, для множества {1, 2, 3} возможны перестановки: (1,2,3), (1,3,2), (2,1,3), (2,3,1), (3,1,2), (3,2,1). 4. Частичные перестановки (partial permutations) из n элементов по m — это упорядоченные наборы из m элементов, взятых из n-элементного множества. Порядок элементов имеет значение. Например, для множества {1, 2, 3} частичные перестановки по два: (1,2), (1,3), (2,1), (2,3), (3,1), (3,2). 5. Сочетания (combinations) из n элементов по m — это неупорядоченные наборы из m элементов, взятых из n-элементного множества. При этом порядок элементов не имеет значения. Например, для множества {1, 2, 3} сочетания по два: (1,2), (1,3), (2,3). Перестановки Пример кода:
var arr := [1, 2, 3];
arr.Permutations.Println;
Вывод:
[1, 2, 3] [1, 3, 2] [2, 1, 3] [2, 3, 1] [3, 1, 2] [3, 2, 1]Частичные перестановки Пример кода:
var arr := [1, 2, 3, 4];
arr.Permutations(2).Println;
Вывод:
[1, 2] [1, 3] [1, 4] [2, 1] [2, 3] [2, 4] [3, 1] [3, 2] [3, 4] [4, 1] [4, 2] [4, 3]Сочетания В PascalABC.NET можно использовать встроенную функцию
Combinations, которая возвращает последовательность массивов:
var arr := [1, 2, 3, 4];
arr.Combinations(2).Println;
Вывод:
[1, 2] [1, 3] [1, 4] [2, 3] [2, 4] [3, 4]Итог В PascalABC.NET можно использовать встроенные методы
Cartesian, CartesianPower, Combinations, Permutations(k) и Permutations, чтобы легко работать с комбинаторными структурами. Это удобно для олимпиадных задач и задач на перебор.Метод ToSet
При преобразовании к множеству из коллекции удаляются дубли. Поэтому метод .ToSet - это один из способов избавиться от дублей и заодно получить множество элементов без дублей
Пересечения и объединения множеств
Пересечение множеств s1 * s2
Объединение множеств s1 + s2
Полезные задачи решаются красиво и просто
Инициализатор пустой коллекции []
В 3.10.3 появился инициализатор [] любой коллекции. Он заменяет собой вызов конструктора по умолчанию.
Особенно удобно использовать [] для передачи в качестве параметра - тип формального параметра уже указан при описании, а при вызове в параметрах мы всего лишь указываем [].
procedure ppp(s: sequence of integer; a: array of integer; lst: List<(real,real)>;
d: Dictionary<string,integer>; hs: HashSet<integer>; ss: SortedSet<integer>);
begin end;
begin
var old: set of integer := [];
var s: sequence of integer := [];
var a: array of integer := [];
var lst: List<(real,real)> := [];
var d: Dictionary<string,integer> := [];
var st: Stack<string> := [];
var q: Queue<string> := [];
var hs: HashSet<integer> := [];
var ss: SortedSet<integer> := [];
ppp([],[],[],[],[],[]);
var aa: array of array of integer := [[1],[],[2,3]];
end.
#новоеПостроение графа маршрутов между городами
Дан список городов и прямых маршрутов между ними. Требуется построить граф, в котором:
✔️ Вершины — это города.
✔️ Рёбра — это прямые маршруты между городами.
🔹 Маршруты между городами:
🟢 Москва → 🔵 Череповец
🟢 Москва → 🔵 Петрозаводск
🟢 Москва → 🔵 Великий Устюг
🟢 Москва → 🔵 Екатеринбург
🟢 Москва → 🔵 Сочи
🔵 Череповец → 🟢 Москва
🔵 Череповец → 🔴 Санкт-Петербург
🔵 Петрозаводск → 🟢 Москва
🔴 Санкт-Петербург → 🔵 Череповец
🔵 Апатиты → 🟢 Москва
🔴 Санкт-Петербург → 🔵 Апатиты
🔵 Ухта → 🟢 Москва
🔵 Череповец → 🟣 Мурманск
🔵 Череповец → 🟠 Сочи
🔵 Череповец → 🟡 Екатеринбург
📌 Цель — визуализировать этот граф, расположив Москву в центре и минимизировав пересечения рёбер.
GhatGPT сгенерировал такую программу:
uses GraphWPF;
begin
var edges := [
'Москва' to 'Череповец',
'Москва' to 'Петрозаводск',
'Москва' to 'Великий Устюг',
'Москва' to 'Екатеринбург',
'Москва' to 'Сочи',
'Череповец' to 'Москва',
'Череповец' to 'Санкт-Петербург',
'Петрозаводск' to 'Москва',
'Санкт-Петербург' to 'Череповец',
'Апатиты' to 'Москва',
'Санкт-Петербург' to 'Апатиты',
'Ухта' to 'Москва',
'Череповец' to 'Мурманск',
'Череповец' to 'Сочи',
'Череповец' to 'Екатеринбург'
];
var positions := Dict(
'Москва' to Pnt(400, 300), // Центр
'Череповец' to Pnt(550, 250),
'Петрозаводск' to Pnt(500, 150),
'Великий Устюг' to Pnt(600, 300),
'Екатеринбург' to Pnt(700, 350),
'Сочи' to Pnt(400, 500),
'Санкт-Петербург' to Pnt(300, 150),
'Апатиты' to Pnt(200, 100),
'Ухта' to Pnt(250, 400),
'Мурманск' to Pnt(150, 200)
);
Window.Title := 'Граф маршрутов';
foreach var e in edges do
Line(positions[e.Key], positions[e.Value], Colors.Black);
foreach var p in positions do
Circle(p.Value.X, p.Value.Y, 5, Colors.Red);
foreach var p in positions do
TextOut(p.Value.X + 10, p.Value.Y, p.Key);
end.Находим главных героев в тексте произведения "Война и мир"
Можно ли установить главных героев, не читая произведение "Война и мир"?
Да, надо выдать частоту встречаемости имен.
Мы видим, что наиболее часто встречаются имена собственные Андрей, Ростов, Пьер и Анна.
faststring - новый тип в PascalABC.NET 3.10.3
На самом деле faststring - это просто синоним StringBuilder с немного дополненной функциональностью (методами Replace и IndexOf и операцией in)
Однако faststring работает действительно быстро: в примере на скрине, предложенном @tpehep33, метод PascalABC.NET опережает аналогичную функцию Python, написанную на C++, в 2 раза.
// 6.0 sec PascalABC.NET vs 11.4 sec Python
begin
var mx := 0;
for var n := 4 to 9999 do
begin
var s: faststring := '4' + '1' * n;
while ('411' in s) or ('1111' in s) do
s.Replace('411', '14', 1)
.Replace('1111', '1', 1);
mx := max(mx, s.ToString.Sum(d -> d.todigit));
end;
print(mx, Milliseconds / 1000);
end.
#новоеАлгоритм Дейкстры на Rosetta Code
Алгоритм полностью сгенерирован ChatGPT по коду на Python с минимальными правками.
https://rosettacode.org/wiki/Dijkstra%27s_algorithm#PascalABC.NET
Ну а мы в Rosetta Code уже на 67 месте с 553 задачами благодаря стараниям тайного друга. Позади Elixir, Erlang, PowerShell и Groovy.
type
Edge = auto class
start, &end: char;
cost: real;
end;
Graph = auto class
edges: array of Edge;
vertices: HashSet<char>;
constructor(params edges: array of (char, char, real));
begin
Self.edges := edges.Select(e -> new Edge(e[0], e[1], e[2])).ToArray;
Self.vertices := new HashSet<char>(
Self.edges.Select(e -> e.start) + Self.edges.Select(e -> e.end)
);
end;
function Dijkstra(source, dest: char): sequence of char;
begin
assert(vertices.Contains(source));
var inf := real.MaxValue;
var dist := Dict(vertices.Select(v -> (v, inf)));
var previous := Dict(vertices.Select(v -> (v, ' ')));
dist[source] := 0;
var q := vertices.ToHashSet;
var neighbours := Dict(vertices.Select(v -> (v, new HashSet<(char, real)>)));
foreach var edge in edges do
begin
neighbours[edge.start].Add((edge.end, edge.cost));
neighbours[edge.end].Add((edge.start, edge.cost));
end;
while q.Count > 0 do
begin
var u := q.MinBy(v -> dist[v]);
q.Remove(u);
if (dist[u] = inf) or (u = dest) then
break;
foreach var (v, cost) in neighbours[u] do
begin
var alt := dist[u] + cost;
if alt < dist[v] then
begin
dist[v] := alt;
previous[v] := u;
end;
end;
end;
var s := new List<char>;
var u := dest;
while previous[u] <> ' ' do
begin
s.Insert(0, u);
u := previous[u];
end;
s.Insert(0, u);
Result := s;
end;
end;
begin
var gr := new Graph(
('a', 'b', 7.0), ('a', 'c', 9.0), ('a', 'f', 14.0),
('b', 'c', 10.0), ('b', 'd', 15.0), ('c', 'd', 11.0),
('c', 'f', 2.0), ('d', 'e', 6.0), ('e', 'f', 9.0)
);
gr.Dijkstra('a', 'e').Println; // Результат: ['a', 'c', 'f', 'e']
end.Перевод градусов Цельсия в градусы Фаренгейта
Перевод градусов Цельсия в градусы Фаренгейта и обратно можно выполнить с помощью operator implicit.
type
Farenheit = class;
Celsius = auto class
value: real;
public
constructor (v: real) := value := v;
static function operator implicit(c: Celsius): Farenheit;
function ToString: string; override
:= $'{value}°C';
end;
Farenheit = auto class
value: real;
public
constructor (v: real) := value := v;
static function operator implicit(f: Farenheit): Celsius;
function ToString: string; override
:= $'{value}°F';
end;
static function Celsius.operator implicit
(c: Celsius): Farenheit
:= new Farenheit(c.value * 9 / 5 + 32);
static function Farenheit.operator implicit
(f: Farenheit): Celsius
:= new Celsius((f.value - 32) * 5 / 9);
begin
var c := new Celsius(25);
var f: Farenheit := c; // Неявное преобразование из Цельсия в Фаренгейт
Println($'Температура: {c} = {f}');
var f2 := new Farenheit(77);
var c2: Celsius := f2; // Неявное преобразование из Фаренгейта в Цельсий
Println($'Температура: {f2} = {c2}');
end.pys - хорошее расширение, дети придумают много с ним комбинаций. В Брюсселе есть Манекен-пис и Жаннеке-пис, а у нас будет столько всячины, что Бельгия обзавидуется!
2025 год. В виде шутки
- Запретят ли Паскалев?
- Тогда у нас будет своих Питонов!
- Красивое...
Текстовые файлы в PascalABC.NET
Простая задача - добавить в конец каждой строки слово 'строка'.
Работа с файловыми переменными в PascalABC.NET - полностью объектно-ориентированная. И открывается файл - одной строкой - на чтение или за запись.
Рейтинг TIOBE 2025
Вышел рейтинг TIOBE популярности языков программирования январь 2025.
Питон объявлен языком года - он вырос почти на 10%.
Из других наблюдений. Языки из Top 12 тоже выросли. Это значит, что остальные языки уменьшились.
С++ поднялся на 2 позицию, повторив результат 2000 года.
C# и JavaScript сохраняют свои позиции как 5-го и 6-го языков.
Язык Go с 11 места переместился на 7-е.
Вновь ворвался в десятку Фортран.
И - Delphi - на 11 месте, поднявшись на 2 позиции. А всё потому что сделали for var i. Сделают лямбды как у нас - поднимутся ещё выше.
Язык Kotlin выскочил из двадцатки. А мы на него равняемся :(
Язык Rust поднялся с 19 места на 14-е.
Замыкает 20-ку COBOL, никуда не собираясь уходить.
Функции как объекты первого класса
Функции называют "объектами первого класса" (first-class objects) в языках программирования, если они обладают такими же возможностями, как и другие типы данных (например, числа, строки, массивы). Это означает, что функции можно передавать, возвращать, присваивать переменным и использовать в выражениях, как любые другие объекты.
В примере на скриншоте создается словарь, значениями которого являются лямбда-функции, которые затем вызываются по строковому ключу.
Learn PascalABC.NET in Y minutes
На вики-странице Learn PascalABC.NET in Y minutes впервые представлены все ключевые возможности PascalABC.NET, отражающие 17 лет его эволюции.
📌 Важнейшие разделы:
🔹 Структуры данных: кортежи, диапазоны, строки, массивы, списки, словари, множества, записи и классы.
🔹 Современные языковые средства: автовыведение типа, внутриблочные описания, циклы loop и foreach, цикл for с шагом, интерполяция строк, многострочные строки, параметры по умолчанию и именованные аргументы.
🔹 Современные операции:
in, срезы, индексация с конца. to для создания пар "ключ-значение" — лаконичные инструменты для работы с данными.
🔹 Новые литеральные массивы [1,2,3].
🔹 Лямбда-выражения и функциональные переменные: гибкость функционального подхода.
🔹 Последовательности: мощный инструмент для работы с данными, включая LINQ.
🔹 Поддержка разных парадигм: процедурное, функциональное, обобщенное и объектно-ориентированное программирование.
🔹 Полная интеграция со стандартной библиотекой .NET.
📖 Этот документ — уникальное собрание возможностей, отражающих эволюцию и современность PascalABC.NET.
🎖 Специальная благодарность @ulysses4ever за идею создания данного документа.
#PascalABCNET #новоеС Новым 2025 годом!
Дорогие читатели канала PascalABC.NET!
Поздравляем вас с наступающим Новым 2025 годом!
Пусть этот год принесет вам новые знания, вдохновение и успехи в изучении программирования и обучении программированию. Мы искренне рады быть частью вашего пути, связанного с программированием на PascalABC.NET, и готовы радовать вас интересными задачами, полезными примерами и увлекательными материалами.
Желаем, чтобы каждый ваш проект компилировался с первого раза, алгоритмы были элегантными, а решения — находились легко. Пусть PascalABC.NET продолжает вдохновлять вас на изучение нового и делать программирование доступным и увлекательным.
Спасибо, что вы с нами! До встречи в Новом 2025 году! Все вычисления говорят, что он скоро наступит:
##
Arr(1..9).Select(x -> x * x * x).Sum.Println;
Arr(1..9).Sum.Sqr.Println;
'2025'.Batch(2).Select(x -> x[0]+x[1])
.Select(x -> x.ToInteger).Sum.Sqr.Println;
Seq(1,8,8,10).Select(x -> x ** 3)
.Sum.Round.Println;
(2026..2029).Zip([4,-6,4,-1]
,(x,y) -> x * y).Sum.Println;
(2026..2029).Select(x -> x*x)
.Zip([4,-6,4,-1],(x,y) -> x * y)
.Sum.Sqrt.Round.Println;
(2021..2024).Reverse
.Zip([4,-6,4,-1],(x,y) -> x * y).Sum.Println;
(2021..2024).Reverse.Select(x -> x*x)
.Zip([4,-6,4,-1],(x,y) -> x * y)
.Sum.Sqrt.Round.Println;
Как вы верно догадываетесь, вывод:
2025 2025 2025 2025 2025 2025 2025 2025Ваш PascalABC.NET
Косой косой косой
Пять смыслов слова "косой" в одной строке.
Ну а мы разбиваем строку на слова замечательным методом ToWords - сразу и без колебаний.
Раньше на это ползанятия уходило... Были времена!
#методика
Метод Distinct для символов строк
Прекрасная комбинация методов Where, IsDigit, Order и Distinct.
Ну и конечно - косвенная транзакция как говорят психологи - строка без цифр, несущая отдельную положительную нагрузку: "It's better to light a candle than curse the darkness"
Что мы и делаем каждый день!
#методика
Корни n-той степени из комплексной единицы
Известно, что имеется ровно n корней n-той степени из единицы если рассматривать её в комплексной плоскости.
Код очень прост:
function RootsOfUnity(n: integer)
:= (0..n-1).Select(x -> Complex.FromPolarCoordinates(1, 2 * PI * x / n));
begin
RootsOfUnity(3).PrintLines
end.
И вывод
1+0i -0.5+0.866025403784439i -0.5-0.866025403784438iА мы в Rosetta Code - на 72 месте с 511 задачами. Позади уже Prolog и PHP. Болеем за наших! И хвалим claude.ai за сгенерированную картинку!
Сумма цифр в строке
Одно удовольствие - комбинировать уже известные методы для строк. Здесь их - 6 штук - и все в одной строке кода!
Как бедно жили люди когда не было методов - писали всё это руками. И плакали...
#методика
