Книга адресована школьникам средних и старших классов, желающим испытать себя в «олимпийских схватках». Может быть полезна студентам-первокурсникам и преподавателям информатики.
function PassWord_3: string; var S: string; { результат } v: integer; { вариант очередного символа } C: char; { очередной символ } begin S:=''; v:= Random(3); while Length(S)<8+Random(5) do begin case v of 0: C:= Char(Random(10)+Ord('0')); 1: C:= Char(Random(26)+Ord('a')); 2: C:= Char(Random(26)+Ord('A')); end; S:= S+C; v:= (v+1+Random(2)) mod 3; end; PassWord_3:=S; end;
Ну очень интересно, сколько времени ушло на то, чтобы найти эту формулу.
Пара минут, наверное. Вы и сами скоро этому научитесь, а логика такова. Имеем исходное число V, значение которого лежит в диапазоне 0..2 (0, 1, 2). Из него случайным образом надо получить другое число в этом же диапазоне. Это можно сделать прибавлением любого числа, не кратного трём (ноль прибавлять не имеет смысла). Стало быть, имеет смысл прибавить либо 1, либо 2 (либо 4, 5, 7, 8 …). Отсюда выражение 1+Random(2). Разумеется, после сложения результат может оказаться больше 2, поэтому берём остаток от деления на 3.
Добавлено спустя 19 часов 37 минут 1 секунду: Вот ещё один вариант решения той же проблемы: сформировать случайное число, отличное от текущего значения V: var V, N : integer; . . . repeat N:= Random(3) until N<>V; V:= N; ----- Кстати, в нашей Галактике нередко случаются задачи, в которых надо формировать псевдо-случайные числа или их последовательности в соответствии с некоторыми требованиями. Например, сгенерировать случайное число, принадлежащее некоторому множеству S: repeat N:= Random(100) until N in S; Или не принадлежащее ему: repeat N:= Random(100) until not (N in S);
В этой связи предлагаю всем желающим задачу: написать процедуру, выводящую на экран при каждом своём вызове группу из пяти чисел в диапазоне 0..99 так, чтобы числа следовали по возрастанию (или по убыванию). Например: 1) 18 31 40 90 91 2) 6 7 54 70 81 3) 49 77 89 95 97 и т.д.
Первый вариант проверил -- работает. Но возникло сильное подозрение, что генерируемые числа чаще будут смещаться в бОльшую сторону. Из любопытства взялся проверить. Заодно проверил и свой вариант генерации такой последовательности. В представленной ниже программе формируется массив с плотностью распределения чисел в интервале 0..99. Для сокращения массива квант по оси X взят равным 5% (можно взять 2% или даже 1%). Вот код:
const Cu=100; { диапазон генерируемых чисел } Cn=5; { количество чисел в последовательности } Cq=5; { квант для массива = 5% } Cr=1000; { количество испытаний }
type TSet = set of byte; { массив для накопления результатов } TArr = array [0..Cu div Cq -1] of integer;
var Arr : TArr; { массив для накопления результатов }
{ Накопление результатов в массиве }
procedure AddToArray(const aSet: TSet); var i: integer; begin for i:=0 to 255 do begin if i in aSet then Inc(Arr[i div Cq]); end; end;
{ Вывод массива в файл }
procedure ShowArray(var aFile: Text); var i: integer; pc : extended; begin for i:= 0 to Cu div Cq - 1 do begin pc:= 100*(Arr[i]/(Cr*Cn)); Writeln(aFile, i*Cq:2,'-',(i+1)*Cq-1:2, pc:5:1,' %'); end; end;
{ Генерация одной последовательности }
procedure _Bormant(var aSet: TSet); var a, i: Integer; begin aSet:=[]; a:=-1; for i:=Cn-1 downto 0 do begin a:=a+1+Random(Cu-1-a-i); aSet:= aSet + [a]; end; end;
{ Генерация одной последовательности }
procedure _Oleg(var aSet: TSet); var i, n: integer; begin aSet:=[]; for i:=1 to Cn do begin repeat n:= Random(Cu) until not (n in aSet); aSet:= aSet +[n]; end; end;
var L: string; S: TSet; n: integer; F: Text; begin FillChar(Arr, SizeOf(Arr), 0); for n:= 1 to Cr do begin _Bormant(S); AddToArray(S); end; ShowArray(Output); Assign(F,'Bormant.txt'); Rewrite(F); ShowArray(F); Close(F); Writeln('- - - - - - - - - - - - - - -'); FillChar(Arr, SizeOf(Arr), 0); for n:= 1 to Cr do begin _Oleg(S); AddToArray(S); end; ShowArray(Output); Assign(F,'Oleg.txt'); Rewrite(F); ShowArray(F); Close(F); Readln; end.
Oleg_D, в условии не было ничего про распределение полученных 5 чисел Безусловно, отсортированные 5 чисел (использование множества в этом случае -- вариант сортировки подсчетом) без повторов из диапазона 0..99 распределены более равномерно, чем из сужающегося к концу интервала.