powered by simpleCommunicator - 2.0.52     © 2025 Programmizd 02
Форумы / Oracle [игнор отключен] [закрыт для гостей] / Обход шахматной доски конем pl/sql
13 сообщений из 13, страница 1 из 1
Обход шахматной доски конем pl/sql
    #39937645
kochhar
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Всем доброго времени суток!
Возникла проблема с решением задачи обхода конем клеток шахматной доски, он должен побывать в каждой клетке ровно один раз и закончить в клетке, из которой сможет вернуться в исходную. Задачу нужно решить при помощи циклов(без использования функций, процедур, пакетов). Есть вариант решения, но возникла сложность с адаптированием его под условие решения только через циклы:

Код: 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.
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);
     function cnt_unvisited(x in binary_integer, y in binary_integer)
   	 return binary_integer as
   	 result binary_integer := 0;
     begin
   	 for i in (select x + dx x, y + dy y
   		     from
   		     -- NoFormat Start
   			   (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)
   			   -- NoFormat End
   		    where x + dx >= 1
   		      and x + dx <= 8
   		      and y + dy >= 1
   		      and y + dy <= 8) loop
   	   result := result + (1 - sign(desk(i.x) (i.y)));
   	 end loop;
   	 return result;
     end;
     procedure find_next(x in out binary_integer, y in out binary_integer) as
   	 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 x + dx x, y + dy y
   		       from
   		       -- NoFormat Start
   			     (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)
   			     -- NoFormat End
   		      where x + dx >= 1
   			and x + dx <= 8
   			and y + dy >= 1
   			and y + dy <= 8) loop
   	     if desk(i.x) (i.y) = 0 then
   	       tmp.extend;
   	       tmp(tmp.count) := to_char(cnt_unvisited(i.x, i.y), 'fm00') ||
   				 to_char(i.x, 'fm00') || to_char(i.y, 'fm00');
   	     end if;
   	   end loop;
   	   if tmp.count = 0 then
   	     raise_application_error(-20000, 'It''s a dead end!');
   	   end if;
   	   select t.x, t.y
   	     into find_next.x, find_next.y
   	     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;
   begin
     loop
   	 ii    := 1;
   	 jj    := 1;
   	 ind   := 1;
     -- initializing
   	 for i in 1 .. 8 loop
   	   for j in 1 .. 8 loop
   	     desk(i)(j) := 0;
   	   end loop;
   	 end loop;
   	 -- finding solution
   	 begin
   	   for i in 1 .. 8 loop
   	     for j in 1 .. 8 loop
   	       desk(ii)(jj) := ind;
   	       find_next(ii, jj);
   	       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;
    -- printing result
    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;



Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
|01|46|15|24|61|28|13|26|
|16|23|64|47|14|25|62|29|
|51|02|45|54|63|60|27|12|
|22|17|52|57|48|55|30|59|
|03|50|21|44|53|58|11|34|
|18|39|42|49|56|33|08|31|
|41|04|37|20|43|06|35|10|
|38|19|40|05|36|09|32|07|

Если есть возможность, помогите, пожалуйста.
...
Рейтинг: 0 / 0
Обход шахматной доски конем pl/sql
    #39937646
Фотография -2-
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
...
Рейтинг: 0 / 0
Обход шахматной доски конем pl/sql
    #39937656
kochhar
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
-2-,

Спасибо!
но проблема в том, что в этой статье нет варианта без функций, процедур и пакетов, так что буду пока пытаться дальше.
...
Рейтинг: 0 / 0
Обход шахматной доски конем pl/sql
    #39937672
Фотография Кобанчег
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
kochhar
Есть вариант решения

kochhar
буду пока пытаться дальше
Хватило способностей скопипастить вариант dbms_photoshop, но не осилил еще одну страницу чтоб дойти до rec with от andreymx?
Или проблема в том, чтоб избавиться от функции и продедуры в PL/SQL решении путем переписывания его в тупой spaghetti code?
...
Рейтинг: 0 / 0
Обход шахматной доски конем pl/sql
    #39938214
kochhar
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Проблема именно в избавлении от процедур и функций, все не получается нормально исправить.
С рекурсивным with вариант решения видел, он превосходен, но нужно решить именно на pl/sql.
...
Рейтинг: 0 / 0
Обход шахматной доски конем pl/sql
    #39938240
Фотография Кобанчег
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
kochhar,

Решение - это анонимный блок, процедуры и функции объявлены только для модульности.
Зачем там от них избавляться?
Препод над тобой решил поприкалываться?
...
Рейтинг: 0 / 0
Обход шахматной доски конем pl/sql
    #39938244
kochhar
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Кобанчег,

Задание действительно именно так и звучит. Тоже считаю, что не вполне понятно, зачем решать без процедур или функций, но никуда от этого не деться, нужно представить решение только анонимным блоком, но нормально переписать у меня не получается.
...
Рейтинг: 0 / 0
Обход шахматной доски конем pl/sql
    #39938257
Фотография Кобанчег
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
kochhar,

Раз ты не в состоянии сделать copy & paste + replace в чужом решиении из 100 строчек тогда надо платить деньги.

Хотя здесь есть некто Станислав, подожди может он сделает за тебя всё бесплатно.
...
Рейтинг: 0 / 0
Обход шахматной доски конем pl/sql
    #39938307
Фотография -2-
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
kochhar
Задание действительно именно так и звучит.
Понятие "процедура" может трактоваться. А еще есть еще "методы".
...
Рейтинг: 0 / 0
Обход шахматной доски конем pl/sql
    #39938322
kochhar
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Кобанчег,

Дело в том, что я так и делаю, но при замене процедуры вывод получается другим, а при замене функции - возникает ошибка.
Если есть возможность помочь за деньги, подскажите, пожалуйста, как с Вами можно связаться?
...
Рейтинг: 0 / 0
Обход шахматной доски конем pl/sql
    #39938350
Фотография Stax
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Кобанчег

Хотя здесь есть некто Станислав


не собирался я сделывать

поменял влоб (ctrl c/v), не тестировал

Код: 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.
122.
123.
124.
125.
126.
127.
128.
129.
130.
131.
132.
133.
134.
135.
136.
137.
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;
     -- initializing
   	 for i in 1 .. 8 loop
   	   for j in 1 .. 8 loop
   	     desk(i)(j) := 0;
   	   end loop;
   	 end loop;
   	 -- finding solution
   	 begin
   	   for i in 1 .. 8 loop
   	     for j in 1 .. 8 loop
   	       desk(ii)(jj) := ind;
--   find_next(ii, jj);
    <<f_next>>
     declare
--     procedure find_next_old(x in out binary_integer, y in out binary_integer) as
   	 tmp sys.odcivarchar2list := sys.odcivarchar2list();
     begin
--     x:=ii;
--     y:=jj;
   	 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
   		       -- NoFormat Start
   			     (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)
   			     -- NoFormat End
   		      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;
--
--
--     function cnt_unvisited(x in binary_integer, y in binary_integer)
--   	 return binary_integer as
  	 result := 0;
     begin
   	 for ri in (select i.ii + dx x, i.jj + dy y
   		     from
   		     -- NoFormat Start
   			   (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)
   			   -- NoFormat End
   		    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;
--   	 return result;
     end;
   	       tmp(tmp.count) := to_char(/*cnt_unvisited(i.ii, i.jj)*/ 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, 'It''s a dead end!');
   	   end if;
   	   select t.x, t.y
--   	     into find_next.x, find_next.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;
    -- printing result
    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;
/
SQL> /
|01|34|03|18|39|32|13|16|
|04|19|64|33|14|17|40|31|
|63|02|35|38|59|42|15|12|
|20|05|58|61|36|49|30|41|
|55|62|37|50|43|60|11|26|
|06|21|54|57|48|27|44|29|
|53|56|23|08|51|46|25|10|
|22|07|52|47|24|09|28|45|



.....
stax
...
Рейтинг: 0 / 0
Обход шахматной доски конем pl/sql
    #39938355
kochhar
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Stax,
Спасибо огромное!
Вроде также пытался делать, но был неверный вывод. Буду разбираться, где ошибся.
...
Рейтинг: 0 / 0
Обход шахматной доски конем pl/sql
    #39941073
Jack963
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
kochhar, а можете пожалуйста объяснить решение? Не в каждой строчке понимаю что происходит? хотя бы комментариями
...
Рейтинг: 0 / 0
13 сообщений из 13, страница 1 из 1
Форумы / Oracle [игнор отключен] [закрыт для гостей] / Обход шахматной доски конем pl/sql
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


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