Форум программистов, компьютерный форум, киберфорум
Наши страницы
C++ Builder
Войти
Регистрация
Восстановить пароль
 
Рейтинг 4.60/5: Рейтинг темы: голосов - 5, средняя оценка - 4.60
gunslinger
случайный прохожий
1290 / 812 / 319
Регистрация: 20.07.2013
Сообщений: 2,287
1

Тест Люка - Лемера

14.05.2015, 02:54. Просмотров 871. Ответов 12

Стало немного скучновато, решил разбавить обстановку.
Мат. часть: https://ru.wikipedia.org/wiki/%D0%A2...B5%D1%80%D0%B0 (и далее по ссылкам)
Функции (unsigned __int64 можно заменить на unsigned long long и ui64 на ull):
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
// нахождение остатка от деления на n числа number, возведенного в степень power
unsigned __int64 mod(unsigned __int64 number, unsigned int power, unsigned __int64 n)  // (number ^ power) % n
{
  unsigned __int64 res = 1;
  while (power)
  {
    if (power & 1)  // power % 2
      res = (1ui64 * res * number) % n;
    number = (1ui64 * number * number) % n;
    power >>= 1;  // power /= 2
  }
  return res;
}
//---------------------------------------------------------------------------
// тест Люка - Лемера
bool lucas_lehmer_test(unsigned int q)  // q - простое число, причем q > 2
{
  unsigned __int64 L = 4;  // возможные значения: 4, 10, 52, 724, 970, 10084, ...
  unsigned __int64 mersenne_number = (1ui64 << q) - 1;
  for (unsigned int i = 1; i <= q-2; i++)
  {
    L = mod(L, 2, mersenne_number);
    L += (L < 2) ? mersenne_number - 2 : -2;
  }
  return !L;
}
Пример вызова:
C++
1
2
3
4
5
6
7
  unsigned int q = 31;
  String res = "Число " + String((1ui64 << q) - 1);
  if (lucas_lehmer_test(q))
    res += " простое.";
  else
    res += " составное.";
  ShowMessage(res);
Программа (правильно) работает вплоть до q = 31 включительно (или 32, но в этом случае итоговый результат не меняется).
Результаты:
Число 2147483647 простое.
Далее идет переполнение (в функции mod) и получаются ошибочные результаты
при q = 61
Число 2305843009213693951 составное.
хотя число простое.
По сути остается лишь прикрутить длинную арифметику (как обычно в таких ситуациях).

Далее (при наличии квантового компьютера, иначе можно не дождаться) находим простое число, состоящее из 100 000 000+ десятичных цифр, получаем 150 000 баксов, радуемся жизни.
P.S.: можно "побаловаться", запустив Prime 95.
1
Миниатюры
Тест Люка - Лемера  
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
14.05.2015, 02:54
Ответы с готовыми решениями:

Тест Люка-Лемера для простых чисел
Добрый день. Нужно реализовать тест Люка-Лемера на C#. Вот ссылка на алгоритм:...

СМА BOSCH WOR 16153 OE крючок люка, разбор крышки люка (вертикалка)
Ребята, может кто знает технологию разбора крышки люка у BOSCH WOR 16153 OE с...

Сма Beko WML 15085 D, Не видит блокировку люка.., Не видит блокировку люка
Попала в ремонт СМА BEKO WML15085 D. Зависла на одной программе, блокирует...

Генератор вещественных случайных чисел по алгоритму Лемера
Добрый вечер форумчане. Надо найти площадь фигуры методом монте-карло. Есть...

Тест (Тест->Создать тест.->Модульный тест.)
есть нечто подобное в билдере ? или вообще программа создающая тесты и на VS и...

12
SatanaXIII
Супер-модератор
Эксперт С++
5773 / 2772 / 376
Регистрация: 01.11.2011
Сообщений: 6,744
Завершенные тесты: 1
14.05.2015, 09:08 2
Отлично. Теперь пишите распределенную систему - каждый киберфорумчанин установит себе по модулю вичислений и в уговоренное время запустит, чтобы посчитать все за пол часика плюс сетевые потери. Пятьдесят процентов гонорара на развитие форума, остальное себе.
0
gunslinger
случайный прохожий
1290 / 812 / 319
Регистрация: 20.07.2013
Сообщений: 2,287
14.05.2015, 12:04  [ТС] 3
Так давно уже все придумано: http://www.mersenne.org/ (не зря же я скрин программы приложил).
Видел где-то оценку, что потребуется примерно года 3 (с учетом высокого качества программы и количества участников).
Поэтому и упомянул про квантовый компьютер. Ту программу далеко не дурак писал (я тоже вроде не дурак, но до гения мне точно далеко), да и активных участников здесь гораздо меньше набралось бы.
Поэтому остается "пускать слюни". Хотя, если с помощью Prime 95 удастся получить результат, то непосредственному участнику какие-то дивиденды полагаются. Но главное - имя его останется в истории, что более ценно (на мой взгляд).
0
gunslinger
случайный прохожий
1290 / 812 / 319
Регистрация: 20.07.2013
Сообщений: 2,287
16.05.2015, 01:23  [ТС] 4
Используя bigint.zip (там всего два файла - cpp и h) отсюда, немного доработал программу.

cpp:
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
#include <vcl.h>
#pragma hdrstop
 
#include "Unit1.h"
//---------------------------------------------------------------------------
#pragma package(smart_init)
#pragma resource "*.dfm"
TForm1 *Form1;
//---------------------------------------------------------------------------
__fastcall TForm1::TForm1(TComponent* Owner)
    : TForm(Owner)
{
}
//---------------------------------------------------------------------------
// нахождение остатка от деления на n числа number, возведенного в степень power
BigInt mod(BigInt number, BigInt power, BigInt n)  // (number ^ power) % n
{
  BigInt res = 1;
  while (power > 0)
  {
    if ((power % 2) > 0)
      res = (res * number) % n;
    number = (number * number) % n;
    power /= 2;
  }
  return res;
}
//---------------------------------------------------------------------------
// тест Люка - Лемера
bool lucas_lehmer_test(BigInt q)  // q - простое число, причем q > 2
{
  BigInt L = 4;  // возможные значения: 4, 10, 52, 724, 970, 10084, ...
  BigInt mersenne_number = pow(2, q) - 1;
  BigInt temp = 0;
  for (BigInt i = 1; i <= q-2; i++)
  {
    L = mod(L, 2, mersenne_number);
    if (L < 2)
      temp = mersenne_number;
    L += temp - 2;
    Form1->GaugeProgress->Progress = StrToInt((Form1->GaugeProgress->MaxValue*i/(q-2)).toString().c_str());
    Application->ProcessMessages();
  }
  return (L == 0);
}
//---------------------------------------------------------------------------
void __fastcall TForm1::ButtonTestClick(TObject *Sender)
{
  LabelResult->Visible = 0;
  DWORD start = GetTickCount();
  String temp = EditPowerQValue->Text;
  if (temp == "" || StrToInt(temp) < 3)
    EditPowerQValue->Text = 3;
  BigInt q = AnsiString(EditPowerQValue->Text).c_str();
  MemoNumber->Text = String((pow(2, q) - 1).toString().c_str());
  String res = "число ";
  if (lucas_lehmer_test(q))
    res += " простое ";
  else
    res += " составное ";
  res += " (процесс занял ";
  res += FloatToStr((GetTickCount()-start)/1000.) + " сек)";
  LabelResult->Caption = res;
  LabelResult->Visible = 1;
}
//---------------------------------------------------------------------------
void __fastcall TForm1::EditPowerQValueKeyPress(TObject *Sender, System::WideChar &Key)
{
  if (Key == VK_RETURN)
    ButtonTest->Click();
}
h:
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
#ifndef Unit1H
#define Unit1H
//---------------------------------------------------------------------------
#include <System.Classes.hpp>
#include <Vcl.Controls.hpp>
#include <Vcl.StdCtrls.hpp>
#include <Vcl.Forms.hpp>
#include "bigint.cpp"
#include <Vcl.Samples.Gauges.hpp>
//---------------------------------------------------------------------------
class TForm1 : public TForm
{
__published:    // IDE-managed Components
    TButton *ButtonTest;
    TLabel *Label1;
    TEdit *EditPowerQValue;
    TLabel *Label2;
    TMemo *MemoNumber;
    TGauge *GaugeProgress;
    TLabel *LabelResult;
    TLabel *LabelHint;
    void __fastcall ButtonTestClick(TObject *Sender);
    void __fastcall EditPowerQValueKeyPress(TObject *Sender, System::WideChar &Key);
private:    // User declarations
public:     // User declarations
    __fastcall TForm1(TComponent* Owner);
};
//---------------------------------------------------------------------------
extern PACKAGE TForm1 *Form1;
//---------------------------------------------------------------------------
#endif
dfm:
Код
object Form1: TForm1
  Left = 0
  Top = 0
  BorderIcons = [biSystemMenu, biMinimize]
  BorderStyle = bsSingle
  Caption = #1058#1077#1089#1090' '#1051#1102#1082#1072' - '#1051#1077#1084#1077#1088#1072
  ClientHeight = 305
  ClientWidth = 544
  Color = clBtnFace
  Font.Charset = DEFAULT_CHARSET
  Font.Color = clWindowText
  Font.Height = -11
  Font.Name = 'Tahoma'
  Font.Style = []
  OldCreateOrder = False
  Position = poScreenCenter
  PixelsPerInch = 96
  TextHeight = 13
  object Label1: TLabel
    Left = 16
    Top = 40
    Width = 17
    Height = 39
    Caption = '2'
    Font.Charset = DEFAULT_CHARSET
    Font.Color = clWindowText
    Font.Height = -32
    Font.Name = 'Tahoma'
    Font.Style = []
    ParentFont = False
  end
  object Label2: TLabel
    Left = 167
    Top = 40
    Width = 92
    Height = 39
    Caption = ' - 1 = '
    Font.Charset = DEFAULT_CHARSET
    Font.Color = clWindowText
    Font.Height = -32
    Font.Name = 'Tahoma'
    Font.Style = []
    ParentFont = False
  end
  object GaugeProgress: TGauge
    Left = 16
    Top = 272
    Width = 513
    Height = 25
    ForeColor = clBlue
    Font.Charset = DEFAULT_CHARSET
    Font.Color = clWindowText
    Font.Height = -11
    Font.Name = 'Tahoma'
    Font.Style = []
    ParentFont = False
    Progress = 0
  end
  object LabelResult: TLabel
    Left = 16
    Top = 152
    Width = 233
    Height = 97
    Alignment = taCenter
    AutoSize = False
    Caption = #1095#1080#1089#1083#1086' '#1089#1086#1089#1090#1072#1074#1085#1086#1077' ('#1087#1088#1086#1094#1077#1089#1089' '#1079#1072#1085#1103#1083' 0 '#1089#1077#1082#1091#1085#1076')'
    Font.Charset = DEFAULT_CHARSET
    Font.Color = clWindowText
    Font.Height = -27
    Font.Name = 'Tahoma'
    Font.Style = []
    ParentFont = False
    Visible = False
    WordWrap = True
  end
  object LabelHint: TLabel
    Left = 167
    Top = 8
    Width = 92
    Height = 26
    AutoSize = False
    Caption = #1074#1074#1077#1076#1080#1090#1077' '#1087#1088#1086#1089#1090#1086#1077' '#1095#1080#1089#1083#1086' >2'
    Font.Charset = DEFAULT_CHARSET
    Font.Color = clWindowText
    Font.Height = -11
    Font.Name = 'Tahoma'
    Font.Style = []
    ParentFont = False
    WordWrap = True
  end
  object ButtonTest: TButton
    Left = 16
    Top = 96
    Width = 233
    Height = 33
    Caption = #1058' '#1045' '#1057' '#1058
    Font.Charset = DEFAULT_CHARSET
    Font.Color = clWindowText
    Font.Height = -21
    Font.Name = 'Tahoma'
    Font.Style = []
    ParentFont = False
    TabOrder = 1
    OnClick = ButtonTestClick
  end
  object EditPowerQValue: TEdit
    Left = 48
    Top = 8
    Width = 113
    Height = 47
    Font.Charset = DEFAULT_CHARSET
    Font.Color = clWindowText
    Font.Height = -32
    Font.Name = 'Tahoma'
    Font.Style = []
    NumbersOnly = True
    ParentFont = False
    ParentShowHint = False
    ShowHint = False
    TabOrder = 0
    OnKeyPress = EditPowerQValueKeyPress
  end
  object MemoNumber: TMemo
    Left = 265
    Top = 8
    Width = 264
    Height = 249
    Font.Charset = DEFAULT_CHARSET
    Font.Color = clWindowText
    Font.Height = -11
    Font.Name = 'Tahoma'
    Font.Style = []
    ParentFont = False
    ReadOnly = True
    ScrollBars = ssVertical
    TabOrder = 2
  end
end
Для проверки можно использовать в качестве показателя степени значения отсюда https://oeis.org/A000043.

Пример результата
Тест Люка - Лемера


для моего старого компа с 4ГБ оперативки
Тест Люка - Лемера


Если кому интересно, выкладываю exe (надеюсь, он не будет требовать библиотек; я люблю свой кривой билдер).
При желании можете попробовать протестировать.
0
Вложения
Тип файла: zip lucas_lehmer_test.zip (1.38 Мб, 11 просмотров)
gunslinger
случайный прохожий
1290 / 812 / 319
Регистрация: 20.07.2013
Сообщений: 2,287
16.05.2015, 03:55  [ТС] 5
P.S.: ссылка на источник в начала предыдущего поста должна быть такая http://sources.codenet.ru/download/4366/bigint.html.

И вот еще пара результатов:
получен за полчаса
Тест Люка - Лемера


получен за почти 1 час 37 минут
простое число:
Код
259117086013202627776246767922441530941818887553125427303974923161874019266586362086201209516800483406550695241733194177441689509238807017410377709597512042313066624082916353517952311186154862265604547691127595848775610568757931191017711408826252153849035830401185072116424747461823031471398340229288074545677907941037288235820705892351068433882986888616658650280927692080339605869308790500409503709875902119018371991620994002568935113136548829739112656797303241986517250116412703509705427773477972349821676443446668383119322540099648994051790241624056519054483690809616061625743042361721863339415852426431208737266591962061753535748892894599629195183082621860853400937932839420261866586142503251450773096274235376822938649407127700846077124211823080804139298087057504713825264571448379371125032081826126566649084251699453951887789613650248405739378594599444335231188280123660406262468609212150349937584782292237144339628858485938215738821232393687046160677362909315071
Тест Люка - Лемера
1
gunslinger
случайный прохожий
1290 / 812 / 319
Регистрация: 20.07.2013
Сообщений: 2,287
17.05.2015, 16:25  [ТС] 6
Немного "оптимизировал" программу. Заменил возведение в степень умножением в цикле (в принципе то же самое, но результат улучшился), отказался от функции mod в пользу вычисления остатка от деления "напрямую" (меньше операций, так как степень числа L в тесте постоянна и равна 2).
Скорость работы уменьшилась примерно в 2 раза.

Тест Люка - Лемера


cpp:
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
#include <vcl.h>
#pragma hdrstop
 
#include "Unit1.h"
//---------------------------------------------------------------------------
#pragma package(smart_init)
#pragma resource "*.dfm"
TForm1 *Form1;
//---------------------------------------------------------------------------
__fastcall TForm1::TForm1(TComponent* Owner)
    : TForm(Owner)
{
}
//---------------------------------------------------------------------------
BigInt mersenne_number;
//---------------------------------------------------------------------------
void TForm1::UpdateProgress(BigInt i, BigInt q)
{
  GaugeProgress->Progress = StrToInt((GaugeProgress->MaxValue*i/q).toString().c_str());
  Application->ProcessMessages();
}
//---------------------------------------------------------------------------
// тест Люка - Лемера
bool TForm1::lucas_lehmer_test(BigInt q)  // q - простое число, причем q > 2
{
  BigInt L = 4;  // возможные значения: 4, 10, 52, 724, 970, 10084, ...
 
  for (BigInt i = 1; i <= q-2; i++)
  {
    L = (L * L - 2) % mersenne_number;
    UpdateProgress(i, q-2);
  }
  return (L == 0);
}
//---------------------------------------------------------------------------
void __fastcall TForm1::ButtonTestClick(TObject *Sender)
{
  LabelResult->Visible = 0;
  DWORD start = GetTickCount();
  String temp = EditPowerQValue->Text;
  if (temp == "" || StrToInt(temp) < 3)
    EditPowerQValue->Text = 3;
  BigInt q = AnsiString(EditPowerQValue->Text).c_str();
 
//  mersenne_number = pow(2, q) - 1;
  mersenne_number = 1;
  for (BigInt i = 1; i <= q; ++i)
  {
    mersenne_number *= 2;
    UpdateProgress(i, q);
  }
  --mersenne_number;
 
  MemoNumber->Text = String(mersenne_number.toString().c_str());
  Caption = "Тест Люка - Лемера (кол-во цифр: " + String(MemoNumber->Text.Length()) + ")";
  String res = "число ";
 
  if (lucas_lehmer_test(q))
    res += " простое";
  else
    res += " составное";
 
  res += "\nпроцесс занял\n";
  DWORD diff = (GetTickCount()-start)/1000;
  res += String(diff/3600) + "ч : " + String(diff/60%60) + "м : " + String(diff%60) + "с";
  LabelResult->Caption = res;
  LabelResult->Visible = 1;
}
//---------------------------------------------------------------------------
void __fastcall TForm1::EditPowerQValueKeyPress(TObject *Sender, System::WideChar &Key)
{
  if (Key == VK_RETURN)
    ButtonTest->Click();
}
h:
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
#ifndef Unit1H
#define Unit1H
//---------------------------------------------------------------------------
#include <System.Classes.hpp>
#include <Vcl.Controls.hpp>
#include <Vcl.StdCtrls.hpp>
#include <Vcl.Forms.hpp>
#include "bigint.cpp"
#include <Vcl.Samples.Gauges.hpp>
//---------------------------------------------------------------------------
class TForm1 : public TForm
{
__published:    // IDE-managed Components
    TButton *ButtonTest;
    TLabel *Label1;
    TEdit *EditPowerQValue;
    TLabel *Label2;
    TMemo *MemoNumber;
    TGauge *GaugeProgress;
    TLabel *LabelResult;
    TLabel *LabelHint;
    void __fastcall ButtonTestClick(TObject *Sender);
    void __fastcall EditPowerQValueKeyPress(TObject *Sender, System::WideChar &Key);
private:    // User declarations
public:     // User declarations
    __fastcall TForm1(TComponent* Owner);
    void UpdateProgress(BigInt i, BigInt q);
    bool lucas_lehmer_test(BigInt q);
};
//---------------------------------------------------------------------------
extern PACKAGE TForm1 *Form1;
//---------------------------------------------------------------------------
#endif
Обнаружил (у себя) некоторые ограничения. При 7-значной (1257787) степени двойки число находится, но на тесте программа зависает (загружает одно ядро). Видимо оперировать таким большим числом не получается.
При 6-значной (216091) степени программа (долго, но) отрабатывает.
1
gunslinger
случайный прохожий
1290 / 812 / 319
Регистрация: 20.07.2013
Сообщений: 2,287
19.05.2015, 03:30  [ТС] 7
Заметил интересный момент.
C++
1
L = (L * L - 2) % mersenne_number;  // сложение и вычитание - "узкие" места (медленно работают)
Если в этом коде убрать вычитание, то скорость возрастет более чем в 3 раза.
Результаты, конечно, будут ошибочные, но сам факт...
То есть умножение и получение остатка от деления происходят быстрее, чем "простейшая" операция.
Третий тест на скрине отрабатывает уже много часов, дождаться не получится.
P.S.: постараюсь далее тему не поднимать "по всякой ерунде", пока не появится что-то стоящее (если появится).
1
Миниатюры
Тест Люка - Лемера  
SatanaXIII
Супер-модератор
Эксперт С++
5773 / 2772 / 376
Регистрация: 01.11.2011
Сообщений: 6,744
Завершенные тесты: 1
19.05.2015, 09:31 8
Цитата Сообщение от gunslinger Посмотреть сообщение
Если в этом коде убрать вычитание, то скорость возрастет более чем в 3 раза.
Результаты, конечно, будут ошибочные, но сам факт...
То есть умножение и получение остатка от деления происходят быстрее, чем "простейшая" операция.
Если убрать одну операцию, то их просто станет меньше, то есть меньше вычислений надо будет произвести. Следовательно конечно общая скорость вычисления возрастет. Или в чем заключалась шутка юмора?

На самом деле невероятно трудно сравнить скорость работы двух кусков кода. Надо досконально знать устройство своего компилятора. Как именно он оптимизирует вычисления. И отсюда так же следует, что на другой машине, с тем же компилятором, но другим процессором, результаты могут опять отличаться от замеренных. Тут куча тонкостей. Лично я б не взялся утверждать вот вами сказанное.
0
gunslinger
случайный прохожий
1290 / 812 / 319
Регистрация: 20.07.2013
Сообщений: 2,287
19.05.2015, 13:53  [ТС] 9
Простые факты.
Пример (все ниже сказанное относится к реализации длинной арифметики): я заменил возведение в степень умножением в цикле, скорость возросла - значит, функция pow далеко не оптимальна.
Я заменил умножение при вычислении L сложением в цикле, скорость упала катастрофически.
Дело не в компиляторе, реализация сложения / вычитания сделана (не скажу "криво") если не плохо, то весьма не идеально.
Вывод: умножение / деление работают гораздо лучше сложения / вычитания.

Добавлено через 8 минут
Повторюсь:
Если в коде [из цикла] убрать вычитание, то скорость возрастет более чем в 3 раза.
Убрали одну операцию на итерацию - производительность значительно выросла.
А остаются еще умножение и деление с остатком. Тут не нужно быть Шерлоком Холмсом, чтобы сделать выводы.
0
D1973
19.05.2015, 14:12
  #10

Не по теме:

Вот это и называется: "Программисты балуются" :D

0
Avazart
Эксперт С++
7722 / 5631 / 549
Регистрация: 10.12.2010
Сообщений: 25,397
Записей в блоге: 17
28.05.2015, 18:34 11
Цитата Сообщение от gunslinger Посмотреть сообщение
спользуя bigint.zip (там всего два файла - cpp и h) отсюда, немного доработал программу.
gmp, mpir, NTL ?
1
gunslinger
случайный прохожий
1290 / 812 / 319
Регистрация: 20.07.2013
Сообщений: 2,287
28.05.2015, 18:58  [ТС] 12
Я в курсе про нормальные реализации, но не хотелось возиться, прикручивая кучу всего не особо нужного в довесок.
Цель была "протестировать", глобальные планы выполнять не собирался.
0
Avazart
Эксперт С++
7722 / 5631 / 549
Регистрация: 10.12.2010
Сообщений: 25,397
Записей в блоге: 17
28.05.2015, 19:15 13
Цитата Сообщение от gunslinger Посмотреть сообщение
прикручивая кучу всего не особо нужного в довесок.
Хз, чего всего? там в gmp одна длл-ка и заголовки.
0
28.05.2015, 19:15
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
28.05.2015, 19:15

Число Люка
Числа Люка определяются так: первое число равно 1, второе 3, каждое следующее...

СМА AEG 41030 913729401 вход в тест, Стиралка не включается , в тест не входит
Всем привет стиралка AEG 41030 913729401 Typ 93P22599 .Замок блокируется и...

Найти глубину люка
Здравствуйте! Собственно вот: &quot;На какой глубине может находиться вода в люке,...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
13
Ответ Создать тему
Опции темы

КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2018, vBulletin Solutions, Inc.
Рейтинг@Mail.ru