pascalabcnet/TestSuite/CompilationSamples/PT4.pas
2016-07-10 14:49:12 +03:00

1810 lines
50 KiB
ObjectPascal
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

/// Модуль электронного задачника Programming Taskbook 4
unit PT4;
//------------------------------------------------------------------------------
// Модуль для подключения задачника Programming Taskbook
// Версия 4.13
// Copyright (c) 2006-2008 DarkStar, SSM
// Copyright (c) 2010 М.Э.Абрамян, дополнения к версии 1.3
// Copyright (c) 2014-2015 М.Э.Абрамян, дополнения к версии 4.13
// Copyright (c) 2015 М.Э.Абрамян, дополнения к версии 4.14
// Электронный задачник Programming Taskbook Copyright (c)М.Э.Абрамян, 1998-2015
//------------------------------------------------------------------------------
{$apptype windows}
{$platformtarget x86}
interface
uses System,
System.Collections,
System.Runtime.InteropServices;
type
/// Тип указателя на узел списка
PNode = ^TNode;
/// Тип узла списка
TNode = record
Data: integer;
Next,Prev,Left,Right,Parent: PNode;
end;
InternalNode = record
Data: integer;
Next,Prev,Left,Right,Parent: IntPtr;
end;
IOPT4System = class(IOStandardSystem)
public
procedure write(obj: object); override;
procedure writeln; override;
end;
PT4Exception = Exception;
Node = class(IDisposable)
private
isAllocMem: boolean;
isDisposed: boolean;
x: InternalNode;
addr: IntPtr;
constructor Create(x: InternalNode; a: IntPtr);
procedure Init(Data: integer; Next,Prev,Left,Right,Parent: Node);
procedure internalDispose(disposing: boolean);
procedure setNext(value: Node);
function getNext: Node;
procedure setPrev(value: Node);
function getPrev: Node;
procedure setLeft(value: Node);
function getLeft: Node;
procedure setRight(value: Node);
function getRight: Node;
procedure setParent(value: Node);
function getParent: Node;
procedure setData(value: integer);
function getData: integer;
public
constructor Create;
constructor Create(aData: integer);
constructor Create(aData: integer; aNext: Node);
constructor Create(aData: integer; aNext,aPrev: Node);
constructor Create(left,right: Node; data: integer);
constructor Create(left,right: Node; data: integer; parent: Node);
procedure Dispose;
property Next: Node read getNext write SetNext;
property Prev: Node read getPrev write SetPrev;
property Left: Node read getLeft write SetLeft;
property Right: Node read getRight write SetRight;
property Parent: Node read getParent write SetParent;
property Data: integer read getData write SetData;
end;
/// Вывести формулировку задания
procedure Task(name: string);
/// Ввести и вернуть значение целого типа
function GetInt: integer;
/// Ввести и вернуть значение целого типа
function GetInteger: integer;
/// Ввести и вернуть значение вещественного типа
function GetReal: real;
/// Ввести и вернуть значение вещественного типа
function GetDouble: real;
/// Ввести и вернуть значение символьного типа
function GetChar: char;
/// Ввести и вернуть значение строкового типа
function GetString: string;
/// Ввести и вернуть значение логического типа
function GetBool: boolean;
/// Ввести и вернуть значение логического типа
function GetBoolean: boolean;
/// Ввести и вернуть значение типа Node
function GetNode: Node;
/// Ввести и вернуть значение типа PNode
function GetPNode: PNode;
/// Возвращает введенное значение типа integer
function ReadInteger: integer;
/// Возвращает введенное значение типа real
function ReadReal: real;
/// Возвращает введенное значение типа char
function ReadChar: char;
/// Возвращает введенное значение типа string
function ReadString: string;
/// Возвращает введенное значение типа boolean
function ReadBoolean: boolean;
/// Возвращает введенное значение типа PNode
function ReadPNode: PNode;
/// Возвращает введенное значение типа Node
function ReadNode: Node;
/// Возвращает введенное значение типа integer
function ReadlnInteger: integer;
/// Возвращает введенное значение типа real
function ReadlnReal: real;
/// Возвращает введенное значение типа char
function ReadlnChar: char;
/// Возвращает введенное значение типа string
function ReadlnString: string;
/// Возвращает введенное значение типа boolean
function ReadlnBoolean: boolean;
/// Возвращает введенное значение типа PNode
function ReadlnPNode: PNode;
/// Возвращает введенное значение типа Node
function ReadlnNode: Node;
procedure GetR(var param: real);
procedure GetN(var param: integer);
procedure GetC(var param: char);
procedure GetS(var param: string);
procedure GetB(var param: boolean);
procedure GetP(var param: PNode);
procedure GetP(var param: Node);
procedure PutR(param: real);
procedure PutN(param: integer);
procedure PutC(param: char);
procedure PutS(param: string);
procedure PutB(param: boolean);
procedure PutP(param: PNode);
procedure PutP(param: Node);
procedure Put(params args: array of Object);
procedure Put(param: real);
procedure Put(param: integer);
procedure Put(param: char);
procedure Put(param: string);
procedure Put(param: boolean);
procedure Put(param: PNode);
procedure Put(param: Node);
//Ввод этих данных не поддерживается
///- read(a,b,...)
/// Вводит значения a,b,... из окна электронного задачника
procedure read(var x: byte);
///--
procedure read(var x: shortint);
///--
procedure read(var x: smallint);
///--
procedure read(var x: word);
///--
procedure read(var x: longword);
///--
procedure read(var x: int64);
///--
procedure read(var x: uint64);
///--
procedure read(var x: single);
//---------------------------------
///--
procedure Read(var val: integer);
///--
procedure Read(var val: real);
///--
procedure Read(var val: char);
///--
procedure Read(var val: string);
///--
procedure Read(var val: boolean);
///--
procedure Read(var val: Node);
///--
procedure Read(var val: PNode);
///--
procedure Readln;
procedure Print(params args: array of object);
procedure Println(params args: array of object);
/// Освобождает память, выделенную динамически, на которую указывает p
procedure Dispose(p: pointer);
// Фиктивная пустая процедура - для Intellisense
// Нет, нельзя пользоваться - закрываются процедуры write системного модуля
///- write(a,b,...)
/// Выводит значения a,b,... в окно электронного задачника
//procedure write;
///--
procedure __InitModule__;
///--
procedure __FinalizeModule__;
// == Версия 1.3. Дополнения ==
/// Выводит строку S в разделе отладки окна задачника
procedure Show(S: string);
/// Выводит число A с комментарием S в разделе отладки
/// окна задачника; для вывода числа отводится W экранных позиций
procedure Show(S: string; A: integer; W: integer);
/// Выводит число A с комментарием S в разделе отладки
/// окна задачника; для вывода числа отводится W экранных позиций
procedure Show(S: string; A: real; W: integer);
/// Выводит число A с комментарием S в разделе отладки окна задачника
procedure Show(S: string; A: integer);
/// Выводит число A с комментарием S в разделе отладки окна задачника
procedure Show(S: string; A: real);
/// Выводит число A в разделе отладки окна задачника;
/// для вывода отводится W экранных позиций
procedure Show(A: integer; W: integer);
/// Выводит число A в разделе отладки окна задачника;
/// для вывода отводится W экранных позиций
procedure Show(A: real; W: integer);
/// Выводит число A в разделе отладки окна задачника
procedure Show(A: integer);
/// Выводит число A в разделе отладки окна задачника
procedure Show(A: real);
/// Выполняет переход на новую экранную строку
/// в разделе отладки окна задачника
procedure ShowLine;
/// Выводит строку S в разделе отладки окна задачника,
/// после чего выполняет переход на новую экранную строку
procedure ShowLine(S: string);
/// Выводит число A с комментарием S в разделе отладки
/// окна задачника; для вывода числа отводится W экранных позиций.
/// После вывода данных выполняет переход на новую экранную строку
procedure ShowLine(S: string; A: integer; W: integer);
/// Выводит число A с комментарием S в разделе отладки
/// окна задачника; для вывода числа отводится W экранных позиций.
/// После вывода данных выполняет переход на новую экранную строку
procedure ShowLine(S: string; A: real; W: integer);
/// Выводит число A с комментарием S в разделе отладки окна задачника,
/// после чего выполняет переход на новую экранную строку
procedure ShowLine(S: string; A: integer);
/// Выводит число A с комментарием S в разделе отладки окна задачника,
/// после чего выполняет переход на новую экранную строку
procedure ShowLine(S: string; A: real);
/// Выводит число A в разделе отладки окна задачника;
/// для вывода отводится W экранных позиций.
/// После вывода числа выполняет переход на новую экранную строку
procedure ShowLine(A: integer; W: integer);
/// Выводит число A в разделе отладки окна задачника;
/// для вывода отводится W экранных позиций.
/// После вывода числа выполняет переход на новую экранную строку
procedure ShowLine(A: real; W: integer);
/// Выводит число A в разделе отладки окна задачника,
/// после чего выполняет переход на новую экранную строку
procedure ShowLine(A: integer);
/// Выводит число A в разделе отладки окна задачника,
/// после чего выполняет переход на новую экранную строку
procedure ShowLine(A: real);
/// Настраивает формат вывода вещественных чисел в разделе отладки
/// окна задачника. Если N > 0, то число выводится в формате
/// с фиксированной точкой и N дробными знаками. Если N = 0,
/// то число выводится в экспоненциальном формате, число дробных
/// знаков определяется шириной поля вывода
procedure SetPrecision(N: integer);
/// Обеспечивает автоматическое скрытие всех разделов
/// окна задачника, кроме раздела отладки
procedure HideTask;
// == Конец дополнений к версии 1.3 ==
// == Версия 4.14. Дополнения ==
/// Вводит n целых чисел
/// и возвращает введенные числа в виде массива
function ReadArrInteger(n: integer): array of integer;
/// Вводит n вещественных чисел
/// и возвращает введенные числа в виде массива
function ReadArrReal(n: integer): array of real;
/// Вводит n строк
/// и возвращает введенные строки в виде массива
function ReadArrString(n: integer): array of string;
/// Вводит n целых чисел
/// и возвращает введенные числа в виде последовательности
function ReadSeqInteger(n: integer): sequence of integer;
/// Вводит n вещественных чисел
/// и возвращает введенные числа в виде последовательности
function ReadSeqReal(n: integer): sequence of real;
/// Вводит n строк
/// и возвращает введенные строки в виде последовательности
function ReadSeqString(n: integer): sequence of string;
/// Вводит размер набора целых чисел и его элементы
/// и возвращает введенный набор в виде последовательности
function ReadSeqInteger(): sequence of integer;
/// Вводит размер набора вещественных чисел и его элементы
/// и возвращает введенный набор в виде последовательности
function ReadSeqReal(): sequence of real;
/// Вводит размер набора строк и его элементы
/// и возвращает введенный набор в виде последовательности
function ReadSeqString(): sequence of string;
/// Вводит размер набора целых чисел и его элементы
/// и возвращает введенный набор в виде массива
function ReadArrInteger(): array of integer;
/// Вводит размер набора вещественных чисел и его элементы
/// и возвращает введенный набор в виде массива
function ReadArrReal(): array of real;
/// Вводит размер набора строк и его элементы
/// и возвращает введенный набор в виде массива
function ReadArrString(): array of string;
/// Вводит целую матрицу размера m на n по строкам
function ReadMatrInteger(m,n: integer): array [,] of integer;
/// Вводит размеры матрицы и затем целую матрицу указанных размеров по строкам
function ReadMatrInteger(): array [,] of integer;
/// Вводит вещественную матрицу размера m на n по строкам
function ReadMatrReal(m,n: integer): array [,] of real;
/// Вводит размеры матрицы и затем вещественную матрицу указанных размеров по строкам
function ReadMatrReal(): array [,] of real;
/// Вводит матрицу из строк размера m на n по строкам
function ReadMatrString(m,n: integer): array [,] of string;
/// Вводит размеры матрицы и затем строковую матрицу указанных размеров по строкам
function ReadMatrString(): array [,] of string;
procedure ReadMatr(var m, n: integer; var a: array [,] of integer);
procedure ReadMatr(var m, n: integer; var a: array [,] of real);
procedure ReadMatr(var m, n: integer; var a: array [,] of string);
procedure ReadMatr(var m: integer; var a: array [,] of integer);
procedure ReadMatr(var m: integer; var a: array [,] of real);
procedure ReadMatr(var m: integer; var a: array [,] of string);
procedure ReadMatr(var m, n: integer; var a: array of array of integer);
procedure ReadMatr(var m, n: integer; var a: array of array of real);
procedure ReadMatr(var m, n: integer; var a: array of array of string);
procedure ReadMatr(var m: integer; var a: array of array of integer);
procedure ReadMatr(var m: integer; var a: array of array of real);
procedure ReadMatr(var m: integer; var a: array of array of string);
procedure ReadMatr(var m, n: integer; var a: List<List<integer>>);
procedure ReadMatr(var m, n: integer; var a: List<List<real>>);
procedure ReadMatr(var m, n: integer; var a: List<List<string>>);
procedure ReadMatr(var m: integer; var a: List<List<integer>>);
procedure ReadMatr(var m: integer; var a: List<List<real>>);
procedure ReadMatr(var m: integer; var a: List<List<string>>);
procedure WriteMatr<T>(a: array[,] of T);
procedure WriteMatr<T>(a: array of array of T);
procedure WriteMatr<T>(a: List<List<T>>);
// == Конец дополнений к версии 4.14 ==
implementation
const
NotSupportedReadTypeMessage = 'Ввод данных типа {0} не поддерживается';
NotSupportedWriteTypeMessage = 'Вывод данных типа {0} не поддерживается';
eMessage = 'Попытка обращения к объекту Node после вызова его метода Dispose';
var
loadNodes: ArrayList;
InfoT: integer;
InfoS: string;
ExceptionThrowed := false;
procedure PutInt(val: integer); forward;
procedure PutReal(val: real); forward;
procedure PutChar(val: char); forward;
procedure PutString(val: string); forward;
procedure PutBoolean(val: boolean); forward;
procedure PutNode(val: Node); forward;
procedure PutPNode(val: PNode); forward;
procedure StartPT(options: integer); external '%PABCSYSTEM%\PT4\PT4PABC.dll' name 'startpt';
procedure FreePT; external '%PABCSYSTEM%\PT4\PT4PABC.dll' name 'freept';
function CheckPT(var res: integer):string;external '%PABCSYSTEM%\PT4\PT4PABC.dll' name 'checkptf';
procedure RaisePT(s1,s2: string); external '%PABCSYSTEM%\PT4\PT4PABC.dll' name 'raisept';
procedure Task(name: string); external '%PABCSYSTEM%\PT4\PT4PABC.dll' name 'task';
procedure GetR(var param: real); external '%PABCSYSTEM%\PT4\PT4PABC.dll' name 'getr';
procedure PutR(param: real); external '%PABCSYSTEM%\PT4\PT4PABC.dll' name 'putr';
procedure GetN(var param: integer); external '%PABCSYSTEM%\PT4\PT4PABC.dll' name 'getn';
procedure PutN(param: integer); external '%PABCSYSTEM%\PT4\PT4PABC.dll' name 'putn';
procedure GetC(var param: char); external '%PABCSYSTEM%\PT4\PT4PABC.dll' name 'getc';
procedure PutC(param: char); external '%PABCSYSTEM%\PT4\PT4PABC.dll' name 'putc';
procedure _GetS(param: System.Text.StringBuilder);external '%PABCSYSTEM%\PT4\PT4PABC.dll' name 'gets';
procedure PutS(param: string); external '%PABCSYSTEM%\PT4\PT4PABC.dll' name 'puts';
procedure _GetB(var param: integer); external '%PABCSYSTEM%\PT4\PT4PABC.dll' name 'getb';
procedure _PutB(param: integer); external '%PABCSYSTEM%\PT4\PT4PABC.dll' name 'putb';
procedure _GetP(var param: IntPtr); external '%PABCSYSTEM%\PT4\PT4PABC.dll' name 'getp';
procedure _PutP(param: IntPtr); external '%PABCSYSTEM%\PT4\PT4PABC.dll' name 'putp';
procedure DisposeP(sNode: IntPtr); external '%PABCSYSTEM%\PT4\PT4PABC.dll' name 'disposep';
function FinishPT(): integer; external '%PABCSYSTEM%\PT4\PT4PABC.dll' name 'finishpt'; // == 4.13 ==
procedure Dispose(p: pointer);
begin
DisposeP(IntPtr(p));
end;
procedure GetS(var param: string);
begin
param := GetString();
end;
procedure GetB(var param: boolean);
begin
param := GetBoolean();
end;
procedure PutB(param: boolean);
begin
PutBoolean(param);
end;
procedure GetP(var param: PNode);
begin
param := GetPNode();
end;
procedure GetP(var param: Node);
begin
param := GetNode();
end;
procedure PutP(param: PNode);
begin
PutPNode(param);
end;
procedure PutP(param: Node);
begin
PutNode(param);
end;
procedure Put(params args: array of Object);
begin
foreach x: Object in args do
begin
if x.GetType = typeof(integer) then
Put(integer(x))
else if x.GetType = typeof(real) then
Put(real(x))
else if x.GetType = typeof(char) then
Put(char(x))
else if x.GetType = typeof(string) then
Put(string(x))
else if x.GetType = typeof(boolean) then
Put(boolean(x))
else if x.GetType = typeof(Node) then
Put(Node(x))
// else if x.GetType = typeof(PNode) then
// Put(PNode(x))
end;
end;
procedure Put(param: real);
begin
PutR(param);
end;
procedure Put(param: integer);
begin
PutN(param);
end;
procedure Put(param: char);
begin
PutC(param);
end;
procedure Put(param: string);
begin
PutS(param);
end;
procedure Put(param: boolean);
begin
PutB(param);
end;
procedure Put(param: PNode);
begin
PutP(param);
end;
procedure Put(param: Node);
begin
PutP(param);
end;
// -----------------------------------------------------
// Node
// -----------------------------------------------------
constructor Node.Create(x: InternalNode; a: IntPtr);
begin
Self.x.Data := x.Data;
Self.x.Next := x.Next;
Self.x.Prev := x.Prev;
Self.x.Left := x.Left;
Self.x.Right := x.Right;
Self.x.Parent := x.Parent;
addr := a;
isAllocMem := false;
isDisposed := false;
end;
constructor Node.Create;
begin
Init(0, nil, nil, nil, nil, nil);
end;
constructor Node.Create(aData: integer);
begin
Init(aData, nil, nil, nil, nil, nil);
end;
constructor Node.Create(aData: integer; aNext: Node);
begin
Init(aData, aNext, nil, nil, nil, nil);
end;
constructor Node.Create(aData: integer; aNext,aPrev: Node);
begin
Init(aData, aNext, aPrev, nil, nil, nil);
end;
constructor Node.Create(left,right: Node; data: integer);
begin
Init(data,nil,nil,left,right,nil);
end;
constructor Node.Create(left,right: Node; data: integer; parent: Node);
begin
Init(data,nil,nil,left,right,parent);
end;
procedure Node.Dispose;
begin
GC.SuppressFinalize(self);
internalDispose(true);
end;
procedure Node.Init(Data: integer; Next,Prev,Left,Right,Parent: Node);
begin
x.Data := Data;
if Next = nil then
x.Next := IntPtr.Zero
else x.Next := Next.addr;
if Prev = nil then
x.Prev := IntPtr.Zero
else x.Prev := Prev.addr;
if Left = nil then
x.Left := IntPtr.Zero
else x.Left := Left.addr;
if Right = nil then
x.Right := IntPtr.Zero
else x.Right := Right.addr;
if Parent = nil then
x.Parent := IntPtr.Zero
else x.Parent := Parent.addr;
addr := Marshal.AllocHGlobal(sizeof(InternalNode));
Marshal.StructureToPtr(x as object, addr, false);
isAllocMem := true;
isDisposed := false;
loadNodes.Add(self);
end;
procedure Node.setNext(value:Node);
begin
if isDisposed then
raise new ObjectDisposedException(ToString, eMessage);
if value = nil then
begin
x.Next := IntPtr.Zero;
Marshal.StructureToPtr(x as object, addr, isAllocMem);
end else
begin
x.Next := value.addr;
Marshal.StructureToPtr(x as object, addr, isAllocMem);
end;
end;
function Node.getNext:Node;
var tmp: IntPtr;
tmpNode: Node;
i: integer;
begin
result := nil;
if isDisposed then
raise new ObjectDisposedException(ToString, eMessage);
if x.Next <> IntPtr.Zero then
begin
tmp := x.Next;
for i:=0 to loadNodes.Count-1 do
if tmp.Equals(Node(loadNodes[i]).addr) then
result:=Node(loadNodes[i]);
if result=nil then
begin
tmpNode := new Node(InternalNode(Marshal.PtrToStructure(tmp,typeof(InternalNode))), tmp);
loadNodes.Add(tmpNode);
result := tmpNode;
end;
end;
end;
procedure Node.setPrev(value: Node);
begin
if isDisposed then
raise new ObjectDisposedException(ToString, eMessage);
if value = nil then
begin
x.Prev := IntPtr.Zero;
Marshal.StructureToPtr(x as object, addr, isAllocMem);
end else
begin
x.Prev := value.addr;
Marshal.StructureToPtr(x as object, addr, isAllocMem);
end;
end;
function Node.getPrev: Node;
var tmp: IntPtr;
tmpNode:Node;
i:integer;
begin
result := nil;
if isDisposed then
raise new ObjectDisposedException(ToString, eMessage);
if x.Prev <> IntPtr.Zero then begin
tmp := x.Prev;
for i:=0 to loadNodes.Count-1 do
if tmp.Equals(Node(loadNodes[i]).addr) then
result:=Node(loadNodes[i]);
if result=nil then begin
tmpNode := new Node(InternalNode(Marshal.PtrToStructure(tmp,typeof(InternalNode))), tmp);
loadNodes.Add(tmpNode);
result := tmpNode;
end;
end;
end;
procedure Node.setLeft(value: Node);
begin
if isDisposed then
raise new ObjectDisposedException(ToString, eMessage);
if value = nil then
begin
x.Left := IntPtr.Zero;
Marshal.StructureToPtr(x as object, addr, isAllocMem);
end else
begin
x.Left := value.addr;
Marshal.StructureToPtr(x as object, addr, isAllocMem);
end;
end;
function Node.getLeft: Node;
var tmp: IntPtr;
tmpNode:Node;
i:integer;
begin
result := nil;
if isDisposed then
raise new ObjectDisposedException(ToString, eMessage);
if x.Left <> IntPtr.Zero then begin
tmp := x.Left;
for i:=0 to loadNodes.Count-1 do
if tmp.Equals(Node(loadNodes[i]).addr) then
result:=Node(loadNodes[i]);
if result=nil then begin
tmpNode := new Node(InternalNode(Marshal.PtrToStructure(tmp,typeof(InternalNode))), tmp);
loadNodes.Add(tmpNode);
result := tmpNode;
end;
end;
end;
procedure Node.setRight(value: Node);
begin
if isDisposed then
raise new ObjectDisposedException(ToString, eMessage);
if value = nil then
begin
x.Right := IntPtr.Zero;
Marshal.StructureToPtr(x as object, addr, isAllocMem);
end else
begin
x.Right := value.addr;
Marshal.StructureToPtr(x as object, addr, isAllocMem);
end;
end;
function Node.getRight: Node;
var tmp: IntPtr;
tmpNode:Node;
i:integer;
begin
result := nil;
if isDisposed then
raise new ObjectDisposedException(ToString, eMessage);
if x.Right <> IntPtr.Zero then begin
tmp := x.Right;
for i:=0 to loadNodes.Count-1 do
if tmp.Equals(Node(loadNodes[i]).addr) then
result:=Node(loadNodes[i]);
if result=nil then begin
tmpNode := new Node(InternalNode(Marshal.PtrToStructure(tmp,typeof(InternalNode))), tmp);
loadNodes.Add(tmpNode);
result := tmpNode;
end;
end;
end;
procedure Node.setParent(value: Node);
begin
if isDisposed then
raise new ObjectDisposedException(ToString, eMessage);
if value = nil then
begin
x.Parent := IntPtr.Zero;
Marshal.StructureToPtr(x as object, addr, isAllocMem);
end else
begin
x.Parent := value.addr;
Marshal.StructureToPtr(x as object, addr, isAllocMem);
end;
end;
function Node.getParent: Node;
var tmp: IntPtr;
tmpNode:Node;
i:integer;
begin
result := nil;
if isDisposed then
raise new ObjectDisposedException(ToString, eMessage);
if x.Parent <> IntPtr.Zero then begin
tmp := x.Parent;
for i:=0 to loadNodes.Count-1 do
if tmp.Equals(Node(loadNodes[i]).addr) then
result:=Node(loadNodes[i]);
if result=nil then begin
tmpNode := new Node(InternalNode(Marshal.PtrToStructure(tmp,typeof(InternalNode))), tmp);
loadNodes.Add(tmpNode);
result := tmpNode;
end;
end;
end;
procedure Node.setData(value: integer);
begin
if isDisposed then
raise new ObjectDisposedException(ToString, eMessage);
self.x.Data := value;
Marshal.StructureToPtr(x as object, addr, isAllocMem);
end;
function Node.getData: integer;
begin
if isDisposed then
raise new ObjectDisposedException(ToString, eMessage);
result := self.x.Data;
end;
procedure Node.internalDispose(disposing: boolean);
begin
if not isDisposed then
//lock(self)
begin
if disposing then
DisposeP(addr);
if isAllocMem then
Marshal.FreeHGlobal(addr);
isDisposed := true;
end;
end;
procedure internalWrite(args: array of object); forward;
// -----------------------------------------------------
// IOPT4System
// -----------------------------------------------------
procedure IOPT4System.write(obj: object);
var args: array of object;
begin
SetLength(args,1);
args[0] := obj;
internalWrite(args);
end;
procedure IOPT4System.writeln;
begin
end;
// -----------------------------------------------------
// Функции Get
// -----------------------------------------------------
function GetInt: integer;
var val:integer;
begin
Getn(val);
result := val;
end;
function GetInteger: integer;
begin
result := GetInt;
end;
function GetReal: real;
var val: real;
begin
getr(val);
result := val;
end;
function GetDouble: real;
begin
result := GetReal;
end;
function GetChar: char;
var val: char;
begin
getc(val);
result:=val;
end;
function GetString: string;
var val: System.Text.StringBuilder;
begin
val := new System.Text.StringBuilder(200);//TODO почему 200?
_gets(val);
result := val.ToString;
end;
function GetBool: boolean;
var val: integer;
begin
_getb(val);
result := val=1;
end;
function GetBoolean: boolean;
begin
result := GetBool;
end;
function GetNode: Node;
procedure GetPtr(var sNode:InternalNode; var pNode: IntPtr);
var p:IntPtr;
begin
p := IntPtr.Zero;
_GetP(p);
pNode := p;
if p <> IntPtr.Zero then
sNode := InternalNode(Marshal.PtrToStructure(p, typeof(InternalNode)));
end;
var
p: IntPtr;
sNode: InternalNode;
i: integer;
begin
//raise new NotSupportedException('Работа с динамическими структурами задачника PT4 не поддерживается в этой версии компилятора. Исправление ошибки планируется в следуйщей версии');
//result := new PT4Node(sNode, p);// fixme здесь ошибка генерации кода!
p := IntPtr.Zero;
sNode.Data := 0;
sNode.Next := IntPtr.Zero;
sNode.Prev := IntPtr.Zero;
sNode.Left := IntPtr.Zero;
sNode.Right := IntPtr.Zero;
sNode.Parent := IntPtr.Zero;
GetPtr(sNode, p);
if p = IntPtr.Zero then
result := nil
else begin
for i:=0 to loadNodes.Count-1 do
if sNode=Node(loadNodes[i]).x then
result := Node(loadNodes[i]);
if result = nil then begin
result := new Node(sNode, p);
loadNodes.Add(result);
end;
end;
end;
function GetPNode: PNode;
var ip: IntPtr;
begin
_GetP(ip);
Result := PNode(pointer(ip));
end;
function ReadInteger: integer;
begin
Result := GetInt;
end;
function ReadReal: real;
begin
Result := GetReal;
end;
function ReadChar: char;
begin
Result := GetChar;
end;
function ReadString: string;
begin
Result := GetString;
end;
function ReadBoolean: boolean;
begin
Result := GetBool;
end;
function ReadPNode: PNode;
begin
Result := GetPNode;
end;
function ReadNode: Node;
begin
Result := GetNode;
end;
function ReadlnInteger: integer;
begin
Result := GetInt;
end;
function ReadlnReal: real;
begin
Result := GetReal;
end;
function ReadlnChar: char;
begin
Result := GetChar;
end;
function ReadlnString: string;
begin
Result := GetString;
end;
function ReadlnBoolean: boolean;
begin
Result := GetBool;
end;
function ReadlnPNode: PNode;
begin
Result := GetPNode;
end;
function ReadlnNode: Node;
begin
Result := GetNode;
end;
// -----------------------------------------------------
// Процедуры Put
// -----------------------------------------------------
procedure PutInt(val: integer);
begin
putn(val);
end;
procedure PutReal(val: Real);
begin
putr(val);
end;
procedure PutChar(val: char);
begin
putc(val);
end;
procedure PutString(val: string);
begin
puts(val);
end;
procedure PutBoolean(val: boolean);
begin
if val then
_putb(1)
else _putb(0);
end;
procedure PutNode(val: Node);
var p: IntPtr;
begin
p := IntPtr.Zero;
if val <> nil then begin
if val.isDisposed then
raise new ObjectDisposedException(val.ToString, eMessage);
p := val.addr;
end;
_PutP(p);
end;
procedure PutPNode(val: PNode);
var pp: pointer;
begin
pp := pointer(val);
_PutP(IntPtr(pp));
end;
// -----------------------------------------------------
// Генерация исключений
// -----------------------------------------------------
procedure RaisePTAndCheckPT(e: Exception);
begin
RaisePT(e.GetType.ToString, e.Message);
InfoS := CheckPT(InfoT);
if InfoT = 0 then
System.Console.WriteLine(InfoS);
FreePT;
end;
procedure GenerateNotSupportedTypeException(MsgTemplate, TypeName: string);
var e: Exception;
begin
e := new PT4Exception(string.Format(MsgTemplate,TypeName));
RaisePTAndCheckPT(e);
ExceptionThrowed := true;
raise e;
end;
procedure GenerateNotSupportedWriteTypeException(TypeName: string);
begin
GenerateNotSupportedTypeException(NotSupportedWriteTypeMessage,TypeName);
end;
procedure GenerateNotSupportedReadTypeException(TypeName: string);
begin
GenerateNotSupportedTypeException(NotSupportedReadTypeMessage,TypeName);
end;
// -----------------------------------------------------
// read
// -----------------------------------------------------
procedure read(var x: byte);
begin
GenerateNotSupportedReadTypeException(x.GetType.ToString);
end;
procedure read(var x: shortint);
begin
GenerateNotSupportedReadTypeException(x.GetType.ToString);
end;
procedure read(var x: smallint);
begin
GenerateNotSupportedReadTypeException(x.GetType.ToString);
end;
procedure read(var x: word);
begin
GenerateNotSupportedReadTypeException(x.GetType.ToString);
end;
procedure read(var x: longword);
begin
GenerateNotSupportedReadTypeException(x.GetType.ToString);
end;
procedure read(var x: int64);
begin
GenerateNotSupportedReadTypeException(x.GetType.ToString);
end;
procedure read(var x: uint64);
begin
GenerateNotSupportedReadTypeException(x.GetType.ToString);
end;
procedure read(var x: single);
begin
GenerateNotSupportedReadTypeException(x.GetType.ToString);
end;
procedure Read(var val: integer);
begin
val := GetInt;
end;
procedure Read(var val: real);
begin
val := GetReal;
end;
procedure Read(var val: char);
begin
val := GetChar;
end;
procedure Read(var val: string);
begin
val := GetString;
end;
procedure Read(var val: boolean);
begin
val := GetBoolean;
end;
procedure Read(var val: Node);
begin
val := GetNode;
end;
procedure Read(var val: PNode);
begin
val := GetPNode;
end;
procedure Readln;
begin
end;
procedure Print(params args: array of object);
begin
if args.Length = 0 then
exit;
for var i := 0 to args.length - 1 do
write(args[i]);
end;
procedure Println(params args: array of object);
begin
Print(args);
end;
{procedure write;
begin
end;}
// -----------------------------------------------------
// InternalWrite
// -----------------------------------------------------
procedure InternalWrite(args: array of object);
begin
if (args[0] is PABCSystem.Text) then
begin
for var i:=1 to args.length-1 do
PABCSystem.Write(PABCSystem.Text(args[0]),args[i]);
end
else
for var i:=0 to args.length-1 do
if args[i] = nil then PutNode(nil) else
if args[i] is integer then PutInt(integer(args[i])) else
if args[i] is shortint then PutInt(shortint(args[i])) else
if args[i] is smallint then PutInt(smallint(args[i])) else
if args[i] is int64 then PutInt(int64(args[i])) else
if args[i] is byte then PutInt(byte(args[i])) else
if args[i] is word then PutInt(word(args[i])) else
if args[i] is longword then PutInt(longword(args[i])) else
if args[i] is uint64 then PutInt(uint64(args[i])) else
if args[i] is real then PutReal(real(args[i])) else
if args[i] is char then PutChar(char(args[i])) else
if args[i] is string then PutString(string(args[i])) else
if args[i] is boolean then PutBoolean(boolean(args[i])) else
if args[i] is Node then PutNode(Node(args[i])) else
if args[i] is PointerOutput then
begin
var ip := IntPtr(PointerOutput(args[i]).p);
_PutP(ip);
end
else GenerateNotSupportedWriteTypeException(args[i].GetType.ToString);
end;
procedure PT4_ExecuteBeforeProcessTerminateIn__Mode(e: Exception);
begin
if not ExceptionThrowed then
RaisePTAndCheckPT(e);
end;
var __initialized := false;
procedure __InitModule;
begin
CurrentIOSystem := new IOPT4System;
PrintDelimDefault := '';
loadNodes := new ArrayList;
ExecuteBeforeProcessTerminateIn__Mode += PT4_ExecuteBeforeProcessTerminateIn__Mode;
StartPT(512);
end;
procedure __InitModule__;
begin
if not __initialized then
begin
__initialized := true;
__InitModule;
end;
end;
procedure __FinalizeModule__;
begin
InfoS := CheckPT(InfoT);
if InfoT=0 then
Console.WriteLine(InfoS);
FreePT;
// == Начало дополнений к версии 4.13 ==
var fpt := FinishPT;
if fpt = 1 then exit;
var asm := System.Reflection.Assembly.GetExecutingAssembly;
var nm := asm.FullName;
Delete(nm, Pos(',', nm), length(nm));
var prg := asm.GetType(nm+'.Program');
var solveproc := prg.GetMethod('$Main');
var initproc := prg.GetMethod('$_InitVariables_');
var examunit := asm.GetType('PT4Exam.PT4Exam');
var finexamproc: System.Reflection.MethodInfo := nil;
if examunit <> nil then
finexamproc := examunit.GetMethod('FinExam');
var i := 0;
while (fpt = 0) and (i < 10) do
begin
StartPT(512);
try
foreach var f in prg.GetFields do
if not f.Name.StartsWith('$') then
try
f.SetValue(nil, nil);
except
end;
if initproc <> nil then
initproc.Invoke(nil,nil);
solveproc.Invoke(nil,nil);
except
on e: Exception do
RaisePT(e.InnerException.GetType.ToString, e.InnerException.Message);
end;
if finexamproc <> nil then
finexamproc.Invoke(nil,nil);
InfoS := CheckPT(InfoT);
FreePT;
inc(i);
fpt := FinishPT;
end;
// == Конец дополнений к версии 4.13 ==
end;
// == Версия 1.3. Дополнения ==
var
D: integer := 2;
procedure Show(s: string); external '%PABCSYSTEM%\PT4\PT4PABC.dll' name 'show';
procedure Show(S: string; A: Integer; W: Integer);
var s0: string;
begin
Str(A:W, s0);
Show(S + s0);
end;
procedure Show(S: string; A: Real; W: Integer);
var s0: string;
begin
if D > 0 then
s0 := string.Format('{0,'+W+':f'+D+'}', A).Replace(',','.')
else
s0 := string.Format('{0,'+W+':e}', A).Replace(',','.');
Show(S + s0);
end;
procedure Show(S: string; A: Integer);
begin
Show(S, A, 0);
end;
procedure Show(S: string; A: Real);
begin
Show(S, A, 0);
end;
procedure Show(A: Integer; W: Integer);
begin
Show('', A, W);
end;
procedure Show(A: Real; W: Integer);
begin
Show('', A, W);
end;
procedure Show(A: Integer);
begin
Show('', A, 0);
end;
procedure Show(A: Real);
begin
Show('', A, 0);
end;
procedure ShowLine(S: string);
begin
Show(S + #13);
end;
procedure ShowLine;
begin
Show(#13);
end;
procedure ShowLine(S: string; A: Integer; W: Integer);
begin
Show(S, A, W);
Show(#13);
end;
procedure ShowLine(S: string; A: Real; W: Integer);
begin
Show(S, A, W);
Show(#13);
end;
procedure ShowLine(S: string; A: Integer);
begin
Show(S, A, 0);
Show(#13);
end;
procedure ShowLine(S: string; A: Real);
begin
Show(S, A, 0);
Show(#13);
end;
procedure ShowLine(A: Integer; W: Integer);
begin
Show('', A, W);
Show(#13);
end;
procedure ShowLine(A: Real; W: Integer);
begin
Show('', A, W);
Show(#13);
end;
procedure ShowLine(A: Integer);
begin
Show('', A, 0);
Show(#13);
end;
procedure ShowLine(A: Real);
begin
Show('', A, 0);
Show(#13);
end;
procedure HideTask; external '%PABCSYSTEM%\PT4\PT4PABC.dll' name 'hidetask';
procedure SetPrecision(N: Integer);
begin
if N <= 0 then
D := 0
else
D := N;
end;
// == Конец дополнений к версии 1.3 ==
// == Версия 4.14. Дополнения ==
function ReadSeqInteger(): sequence of integer;
begin
result := Range(1, GetInteger()).Select(e -> GetInteger()).ToArray();
end;
function ReadSeqReal(): sequence of real;
begin
result := Range(1, GetInteger()).Select(e -> GetReal()).ToArray();
end;
function ReadSeqString(): sequence of string;
begin
result := Range(1, GetInteger()).Select(e -> GetString()).ToArray();
end;
function ReadSeqInteger(n: integer): sequence of integer;
begin
result := Range(1, n).Select(e -> GetInteger()).ToArray();
end;
function ReadSeqReal(n: integer): sequence of real;
begin
result := Range(1, n).Select(e -> GetReal()).ToArray();
end;
function ReadSeqString(n: integer): sequence of string;
begin
result := Range(1, n).Select(e -> GetString()).ToArray();
end;
function ReadArrInteger(): array of integer;
begin
result := Range(1, GetInteger()).Select(e -> GetInteger()).ToArray();
end;
function ReadArrReal(): array of real;
begin
result := Range(1, GetInteger()).Select(e -> GetReal()).ToArray();
end;
function ReadArrString(): array of string;
begin
result := Range(1, GetInteger()).Select(e -> GetString()).ToArray();
end;
function ReadArrInteger(n: integer): array of integer;
begin
result := Range(1, n).Select(e -> GetInteger()).ToArray();
end;
function ReadArrReal(n: integer): array of real;
begin
result := Range(1, n).Select(e -> GetReal()).ToArray();
end;
function ReadArrString(n: integer): array of string;
begin
result := Range(1, n).Select(e -> GetString()).ToArray();
end;
function ReadMatrInteger(m,n: integer): array [,] of integer;
begin
result := new integer[m,n];
for var i := 0 to m-1 do
for var j := 0 to n-1 do
result[i,j] := ReadInteger;
end;
function ReadMatrInteger(): array [,] of integer;
begin
result := ReadMatrInteger(ReadInteger,ReadInteger);
end;
function ReadMatrReal(m,n: integer): array [,] of real;
begin
result := new real[m,n];
for var i := 0 to m-1 do
for var j := 0 to n-1 do
result[i,j] := ReadReal;
end;
function ReadMatrReal(): array [,] of real;
begin
result := ReadMatrReal(ReadInteger,ReadInteger);
end;
function ReadMatrString(m,n: integer): array [,] of string;
begin
result := new string[m,n];
for var i := 0 to m-1 do
for var j := 0 to n-1 do
result[i,j] := ReadString;
end;
function ReadMatrString(): array [,] of string;
begin
result := ReadMatrString(ReadInteger,ReadInteger);
end;
procedure ReadMatr(var m, n: integer; var a: array [,] of integer);
begin
read(m); read(n);
a := new integer[m, n];
for var i := 0 to m - 1 do
for var j := 0 to n - 1 do
read(a[i,j]);
end;
procedure ReadMatr(var m, n: integer; var a: array [,] of real);
begin
read(m); read(n);
a := new real[m, n];
for var i := 0 to m - 1 do
for var j := 0 to n - 1 do
read(a[i,j]);
end;
procedure ReadMatr(var m, n: integer; var a: array [,] of string);
begin
read(m); read(n);
a := new string[m, n];
for var i := 0 to m - 1 do
for var j := 0 to n - 1 do
read(a[i,j]);
end;
procedure ReadMatr(var m: integer; var a: array [,] of integer);
begin
read(m);
a := new integer[m, m];
for var i := 0 to m - 1 do
for var j := 0 to m - 1 do
read(a[i,j]);
end;
procedure ReadMatr(var m: integer; var a: array [,] of real);
begin
read(m);
a := new real[m, m];
for var i := 0 to m - 1 do
for var j := 0 to m - 1 do
read(a[i,j]);
end;
procedure ReadMatr(var m: integer; var a: array [,] of string);
begin
read(m);
a := new string[m, m];
for var i := 0 to m - 1 do
for var j := 0 to m - 1 do
read(a[i,j]);
end;
procedure ReadMatr(var m, n: integer; var a: array of array of integer);
begin
read(m); read(n);
SetLength(a, m);
for var i := 0 to m - 1 do
a[i] := ReadArrInteger(n);
end;
procedure ReadMatr(var m, n: integer; var a: array of array of real);
begin
read(m); read(n);
SetLength(a, m);
for var i := 0 to m - 1 do
a[i] := ReadArrReal(n);
end;
procedure ReadMatr(var m, n: integer; var a: array of array of string);
begin
read(m); read(n);
SetLength(a, m);
for var i := 0 to m - 1 do
a[i] := ReadArrString(n);
end;
procedure ReadMatr(var m: integer; var a: array of array of integer);
begin
read(m);
SetLength(a, m);
for var i := 0 to m - 1 do
a[i] := ReadArrInteger(m);
end;
procedure ReadMatr(var m: integer; var a: array of array of real);
begin
read(m);
SetLength(a, m);
for var i := 0 to m - 1 do
a[i] := ReadArrReal(m);
end;
procedure ReadMatr(var m: integer; var a: array of array of string);
begin
read(m);
SetLength(a, m);
for var i := 0 to m - 1 do
a[i] := ReadArrString(m);
end;
procedure ReadMatr(var m, n: integer; var a: List<List<integer>>);
begin
read(m); read(n);
a := new List<List<integer>>(m);
for var i := 0 to m - 1 do
a.Add(ReadSeqInteger(n).ToList);
end;
procedure ReadMatr(var m, n: integer; var a: List<List<real>>);
begin
read(m); read(n);
a := new List<List<real>>(m);
for var i := 0 to m - 1 do
a.Add(ReadSeqReal(n).ToList);
end;
procedure ReadMatr(var m, n: integer; var a: List<List<string>>);
begin
read(m); read(n);
a := new List<List<string>>(m);
for var i := 0 to m - 1 do
a.Add(ReadSeqString(n).ToList);
end;
procedure ReadMatr(var m: integer; var a: List<List<integer>>);
begin
read(m);
a := new List<List<integer>>(m);
for var i := 0 to m - 1 do
a.Add(ReadSeqInteger(m).ToList);
end;
procedure ReadMatr(var m: integer; var a: List<List<real>>);
begin
read(m);
a := new List<List<real>>(m);
for var i := 0 to m - 1 do
a.Add(ReadSeqReal(m).ToList);
end;
procedure ReadMatr(var m: integer; var a: List<List<string>>);
begin
read(m);
a := new List<List<string>>(m);
for var i := 0 to m - 1 do
a.Add(ReadSeqString(m).ToList);
end;
procedure WriteMatr<T>(a: array[,] of T);
begin
for var i := 0 to a.GetLength(0)-1 do
for var j := 0 to a.GetLength(1)-1 do
write(a[i,j]);
end;
procedure WriteMatr<T>(a: array of array of T);
begin
for var i := 0 to a.Length-1 do
for var j := 0 to a[i].Length-1 do
write(a[i][j]);
end;
procedure WriteMatr<T>(a: List<List<T>>);
begin
for var i := 0 to a.Count-1 do
for var j := 0 to a[i].Count-1 do
write(a[i][j]);
end;
/// Выводит размер и элементы последовательности
procedure WriteAll<T>(self: sequence of T); extensionmethod;
begin
var b := self.ToArray();
PT4.Put(b.Length);
foreach e : T in b do
PT4.Put(e);
end;
/// Выводит элементы последовательности
procedure Write<T>(self: sequence of T); extensionmethod;
begin
var b := self.ToArray();
foreach e : T in b do
PT4.Put(e);
end;
/// Выводит элементы динамического массива
procedure Write<T>(self: array of T); extensionmethod;
begin
for var i:=0 to self.Length-1 do
PT4.Put(self[i]);
end;
/// Выводит элементы матрицы
procedure Write<T>(self: array [,] of T); extensionmethod;
begin
for var i:=0 to self.GetLength(0)-1 do
for var j:=0 to self.GetLength(1)-1 do
PT4.Put(self[i,j]);
end;
/// Выводит в разделе отладки окна задачника
/// комментарий cmt, размер последовательности и значения,
/// полученные из элементов последовательности
/// с помощью указанного лямбда-выражения
function System.Collections.Generic.IEnumerable<TSource>.Show
(cmt: string; selector: System.Func<TSource, string>):
System.Collections.Generic.IEnumerable<TSource>;
begin
var b := self.Select(selector).ToArray();
PT4.Show(cmt);
PT4.Show((b.Length + ':').PadLeft(3));
foreach var e in b do
PT4.Show(e);
PT4.ShowLine();
result := self;
end;
/// Выводит в разделе отладки окна задачника
/// размер последовательности и значения,
/// полученные из элементов последовательности
/// с помощью указанного лямбда-выражения
function System.Collections.Generic.IEnumerable<TSource>.Show
(selector: System.Func<TSource, string>):
System.Collections.Generic.IEnumerable<TSource>;
begin
result := self.Show('', selector);
end;
/// Выводит в разделе отладки окна задачника
/// комментарий cmt, размер последовательности и ее элементы
function System.Collections.Generic.IEnumerable<TSource>.Show(cmt: string):
System.Collections.Generic.IEnumerable<TSource>;
begin
result := self;
var a := self.ToArray;
var s := '';
var t := '';
if a.Length > 0 then
t := a[0].GetType.Name;
if t = 'Double' then
if D > 0 then
s := '{0,0:f' + D + '}'
else
s := '{0,0:e}';
a.Show(cmt, e -> s = '' ? e.ToString() :
string.Format(s, e).Replace(',', '.'));
end;
/// Выводит в разделе отладки окна задачника
/// размер последовательности и ее элементы.
function System.Collections.Generic.IEnumerable<TSource>.Show():
System.Collections.Generic.IEnumerable<TSource>;
begin
result := self.Show('');
end;
// == Конец дополнений к версии 4.14 ==
initialization
__InitModule;
finalization
__FinalizeModule__;
end.