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

Код: 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
15.03.2020, 20:02
    #39937646
-2-
-2-
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Обход шахматной доски конем pl/sql
...
Рейтинг: 0 / 0
15.03.2020, 21:09
    #39937656
kochhar
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Обход шахматной доски конем pl/sql
-2-,

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

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

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

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

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

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

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

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


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

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


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