Форум программистов, компьютерный форум, киберфорум
Prolog
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск  
 
 
Рейтинг 4.86/22: Рейтинг темы: голосов - 22, средняя оценка - 4.86
130 / 117 / 30
Регистрация: 14.11.2010
Сообщений: 707

головоломка "Фонари"

27.12.2010, 16:30. Показов 5222. Ответов 49
Метки нет (Все метки)

Студворк — интернет-сервис помощи студентам
есть головоломка Фонари, вот условие для решения.

не могу придумать, даже алгоритм для решения, подскажите, пожалуйста...
в принципе можно, исключить ситуацию с пустыми черными клетками и с черными клетками, в которых стоит 0, чтобы проще было...
Миниатюры
головоломка "Фонари"  
0
Programming
Эксперт
39485 / 9562 / 3019
Регистрация: 12.04.2006
Сообщений: 41,671
Блог
27.12.2010, 16:30
Ответы с готовыми решениями:

Головоломка на прологе
Помогите решить головоломку на прологе. Очень нужно!

Головоломка на SWI
Здравствуйте! Мое задание такое: "За столиком в кафе познакомились три девушки: Алёна, Светлана и Марианна. Одна из них работает...

задача-головоломка
нужна помощь в написании программы условие задачи: имеется n городов, некоторые из них соединены дорогами известной длины. Вся система...

49
130 / 117 / 30
Регистрация: 14.11.2010
Сообщений: 707
28.12.2010, 21:10  [ТС]
Студворк — интернет-сервис помощи студентам
Цитата Сообщение от Грымзик Посмотреть сообщение
нет_черной_клетки_на_Iой_строке_между_J_ и_J1_столбцами
а J и J1 это столбцы исходного фонаря(l(I,J)) и фонаря в списке(Fonari)?
0
 Аватар для Грымзик
2507 / 1483 / 37
Регистрация: 14.09.2009
Сообщений: 2,740
28.12.2010, 21:16
Да, именно так.
0
130 / 117 / 30
Регистрация: 14.11.2010
Сообщений: 707
28.12.2010, 21:47  [ТС]
Цитата Сообщение от Грымзик Посмотреть сообщение
Да, а как дела с "проверкой"?

Добавлено через 8 минут
Нет, не правильно. Надо проверять не чтобы на данной строке не было других фонарей или черных клеток, а чтобы не было фонаря, не огороженного черной клеткой. Надо так
proverka(l(I,J),Fonari,Kletki):-member(l(I,J1),Fonari),нет_черной_клетки _на_Iой_строке_между_J_и_J1_столбцами.
а потом уже проверять not(proverka(...)).
вообщем вот что у меня получилось...
в предикате black_net сначала находим черную клетку, чтобы координата ее строки совпадала с координатами строк фонарей, если это выполняется, то смотрим находится ли она между фонарей...
но я тут перебираю список клеток, а как потом после перебора списка клеток, перейти к следующему элементу списка Fonari и снова искать клетку?

Prolog
1
2
3
4
proverka(l(I,J),Fonari,Kletki):-member(l(I,J1),Fonari),not(net_black(l(I,J),Fonari,Kletki)).
 
net_black(l(I,J),[l(II,JJ)|_],[f(III,JJJ,Znachenie)|Tail1]):-I=III,II=III,JJJ<J,JJJ>JJ;
I=III,II=III,JJJ>J,JJJ<JJ;net_black(l(I,J),l(II,JJ),Tail1).
0
 Аватар для Грымзик
2507 / 1483 / 37
Регистрация: 14.09.2009
Сообщений: 2,740
28.12.2010, 22:13
Опять же все гораздо проще
Prolog
1
2
3
4
5
6
7
8
black_gor(I,A,B,Fields):-member(f(I,J,_),Fields),J>A,J<B.
black_gor(I,A,B,Fields):-member(f(I,J,_),Fields),J<A,J>B.
 
black_ver(J,A,B,Fields):-member(f(I,J,_),Fields),I>A,I<B.
black_ver(J,A,B,Fields):-member(f(I,J,_),Fields),I<A,I>B.
 
proverka(l(I,J),Fonari,Kletki):-member(l(I,J1),Fonari),not(black_gor(I,J,J1,Kletki)).
proverka(l(I,J),Fonari,Kletki):-member(l(I1,J),Fonari),not(black_ver(J,I,I1,Kletki)).
1
130 / 117 / 30
Регистрация: 14.11.2010
Сообщений: 707
28.12.2010, 22:19  [ТС]
Цитата Сообщение от Грымзик Посмотреть сообщение
Опять же все гораздо проще
действительно...

проверку же вставляем, перед тем как добавить фонарь?
тут:
Prolog
1
not(member(f(I1,J1,Z),PrevFields)),not(proverka(l(I1,J1),Fonari,PrevFields)),M1=M-1

Prolog
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
DOMAINS
f1=f*
l1=l*
f=f(i,j,znachenie)
l=l(i,j)
i=integer
j=integer
znachenie=integer
 
 
PREDICATES
obstanovka(f1,f1,l1)
member(l,l1)
member(f,f1)
addfon(f,f1,l1,l1)
append(l1,l,l1)
ryadom(l,f)
fonar_nahoditsya_ryadom(f,l1,l)
rasstavit(f,f1,integer,l1,l1)
length(l1,integer)
proverka(l,l1,f1)
net_black
 
CLAUSES
 
member(A,[A|_]).
member(A,[_|P]):-member(A,P).
 
append([],X,[X]).
append([H|Xs],X,[H|Ys]):-append(Xs,X,Ys).
 
obstanovka([f(I,J,-1)|P],PrevFields,Fonari):-obstanovka(P,[f(I,J,-1)|PrevFields],Fonari). 
obstanovka([f(I,J,Znachenie)|P],PrevFields,Fonari):-
        addfon(f(I,J,Znachenie),PrevFields,Fonari,NewFonari),
        obstanovka(P,[f(I,J,Znachenie)|PrevFields],NewFonari).
obstanovka([],_,Fonari):-write(Fonari).
 
ryadom(l(I,J),f(I,J1,_)):-J=J1-1,J>0;J=J1+1,J<=10.
ryadom(l(I,J),f(I1,J,_)):-I=I1-1,I>0;I=I1+1,I<=10.
 
fonar_nahoditsya_ryadom(f(I,J,Z),Fonari,Fonar):-member(Fonar,Fonari),
ryadom(Fonar,f(I,J,Z)).
 
length([],0).
length([_|Tail],L):-length(Tail,L1),L=L1+1.
 
addfon(f(_,_,0),_,Fonari,Fonari):-!.
addfon(f(I,J,K),PrevFields,Fonari,NewFonari):-
findall(Fonar,fonar_nahoditsya_ryadom(f(I,J,_),Fonari,Fonar),FonariRyadom),
length(FonariRyadom,N),
M=K-N,rasstavit(f(I,J,_),PrevFields,M,Fonari,NewFonari).
        
rasstavit(_,_,N,_,_):-N<0,fail,!.
rasstavit(f(I,J,Z),PrevFields,M,Fonari,NewFonari):-ryadom(l(I1,J1),f(I,J,Z)),
not(member(l(I1,J1),Fonari)),
not(member(f(I1,J1,Z),PrevFields)),not(proverka(l(I1,J1),Fonari,PrevFields)),M1=M-1,
rasstavit(f(I,J,Z),PrevFields,M1,[l(I1,J1)|Fonari],NewFonari).
 
black_gor(I,A,B,Fields):-member(f(I,J,_),Fields),J>A,J<B.
black_gor(I,A,B,Fields):-member(f(I,J,_),Fields),J<A,J>B.
 
black_ver(J,A,B,Fields):-member(f(I,J,_),Fields),I>A,I<B.
black_ver(J,A,B,Fields):-member(f(I,J,_),Fields),I<A,I>B.
 
proverka(l(I,J),Fonari,Kletki):-member(l(I,J1),Fonari),not(black_gor(I,J,J1,Kletki)).
proverka(l(I,J),Fonari,Kletki):-member(l(I1,J),Fonari),not(black_ver(J,I,I1,Kletki)).
 
 
 
 
 
GOAL
obstanovka([f(1,1,2),f(1,3,3)],[],[]).
Добавлено через 2 минуты
Грымзик, теперь нужно написать предикат, который ищет неосвещенные клетки?
0
 Аватар для Грымзик
2507 / 1483 / 37
Регистрация: 14.09.2009
Сообщений: 2,740
28.12.2010, 23:13
Да, теперь надо написать предикат, который проверяет все ли клетки освещены. Это опять делается через отрицание того, что есть хоть одна не освещенная клетка. И надо изменить последнее правило
obstanovka([],Fields,Fonari):-check(Fields,Fonari),write(Fonari). И поняла как можно сделать с пустыми черными клетками.
Prolog
1
2
3
obstanovka([f(I,J,-1)|P],PrevFields,Fonari):-!,for(Znachenie,0,4),
        addfon(f(I,J,Znachenie),PrevFields,Fonari,NewFonari),
        obstanovka(P,[f(I,J,-1)|PrevFields],NewFonari).
Предикат for можно найти на форуме.
0
130 / 117 / 30
Регистрация: 14.11.2010
Сообщений: 707
28.12.2010, 23:18  [ТС]
попробовал написать проверку остались ли неосвещенные клетки, вот что вышло:

Prolog
1
2
3
4
proverka_na_neos(Fonari,[f(I1,J1,Znachenie)|Tail1],NeosKletki):-not(proverka_na_neos1(Fonari,f(I1,J1,Znachenie)))
,appendkl(NewNeosKl,f(I1,J1,Znachenie),NeosKletki).
 
proverka_na_neos1([l(I,J)|Tail],f(I1,J1,_)):-not(I=I1),proverka_na_neos1(Tail,f(I1,J1,_));not(J=J1),proverka_na_neos1(Tail,f(I1,J1,_))
а вот итог после всех изменений, вроде так, но могу ошибаться =)
Prolog
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
DOMAINS
f1=f*
l1=l*
f=f(i,j,znachenie)
l=l(i,j)
i=integer
j=integer
znachenie=integer
 
 
PREDICATES
obstanovka(f1,f1,l1)
member(l,l1)
member(f,f1)
addfon(f,f1,l1,l1)
append(l1,l,l1)
appendkl(f,f1)
ryadom(l,f)
fonar_nahoditsya_ryadom(f,l1,l)
rasstavit(f,f1,integer,l1,l1)
length(l1,integer)
proverka(l,l1,f1)
black_gor(i,j,j,f1)
black_ver(j,i,i,f1)
proverka_na_neos(l1,f1,f1)
proverka_na_neos(l1,f)
 
CLAUSES
 
member(A,[A|_]).
member(A,[_|P]):-member(A,P).
 
append([],X,[X]).
append([H|Xs],X,[H|Ys]):-append(Xs,X,Ys).
 
appendkl([],X,[X]).
appendkl([H|Xs],X,[H|Ys]):-appendkl(Xs,X,Ys).
 
obstanovka([f(I,J,-1)|P],PrevFields,Fonari):-!,for(Znachenie,1,4),
        addfon(f(I,J,Znachenie),PrevFields,Fonari,NewFonari),
        obstanovka(P,[f(I,J,Znachenie)|PrevFields],NewFonari).
 
obstanovka([f(I,J,Znachenie)|P],PrevFields,Fonari):-
        addfon(f(I,J,Znachenie),PrevFields,Fonari,NewFonari),
        obstanovka(P,[f(I,J,Znachenie)|PrevFields],NewFonari).
 
obstanovka([],Fields,Fonari):-check(Fields,Fonari),write(Fonari)
 
ryadom(l(I,J),f(I,J1,_)):-J=J1-1,J>0;J=J1+1,J<=10.
ryadom(l(I,J),f(I1,J,_)):-I=I1-1,I>0;I=I1+1,I<=10.
 
fonar_nahoditsya_ryadom(f(I,J,Z),Fonari,Fonar):-member(Fonar,Fonari),
ryadom(Fonar,f(I,J,Z)).
 
length([],0).
length([_|Tail],L):-length(Tail,L1),L=L1+1.
 
addfon(f(_,_,0),_,Fonari,Fonari):-!.
addfon(f(I,J,K),PrevFields,Fonari,NewFonari):-
findall(Fonar,fonar_nahoditsya_ryadom(f(I,J,_),Fonari,Fonar),FonariRyadom),
length(FonariRyadom,N),
M=K-N,rasstavit(f(I,J,_),PrevFields,M,Fonari,NewFonari).
        
rasstavit(_,_,N,_,_):-N<0,fail,!.
rasstavit(f(I,J,Z),PrevFields,M,Fonari,NewFonari):-ryadom(l(I1,J1),f(I,J,Z)),
not(member(l(I1,J1),Fonari)),
not(member(f(I1,J1,Z),PrevFields)),not(proverka(l(I1,J1),Fonari,PrevFields)),M1=M-1,
rasstavit(f(I,J,Z),PrevFields,M1,[l(I1,J1)|Fonari],NewFonari).
 
black_gor(I,A,B,Fields):-member(f(I,J,_),Fields),J>A,J<B.
black_gor(I,A,B,Fields):-member(f(I,J,_),Fields),J<A,J>B.
 
black_ver(J,A,B,Fields):-member(f(I,J,_),Fields),I>A,I<B.
black_ver(J,A,B,Fields):-member(f(I,J,_),Fields),I<A,I>B.
 
proverka(l(I,J),Fonari,Kletki):-member(l(I,J1),Fonari),not(black_gor(I,J,J1,Kletki)).
proverka(l(I,J),Fonari,Kletki):-member(l(I1,J),Fonari),not(black_ver(J,I,I1,Kletki)).
 
proverka_na_neos(Fonari,[f(I1,J1,Znachenie)|Tail1],NeosKletki):-not(proverka_na_neos1(Fonari,f(I1,J1,Znachenie)))
,appendkl(NewNeosKl,f(I1,J1,Znachenie),NeosKletki).
 
proverka_na_neos1([l(I,J)|Tail],f(I1,J1,_)):-not(I=I1),proverka_na_neos1(Tail,f(I1,J1,_));not(J=J1),proverka_na_neos1(Tail,f(I1,J1,_))
 
GOAL
obstanovka([f(1,1,2),f(1,3,3)],[],[]).
0
 Аватар для Грымзик
2507 / 1483 / 37
Регистрация: 14.09.2009
Сообщений: 2,740
28.12.2010, 23:27
Нет, не правильно, у Вас и идея не правильная (надо не только равенство столбцов и строк проверять, ведь черные клетки загораживают свет), и идея эта реализована не правильна. Я же писала, что удобно использовать предикат proverka.
proverka(l(X,Y),Fonari,Kletki) будет проверять освещена ли клетка с координатами (X,Y). Значит надо пройти все клетки (опять же используйте предикат for), если клетка не черная, на ней нет фонаря, то вызывайте предикат not(проверка). Если выполняется, то значит расстановка не подходит.
0
130 / 117 / 30
Регистрация: 14.11.2010
Сообщений: 707
28.12.2010, 23:40  [ТС]
Цитата Сообщение от Грымзик Посмотреть сообщение
proverka(l(X,Y),Fonari,Kletki) будет проверять освещена ли клетка с координатами (X,Y)
так здесь же l(X,Y) это фонарь, нам же не надо проверять его освещенность...
нам же тогда надо еще сделать домен для обозначения пустого поля или как? просто нам же нужно проверять освещенность обычных клеток...
0
 Аватар для Грымзик
2507 / 1483 / 37
Регистрация: 14.09.2009
Сообщений: 2,740
28.12.2010, 23:43
Какая разница фонарь эта или проста клетка?!!!!!!!!!!!!!!!!!! Ведь в самом предикате это значение не имеет. Ну если не лень, то можете написать точно такой же предикат вида proverka(X,Y,Fonari,Kletki).
0
130 / 117 / 30
Регистрация: 14.11.2010
Сообщений: 707
29.12.2010, 13:56  [ТС]
Цитата Сообщение от Грымзик Посмотреть сообщение
Какая разница фонарь эта или проста клетка?!!!!!!!!!!!!!!!!!!
извеняюсь, что так туплю)))
щас буду разбираться с for и переделывать предикат...

Добавлено через 12 часов 36 минут
Цитата Сообщение от Грымзик Посмотреть сообщение
Предикат for можно найти на форуме.
что то на форуме ничего не нашел...
его же надо объявлять в предикатах? если не объявляю, то пишет в этой строке:
Prolog
1
obstanovka([f(I,J,-1)|P],PrevFields,Fonari):-!,for(Znachenie,0,4),
Prolog
1
404 Undeclared predicate or misspelling.
а если объявляю в предикатах
Prolog
1
for(Znachenie,i,i)
, то пишет
Prolog
1
No clauses for this predicate.
Добавлено через 39 секунд
вот код всей проги:

Prolog
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
DOMAINS
f1=f*
l1=l*
f=f(i,j,znachenie)
l=l(i,j)
i=integer
j=integer
znachenie=integer
 
 
PREDICATES
obstanovka(f1,f1,l1)
member(l,l1)
member(f,f1)
addfon(f,f1,l1,l1)
ryadom(l,f)
fonar_nahoditsya_ryadom(f,l1,l)
rasstavit(f,f1,integer,l1,l1)
length(l1,integer)
proverka(l,l1,f1)
black_gor(i,j,j,f1)
black_ver(j,i,i,f1)
for(Znachenie,integer,integer)
 
CLAUSES
 
member(A,[A|_]).
member(A,[_|P]):-member(A,P).
 
 
obstanovka([f(I,J,-1)|P],PrevFields,Fonari):-!,for(Znachenie,0,4),
        addfon(f(I,J,Znachenie),PrevFields,Fonari,NewFonari),
        obstanovka(P,[f(I,J,Znachenie)|PrevFields],NewFonari).
 
obstanovka([f(I,J,Znachenie)|P],PrevFields,Fonari):-
        addfon(f(I,J,Znachenie),PrevFields,Fonari,NewFonari),
        obstanovka(P,[f(I,J,Znachenie)|PrevFields],NewFonari).
 
obstanovka([],Fields,Fonari):-write(Fonari).
 
ryadom(l(I,J),f(I,J1,_)):-J=J1-1,J>0;J=J1+1,J<=10.
ryadom(l(I,J),f(I1,J,_)):-I=I1-1,I>0;I=I1+1,I<=10.
 
fonar_nahoditsya_ryadom(f(I,J,Z),Fonari,Fonar):-member(Fonar,Fonari),
ryadom(Fonar,f(I,J,Z)).
 
length([],0).
length([_|Tail],L):-length(Tail,L1),L=L1+1.
 
addfon(f(_,_,0),_,Fonari,Fonari):-!.
addfon(f(I,J,K),PrevFields,Fonari,NewFonari):-
findall(Fonar,fonar_nahoditsya_ryadom(f(I,J,_),Fonari,Fonar),FonariRyadom),
length(FonariRyadom,N),
M=K-N,rasstavit(f(I,J,_),PrevFields,M,Fonari,NewFonari).
        
rasstavit(_,_,N,_,_):-N<0,fail,!.
rasstavit(f(I,J,Z),PrevFields,M,Fonari,NewFonari):-ryadom(l(I1,J1),f(I,J,Z)),
not(member(l(I1,J1),Fonari)),
not(member(f(I1,J1,Z),PrevFields)),not(proverka(l(I1,J1),Fonari,PrevFields)),M1=M-1,
rasstavit(f(I,J,Z),PrevFields,M1,[l(I1,J1)|Fonari],NewFonari).
 
black_gor(I,A,B,Fields):-member(f(I,J,_),Fields),J>A,J<B.
black_gor(I,A,B,Fields):-member(f(I,J,_),Fields),J<A,J>B.
 
black_ver(J,A,B,Fields):-member(f(I,J,_),Fields),I>A,I<B.
black_ver(J,A,B,Fields):-member(f(I,J,_),Fields),I<A,I>B.
 
proverka(l(I,J),Fonari,Kletki):-member(l(I,J1),Fonari),not(black_gor(I,J,J1,Kletki)).
proverka(l(I,J),Fonari,Kletki):-member(l(I1,J),Fonari),not(black_ver(J,I,I1,Kletki)).
 
 
 
GOAL
obstanovka([f(1,1,2),f(1,3,3)],[],[]).
Добавлено через 28 минут
Цитата Сообщение от Грымзик Посмотреть сообщение
Нет, не правильно, у Вас и идея не правильная (надо не только равенство столбцов и строк проверять, ведь черные клетки загораживают свет), и идея эта реализована не правильна. Я же писала, что удобно использовать предикат proverka.
proverka(l(X,Y),Fonari,Kletki) будет проверять освещена ли клетка с координатами (X,Y). Значит надо пройти все клетки (опять же используйте предикат for), если клетка не черная, на ней нет фонаря, то вызывайте предикат not(проверка). Если выполняется, то значит расстановка не подходит.
вот хоть убейте, не пойму как сделать... =(
не могу даже с предикатом for разобраться, не знаю как с ним работать...
пишу тупую прогу для того чтобы разобраться for, но не работает:

Prolog
1
2
3
4
5
6
7
8
9
10
11
12
13
14
DOMAINS
i=integer
s1=i*
 
PREDICATES
pred(s1)
for(i,i,i)
 
CLAUSES
pred([I|Tail]):-!,for(I,0,4),
I1=I+1,pred(Tail).
 
GOAL
pred([1,4,2,3]).
пишет:
Prolog
1
401 No clauses for this predicate.
для этой строки:
Prolog
1
for(i,i,i)
Добавлено через 51 минуту
Цитата Сообщение от Грымзик Посмотреть сообщение
если клетка не черная, на ней нет фонаря, то вызывайте предикат not(проверка)
т.е. как то так?
Prolog
1
2
3
4
5
6
7
proverka_na_neos(l(X,Y),Fonari,Kletki):-pr1(l(X,Y),Kletki),pr2(l(X,Y),Fonari),not(proverka(l(X,Y),Fonari,Kletki)).
 
 
pr1(l(X,Y),[]).
pr1(l(X,Y),[f(I,J,Znachenie)|Tail]):-not(and(X=I,X=J)),pr1(l(X,Y,),Tail).
pr2(l(X,Y),[]).
pr2(l(X,Y),[l(I,J)|Tail]):-not(and(X=I,X=J)),pr2(l(X,Y,),Tail).
0
 Аватар для Грымзик
2507 / 1483 / 37
Регистрация: 14.09.2009
Сообщений: 2,740
29.12.2010, 14:04
pr1 лишний, используйте member.
Prolog
1
2
for(A,A,_).
for(I,A,B):-A<B,A1=A+1,for(I,A1,B).
0
130 / 117 / 30
Регистрация: 14.11.2010
Сообщений: 707
29.12.2010, 14:21  [ТС]
Цитата Сообщение от Грымзик Посмотреть сообщение
pr1 лишний, используйте member.
а почему лишний нам же надо проверить чтобы онане была черной клеткой, это как раз в pr1 делается...
а в pr2 проверка, что не является фонарем...
Цитата Сообщение от Грымзик Посмотреть сообщение
for(A,A,_). for(I,A,B):-A<B,A1=A+1,for(I,A1,B).
это просто пример для работы с предикатом for?
его все таки надо объявлять в предикатах? например for(i,i,i)

Добавлено через 6 минут
Цитата Сообщение от Грымзик Посмотреть сообщение
pr1 лишний, используйте member.
вот так наверное надо:
Prolog
1
2
3
4
proverka_na_neos(l(X,Y),Fonari,Kletki):-pr(l(X,Y),Kletki),member(l(X,Y),Fonari),not(proverka(l(X,Y),Fonari,Kletki)).
 
pr(l(X,Y),[]).
pr(l(X,Y),[f(I,J,Znachenie)|Tail]):-not(and(X=I,X=J)),pr(l(X,Y,),Tail).
0
 Аватар для Грымзик
2507 / 1483 / 37
Регистрация: 14.09.2009
Сообщений: 2,740
29.12.2010, 21:43
Надо вот так:
Prolog
1
2
proverka_na_neos(l(X,Y),Fonari,Kletki):-not(member(l(X,Y),Fonari)),
not(member(f(X,Y),Kletki)),not(proverka(l(X,Y),Fonari,Kletki)).
Т.е если клетка не является фонарем, не является темной, и не освещена, то это плохо.
1
130 / 117 / 30
Регистрация: 14.11.2010
Сообщений: 707
29.12.2010, 22:40  [ТС]
ясно...

на данном этапе значит программа должна выглядеть так?
Prolog
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
DOMAINS
f1=f*
l1=l*
f=f(i,j,znachenie)
l=l(i,j)
i=integer
j=integer
znachenie=integer
 
 
PREDICATES
obstanovka(f1,f1,l1)
member(l,l1)
member(f,f1)
addfon(f,f1,l1,l1)
ryadom(l,f)
fonar_nahoditsya_ryadom(f,l1,l)
rasstavit(f,f1,integer,l1,l1)
length(l1,integer)
proverka(l,l1,f1)
black_gor(i,j,j,f1)
black_ver(j,i,i,f1)
for(Znachenie,integer,integer)
proverka_na_neos(l,l1,f1)
CLAUSES
 
member(A,[A|_]).
member(A,[_|P]):-member(A,P).
 
 
obstanovka([f(I,J,-1)|P],PrevFields,Fonari):-!,for(Znachenie,0,4),
       addfon(f(I,J,Znachenie),PrevFields,Fonari,NewFonari),
       obstanovka(P,[f(I,J,Znachenie)|PrevFields],NewFonari).
 
obstanovka([f(I,J,Znachenie)|P],PrevFields,Fonari):-
        addfon(f(I,J,Znachenie),PrevFields,Fonari,NewFonari),
        obstanovka(P,[f(I,J,Znachenie)|PrevFields],NewFonari),write(Fonari).
 
obstanovka([],Fields,Fonari):-write(Fonari).
 
ryadom(l(I,J),f(I,J1,_)):-J=J1-1,J>0;J=J1+1,J<=10.
ryadom(l(I,J),f(I1,J,_)):-I=I1-1,I>0;I=I1+1,I<=10.
 
fonar_nahoditsya_ryadom(f(I,J,Z),Fonari,Fonar):-member(Fonar,Fonari),
ryadom(Fonar,f(I,J,Z)).
 
length([],0).
length([_|Tail],L):-length(Tail,L1),L=L1+1.
 
addfon(f(_,_,0),_,Fonari,Fonari):-!.
addfon(f(I,J,K),PrevFields,Fonari,NewFonari):-
findall(Fonar,fonar_nahoditsya_ryadom(f(I,J,_),Fonari,Fonar),FonariRyadom),
length(FonariRyadom,N),
M=K-N,rasstavit(f(I,J,_),PrevFields,M,Fonari,NewFonari).
        
rasstavit(_,_,N,_,_):-N<0,fail,!.
rasstavit(f(I,J,Z),PrevFields,M,Fonari,NewFonari):-ryadom(l(I1,J1),f(I,J,Z)),
not(member(l(I1,J1),Fonari)),
not(member(f(I1,J1,Z),PrevFields)),not(proverka(l(I1,J1),Fonari,PrevFields)),M1=M-1,
rasstavit(f(I,J,Z),PrevFields,M1,[l(I1,J1)|Fonari],NewFonari).
 
black_gor(I,A,B,Fields):-member(f(I,J,_),Fields),J>A,J<B.
black_gor(I,A,B,Fields):-member(f(I,J,_),Fields),J<A,J>B.
 
black_ver(J,A,B,Fields):-member(f(I,J,_),Fields),I>A,I<B.
black_ver(J,A,B,Fields):-member(f(I,J,_),Fields),I<A,I>B.
 
proverka(l(I,J),Fonari,Kletki):-member(l(I,J1),Fonari),not(black_gor(I,J,J1,Kletki)).
proverka(l(I,J),Fonari,Kletki):-member(l(I1,J),Fonari),not(black_ver(J,I,I1,Kletki)).
 
proverka_na_neos(l(X,Y),Fonari,Kletki):-not(member(l(X,Y),Fonari)),
not(member(f(X,Y),Kletki)),not(proverka(l(X,Y),Fonari,Kletki)).
 
 
GOAL
obstanovka([f(1,1,2),f(1,3,3)],[],[]).
куда нужно вставить предикат proverka_na_neos, впринципе же нам нужно, чтобы он еще возвращал список клеток которые не освещены или мы просто потом будем заново вызывать предикат для освещения?

а что по поводу предиката for, я выше описывал ошибку...
дальше, я так понимаю, нужно написать предикат, который освещает неосвещенные клетки с помощь черных клеток в которых стоят 0(точнее для нашего решения -1)?

Добавлено через 50 минут
вот старый код, который выводит список фонарей:

Prolog
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
DOMAINS
f1=f*
l1=l*
f=f(i,j,znachenie)
l=l(i,j)
i=integer
j=integer
znachenie=integer
 
 
PREDICATES
obstanovka(f1,f1,l1)
member(l,l1)
member(f,f1)
addfon(f,f1,l1,l1)
ryadom(l,f)
fonar_nahoditsya_ryadom(f,l1,l)
rasstavit(f,f1,integer,l1,l1)
length(l1,integer)
 
CLAUSES
 
member(A,[A|_]).
member(A,[_|P]):-member(A,P).
 
 
 
obstanovka([f(I,J,Znachenie)|P],PrevFields,Fonari):-
        addfon(f(I,J,Znachenie),PrevFields,Fonari,NewFonari),
        obstanovka(P,[f(I,J,Znachenie)|PrevFields],NewFonari).
obstanovka([],_,Fonari):-write(Fonari).
 
ryadom(l(I,J),f(I,J1,_)):-J=J1-1,J>0;J=J1+1,J<=10.
ryadom(l(I,J),f(I1,J,_)):-I=I1-1,I>0;I=I1+1,I<=10.
 
fonar_nahoditsya_ryadom(f(I,J,Z),Fonari,Fonar):-member(Fonar,Fonari),ryadom(Fonar,f(I,J,Z)).
 
length([],0).
length([_|Tail],L):-length(Tail,L1),L=L1+1.
 
addfon(f(_,_,0),_,Fonari,Fonari):-!.
addfon(f(I,J,K),PrevFields,Fonari,NewFonari):-
        findall(Fonar,fonar_nahoditsya_ryadom(f(I,J,_),Fonari,Fonar),FonariRyadom),length(FonariRyadom,N),
        M=K-N,rasstavit(f(I,J,_),PrevFields,M,Fonari,NewFonari).
        
rasstavit(_,_,0,Fonari,Fonari):-!.
rasstavit(f(I,J,Z),PrevFields,M,Fonari,NewFonari):-ryadom(l(I1,J1),f(I,J,Z)),not(member(l(I1,J1),Fonari)),
        not(member(f(I1,J1,Z),PrevFields)),M1=M-1,[f(1,1,2),f(1,5,3)])),rasstavit(f(I,J,Z),PrevFields,M1,[l(I1,J1)|Fonari],NewFonari).
GOAL
obstanovka([f(1,1,2),f(1,5,3)],[],[]).
а если добавляю proverka:
Prolog
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
DOMAINS
f1=f*
l1=l*
f=f(i,j,znachenie)
l=l(i,j)
i=integer
j=integer
znachenie=integer
 
 
PREDICATES
obstanovka(f1,f1,l1)
member(l,l1)
member(f,f1)
addfon(f,f1,l1,l1)
ryadom(l,f)
fonar_nahoditsya_ryadom(f,l1,l)
rasstavit(f,f1,integer,l1,l1)
length(l1,integer)
proverka(l,l1,f1)
black_gor(i,j,j,f1)
black_ver(j,i,i,f1)
 
CLAUSES
 
member(A,[A|_]).
member(A,[_|P]):-member(A,P).
 
 
 
obstanovka([f(I,J,Znachenie)|P],PrevFields,Fonari):-
        addfon(f(I,J,Znachenie),PrevFields,Fonari,NewFonari),
        obstanovka(P,[f(I,J,Znachenie)|PrevFields],NewFonari).
obstanovka([],_,Fonari):-write(Fonari).
 
ryadom(l(I,J),f(I,J1,_)):-J=J1-1,J>0;J=J1+1,J<=10.
ryadom(l(I,J),f(I1,J,_)):-I=I1-1,I>0;I=I1+1,I<=10.
 
fonar_nahoditsya_ryadom(f(I,J,Z),Fonari,Fonar):-member(Fonar,Fonari),ryadom(Fonar,f(I,J,Z)).
 
length([],0).
length([_|Tail],L):-length(Tail,L1),L=L1+1.
 
addfon(f(_,_,0),_,Fonari,Fonari):-!.
addfon(f(I,J,K),PrevFields,Fonari,NewFonari):-
        findall(Fonar,fonar_nahoditsya_ryadom(f(I,J,_),Fonari,Fonar),FonariRyadom),length(FonariRyadom,N),
        M=K-N,rasstavit(f(I,J,_),PrevFields,M,Fonari,NewFonari).
        
rasstavit(_,_,0,Fonari,Fonari):-!.
rasstavit(f(I,J,Z),PrevFields,M,Fonari,NewFonari):-ryadom(l(I1,J1),f(I,J,Z)),not(member(l(I1,J1),Fonari)),
        not(member(f(I1,J1,Z),PrevFields)),M1=M-1,not(proverka(l(I1,J1),Fonari,[f(1,1,2),f(1,5,3)])),rasstavit(f(I,J,Z),PrevFields,M1,[l(I1,J1)|Fonari],NewFonari).
 
black_gor(I,A,B,Fields):-member(f(I,J,_),Fields),J>A,J<B.
black_gor(I,A,B,Fields):-member(f(I,J,_),Fields),J<A,J>B.
 
black_ver(J,A,B,Fields):-member(f(I,J,_),Fields),I>A,I<B.
black_ver(J,A,B,Fields):-member(f(I,J,_),Fields),I<A,I>B.
 
proverka(l(I,J),Fonari,Kletki):-member(l(I,J1),Fonari),not(black_gor(I,J,J1,Kletki)).
proverka(l(I,J),Fonari,Kletki):-member(l(I1,J),Fonari),not(black_ver(J,I,I1,Kletki)).
 
 
 
GOAL
obstanovka([f(1,1,2),f(1,5,3)],[],[]).
то ничего не выводит... =(

можно программу упростить, чтобы просто выводила список фонарей, главное чтобы proverka работала, даже можно убрать ситуацию с пустой клеткой, вокруг которой могут быть хоть сколько фонарей, а то уже утром сдавать нужно, а еще пояснительную записку делать =(
0
 Аватар для Грымзик
2507 / 1483 / 37
Регистрация: 14.09.2009
Сообщений: 2,740
29.12.2010, 22:46
Prolog
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
DOMAINS
f1=f*
l1=l*
f=f(i,j,znachenie)
l=l(i,j)
i=integer
j=integer
znachenie=integer
 
 
PREDICATES
obstanovka(f1,f1,l1)
member(l,l1)
member(f,f1)
addfon(f,f1,l1,l1)
ryadom(l,f)
fonar_nahoditsya_ryadom(f,l1,l)
rasstavit(f,f1,integer,l1,l1)
length(l1,integer)
proverka(l,l1,f1)
black_gor(i,j,j,f1)
black_ver(j,i,i,f1)
for(i,i,i)
for(j,j,j)
for(znachenie,integer,integer)
proverka_na_neos(l,l1,f1)
est_neosveshennaya_kletka(l1,f1)
 
CLAUSES
for(A,A,_).
for(I,A,B):-A<B,A1=A+1,for(I,A1,B).
 
member(A,[A|_]).
member(A,[_|P]):-member(A,P).
 
 
obstanovka([f(I,J,-1)|P],PrevFields,Fonari):-!,for(Znachenie,0,4),
       addfon(f(I,J,Znachenie),PrevFields,Fonari,NewFonari),
       obstanovka(P,[f(I,J,Znachenie)|PrevFields],NewFonari).
 
obstanovka([f(I,J,Znachenie)|P],PrevFields,Fonari):-
        addfon(f(I,J,Znachenie),PrevFields,Fonari,NewFonari),
        obstanovka(P,[f(I,J,Znachenie)|PrevFields],NewFonari),write(Fonari).
 
obstanovka([],Fields,Fonari):-not(est_neosveshennaya_kletka(Fonari,Fields)),write(Fonari).
 
ryadom(l(I,J),f(I,J1,_)):-J=J1-1,J>0;J=J1+1,J<=3.
ryadom(l(I,J),f(I1,J,_)):-I=I1-1,I>0;I=I1+1,I<=3.
 
fonar_nahoditsya_ryadom(f(I,J,Z),Fonari,Fonar):-member(Fonar,Fonari),
ryadom(Fonar,f(I,J,Z)).
 
length([],0).
length([_|Tail],L):-length(Tail,L1),L=L1+1.
 
addfon(f(_,_,0),_,Fonari,Fonari):-!.
addfon(f(I,J,K),PrevFields,Fonari,NewFonari):-
findall(Fonar,fonar_nahoditsya_ryadom(f(I,J,_),Fonari,Fonar),FonariRyadom),
length(FonariRyadom,N),
M=K-N,rasstavit(f(I,J,_),PrevFields,M,Fonari,NewFonari).
        
rasstavit(_,_,M,_,_):-M<0,!,fail.
rasstavit(_,_,0,Fonari,Fonari):-!.
rasstavit(f(I,J,Z),PrevFields,M,Fonari,NewFonari):-ryadom(l(I1,J1),f(I,J,Z)),
not(member(l(I1,J1),Fonari)),
not(member(f(I1,J1,Z),PrevFields)),not(proverka(l(I1,J1),Fonari,PrevFields)),M1=M-1,
rasstavit(f(I,J,Z),PrevFields,M1,[l(I1,J1)|Fonari],NewFonari).
 
black_gor(I,A,B,Fields):-member(f(I,J,_),Fields),J>A,J<B.
black_gor(I,A,B,Fields):-member(f(I,J,_),Fields),J<A,J>B.
 
black_ver(J,A,B,Fields):-member(f(I,J,_),Fields),I>A,I<B.
black_ver(J,A,B,Fields):-member(f(I,J,_),Fields),I<A,I>B.
 
proverka(l(I,J),Fonari,Kletki):-member(l(I,J1),Fonari),not(black_gor(I,J,J1,Kletki)).
proverka(l(I,J),Fonari,Kletki):-member(l(I1,J),Fonari),not(black_ver(J,I,I1,Kletki)).
 
proverka_na_neos(l(X,Y),Fonari,Kletki):-not(member(l(X,Y),Fonari)),
not(member(f(X,Y,_),Kletki)),not(proverka(l(X,Y),Fonari,Kletki)).
 
est_neosveshennaya_kletka(Fonari,Kletki):-
    for(I,1,3),for(J,1,3),proverka_na_neos(l(I,J),Fonari,Kletki).
 
GOAL
obstanovka([f(1,1,1),f(2,1,1),f(3,3,1)],[],[]).
Только исправьте когда надо будет все 3 на 10, а пока что поле 3х3.
1
130 / 117 / 30
Регистрация: 14.11.2010
Сообщений: 707
29.12.2010, 22:59  [ТС]
вот он выводит здесь [l(2,3),l(3,1),l(1,2)] [l(3,1),l(1,2)] [l(1,2)] []
т.е здесь верный вариант расстановки это первый список?
а как можно сделать, чтобы выводил, только верный вариант?
0
 Аватар для Грымзик
2507 / 1483 / 37
Регистрация: 14.09.2009
Сообщений: 2,740
29.12.2010, 23:39
А я что-то этот баг не заметила, по идее его не должно быть, сейчас исправлю.
0
130 / 117 / 30
Регистрация: 14.11.2010
Сообщений: 707
29.12.2010, 23:45  [ТС]
понял, надо fail поставить, чтобы самый первый выводил...
Prolog
1
obstanovka([],Fields,Fonari):-not(est_neosveshennaya_kletka(Fonari,Fields)),write(Fonari),fail.
0
 Аватар для Грымзик
2507 / 1483 / 37
Регистрация: 14.09.2009
Сообщений: 2,740
29.12.2010, 23:47
Нет бага, это просто когда я отлаживала, я выводила промежуточные расположения фонарей, т.е просто сотрите write на 43 строке.
1
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
inter-admin
Эксперт
29715 / 6470 / 2152
Регистрация: 06.03.2009
Сообщений: 28,500
Блог
29.12.2010, 23:47

Логическая головоломка в Visual Prolog 5.2
Помогите пожалуйста написать программу, которая решает задачу в Visual Prolog 5.2: Билл, Джон и Ричард играют в одном оркестре. Они...

Комбинаторна головоломка на Swi Prolog
Помогите с заданием. Нужно написать программу которая методом &quot;образовать и проверить&quot; даст ответы на вопросы следующей головоломки:...

Головоломка про инструменты и языки
Маша, Лида, Женя и Катя играют на разных инструментах – виолончели, рояли, гитаре, скрипке, но каждая только на одном. Они же владеют...

логическая головоломка про прыжки в высоту
Написать программу на языке Prolog, реализующую логическую головоломку. Три девушки упражнялись, прыгая в высоту перед зачетом по...

Головоломка про аптекаря, бухгалтера и агронома.
http://puzzle-ru.blogspot.ru/2009/02/blog-post_18.html


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

Или воспользуйтесь поиском по форуму:
40
Ответ Создать тему
Новые блоги и статьи
Программный домашний кинотеатр
russiannick 27.09.2026
Сподобился на программный домашний кинотеатр. В качестве ЯВУ по традиции выбрал js. В помощники взял Яндекс-Алису. Было создано три зала на разные интересы. исторические и ретро сериал Хичкок. . .
Беседа с ИИ о программистах, недопускающих к созданию и правке кода генеративные ИИ и причины этого
zorxor 21.09.2026
Раньше я радовался или получал некоторые эмоции, пусть небольшие, но всё же, от самого процесса написания кода, рекомпиляции и запуска, видя постепенное развитие программы и прочее. А теперь лень. . .
Мобильное приложение ColorStep
pavlinmavlin 17.09.2026
Реализовал приложение Красный, Зеленый, Синий в Unity3d + c#. Название изменил на ColorStep. Приложение прошло модерацию и теперь доступно для скачивания. Делал его сам, шаг за шагом — и вот,. . .
Запрет дублирования строк в табличной части
Maks 13.09.2026
Реализация из решения ниже выполнена на нетиповом справочнике "Нормы ТО" с табличной часть "Виды ТО", разработанного в КА2, со следующими реквизитами: - ВидТО (СправочникСсылка. ВидыТО); - ВидГСМ. . .
Скрипты Tampermonkey для CyberForum, ChatGPT, Claude и пр.
Jin X 06.09.2026
Скрипты Tampermonkey для CyberForum, ChatGPT, Claude и пр. Работая с форумом и нейросетями в браузере часто хочется что-то подкорректировать или добавить какого-то функционала. Ниже прикреплён. . .
Программа опроса у.з. расходомера SLS-720F
Argus19 02.09.2026
Программа опроса у. з. расходомера SLS-720F Программа опрашивает один раз в минуту три ультразвуковых расходомера SLS-720F через интерфейс RS-485 по протоколу Modbus RTU. Опрашиваются регистры. . .
Hyper-V: Компьютер должен поддерживать доверенный платформенный модуль 2.0.
Maks 31.08.2026
При установке Windows 11 на виртуальную машину Hyper-V 2-го поколения вылезла такая ошибка: Решение: в параметрах виртуальной машины, в разделе "Безопасность" (Security) активировать флаг. . .
Архитектура биовида Стива в Майнкрафте: Зачем бонобо кубический каннибализм
anaschu 30.08.2026
Кубический Вагинокапитализм в Minecraft: Математический инвариант ОДУ и рок Стивов-бонобо Главная задача разработанной «Модели Всего» — наглядно продемонстрировать наличие системной «судьбы». . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru