Форум: "Прочее";
Текущий архив: 2016.05.01;
Скачать: [xml.tar.bz2];
ВнизГоловоломка выходного дня. Найти похожие ветки
← →
Sha © (2015-08-14 23:58) [0]Предположим, что разработчики Delphi вместо замечательного типа TDateTime
придумали тип TDayTime, который в int64-переменной хранит неотрицательное время
в битовом представлении в формате дни:часы:минуты:секунды следующим образом:
dddd dddd dddd dddd dddd dddd dddd dddd dddd dddd dddd dddh hhhh mmmm mmss ssss
Требуется без использования операций деления-умножения написать процедуры:
procedure DayTimeAdd(p1, p2, p3: PDayTime); //p3^:=p1^+p2^
function DayTimeSub(p1, p2, p3: PDayTime): boolean; //p3^:=abs(p1^-p2^); result:=(p1>p2)
← →
Sha © (2015-08-15 00:43) [1]Ах, да, забыл самое главное.
Побеждает решение с минимальным количеством операторов.
Включая и IFы и их внутренности.
← →
NoUser © (2015-08-15 21:20) [2]
// 30-строчек кода: 4-сложения, 4-вычитания, 10-сравнений( 3-или, 12-масок ) .
← →
Dennis I. Komarov © (2015-08-15 21:37) [3]Не умные программисты такое придумали - это еще и валидность значения каждый раз проверять надо...
DayTimeToStr($3F)?
← →
NoUser © (2015-08-15 21:58) [4]> валидность значения каждый раз проверять надо
так оно везде так, в этом суровом мире ))
TFloatSpecial = ( ...., fsDenormal, fsNDenormal, .... fsInf, fsNInf, fsNaN );
DateTimeToStr( NaN )?
← →
Sha © (2015-08-15 23:07) [5]> NoUser © (15.08.15 21:20) [2]
есть вариант попроще
← →
SergP © (2015-08-17 10:29) [6]
> Побеждает решение с минимальным количеством операторов.
>
> Включая и IFы и их внутренности.
c:=a+b;
это один оператор или два (сложение и присваивание)?
c:=a+b+c+d; - это сколько операторов?
← →
SergP © (2015-08-17 10:56) [7]
> procedure DayTimeAdd(p1, p2, p3: PDayTime); //p3^:=p1^+p2^
Если без всяких проверок валидности, то приблизительно (не проверял или будет правильно работать), должно быть так:
procedure DayTimeAdd(p1, p2, p3: PDayTime);
begin
p3:=p1+p2;
p3:=(((p3+$8104) xor p3 or $21040) shr 4 +$3000) and $4104+p3;
end;
хотя оно слишком мутное, могу и ошибаться...
← →
SergP © (2015-08-17 11:01) [8]не. там я явно ошибся...
вроде так правильнее:procedure DayTimeAdd(p1, p2, p3: PDayTime);
begin
p3:=p1+p2;
p3:=(((p3+$8104) xor p3 or $21040) shr 4 +$6000) and $8104+p3;
end;
← →
SergP © (2015-08-17 12:10) [9]не. вроде нифига не правильно
← →
SergP © (2015-08-17 12:20) [10]
procedure DayTimeAdd(p1, p2, p3: PDayTime);
begin
p3:=p1+p2;
p3:=(((p3+$8104) xor p1 xor p2 or $21040) shr 4 +$6000) and $8104+p3;
end;
← →
SergP © (2015-08-17 13:08) [11]Вроде так: (без проверок на валидность исходных данных)
procedure DayTimeAdd(p1, p2, p3: TDayTime);
begin
p3:=p1+p2;
p3:=(((p3+$8104) xor p1 xor p2 or $21040) shr 4 +$6000) and $8104+p3;
end;
function DayTimeSub(p1, p2, p3: TDayTime): boolean;
result:=p1>p2;
DayTimeAdd(p1, $80c4-p2, p3);
end;
Если с указателями, то хз, иногда путаюсь с ними:procedure DayTimeAdd(p1, p2, p3: PDayTime);
begin
p3^:=p1^+p2^;
p3^:=(((p3^+$8104) xor p1^ xor p2^ or $21040) shr 4 +$6000) and $8104+p3^;
end;
function DayTimeSub(p1, p2, p3: PDayTime): boolean;
result:=p1^>p2^;
DayTimeAdd(p1, @($80c4-p2^), p3);
end;
← →
SergP © (2015-08-17 13:12) [12]
> procedure DayTimeAdd(p1, p2, p3: TDayTime);
> begin
> p3:=p1+p2;
> p3:=(((p3+$8104) xor p1 xor p2 or $21040) shr 4 +$6000)
> and $8104+p3;
> end;
>
> function DayTimeSub(p1, p2, p3: TDayTime): boolean;
> result:=p1>p2;
> DayTimeAdd(p1, $80c4-p2, p3);
> end;
Опять ошибка, не $80c4, а -$80c4procedure DayTimeAdd(p1, p2, p3: TDayTime);
begin
p3:=p1+p2;
p3:=(((p3+$8104) xor p1 xor p2 or $21040) shr 4 +$6000) and $8104+p3;
end;
function DayTimeSub(p1, p2, p3: TDayTime): boolean;
result:=p1>p2;
DayTimeAdd(p1, -$80c4-p2, p3);
end;
← →
SergP © (2015-08-17 13:13) [13]М-да... Ну и нафлудил я тут ))))
← →
Sha © (2015-08-17 13:45) [14]Во-первых хочу исправить небольшую неточность в условии:
при вычитании функция должна возвращать result:=(p1>=p2), а не result:=(p1>p2).
> SergP
Немного подправил функции, чтобы они компилировались:procedure DayTimeAddSergP(p1, p2, p3: pint64);
begin
p3^:=p1^+p2^;
p3^:=(((p3^+$8104) xor p1^ xor p2^ or $21040) shr 4 +$6000) and $8104+p3^;
end;
function DayTimeSubSergP(p1, p2, p3: pint64): boolean;
var
tmp: int64;
begin
result:=p1^>=p2^;
tmp:=-$80c4-p2^;
DayTimeAddSergP(p1, @tmp, p3);
end;
Обе функции тест провалили. Тест не исчерпывающий, но достаточно полный:procedure TForm1.Button3Click(Sender: TObject);
var
d1, h1, m1, s1: integer;
d2, h2, m2, s2: integer;
d3, h3, m3, s3: integer;
i1, i2: integer;
t1, t2, t3: integer;
v1, v2, v3: integer;
x1, x2, x3: int64;
begin;
for i1:=0 to $1FFF do begin;
d1:=i1 shr 12; t1:=d1 shl 17; v1:= d1 * (60*60*24);
h1:=i1 shr 8 and 15; h1:=h1 + h1 and 8; t1:=t1 or h1 shl 12; v1:=v1 + h1 * (60*60);
m1:=i1 shr 4 and 15; if m1>7 then m1:=m1+44; t1:=t1 or m1 shl 6; v1:=v1 + m1 * 60;
s1:=i1 and 15; if s1>7 then s1:=s1+44; t1:=t1 or s1; v1:=v1 + s1;
for i2:=0 to $1FFF do begin;
d2:=i2 shr 12; t2:=d2 shl 17; v2:= d2 * (60*60*24);
h2:=i2 shr 8 and 15; h2:=h2 + h2 and 8; t2:=t2 or h2 shl 12; v2:=v2 + h2 * (60*60);
m2:=i2 shr 4 and 15; if m2>7 then m2:=m2+44; t2:=t2 or m2 shl 6; v2:=v2 + m2 * 60;
s2:=i2 and 15; if s2>7 then s2:=s2+44; t2:=t2 or s2; v2:=v2 + s2;
x1:=t1;
x2:=t2;
DayTimeAdd(@x1, @x2, @x3);
t3:=x3;
d3:=t3 shr 17; v3:= d3 * (60*60*24);
h3:=t3 shr 12 and $1f; v3:=v3 + h3 * (60*60);
m3:=t3 shr 6 and $3f; v3:=v3 + m3 * 60;
s3:=t3 and $3f; v3:=v3 + s3;
if v3<>v1+v2 then begin;
Memo1.Lines.Add(Format("%d %d %d %d",[d1,h1,m1,s1]));
Memo1.Lines.Add(Format("%d %d %d %d",[d2,h2,m2,s2]));
Memo1.Lines.Add(Format("%d %d %d %d",[d3,h3,m3,s3]));
Memo1.Lines.Add("failed");
exit;
end;
end;
end;
Memo1.Lines.Add("done")
end;
procedure TForm1.Button4Click(Sender: TObject);
var
d1, h1, m1, s1: integer;
d2, h2, m2, s2: integer;
d3, h3, m3, s3: integer;
i1, i2: integer;
t1, t2, t3: integer;
v1, v2, v3: integer;
x1, x2, x3: int64;
res: boolean;
begin;
for i1:=0 to $1FFF do begin;
d1:=i1 shr 12; t1:=d1 shl 17; v1:= d1 * (60*60*24);
h1:=i1 shr 8 and 15; h1:=h1 + h1 and 8; t1:=t1 or h1 shl 12; v1:=v1 + h1 * (60*60);
m1:=i1 shr 4 and 15; if m1>7 then m1:=m1+44; t1:=t1 or m1 shl 6; v1:=v1 + m1 * 60;
s1:=i1 and 15; if s1>7 then s1:=s1+44; t1:=t1 or s1; v1:=v1 + s1;
for i2:=0 to $1FFF do begin;
d2:=i2 shr 12; t2:=d2 shl 17; v2:= d2 * (60*60*24);
h2:=i2 shr 8 and 15; h2:=h2 + h2 and 8; t2:=t2 or h2 shl 12; v2:=v2 + h2 * (60*60);
m2:=i2 shr 4 and 15; if m2>7 then m2:=m2+44; t2:=t2 or m2 shl 6; v2:=v2 + m2 * 60;
s2:=i2 and 15; if s2>7 then s2:=s2+44; t2:=t2 or s2; v2:=v2 + s2;
x1:=t1;
x2:=t2;
res:=DayTimeSubSergP(@x1, @x2, @x3);
t3:=x3;
d3:=t3 shr 17; v3:= d3 * (60*60*24);
h3:=t3 shr 12 and $1f; v3:=v3 + h3 * (60*60);
m3:=t3 shr 6 and $3f; v3:=v3 + m3 * 60;
s3:=t3 and $3f; v3:=v3 + s3;
if (res<>(v1>=v2)) or (v3<>abs(v1-v2)) then begin;
Memo1.Lines.Add(Format("%d %d %d %d",[d1,h1,m1,s1]));
Memo1.Lines.Add(Format("%d %d %d %d",[d2,h2,m2,s2]));
Memo1.Lines.Add(Format("%d %d %d %d",[d3,h3,m3,s3]));
Memo1.Lines.Add("failed");
exit;
end;
end;
end;
Memo1.Lines.Add("done")
end;
← →
SergP © (2015-08-17 14:03) [15]Эх. не получилось написать не используя компилятор.... пришлось запускать Delphi
В первой функции нашел ошибку:
там вместо or нужно andprocedure DayTimeAddSergP(p1, p2, p3: pint64);
begin
p3^:=p1^+p2^;
p3^:=((((p3^+$8104) xor p1^ xor p2^) and $21040) shr 4 +$6000) and $8104+p3^;
end;
со второй пока думаю
← →
SergP © (2015-08-17 14:09) [16]Вторая функция обязана передавать в p3 корректный результат, если ее значение false?
← →
SergP © (2015-08-17 14:14) [17]Насчет [16], дело в том, что немного подправил вторую функцию:
function DayTimeSubSergP(p1, p2, p3: pint64): boolean;
var
tmp: int64;
begin
result:=p1^>=p2^;
tmp:=-$8104-p2^;
DayTimeAddSergP(p1, @tmp, p3);
end;
Но тест все равно ее фейлит таким образом:
0 0 0 0
0 0 0 1
32767 23 59 59
failed
← →
Sha © (2015-08-17 14:14) [18]> SergP © (17.08.15 14:09) [16]
Да, но в этом случае результат должен быть как если бы из p2 вычитали p1.
← →
Sha © (2015-08-17 14:18) [19]Sha © (17.08.15 14:14) [18]
т.е. если false, то надо получить p3=p2-p1
← →
SergP © (2015-08-17 14:27) [20]ну в таком случае получается:
procedure DayTimeAddSergP(p1, p2, p3: pint64);
begin
p3^:=p1^+p2^;
p3^:=((((p3^+$8104) xor p1^ xor p2^) and $21040) shr 4 +$6000) and $8104+p3^;
end;
function DayTimeSubSergP(p1, p2, p3: pint64): boolean;
var
tmp: int64;
begin
result:=p1^>=p2^;
tmp:=-$8104-p2^;
DayTimeAddSergP(p1, @tmp, p3);
if not result then p3^:=-$8104-p3^;
end;
← →
SergP © (2015-08-17 14:40) [21]Ну если не объявлять дополнительную переменную, то можно немного сократить код по количеству строк, хотя количество операторов от этого не изменится:
procedure DayTimeAddSergP(p1, p2, p3: pint64);
begin
p3^:=p1^+p2^;
p3^:=((((p3^+$8104) xor p1^ xor p2^) and $21040) shr 4 +$6000) and $8104+p3^;
end;
function DayTimeSubSergP(p1, p2, p3: pint64): boolean;
begin
result:=p1^>=p2^;
p2^:=-$8104-p2^;
DayTimeAddSergP(p1, p2, p3);
if not result then p3^:=-$8104-p3^;
end;
← →
Sha © (2015-08-17 14:44) [22]> SergP © (17.08.15 14:27) [20]
Здорово.
А я не додумался до $6000:const
dtCarry = $00021040;
dtRest = $00008104;
procedure DayTimeAddSha(p1, p2, p3: PDayTime); //p3^:=p1^+p2^
var
delta: integer;
begin;
delta:=(p1.Lo xor p2.Lo xor (p1.Lo + p2.Lo + dtRest)) and dtCarry;
pInt64(p3)^:=(delta shr 4 or delta shr 2) and dtRest + pInt64(p1)^ + pInt64(p2)^;
end;
function DayTimeSubSha(p1, p2, p3: PDayTime): boolean; //p3^:=abs(p1^-p2^); result:=(p1>=p2)
var
delta: integer;
begin;
if pInt64(p1)^ >= pInt64(p2)^ then begin;
delta:=(p1.Lo xor p2.Lo xor (p1.Lo - p2.Lo)) and dtCarry;
pInt64(p3)^:=-((delta shr 4 or delta shr 2) and dtRest) + pInt64(p1)^ - pInt64(p2)^;
Result:=true;
end
else begin; //p1^ < p2^
delta:=(p2.Lo xor p1.Lo xor (p2.Lo - p1.Lo)) and dtCarry;
pInt64(p3)^:=-((delta shr 4 or delta shr 2) and dtRest) + pInt64(p2)^ - pInt64(p1)^;
Result:=false;
end;
end;
Получилось длиннее, потому что еще старался не потерять эффективность.
← →
Sha © (2015-08-17 14:46) [23]> SergP © (17.08.15 14:40) [21]
нет, так не надо, испортишь переданные данные
← →
Sha © (2015-08-17 14:47) [24]Sha © (17.08.15 14:44) [22]
потерялtype
PDayTime= ^Int64Rec;
← →
Sha © (2015-08-17 17:06) [25]В общем, вот что вышло в итоге:
type
PDayTime= ^Int64Rec;
const
dtCarry = $00021040;
dtRest = $00008104;
dtSergP = $00006000; //преобразует двухчасовую дельту к восьмичасовой
procedure DayTimeAdd(p1, p2, p3: PDayTime); //p3^:=p1^+p2^
var
delta: integer;
begin;
delta:=((p1.Lo xor p2.Lo xor (p1.Lo + p2.Lo + dtRest)) and dtCarry shr 4 + dtSergP) and dtRest;
pInt64(p3)^:=delta + pInt64(p1)^ + pInt64(p2)^;
end;
function DayTimeSub(p1, p2, p3: PDayTime): boolean; //p3^:=abs(p1^-p2^); result:=(p1>=p2)
begin;
if pInt64(p1)^ >= pInt64(p2)^ then begin;
pInt64(p3)^:=-(((p1.Lo xor p2.Lo xor (p1.Lo - p2.Lo)) and dtCarry shr 4 + dtSergP) and dtRest) + pInt64(p1)^ - pInt64(p2)^;
Result:=true;
end
else begin; //p1^ < p2^
pInt64(p3)^:=-(((p1.Lo xor p2.Lo xor (p2.Lo - p1.Lo)) and dtCarry shr 4 + dtSergP) and dtRest) + pInt64(p2)^ - pInt64(p1)^;
Result:=false;
end;
end;
Результирующий ассемблерный код получился довольно эффективным.
> Dennis I. Komarov © (15.08.15 21:37) [3]
> это еще и валидность значения каждый раз проверять надо...
Зачем проверять? Оно всегда валидно, если не портить.
Для пущей красивости можно добавить функции вроде IncDayTimeBySeconds.
← →
SergP © (2015-08-17 18:07) [26]
> Результирующий ассемблерный код получился довольно эффективным.
К сожалению почти никогда не интересовался эффективностью кода, который создает компилятор. Посему может и фигню спрошу,
но точки зрения эффективности не будет ли такое лучше: (типа на 1 операцию меньше) ?procedure DayTimeAdd(p1, p2, p3: PDayTime); //p3^:=p1^+p2^
var
delta: integer;
begin;
pInt64(p3)^:= pInt64(p1)^ + pInt64(p2)^;
delta:=((p1.Lo xor p2.Lo xor (p3.Lo + dtRest)) and dtCarry shr 4 + dtSergP) and dtRest;
Inc(pInt64(p3)^,delta);
end;
← →
Sha © (2015-08-17 18:33) [27]> SergP © (17.08.15 18:07) [26]
Думаю, что будет примерно одинаково, т.к. в обоих случаях мы имеем цепочку последовательных зависимых вычислений. Хотя я склоняюсь к первому варианту, т.к. он меньше изменяет память и короче (количество ассемблерных инструкций 11+8<12+10+4).
← →
SergP © (2015-08-17 19:01) [28]Хм. А почeму это:
pInt64(p3)^:=delta + pInt64(p1)^ + pInt64(p2)^; 8 инструкций
а
pInt64(p3)^:= pInt64(p1)^ + pInt64(p2)^; 12 инструкций
?
← →
NoUser © (2015-08-17 19:12) [29]сложение не прошло тест - пока только вычитание
const
cSm = $3F;
cMm = $0FC0;
cHm = $0001F000;
cSa = $04;
cMa = $0100;
cHa = $8000;
cSx = $3B;
cMx = $0EC0;
cHx = $00017000;
function DayTimeSub(a, b, c :PDayTime) :Boolean;
begin
if ( a^ >= b^ ) then
begin
c^ := a^ - b^;
if ( ((c^ and cSm) > cSx) or ( (a^ and cSm) < (b^ and cSm) ) ) then Dec(c^, cSa);
if ( ((c^ and cMm) > cMx) or ( (a^ and cMm) < (b^ and cMm) ) ) then Dec(c^, cMa);
if ( ((c^ and cHm) > cHx) or ( (a^ and cHm) < (b^ and cHm) ) ) then Dec(c^, cHa);
Result := True ;
end
else Result :=( not DayTimeSub(b, a, c) );
end;
← →
Sha © (2015-08-17 19:13) [30]> SergP © (17.08.15 19:01) [28]
это оптимизатор чудит, по идее там достаточно 6, а не 12 инструкций
← →
Sha © (2015-08-17 19:20) [31]> NoUser © (17.08.15 19:12) [29]
а будет ли разность вычислена правильно,
если ее адрес совпадает с адресом уменьшаемого или вычитаемого?
← →
Sha © (2015-08-17 20:58) [32]>NoUser © (17.08.15 19:12) [29]
усилил тест дополнительными проверками
procedure TForm1.Button4Click(Sender: TObject);
var
d1, h1, m1, s1: integer;
d2, h2, m2, s2: integer;
d3, h3, m3, s3: integer;
i1, i2: integer;
t1, t2, t3: integer;
v1, v2, v3: integer;
x1, x2, x3: int64;
error: integer;
res: boolean;
begin;
for i1:=0 to $1FFF do begin;
d1:=i1 shr 12; t1:=d1 shl 17; v1:= d1 * (60*60*24);
h1:=i1 shr 8 and 15; h1:=h1 + h1 and 8; t1:=t1 or h1 shl 12; v1:=v1 + h1 * (60*60);
m1:=i1 shr 4 and 15; if m1>7 then m1:=m1+44; t1:=t1 or m1 shl 6; v1:=v1 + m1 * 60;
s1:=i1 and 15; if s1>7 then s1:=s1+44; t1:=t1 or s1; v1:=v1 + s1;
for i2:=0 to $1FFF do begin;
d2:=i2 shr 12; t2:=d2 shl 17; v2:= d2 * (60*60*24);
h2:=i2 shr 8 and 15; h2:=h2 + h2 and 8; t2:=t2 or h2 shl 12; v2:=v2 + h2 * (60*60);
m2:=i2 shr 4 and 15; if m2>7 then m2:=m2+44; t2:=t2 or m2 shl 6; v2:=v2 + m2 * 60;
s2:=i2 and 15; if s2>7 then s2:=s2+44; t2:=t2 or s2; v2:=v2 + s2;
x1:=t1;
x2:=t2;
res:=DayTimeSub(@x1, @x2, @x3);
t3:=x3;
d3:=t3 shr 17; v3:= d3 * (60*60*24);
h3:=t3 shr 12 and $1f; v3:=v3 + h3 * (60*60);
m3:=t3 shr 6 and $3f; v3:=v3 + m3 * 60;
s3:=t3 and $3f; v3:=v3 + s3;
error:=0;
if (res<>(v1>=v2)) or (v3<>abs(v1-v2)) or (h3>=24) or (m3>=60) or (s3>=60)
then error:=3
else begin;
x1:=t1;
x2:=t2;
if (res<>DayTimeSub(@x1, @x2, @x2)) or (x3<>x2) then begin;
x3:=x2;
error:=2;
end
else begin;
x1:=t1;
x2:=t2;
if (res<>DayTimeSub(@x1, @x2, @x1)) or (x3<>x1) then begin;
x3:=x1;
error:=1;
end;
end;
if error<>0 then begin;
t3:=x3;
d3:=t3 shr 17;
h3:=t3 shr 12 and $1f;
m3:=t3 shr 6 and $3f;
s3:=t3 and $3f;
end;
end;
if error<>0 then begin;
Memo1.Lines.Add(Format("%d %d %d %d",[d1,h1,m1,s1]));
Memo1.Lines.Add(Format("%d %d %d %d",[d2,h2,m2,s2]));
Memo1.Lines.Add(Format("%d %d %d %d",[d3,h3,m3,s3]));
Memo1.Lines.Add(Format("failed %d",[error]));
exit;
end;
end;
end;
Memo1.Lines.Add("done")
end;
после этого DayTimeSubNoUser проваливает тест:
0 0 0 1
0 0 0 1
32767 23 59 60
failed 1
← →
NoUser © (2015-08-17 23:05) [33]> после этого DayTimeSubNoUser проваливает тест:
Значит DayTimeSubNoUser было тестом для теста ))
← →
SergP © (2015-08-18 05:10) [34]
> Sha © (17.08.15 19:13) [30]
>
> > SergP © (17.08.15 19:01) [28]
>
> это оптимизатор чудит, по идее там достаточно 6, а не 12
> инструкций
вот, кстати интересно, а как компилятор соптимизирует такое:
a:=b-c;
if a=0 then ...
по идее после a:=b-c операцию сравнения не нужно делать, ибо флаги и так будут выставленны должным образом...
← →
Sha © (2015-08-18 10:11) [35]> SergP © (18.08.15 05:10) [34]
насколько знаю, Delphi сравнивает
← →
DayGaykin © (2015-08-18 16:43) [36]
> вместо замечательного типа TDateTime
Как по моему, так не очень и замечательный.
← →
Sha © (2015-08-19 01:04) [37]Нашел один вариант решения:
const
dtCarry = $00021040;
dtMagic = 8667136;
dtDeltas: array[0..7] of integer= (0, $4, $100, $104, $8000, $8004, $8100, $8104);
procedure DayTimeAdd(p1, p2, p3: PDayTime); //p3^:=p1^+p2^
var
delta: integer;
begin;
delta:=dtDeltas[(p1.Lo xor p2.Lo xor (p1.Lo + p2.Lo + dtRest)) and dtCarry * dtMagic shr 29];
pInt64(p3)^:=delta + pInt64(p1)^ + pInt64(p2)^;
end;
Замечательной особенностью этого варианта является то,
что он годится и для формата времени с миллисекундами,
меняется только магия.
← →
SergP © (2015-08-20 09:33) [38]
> Sha © (19.08.15 01:04) [37]
Угу. Вроде так получается более универсально... Но первоначальному заданию не соответствует:
> Требуется без использования операций деления-умножения написать
> процедуры:
Кстати, давай еще какие-нить задачи-головоломки, а то в последние годы тут как-то скучновато.
Страницы: 1 вся ветка
Форум: "Прочее";
Текущий архив: 2016.05.01;
Скачать: [xml.tar.bz2];
Память: 0.57 MB
Время: 0.003 c