Если у Вас подразумевается серьезная работа с переборами в стиле брутфорса, тогда нужно действительно озаботиться оптимизацией, забыть о функциональном программировании и делать все на циклах. А еще лучше - реализовать это на С++, поскольку PascalABC.NЕТ никогда не позиционировался, как язык, дающий высокую степень оптимизации программ по времени исполнения.
Ну вот, хотел вспомнить как подвести две схожие функции под общую основу и снова получил замечания про анти-паттерны и совет писать на другом языке) Дело в том, что многое уже давно было реализовано на TP5+, но либо потерялось и устарело, либо опиралось на asm/inline, поэтому PABC.NEТ как раз подходит как по многообразию сути и формы написания, так и по требованиям памяти/скорости
Нельзя тут дать какой-то рецепт, если нет текста функций. В Fortran было хулиганство - определение точек входа в программные единицы. Т.е. пишутся отдельные Entry, а еще есть общая часть, реализующая общий же алгоритм. Но это идеология 70-х годов, почти полвека прошло, сейчас все иначе решается. Может, Вам проще сделать класс и там прописать какие-то методы. Надо смотреть тексты. И задачу саму. А то, быть может, на деле это художество и не нужно, а практичнее так и оставить две функции. Просто будут две функции с одним именем и разным набором параметров. И будет выбираться нужная автоматом.
- Попробовал пример не из PABC.NEТ для динамического парсинга Linq переписать на PABC.NEТ, но сразу застрял на неймспейсе:
uses System.Linq;
{$reference System.Linq.Dynamic} // <-- АшЫпка!
begin
var expression: string := '14 + 3 / 7';
var func := System.Linq.Dynamic.DynamicExpression.ParseLambda(new ParameterExpression[0], typeof(double), expression).Compile();
print(func);
end.
А сборки 3.5 и выше вроде должны держать, куда копать?
-
Есть ли эквивалент или альтернатива старым директивам компилятора $I filename / $R filename, чтобы итого всё было в едином файле? Может какой-то Any2bin?
-
Также в связи с подгрузкой значительного кол-ва внешних ресурсов (графика, звуки), чтобы не переизобретать, интересует рекомендуемый способ управления такими ресурсами (например, архив)
Спс
А .dll
кто съел?
$reference
прописывается не для неймспейсов а для библиотек, то есть .dll
файлов. При этом в библиотеке может быть любое кол-во неймспейсов.
Можно использовать неймспейсы. Правда, придётся отлавливать много багов, и анализатор кода для них всё ещё не сделали.
Так же никто не запрещал вам найти чью то библиотеку в интернете.
На PABC нашёл пример OGL, но нет примеров [managed] DirectX. Подскажите, где глянуть и нужно ли какую-то SDK/библиотечку качать
Я пробовал SharpDX. Не сильно далеко продвинулся, хотя скоро понадобится. В общем найдёте хороший туториал по нему или что то типа того - напишите пожалуйста.
Задача: есть свёрнутое приложение-таймер, которое ожидает нажатие клавиши “Win” вместе с последующими цифрами. Например, удержание “Win” и нажатие “1” и “5” устанавливает таймер программы на 15 минут, не активируя форму. Так как .Net прямо не поддерживает глобальные хуки, думал через RegisterHotKey или API подыскать, но слишком много горячих клавиш получается…
Я всегда использую GetKeyState
и не парюсь. У меня даже уже есть таймер (потому что без него у меня на плите всегда всё сгорает).
Правда, ввод устроен по другому, чтоб поставить на 15 мин - надо ввести 0:15
. А чтоб ещё на 30 сек - 0:15:30
. После этого консоль пропадает, но в любой момент можно нажать Ctrl+A и она появится снова (чтоб проверить сколько осталось).
Работает это всё криво (особенно FreeConsole
глючно визуально работает, но хоть не ломает ничего), потому что я его заменить собираюсь (когда BH будет работать). Но вам оттуда нужна строчка:
while ks.All(kk->GetKeyState(kk) shr 7 = $01) do
Это ожидание нажатия всех клавишь, номера которых хранятся в ks
. Ещё, наверное, поможет WK.pas, чтоб узнавать номера каждой клавиши.
Ну и напоследок - ИМХО, но делать всё в бекграунд режиме, без каких то обозначений, или хотя бы писка System.Console.Beep
после успешного ввода - это прямо просьба получить неприятности на 5 точку. Всегда что то может пойти не так. Вот я для этого сделал более простой ввод и возможность проверить, идёт ли таймер нормально.
Надо попробовать, чтобы не из пушки по воробьям)
Без активации формы не значит без feedback вообще: beep на каждом подтверждённом вводе и оглашение итога Text-To-Speech.
Почему так не работает, обобщенный тип для записи
type
PNode = ^TNode<T>;
TNode<T> = record
data: T;
next: PNode;
end;
begin
var p: PNode;
New(p);
p^.data := 'Hello';
Writeln(p^.data)
end.
А шаблонный параметр T
в выражении TNode<T>
откуда брать должно?
type
PNode<T> = ^TNode<T>;
TNode<T> = record
data: T;
next: PNode<T>;
end;
begin
var p: PNode<byte>;
New(p);
p^.data := 'Hello';
Writeln(p^.data)
end.
Так, конечно, другая проблема, потому что New
не работает…
Получается нельзя?
Ну, криво но можно:
type
PNode<T> = ^TNode<T>;
TNode<T> = record
data: T;
next: PNode<T>;
end;
procedure OtherNew<T>(var ptr: ^T);
begin
var a: T;
ptr := System.Runtime.InteropServices.Marshal.AllocHGlobal(
System.Runtime.InteropServices.Marshal.SizeOf(a)
).ToPointer;
end;
begin
var p: PNode<byte>;
OtherNew(p);
p^.data := 5;
Writeln(p^.data)
end.
Marshal.AllocHGlobal
использует и стандартное New()
:
Program.@new((void*&) @numPtr, Marshal.SizeOf(typeof (byte)));
public static unsafe void @new(ref void* ptr, int size)
{
ptr = (void*) Marshal.AllocHGlobal(size);
Marshal.Copy(new byte[size], 0, (IntPtr) ptr, size);
}
( New()
это синтаксический сахар, поэтому то что кол-во параметров не совпадает это норма)
Но, Marshal.SizeOf
не работает для шаблонных типов. Надо чтоб была переменная (как у меня - переменная a
в OtherNew
), чтоб вычислить размер. То есть для этого надо выделить лишнюю память. Хотя, в данном случае это на стеке, так что я не уверен имеет ли это хоть какое то влияние…
@Admin, может добавите такое new()
для указателей на шаблонные записи? Всё же лучше, если хоть как то работать будет. Может, с предупреждением.
С Наступившими и Наступающими! (и сессия – всегда праздник алсо!)
Думал, что нюансы будут разве что со stringbuilder, однако так и не нашёл пример функции заточенной под .Net для удобной генерации случайной строки, чтобы можно сразу указать алфавит и длину:
var name:=randomstr('[A-Za-z0-9]',15);
Вроде указывать алфавит через строку - старый (не наш) метод, через диапазоны подобно set of char не очень подходит, т.к. придётся кидать в промежуточный массив, а вот RegEx кажется получше, не?
Либо невнимательно смотрел, либо немного странно, что подобной функции нет в базовой библиотеке PABC аналогично Random/Random2/Random3
Это ожидаемо. Я открою страшную пионерскую тайну: и готового примитива, формирующего целочисленные значения из нескольких диапазонов, тоже нет! Вроде randomint([-5…10,15…30],15). И вообще, страшно подумать, каких только хотелок нет в этом языке)))
Я вот хочу такой интерфейс, чтобы там была такая красивая кнопка, с надписью “Я - величайший программист!”, чтобы щелкнул ее - и сразу окошко раскрывается, а там указываешь реквизиты своего банковского счета и тебе туда - бабах - $1000 за каждый клик падает! ))) Ну вот такая новогодняя хотелка…
@Алекс, и вас с Новогодними) Суть не в невозможном или чрезмерном, а в том как правильно именно для .NET, ведь можно через строку/массивы и комбинировать даже случайные файлы/контент. В общем, для обучающих задач авто/пре/генерация довольно-таки полезная штука, а если чуть серьёзнее, вы относительно правы касательно того же Range.
Спасибо)) Я всего лишь о том, что в свое время пытался обосновать разработчикам свою позицию относительно нехватки различных примитивов. На что мне было сказано насчет принципа разумной достаточности.
Допустим, что несмотря на наличие подобных функций, в базовой библиотеке такое хотя полезно, но не самое главное. Однако какой правильный/одобренный пример для .NET? - вот в чём вопрос.
Строки устроены в .Net так, что нельзя сначала выделить под строку память а потом заполнять. Поэтому надо сначала выделить память, в каком то виде, а затем уже создавать строку, которая будет содержать копию этого участка памяти.
2 лучших способа создать строку - это массивом (у строк есть конструктор для этого) и стринг билдером. Массивом само собой разумеется, а вот стринг билдером:
function RandStr(l: integer; params chars: array of char): string;
begin
var res := new StringBuilder(l);
loop l do res += chars[Random(chars.Length)];
Result := res.ToString;
end;