powered by simpleCommunicator - 2.0.52     © 2025 Programmizd 02
Форумы / Oracle [игнор отключен] [закрыт для гостей] / Oracle.Ход конем
9 сообщений из 9, страница 1 из 1
Oracle.Ход конем
    #39945945
Jack963
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Здравствуйте, помогите, пожалуйста, разобраться с кодом. Не могу понять как он работает.
Есть шахматная доска . За 64 хода обойти конем все
её клетки (не наступая ни на какое поле дважды), с условием, что с поля 64-го хода конь
может допрыгнуть до начальной своей позиции (то есть зациклить всю траекторию).
Результат представить в виде таблицы 8х8, в клетках которой должны быть проставлены
числа, указывающие номер хода, на котором конь оказался в данной клетке.
Задача решается при помощь правила Варнсдорфа
Правило: следующий ход коня нужно делать на клетку, откуда существует наименьшее количество возможных ходов. Если клеток с одинаковым количеством ходом несколько, то можно выбрать любую.
На практике это реализуется, например, следующим образом. Перед каждым ходом коня вычисляется рейтинг ближайших доступных полей - полей, на которых конь еще не был, и на которые он может перейти за один ход. Рейтинг поля определяется числом ближайших доступных с него полей. Чем меньше рейтинг, тем он лучше. Потом делается ход на поле с наименьшим рейтингом (на любое из таковых, если их несколько), и так далее, пока есть куда ходить.
Код: plsql
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.
75.
76.
77.
78.
79.
80.
81.
82.
83.
84.
85.
86.
87.
88.
89.
90.
91.
92.
93.
94.
95.
96.
97.
98.
99.
100.
101.
102.
103.
104.
105.
106.
107.
108.
109.
110.
111.
112.
113.
114.
115.
116.
117.
118.
119.
120.
121.
set serveroutput on;
 declare
     type t is table of binary_integer index by binary_integer;
      type tt is table of t index by binary_integer;
      desk tt; -- массив доски
      ii   binary_integer := 1; -- строки
      jj   binary_integer := 1; -- столбцы
      ind  binary_integer := 1; -- счетчик 
      rpt  binary_integer := 1; -- для ошибки 
      v    varchar2(25); -- для вывода на экран
     result binary_integer := 0; -- для запоминания значения 
   begin
     loop
            ii    := 1;
            jj    := 1;
            ind   := 1;
     -- заполнение массива
            for i in 1 .. 8 loop
              for j in 1 .. 8 loop
                desk(i)(j) := 0;
              end loop;
            end loop;
            -- поиск решения
            begin
              for i in 1 .. 8 loop
                for j in 1 .. 8 loop
                  desk(ii)(jj) := ind;
     declare
            tmp sys.odcivarchar2list := sys.odcivarchar2list();
     begin
     --для заполнения последнего 
            if ind = 64 then
              for i in 1 .. 8 loop
                for j in 1 .. 8 loop
                  if desk(i) (j) = 0 then
                    desk(i)(j) := 64;
                  end if;
                end loop;
              end loop;
            else
            --перемещение конем
              for i in (select ii + dx ii, jj + dy jj
                          from
                                (select 2 dx, -1 dy from dual --координаты x и y
                                union all select 2 dx, 1 dy from dual
                                union all select 1 dx, 2 dy from dual
                                union all select -1 dx, 2 dy from dual
                                union all select -2 dx, +1 dy from dual
                                union all select -2 dx, -1 dy from dual
                                union all select -1 dx, -2 dy from dual
                                union all select 1 dx, -2 dy from dual)
                        -- проверяем, что после выполенения хода конь остается на шахматной доске 
                         where ii + dx >= 1
                           and ii + dx <= 8
                           and jj + dy >= 1
                           and jj + dy <= 8) loop
                if desk(i.ii) (i.jj) = 0 then--Проверяет, является ли квадрат действительно пустым или нет
                  tmp.extend;
           result := 0;
     begin
     -- перемещение конем
            for ri in (select i.ii + dx x, i.jj + dy y--координаты x и y
                        from
                              (select 2 dx, -1 dy from dual
                              union all select 2 dx, 1 dy from dual
                              union all select 1 dx, 2 dy from dual
                              union all select -1 dx, 2 dy from dual
                              union all select -2 dx, +1 dy from dual
                              union all select -2 dx, -1 dy from dual
                              union all select -1 dx, -2 dy from dual
                              union all select 1 dx, -2 dy from dual)
                       -- проверяем, что после выполенения хода конь остается на шахматной доске 
                       where i.ii + dx >= 1
                         and i.ii + dx <= 8
                         and i.jj + dy >= 1
                         and i.jj + dy <= 8) loop
              result := result + (1 - sign(desk(ri.x) (ri.y)));--отмечаем ход
            end loop;
     end;
                  tmp(tmp.count) := to_char(result, 'fm00') ||
                                    to_char(i.ii, 'fm00') || to_char(i.jj, 'fm00');
                end if;
              end loop;
              --ошибка 
              if tmp.count = 0 then
                raise_application_error(-20000, 'Это тупик');
              end if;
              -- запоминаем координаты 
              select t.x, t.y
                into ii, jj
                from (select substr(column_value, 3, 2) x,
                             substr(column_value, 5, 2) y
                        from table(tmp)
                       order by substr(column_value, 1, 2), dbms_random.value) t
               where rownum = 1;
            end if;
     end;
                  ind := ind + 1;
                end loop;
              end loop;
           exception --если ошибка заходим в этот блок
             when others then
               if sqlcode = -20000 then
                 null;
               else
                 raise;
               end if;
           end;
           --останавливаем если прошли цикл
           exit when 64 in (desk(2)(3),desk(3)(2)) or rpt>10000;
           rpt := rpt+1;
    end loop;
    -- вывод результата
    for i in 1 .. 8 loop
           v := '|';
           for j in 1 .. 8 loop
             v := v || to_char(desk(i) (j), 'fm00') || '|';
           end loop;
           dbms_output.put_line(v);
    end loop;
  end;
...
Рейтинг: 0 / 0
Oracle.Ход конем
    #39945952
Dimitry Sibiryakov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Откуда вас с конями такая куча попёрла? Три или четыре темы за пару недель...
Posted via ActualForum NNTP Server 1.5
...
Рейтинг: 0 / 0
Oracle.Ход конем
    #39945953
Фотография Elic
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Jack963
Не могу понять
откуда у вас неприязнь ко всем остальным на форуме с вашим нежеланием элементарно отформатировать свой говнокод?
...
Рейтинг: 0 / 0
Oracle.Ход конем
    #39945964
Фотография Кобанчег
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Jack963
Это тупик
Действительно, если человек для того чтоб понять код сначала избавляется от процедур и функций - это тупик.
...
Рейтинг: 0 / 0
Oracle.Ход конем
    #39946379
Jack963
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Мне больше всего интересно почему здесь используют sys.odcivarchar2list? И вообще что эта за коллекция особо информации про нее нет
...
Рейтинг: 0 / 0
Oracle.Ход конем
    #39946537
Фотография Stax
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Jack963,

чтоб не создавать свою VARRAY
пользуют "встроенную/системную"

Код: plsql
1.
2.
SQL> desc  sys.odcivarchar2list
 sys.odcivarchar2list VARRAY(32767) OF VARCHAR2(4000)



....
stax
...
Рейтинг: 0 / 0
Oracle.Ход конем
    #39948363
Jack963
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Stax, а зачем используется пакет dbms_random?
...
Рейтинг: 0 / 0
Oracle.Ход конем
    #39948378
Фотография Stax
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Jack963
Stax, а зачем используется пакет dbms_random?


order by substr(column_value, 1, 2), dbms_random.value) t

dbms_random.value в order by применяется для получения случайного результата (хода)

выполните несколько раз с и без (закоментировав) dbms_random, и сравните

зы
имхо
разбирать (исследовать) легче/удобнее в варианте автора dbms_photoshop (с фукцией/процедурой)

.....
stax
...
Рейтинг: 0 / 0
Oracle.Ход конем
    #39948538
Фотография orawish
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Dimitry Sibiryakov

Откуда вас с конями такая куча попёрла? Три или четыре темы за пару недель...

дыкть, сезонное обострение (от очередного первого апреля)
...
Рейтинг: 0 / 0
9 сообщений из 9, страница 1 из 1
Форумы / Oracle [игнор отключен] [закрыт для гостей] / Oracle.Ход конем
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]