This commit is contained in:
Mikhalkovich Stanislav 2023-09-18 11:00:06 +03:00
parent 80904b2646
commit 08b1cfa442
9 changed files with 370 additions and 296 deletions

View file

@ -15,7 +15,7 @@ internal static class RevisionClass
public const string Major = "3";
public const string Minor = "9";
public const string Build = "0";
public const string Revision = "3351";
public const string Revision = "3357";
public const string MainVersion = Major + "." + Minor;
public const string FullVersion = Major + "." + Minor + "." + Build + "." + Revision;

View file

@ -1,4 +1,4 @@
%MINOR%=9
%REVISION%=3351
%REVISION%=3357
%COREVERSION%=0
%MAJOR%=3

View file

@ -1 +1 @@
3.9.0.3351
3.9.0.3357

View file

@ -1 +1 @@
!define VERSION '3.9.0.3351'
!define VERSION '3.9.0.3357'

View file

@ -1,49 +1,59 @@
/// Учебный модуль, реализующий базовые алгоритмы информатики.
/// Учебный модуль, реализующий базовые алгоритмы информатики (09.10.2023)
unit School;
interface
/// Перевод десятичного числа в двоичную систему счисления
function Bin(Число: int64): string;
function Bin(number: int64): string;
/// Перевод десятичного числа в двоичную систему счисления
function Bin(Число: BigInteger): string;
function Bin(number: BigInteger): string;
/// Перевод десятичного числа в двоичную систему счисления с форматированием.
/// bytes - требуемая длина в байтах, автоматически увеличивается, если недостаточна
/// split - разделитель байтов, можено задать пустое значение ''
function BinFormat(number: BigInteger; bytes: integer := 0; split: string := ' '): string;
/// Перевод десятичного числа в двоичную систему счисления с форматированием.
/// bytes - требуемая длина в байтах, автоматически увеличивается, если недостаточна
/// split - разделитель байтов, можено задать пустое значение ''
function BinFormat(number: int64; bytes: integer := 0; split: string := ' '): string;
/// Перевод десятичного числа в восьмеричную систему счисления
function Oct(Число: int64): string;
function Oct(number: int64): string;
/// Перевод десятичного числа в восьмеричную систему счисления
function Oct(Число: BigInteger): string;
function Oct(number: BigInteger): string;
/// Перевод десятичного числа в шестнадцатиричную систему счисления
function Hex(Число: int64): string;
function Hex(number: int64): string;
/// Перевод десятичного числа в шестнадцатиричную систему счисления
function Hex(Число: BigInteger): string;
function Hex(number: BigInteger): string;
/// Перевод из системы по основанию base [2..36] в десятичную
function Dec(СтроковоеПредставление: string; Основание: integer): int64;
function Dec(str: string; base: integer): int64;
/// Перевод из системы по основанию base [2..36] в десятичную
function DecBig(СтроковоеПредставление: string; Основание: integer): BigInteger;
function DecBig(str: string; base: integer): BigInteger;
/// Перевод BigInteger в систему счисления по основанию base (2..36)
function ToBase(Число: BigInteger; Основание: integer): string;
function ToBase(number: BigInteger; base: integer): string;
/// Перевод десятичного числа в систему счисления по основанию base (2..36)
function ToBase(СтроковоеПредставление: string; Основание: integer): string;
function ToBase(str: string; base: integer): string;
/// Возвращает кортеж из минимума и максимума последовательности
function MinMax(Последовательность: sequence of int64): (int64, int64);
function MinMax(seq: sequence of int64): (int64, int64);
/// Возвращает кортеж из минимума и максимума последовательности
function MinMax(Последовательность: sequence of integer): (integer, integer);
function MinMax(seq: sequence of integer): (integer, integer);
/// Возвращает кортеж из минимума и максимума последовательности
function MinMax(Последовательность: sequence of real): (real, real);
function MinMax(seq: sequence of real): (real, real);
/// Возвращает кортеж из минимума и максимума последовательности
function MinMax(Последовательность: sequence of BigInteger): (BigInteger, BigInteger);
function MinMax(seq: sequence of BigInteger): (BigInteger, BigInteger);
/// Возвращает НОД пары чисел
function НОД(a, b: int64): int64;
@ -140,7 +150,7 @@ function TrueTable(f: function(a, b, c, d, e: boolean): boolean):
procedure TrueTablePrint(a: array[,] of boolean; f: integer := 2; s: string := 'abcde');
/// Заменяет последнее вхождение подстроки в строку
procedure ReplaceLast(var Строка: string; ЧтоЗаменить, ЧемЗаменить: string);
procedure ReplaceLast(var s: string; source, target: string);
/// Множественная замена символов в строке s
/// Каждый символ source[i] заменяется во всей строке s символом target[i]
@ -170,249 +180,263 @@ var
{$region Bin}
function Bin(Число: int64): string;
function Bin(number: int64): string;
begin
Число := Abs(Число);
if number < 0 then number := -number;
Result := '';
while Число >= 2 do
while number >= 2 do
begin
Result += Число mod 2;
Число := Число div 2
Result += number mod 2;
number := number div 2
end;
Result += Число;
Result += number;
Result := Result.Inverse
end;
function Bin(Число: BigInteger): string;
function Bin(number: BigInteger): string;
begin
Число := Abs(Число);
if number < 0 then number := -number;
Result := '';
while Число >= 2 do
while number >= 2 do
begin
Result += byte(Число mod 2);
Число := Число div 2
Result += byte(number mod 2);
number := number div 2
end;
Result += byte(Число);
Result += byte(number);
Result := Result.Inverse
end;
function BinFormat(number: BigInteger; bytes: integer; split: string): string;
begin
if number < 0 then number := -number;
var a := number = 0 ? |byte(0)| : number.ToByteArray;
var len := a.Length;
if (number > 0) and (a[^1] = 0) then Dec(len);
SetLength(a, Max(bytes, len));
Result := a.Reverse.Select(t -> (Convert.ToString(t, 2)).PadLeft(8, '0')).JoinToString(split)
end;
function BinFormat(number: int64; bytes: integer; split: string): string :=
BinFormat(BigInteger(number), bytes, split);
{$endregion}
{$region Oct}
function Oct(Число: int64): string;
function Oct(number: int64): string;
begin
Число := Abs(Число);
if number < 0 then number := -number;
Result := '';
while Число >= 8 do
while number >= 8 do
begin
Result += Число mod 8;
Число := Число div 8
Result += number mod 8;
number := number div 8
end;
Result += Число;
Result := Result.Inverse
Result += number;
Result := Result.Inverse;
end;
function Oct(Число: BigInteger): string;
function Oct(number: BigInteger): string;
begin
Число := Abs(Число);
if number < 0 then number := -number;
Result := '';
while Число >= 8 do
while number >= 2 do
begin
Result += byte(Число mod 8);
Число := Число div 8
Result += byte(number mod 8);
number := number div 8
end;
Result += byte(Число);
Result := Result.Inverse
Result += byte(number);
Result := Result.Inverse;
end;
{$endregion}
{$region Hex}
function Hex(Число: int64): string;
function Hex(number: int64): string;
begin
Число := Abs(Число);
var ШестнадцатиричныеЦифры := '0123456789ABCDEF';
if number < 0 then number := -number;
var hex_nums := '0123456789ABCDEF';
Result := '';
while Число >= 16 do
while number >= 16 do
begin
Result += ШестнадцатиричныеЦифры[Число mod 16 + 1];
Число := Число div 16
Result += hex_nums[number mod 16 + 1];
number := number div 16
end;
Result += ШестнадцатиричныеЦифры[Число + 1];
Result := Result.Inverse
Result += hex_nums[number + 1];
Result := Result.Inverse;
end;
function Hex(Число: BigInteger): string;
function Hex(number: BigInteger): string;
begin
Число := Abs(Число);
var ШестнадцатиричныеЦифры := '0123456789ABCDEF';
if number < 0 then number := -number;
var hex_nums := '0123456789ABCDEF';
Result := '';
while Число >= 16 do
while number >= 16 do
begin
Result += ШестнадцатиричныеЦифры[byte(Число mod 16) + 1];
Число := Число div 16
Result += hex_nums[byte(number mod 16 + 1)];
number := number div 16
end;
Result += ШестнадцатиричныеЦифры[byte(Число) + 1];
Result := Result.Inverse
Result += hex_nums[byte(number + 1)];
Result := Result.Inverse;
end;
{$endregion}
const
ДопустимыеСимволы = '0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ';
valid_chars = '0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ';
{$region Dec}
function Dec(СтроковоеПредставление: string; Основание: integer): int64;
function Dec(str: string; base: integer): int64;
begin
if not (Основание in 2..36) then
if not (base in 2..36) then
raise new School_InvalidBase
($'ToDecimal: Недопустимое основание {Основание}');
СтроковоеПредставление := СтроковоеПредставление.ToUpper;
var НедопустимыеСимволы :=
СтроковоеПредставление.Except(ДопустимыеСимволы[:Основание + 1]).JoinToString;
if НедопустимыеСимволы.Length > 0 then
($'ToDecimal: Недопустимое основание {base}');
str := str.ToUpper;
var invalid_chars :=
str.Except(valid_chars[:base + 1]).JoinToString;
if invalid_chars.Length > 0 then
raise new School_BadCharInString
($'ToDecimal: Недопустимые символы "{НедопустимыеСимволы}"');
var ВесРазряда := 1bi;
var Результат := 0bi;
foreach var Символ in СтроковоеПредставление.Reverse do
($'ToDecimal: Недопустимые символы "{invalid_chars}"');
var rank_weight := 1bi;
var res := 0bi;
foreach var char in str.Reverse do
begin
var ЗначениеРазряда := Pos(Символ, ДопустимыеСимволы) - 1;
Результат += ВесРазряда * ЗначениеРазряда;
ВесРазряда *= Основание
var rank_value := Pos(char, valid_chars) - 1;
res += rank_weight * rank_value;
rank_weight *= base
end;
Result := int64(Результат)
Result := int64(res)
end;
function DecBig(СтроковоеПредставление: string; Основание: integer): BigInteger;
function DecBig(str: string; base: integer): BigInteger;
begin
if not (Основание in 2..36) then
if not (base in 2..36) then
raise new School_InvalidBase
($'ToDecimal: Недопустимое основание {Основание}');
СтроковоеПредставление := СтроковоеПредставление.ToUpper;
var НедопустимыеСимволы :=
СтроковоеПредставление.Except(ДопустимыеСимволы[:Основание + 1]).JoinToString;
if НедопустимыеСимволы.Length > 0 then
($'ToDecimal: Недопустимое основание {base}');
str := str.ToUpper;
var invalid_chars :=
str.Except(valid_chars[:base + 1]).JoinToString;
if invalid_chars.Length > 0 then
raise new School_BadCharInString
($'ToDecimal: Недопустимые символы "{НедопустимыеСимволы}"');
var ВесРазряда := 1bi;
($'ToDecimal: Недопустимые символы "{invalid_chars}"');
var rank_weight := 1bi;
Result := 0bi;
foreach var Символ in СтроковоеПредставление.Reverse do
foreach var char in str.Reverse do
begin
var ЗначениеРазряда := Pos(Символ, ДопустимыеСимволы) - 1;
Result += ВесРазряда * ЗначениеРазряда;
ВесРазряда *= Основание
var rank_value := Pos(char, valid_chars) - 1;
Result += rank_weight * rank_value;
rank_weight *= base
end
end;
{$endregion}
{$region ToBase}
/// Перевод BigInteger в систему счисления по основанию base (2..36)
function ToBase(Число: BigInteger; Основание: integer): string;
function ToBase(number: BigInteger; base: integer): string;
begin
if not (Основание in 2..36) then
if not (base in 2..36) then
raise new School_InvalidBase
($'ToDecimal: Недопустимое основание {Основание}');
var СтроковоеПредставление := new System.Text.StringBuilder('');
while Число > 0 do
($'ToDecimal: Недопустимое основание {base}');
var sb := new System.Text.StringBuilder('');
while number > 0 do
begin
СтроковоеПредставление.Insert(0, ДопустимыеСимволы[integer(Число mod Основание) + 1]);
Число := Число div Основание
sb.Insert(0, valid_chars[integer(number mod base) + 1]);
number := number div base
end;
Result := if СтроковоеПредставление.Length = 0 then '0'
else СтроковоеПредставление.ToString
Result := if sb.Length = 0 then '0'
else sb.ToString
end;
/// Перевод BigInteger в систему счисления по основанию base (2..36)
function ToBase(Self: BigInteger; Основание: integer): string; extensionmethod :=
ToBase(Self, Основание);
function ToBase(Self: BigInteger; base: integer): string; extensionmethod :=
ToBase(Self, base);
/// Перевод десятичного числа в систему счисления по основанию base (2..36)
function ToBase(СтроковоеПредставление: string; Основание: integer): string;
function ToBase(str: string; base: integer): string;
begin
if not (Основание in 2..36) then
if not (base in 2..36) then
raise new School_InvalidBase
($'ToDecimal: Недопустимое основание {Основание}');
var Число: BigInteger;
if BigInteger.TryParse(СтроковоеПредставление, Число) then
Result := ToBase(Число, Основание)
($'ToDecimal: Недопустимое основание {base}');
var number: BigInteger;
if BigInteger.TryParse(str, number) then
Result := ToBase(number, base)
end;
/// Перевод десятичного числа в систему счисления по основанию base (2..36)
function ToBase(Self: string; Основание: integer): string; extensionmethod :=
ToBase(Self, Основание);
function ToBase(Self: string; base: integer): string; extensionmethod :=
ToBase(Self, base);
{$endregion}
{$region MinMax}
/// Возвращает кортеж из минимума и максимума последовательности
function MinMax(Последовательность: sequence of int64): (int64, int64);
function MinMax(seq: sequence of int64): (int64, int64);
begin
var min := int64.MaxValue;
var max := int64.MinValue;
foreach var Элемент in Последовательность do
foreach var elem in seq do
begin
if Элемент < min then
min := Элемент;
if Элемент > max then
max := Элемент
if elem < min then
min := elem;
if elem > max then
max := elem
end;
Result := (min, max)
end;
/// Возвращает кортеж из минимума и максимума последовательности
function MinMax(Последовательность: sequence of integer): (integer, integer);
function MinMax(seq: sequence of integer): (integer, integer);
begin
var min := integer.MaxValue;
var max := integer.MinValue;
foreach var Элемент in Последовательность do
foreach var elem in seq do
begin
if Элемент < min then
min := Элемент;
if Элемент > max then
max := Элемент
if elem < min then
min := elem;
if elem > max then
max := elem
end;
Result := (min, max)
end;
/// Возвращает кортеж из минимума и максимума последовательности s
function MinMax(Последовательность: sequence of real): (real, real);
function MinMax(seq: sequence of real): (real, real);
begin
var min := real.MaxValue;
var max := real.MinValue;
foreach var Элемент in Последовательность do
var max := -real.MaxValue;
foreach var elem in seq do
begin
if Элемент < min then
min := Элемент;
if Элемент > max then
max := Элемент
if elem < min then
min := elem;
if elem > max then
max := elem
end;
Result := (min, max)
end;
/// Возвращает кортеж из минимума и максимума последовательности s
function MinMax(Последовательность: sequence of BigInteger): (BigInteger, BigInteger);
function MinMax(seq: sequence of BigInteger): (BigInteger, BigInteger);
begin
var min, max: BigInteger;
var ЭтоПервыйЭлемент := True;
foreach var Элемент in Последовательность do
if ЭтоПервыйЭлемент then
var is_first := True;
foreach var elem in seq do
if is_first then
begin
min := Элемент;
max := Элемент;
ЭтоПервыйЭлемент := False
(min, max) := (elem, elem);
is_first := False
end
else
begin
if Элемент < min then
min := Элемент;
if Элемент > max then
max := Элемент
end;
if elem < min then
min := elem;
if elem > max then
max := elem
end;
Result := (min, max)
end;
@ -574,10 +598,10 @@ begin
else
begin
Result := True;
foreach var Простое in LPrimes do
if Sqr(Простое) > Self then
foreach var prime in LPrimes do
if Sqr(prime) > Self then
break
else if Self mod Простое = 0 then
else if Self mod prime = 0 then
begin
Result := False;
break
@ -931,13 +955,13 @@ end;
{$region String}
/// Заменяет последнее вхождение подстроки в строку
procedure ReplaceLast(var Строка: string; ЧтоЗаменить, ЧемЗаменить: string);
procedure ReplaceLast(var s: string; source, target: string);
begin
var Позиция := LastPos(ЧтоЗаменить, Строка);
if Позиция > 0 then
var position := LastPos(source, s);
if position > 0 then
begin
Delete(Строка, Позиция, ЧтоЗаменить.Length);
Insert(ЧемЗаменить, Строка, Позиция)
Delete(s, position, source.Length);
Insert(target, s, position)
end
end;

3
TestSuite/SingleReal.pas Normal file
View file

@ -0,0 +1,3 @@
begin
Assert(Arr(1.0,2.0).Sum(x -> x*x).GetType = typeof(real))
end.

View file

@ -0,0 +1,11 @@
procedure CheckOutputSeq(a: sequence of integer);
begin
end;
procedure CheckOutputSeq(a: sequence of object);
begin
end;
begin
CheckOutputSeq(Arr(1,2,3));
end.

View file

@ -575,8 +575,8 @@ namespace PascalABCCompiler.TreeRealization
// Но без этой строчки не работает преобразование sequence of Student к sequence of Person и sequence of object
// SSM 19/07/23 - снова раскомментировал - теперь не работало
// CheckOutputSeq(a); в Tasks где var a: array of char
if (tnode.IsInterface)
ImplementingInterfaces.Add(tnode);
//if (tnode.IsInterface) // SSM закомментировал опять 17.09.23 - single - неточные вычисления!
// ImplementingInterfaces.Add(tnode);
foreach (var interf in ImplementingInterfaces)
{
var ctn = interf as compiled_type_node;
@ -809,6 +809,18 @@ namespace PascalABCCompiler.TreeRealization
public static type_compare compare_types(type_node left, type_node right)
{
type_compare ret = get_table_type_compare(left, right);
// SSM 18.09.23 исправление #2872 (частное!!! только первый параметр!)
var ctnl = left as compiled_type_node;
var ctnr = right as compiled_type_node;
if (ctnl != null && ctnr != null && ctnl.original_generic == ctnr.original_generic
&& ctnl.compiled_type.IsInterface && ctnl.generic_params != null && ctnl.generic_params.Count == 1)
{
var interf_compiled_type = (ctnr.original_generic as compiled_type_node).compiled_type;
if ((interf_compiled_type.GetGenericArguments()[0].GenericParameterAttributes & System.Reflection.GenericParameterAttributes.Covariant) != 0)
return compare_types(ctnl.generic_params[0], ctnr.generic_params[0]);
}
// IEnumerable<object> д.б. < IEnumerable<integer>
// Проверить, что оба - IEnumerable. И если object < integer, то вернуть type_compare.less_type
if (ret != type_compare.non_comparable_type)
{
return ret;

View file

@ -1,49 +1,59 @@
/// Учебный модуль, реализующий базовые алгоритмы информатики.
/// Учебный модуль, реализующий базовые алгоритмы информатики (09.10.2023)
unit School;
interface
/// Перевод десятичного числа в двоичную систему счисления
function Bin(Число: int64): string;
function Bin(number: int64): string;
/// Перевод десятичного числа в двоичную систему счисления
function Bin(Число: BigInteger): string;
function Bin(number: BigInteger): string;
/// Перевод десятичного числа в двоичную систему счисления с форматированием.
/// bytes - требуемая длина в байтах, автоматически увеличивается, если недостаточна
/// split - разделитель байтов, можено задать пустое значение ''
function BinFormat(number: BigInteger; bytes: integer := 0; split: string := ' '): string;
/// Перевод десятичного числа в двоичную систему счисления с форматированием.
/// bytes - требуемая длина в байтах, автоматически увеличивается, если недостаточна
/// split - разделитель байтов, можено задать пустое значение ''
function BinFormat(number: int64; bytes: integer := 0; split: string := ' '): string;
/// Перевод десятичного числа в восьмеричную систему счисления
function Oct(Число: int64): string;
function Oct(number: int64): string;
/// Перевод десятичного числа в восьмеричную систему счисления
function Oct(Число: BigInteger): string;
function Oct(number: BigInteger): string;
/// Перевод десятичного числа в шестнадцатиричную систему счисления
function Hex(Число: int64): string;
function Hex(number: int64): string;
/// Перевод десятичного числа в шестнадцатиричную систему счисления
function Hex(Число: BigInteger): string;
function Hex(number: BigInteger): string;
/// Перевод из системы по основанию base [2..36] в десятичную
function Dec(СтроковоеПредставление: string; Основание: integer): int64;
function Dec(str: string; base: integer): int64;
/// Перевод из системы по основанию base [2..36] в десятичную
function DecBig(СтроковоеПредставление: string; Основание: integer): BigInteger;
function DecBig(str: string; base: integer): BigInteger;
/// Перевод BigInteger в систему счисления по основанию base (2..36)
function ToBase(Число: BigInteger; Основание: integer): string;
function ToBase(number: BigInteger; base: integer): string;
/// Перевод десятичного числа в систему счисления по основанию base (2..36)
function ToBase(СтроковоеПредставление: string; Основание: integer): string;
function ToBase(str: string; base: integer): string;
/// Возвращает кортеж из минимума и максимума последовательности
function MinMax(Последовательность: sequence of int64): (int64, int64);
function MinMax(seq: sequence of int64): (int64, int64);
/// Возвращает кортеж из минимума и максимума последовательности
function MinMax(Последовательность: sequence of integer): (integer, integer);
function MinMax(seq: sequence of integer): (integer, integer);
/// Возвращает кортеж из минимума и максимума последовательности
function MinMax(Последовательность: sequence of real): (real, real);
function MinMax(seq: sequence of real): (real, real);
/// Возвращает кортеж из минимума и максимума последовательности
function MinMax(Последовательность: sequence of BigInteger): (BigInteger, BigInteger);
function MinMax(seq: sequence of BigInteger): (BigInteger, BigInteger);
/// Возвращает НОД пары чисел
function НОД(a, b: int64): int64;
@ -140,7 +150,7 @@ function TrueTable(f: function(a, b, c, d, e: boolean): boolean):
procedure TrueTablePrint(a: array[,] of boolean; f: integer := 2; s: string := 'abcde');
/// Заменяет последнее вхождение подстроки в строку
procedure ReplaceLast(var Строка: string; ЧтоЗаменить, ЧемЗаменить: string);
procedure ReplaceLast(var s: string; source, target: string);
/// Множественная замена символов в строке s
/// Каждый символ source[i] заменяется во всей строке s символом target[i]
@ -170,249 +180,263 @@ var
{$region Bin}
function Bin(Число: int64): string;
function Bin(number: int64): string;
begin
Число := Abs(Число);
if number < 0 then number := -number;
Result := '';
while Число >= 2 do
while number >= 2 do
begin
Result += Число mod 2;
Число := Число div 2
Result += number mod 2;
number := number div 2
end;
Result += Число;
Result += number;
Result := Result.Inverse
end;
function Bin(Число: BigInteger): string;
function Bin(number: BigInteger): string;
begin
Число := Abs(Число);
if number < 0 then number := -number;
Result := '';
while Число >= 2 do
while number >= 2 do
begin
Result += byte(Число mod 2);
Число := Число div 2
Result += byte(number mod 2);
number := number div 2
end;
Result += byte(Число);
Result += byte(number);
Result := Result.Inverse
end;
function BinFormat(number: BigInteger; bytes: integer; split: string): string;
begin
if number < 0 then number := -number;
var a := number = 0 ? |byte(0)| : number.ToByteArray;
var len := a.Length;
if (number > 0) and (a[^1] = 0) then Dec(len);
SetLength(a, Max(bytes, len));
Result := a.Reverse.Select(t -> (Convert.ToString(t, 2)).PadLeft(8, '0')).JoinToString(split)
end;
function BinFormat(number: int64; bytes: integer; split: string): string :=
BinFormat(BigInteger(number), bytes, split);
{$endregion}
{$region Oct}
function Oct(Число: int64): string;
function Oct(number: int64): string;
begin
Число := Abs(Число);
if number < 0 then number := -number;
Result := '';
while Число >= 8 do
while number >= 8 do
begin
Result += Число mod 8;
Число := Число div 8
Result += number mod 8;
number := number div 8
end;
Result += Число;
Result := Result.Inverse
Result += number;
Result := Result.Inverse;
end;
function Oct(Число: BigInteger): string;
function Oct(number: BigInteger): string;
begin
Число := Abs(Число);
if number < 0 then number := -number;
Result := '';
while Число >= 8 do
while number >= 2 do
begin
Result += byte(Число mod 8);
Число := Число div 8
Result += byte(number mod 8);
number := number div 8
end;
Result += byte(Число);
Result := Result.Inverse
Result += byte(number);
Result := Result.Inverse;
end;
{$endregion}
{$region Hex}
function Hex(Число: int64): string;
function Hex(number: int64): string;
begin
Число := Abs(Число);
var ШестнадцатиричныеЦифры := '0123456789ABCDEF';
if number < 0 then number := -number;
var hex_nums := '0123456789ABCDEF';
Result := '';
while Число >= 16 do
while number >= 16 do
begin
Result += ШестнадцатиричныеЦифры[Число mod 16 + 1];
Число := Число div 16
Result += hex_nums[number mod 16 + 1];
number := number div 16
end;
Result += ШестнадцатиричныеЦифры[Число + 1];
Result := Result.Inverse
Result += hex_nums[number + 1];
Result := Result.Inverse;
end;
function Hex(Число: BigInteger): string;
function Hex(number: BigInteger): string;
begin
Число := Abs(Число);
var ШестнадцатиричныеЦифры := '0123456789ABCDEF';
if number < 0 then number := -number;
var hex_nums := '0123456789ABCDEF';
Result := '';
while Число >= 16 do
while number >= 16 do
begin
Result += ШестнадцатиричныеЦифры[byte(Число mod 16) + 1];
Число := Число div 16
Result += hex_nums[byte(number mod 16 + 1)];
number := number div 16
end;
Result += ШестнадцатиричныеЦифры[byte(Число) + 1];
Result := Result.Inverse
Result += hex_nums[byte(number + 1)];
Result := Result.Inverse;
end;
{$endregion}
const
ДопустимыеСимволы = '0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ';
valid_chars = '0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ';
{$region Dec}
function Dec(СтроковоеПредставление: string; Основание: integer): int64;
function Dec(str: string; base: integer): int64;
begin
if not (Основание in 2..36) then
if not (base in 2..36) then
raise new School_InvalidBase
($'ToDecimal: Недопустимое основание {Основание}');
СтроковоеПредставление := СтроковоеПредставление.ToUpper;
var НедопустимыеСимволы :=
СтроковоеПредставление.Except(ДопустимыеСимволы[:Основание + 1]).JoinToString;
if НедопустимыеСимволы.Length > 0 then
($'ToDecimal: Недопустимое основание {base}');
str := str.ToUpper;
var invalid_chars :=
str.Except(valid_chars[:base + 1]).JoinToString;
if invalid_chars.Length > 0 then
raise new School_BadCharInString
($'ToDecimal: Недопустимые символы "{НедопустимыеСимволы}"');
var ВесРазряда := 1bi;
var Результат := 0bi;
foreach var Символ in СтроковоеПредставление.Reverse do
($'ToDecimal: Недопустимые символы "{invalid_chars}"');
var rank_weight := 1bi;
var res := 0bi;
foreach var char in str.Reverse do
begin
var ЗначениеРазряда := Pos(Символ, ДопустимыеСимволы) - 1;
Результат += ВесРазряда * ЗначениеРазряда;
ВесРазряда *= Основание
var rank_value := Pos(char, valid_chars) - 1;
res += rank_weight * rank_value;
rank_weight *= base
end;
Result := int64(Результат)
Result := int64(res)
end;
function DecBig(СтроковоеПредставление: string; Основание: integer): BigInteger;
function DecBig(str: string; base: integer): BigInteger;
begin
if not (Основание in 2..36) then
if not (base in 2..36) then
raise new School_InvalidBase
($'ToDecimal: Недопустимое основание {Основание}');
СтроковоеПредставление := СтроковоеПредставление.ToUpper;
var НедопустимыеСимволы :=
СтроковоеПредставление.Except(ДопустимыеСимволы[:Основание + 1]).JoinToString;
if НедопустимыеСимволы.Length > 0 then
($'ToDecimal: Недопустимое основание {base}');
str := str.ToUpper;
var invalid_chars :=
str.Except(valid_chars[:base + 1]).JoinToString;
if invalid_chars.Length > 0 then
raise new School_BadCharInString
($'ToDecimal: Недопустимые символы "{НедопустимыеСимволы}"');
var ВесРазряда := 1bi;
($'ToDecimal: Недопустимые символы "{invalid_chars}"');
var rank_weight := 1bi;
Result := 0bi;
foreach var Символ in СтроковоеПредставление.Reverse do
foreach var char in str.Reverse do
begin
var ЗначениеРазряда := Pos(Символ, ДопустимыеСимволы) - 1;
Result += ВесРазряда * ЗначениеРазряда;
ВесРазряда *= Основание
var rank_value := Pos(char, valid_chars) - 1;
Result += rank_weight * rank_value;
rank_weight *= base
end
end;
{$endregion}
{$region ToBase}
/// Перевод BigInteger в систему счисления по основанию base (2..36)
function ToBase(Число: BigInteger; Основание: integer): string;
function ToBase(number: BigInteger; base: integer): string;
begin
if not (Основание in 2..36) then
if not (base in 2..36) then
raise new School_InvalidBase
($'ToDecimal: Недопустимое основание {Основание}');
var СтроковоеПредставление := new System.Text.StringBuilder('');
while Число > 0 do
($'ToDecimal: Недопустимое основание {base}');
var sb := new System.Text.StringBuilder('');
while number > 0 do
begin
СтроковоеПредставление.Insert(0, ДопустимыеСимволы[integer(Число mod Основание) + 1]);
Число := Число div Основание
sb.Insert(0, valid_chars[integer(number mod base) + 1]);
number := number div base
end;
Result := if СтроковоеПредставление.Length = 0 then '0'
else СтроковоеПредставление.ToString
Result := if sb.Length = 0 then '0'
else sb.ToString
end;
/// Перевод BigInteger в систему счисления по основанию base (2..36)
function ToBase(Self: BigInteger; Основание: integer): string; extensionmethod :=
ToBase(Self, Основание);
function ToBase(Self: BigInteger; base: integer): string; extensionmethod :=
ToBase(Self, base);
/// Перевод десятичного числа в систему счисления по основанию base (2..36)
function ToBase(СтроковоеПредставление: string; Основание: integer): string;
function ToBase(str: string; base: integer): string;
begin
if not (Основание in 2..36) then
if not (base in 2..36) then
raise new School_InvalidBase
($'ToDecimal: Недопустимое основание {Основание}');
var Число: BigInteger;
if BigInteger.TryParse(СтроковоеПредставление, Число) then
Result := ToBase(Число, Основание)
($'ToDecimal: Недопустимое основание {base}');
var number: BigInteger;
if BigInteger.TryParse(str, number) then
Result := ToBase(number, base)
end;
/// Перевод десятичного числа в систему счисления по основанию base (2..36)
function ToBase(Self: string; Основание: integer): string; extensionmethod :=
ToBase(Self, Основание);
function ToBase(Self: string; base: integer): string; extensionmethod :=
ToBase(Self, base);
{$endregion}
{$region MinMax}
/// Возвращает кортеж из минимума и максимума последовательности
function MinMax(Последовательность: sequence of int64): (int64, int64);
function MinMax(seq: sequence of int64): (int64, int64);
begin
var min := int64.MaxValue;
var max := int64.MinValue;
foreach var Элемент in Последовательность do
foreach var elem in seq do
begin
if Элемент < min then
min := Элемент;
if Элемент > max then
max := Элемент
if elem < min then
min := elem;
if elem > max then
max := elem
end;
Result := (min, max)
end;
/// Возвращает кортеж из минимума и максимума последовательности
function MinMax(Последовательность: sequence of integer): (integer, integer);
function MinMax(seq: sequence of integer): (integer, integer);
begin
var min := integer.MaxValue;
var max := integer.MinValue;
foreach var Элемент in Последовательность do
foreach var elem in seq do
begin
if Элемент < min then
min := Элемент;
if Элемент > max then
max := Элемент
if elem < min then
min := elem;
if elem > max then
max := elem
end;
Result := (min, max)
end;
/// Возвращает кортеж из минимума и максимума последовательности s
function MinMax(Последовательность: sequence of real): (real, real);
function MinMax(seq: sequence of real): (real, real);
begin
var min := real.MaxValue;
var max := real.MinValue;
foreach var Элемент in Последовательность do
var max := -real.MaxValue;
foreach var elem in seq do
begin
if Элемент < min then
min := Элемент;
if Элемент > max then
max := Элемент
if elem < min then
min := elem;
if elem > max then
max := elem
end;
Result := (min, max)
end;
/// Возвращает кортеж из минимума и максимума последовательности s
function MinMax(Последовательность: sequence of BigInteger): (BigInteger, BigInteger);
function MinMax(seq: sequence of BigInteger): (BigInteger, BigInteger);
begin
var min, max: BigInteger;
var ЭтоПервыйЭлемент := True;
foreach var Элемент in Последовательность do
if ЭтоПервыйЭлемент then
var is_first := True;
foreach var elem in seq do
if is_first then
begin
min := Элемент;
max := Элемент;
ЭтоПервыйЭлемент := False
(min, max) := (elem, elem);
is_first := False
end
else
begin
if Элемент < min then
min := Элемент;
if Элемент > max then
max := Элемент
end;
if elem < min then
min := elem;
if elem > max then
max := elem
end;
Result := (min, max)
end;
@ -574,10 +598,10 @@ begin
else
begin
Result := True;
foreach var Простое in LPrimes do
if Sqr(Простое) > Self then
foreach var prime in LPrimes do
if Sqr(prime) > Self then
break
else if Self mod Простое = 0 then
else if Self mod prime = 0 then
begin
Result := False;
break
@ -931,13 +955,13 @@ end;
{$region String}
/// Заменяет последнее вхождение подстроки в строку
procedure ReplaceLast(var Строка: string; ЧтоЗаменить, ЧемЗаменить: string);
procedure ReplaceLast(var s: string; source, target: string);
begin
var Позиция := LastPos(ЧтоЗаменить, Строка);
if Позиция > 0 then
var position := LastPos(source, s);
if position > 0 then
begin
Delete(Строка, Позиция, ЧтоЗаменить.Length);
Insert(ЧемЗаменить, Строка, Позиция)
Delete(s, position, source.Length);
Insert(target, s, position)
end
end;