program SlnComp; {$APPTYPE CONSOLE} uses SysUtils, DateUtils; type TTestCase = procedure; procedure RunTest(Author: string; TestCase: TTestCase); var StartTime: TDateTime; EndTime: TDateTime; TimeSpan: double; begin WriteLn('Running solution by ', Author); StartTime := Now(); TestCase(); EndTime := Now(); TimeSpan := SecondSpan(StartTime, EndTime); WriteLn('Completed in ', FloatToStr(TimeSpan), ' seconds'); WriteLn; end; const MaxK = 20000; procedure TestKelm4; function DigitInfo(const k: LongInt): Char; var temp, curr, digit_len, digit_owner_number, digit_group: LongInt; digit_pred_group: LongInt; s: String; begin digit_group := 9; digit_pred_group := 0; digit_len := 1; temp := 9; while (k > digit_group) do begin inc(digit_len); temp := 9 * digit_len * round(exp(pred(digit_len) * ln(10))); digit_pred_group := digit_group; digit_group := temp + digit_group; end; digit_owner_number := (k - digit_pred_group - 1) div digit_len + 1; str(round(exp((digit_len - 1) * ln(10))) + digit_owner_number - 1, s); DigitInfo := s[k - (digit_pred_group + digit_len * (digit_owner_number - 1) + 1) + 1]; end; var i: integer; res: Char; begin for i := 1 to MaxK do res := DigitInfo(i); end; procedure TestHardcase; function GetDigit(k: integer): integer; var counter: integer; // счетчик натуральных чисел number: integer; // текущее разбираемое число needNewNumber: boolean; // флаг - "завершился ли разбор числа?" maxDecimalMask: integer; // максимальная маска десятичного разряда nextDecimalMask: integer; // maxDecimalMask * 10 decimalMask: integer; // текущая маска десятичного разряда procedure Init; begin counter := 0; maxDecimalMask := 1; nextDecimalMask := maxDecimalMask * 10; needNewNumber := true; end; function GetNextDigit: integer; var digit: integer; begin // получаем следующее натуральное число if needNewNumber then begin needNewNumber := false; inc(counter); number := counter; if (counter mod nextDecimalMask) = 0 then begin maxDecimalMask := nextDecimalMask; nextDecimalMask := maxDecimalMask * 10; end; // сбрасываем маску decimalMask := maxDecimalMask; end; // получаем число в разряде digit := number div decimalMask; number := number mod decimalMask; decimalMask := decimalMask div 10; // если маска нулевая, то мы разобрали число if decimalMask = 0 then needNewNumber := true; // возвращаем результат GetNextDigit := digit; end; var i: integer; digit: integer; begin Init; // тупо перебираем k-разрядов digit := 0; for i := 1 to k do digit := GetNextDigit; // возращаем результат GetDigit := digit; end; var i: integer; res: integer; begin for i := 1 to MaxK do res := GetDigit(i); end; procedure TestMalice; function test (x:longint): char; var i:longint; s:string; begin i:=0; repeat inc (i); str (i,s); if x<=length(s) then begin test:=s[x]; x:=0; end else x:=x-length(s); until x=0; end; var i: integer; res: Char; begin for i := 1 to MaxK do res := test(i); end; begin RunTest('kelm4', @TestKelm4); RunTest('hardcase', @TestHardcase); RunTest('Malice', @TestMalice); ReadLn; end.