#prolog
#пролог
Вопрос:
этот код используется для рисования треугольника, пожалуйста, кто-нибудь может объяснить, как это работает
predicates
star(integer).
count(integer,integer).
clauses
star(1):-write('*'),!.
star(X):-X<=0,!.
star(X):-count(1,X),Z=x-1,nl,star(Z),!.
count(X,Y):-X<=Y,write('*'),X1=X 1,count(X1,Y),!.
count(X<Y):-X>Y,!.
этот код рисует 5 звезд,
4,3,2,1, как я делаю, чтобы начать с 1,2,3,4,5
Комментарии:
1. с другим прологом,
?- N=5,forall(between(1,N,R),(forall(between(1,R,_),write(*)),nl)).
2. Синтаксические ошибки:
<=
следует заменить на=<
поскольку<=
имеет другое значение в prolog.x-1
должно бытьX-1
. Назначение выполняется сis
помощью not=
, так, например,X1=X 1
должно бытьX1 is X 1
.3. @mbratch: я думаю, что это синтаксис, используемый Win-Prolog
4. @CapelliC ах, хорошо. Я не знаком с Win-Prolog. OP пометил это как SWI. Это означает, что ваш альтернативный 1-liner — хорошая альтернатива.
Ответ №1:
CapelliC получает похвалу за решение, но я лишь слегка изменю его для ясности и попытаюсь добавить некоторые пояснения:
% Print a triangle of 1 to N stars
star(N) :- star(1, N). % (I modified this slightly to accept N parameter)
% Print rows of NStars stars up to MaxStars stars
star(NStars , MaxStars ) :-
NStars =< MaxStars , % Print this row if NStars <= MaxStars
row_of_stars(NStars), % Print NStars for this row
NStars1 is NStars 1, % Increment the star count
star(NStars1, MaxStars ). % recursively print NStar1 to MaxStars triangle
star(NStars, MaxStars) :-
NStars > MaxStars . % Done when exceed MaxStars
% Print NumStars stars
row_of_stars(NumStars) :-
row_of_stars(1, NumStars). % Print NumStars starting with star number 1
row_of_stars(N, MaxStars) :-
N =< MaxStars, % This case is if star number doesn't exceed max
write('*'), % Print a star
N1 is N 1, % Increment the star count
print_a_star(N1, MaxStars). % Print the next star in the row
row_of_stars(N, MaxStars) :-
N > MaxStars, nl. % Done when exceed MaxStars
Эта проблема была решена с использованием двух основных предикатов: star
и row_of_stars
(ранее, count
). star
Предикат управляет проблемой на уровне «треугольника». То есть он фокусируется на строках: сколько строк нужно напечатать и сколько звездочек должна получить каждая строка при печати. Другой предикат row_of_stars
(или ранее count
) фокусируется на одном ряду из заданного количества звезд. Он просто печатает количество звезд, которое ему указано для печати. Поскольку проблема требует повторения или итерации по строкам, а также количества звездочек в строке, проблема упрощается путем разделения решения на эти две области.
Комментарии:
1. @CapelliC хаха, нет проблем. 🙂
Ответ №2:
Вы должны обойти верхний предел:
star :- star(0, 5).
star(C, X) :- C < X, count(0, C), C1 is C 1, star(C1, X).
star(C, X) :- C >= X.
count(X, Y) :- X =< Y, write('*'), X1 is X 1, count(X1,Y).
count(X, Y) :- X > Y, nl.
Измените обратные операторы, чтобы они соответствовали вашему prolog (т. Е. is
become =
, >=
become =>
и т. Д.).
Обратите внимание, что сокращения не являются обязательными… Используйте с осторожностью.
?- star.
*
**
***
****
*****
Комментарии:
1. КапеллиК, пожалуйста, можешь объяснить, как работают счетчик и звезда, пожалуйста
2. Сейчас я немного ленив 🙂 Подробное объяснение требует гораздо больше усилий, чем написание такого простого кода. Что там вы не можете понять?
3. о, ^ _^ большое спасибо… Я не могу понять, почему мы используем star и count вместе
4. Возможно, код мог бы быть проще, но я предпочел сохранить вашу структуру. В любом случае, я думаю, что ограничение цикла в вашем коде неявно равно 0, тогда, как я уже сказал, необходимость его обойти…