序言。如何返回范围内的整数列表

发布于 2025-01-15 09:33:55 字数 451 浏览 0 评论 0原文

我想返回给定输入的整数列表: rList :- (X,Y,[]) (1,4, N) 返回 N= [1,2,3,4]。 这也需要适用于负整数,反之亦然 输入 (4,-2, N) 返回 N= [4,3,2,1,0,-1,-2]。

到目前为止,我已经编写了开头的程序,但我被困住了。有人可以向我解释我应该如何继续吗?

rList(_ , _ ,[ ]).
rList(X, Y, [X|T])  :-
    must_be(integer, X),
    must_be(integer, Y),
    X =< Y,
    N is X + 1,
    rList(N,Y,T).

返回:rList(1,4,N) N= [], [1], [1,2], [1,2,3], [1,2,3,4], false。此外,所有这些第一步不应因此而被退回。我只需要最后一个列表 ([1,2,3,4]) 作为输出。

I want to return a list of integers given an input:
rList :- (X,Y,[])
(1,4, N) returns N= [1,2,3,4].
This also needs to work for negative integers and for the other way around such that
the input (4,-2, N) returns N= [4,3,2,1,0,-1,-2].

So far i have programmed the beginning, but I am stuck. Can someone explain to me how I should continue?

rList(_ , _ ,[ ]).
rList(X, Y, [X|T])  :-
    must_be(integer, X),
    must_be(integer, Y),
    X =< Y,
    N is X + 1,
    rList(N,Y,T).

this returns for: rList(1,4,N) N= [], [1], [1,2], [1,2,3], [1,2,3,4], false. Also all those first steps should not be given back as a result. I just need the last list ([1,2,3,4]) as an output.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

余厌 2025-01-22 09:33:55

为了性能,增量或减量决策应该一次,所以这里是:

range_list2(IntStart, IntEnd, Lst) :-
    integer(IntStart),
    integer(IntEnd),
    IntInc is sign(IntEnd - IntStart),
    range_list2_(IntStart, IntEnd, IntInc, Lst).
    
range_list2_(Int, Int, _IntInc, [Int]) :- !.
range_list2_(IntUpto, IntEnd, IntInc, [IntUpto|Lst]) :-
    IntUpto1 is IntUpto + IntInc,
    range_list2_(IntUpto1, IntEnd, IntInc, Lst).

swi-prolog 中的结果:

?- time(range_list2(-5, 5, L)).
% 23 inferences, 0.000 CPU in 0.000 seconds (89% CPU, 438237 Lips)
L = [-5,-4,-3,-2,-1,0,1,2,3,4,5].

?- time(range_list2(5, -5, L)).
% 23 inferences, 0.000 CPU in 0.000 seconds (89% CPU, 430623 Lips)
L = [5,4,3,2,1,0,-1,-2,-3,-4,-5].

The increment-or-decrement decision should be made once, for performance, so here it is:

range_list2(IntStart, IntEnd, Lst) :-
    integer(IntStart),
    integer(IntEnd),
    IntInc is sign(IntEnd - IntStart),
    range_list2_(IntStart, IntEnd, IntInc, Lst).
    
range_list2_(Int, Int, _IntInc, [Int]) :- !.
range_list2_(IntUpto, IntEnd, IntInc, [IntUpto|Lst]) :-
    IntUpto1 is IntUpto + IntInc,
    range_list2_(IntUpto1, IntEnd, IntInc, Lst).

Result in swi-prolog:

?- time(range_list2(-5, 5, L)).
% 23 inferences, 0.000 CPU in 0.000 seconds (89% CPU, 438237 Lips)
L = [-5,-4,-3,-2,-1,0,1,2,3,4,5].

?- time(range_list2(5, -5, L)).
% 23 inferences, 0.000 CPU in 0.000 seconds (89% CPU, 430623 Lips)
L = [5,4,3,2,1,0,-1,-2,-3,-4,-5].
时光无声 2025-01-22 09:33:55

一个可能的解决方案是:

range(Start, Stop, List) :-
    must_be(integer, Start),
    must_be(integer, Stop),
    findall(X, elem(Start,Stop,X), List).

elem(Start, Stop, Element) :-
    Step is sign(Stop-Start),
    N is abs(Stop-Start),
    between(0, N, I),
    Element is Start + I*Step.

示例:

?- range(1, 4, L).
L = [1, 2, 3, 4].

?- range(4, 1, L).
L = [4, 3, 2, 1].

?- range(-3, 3, L).
L = [-3, -2, -1, 0, 1, 2, 3].

?- range(5, 5, L).
L = [5].

?- range(5, 5, []).
false.

?- range(5, 6, [5, 6]).
true.

?- range(-5, -1, L).
L = [-5, -4, -3, -2, -1].

?- range(-1, -5, L).
L = [-1, -2, -3, -4, -5].

A possible solution is:

range(Start, Stop, List) :-
    must_be(integer, Start),
    must_be(integer, Stop),
    findall(X, elem(Start,Stop,X), List).

elem(Start, Stop, Element) :-
    Step is sign(Stop-Start),
    N is abs(Stop-Start),
    between(0, N, I),
    Element is Start + I*Step.

Examples:

?- range(1, 4, L).
L = [1, 2, 3, 4].

?- range(4, 1, L).
L = [4, 3, 2, 1].

?- range(-3, 3, L).
L = [-3, -2, -1, 0, 1, 2, 3].

?- range(5, 5, L).
L = [5].

?- range(5, 5, []).
false.

?- range(5, 6, [5, 6]).
true.

?- range(-5, -1, L).
L = [-5, -4, -3, -2, -1].

?- range(-1, -5, L).
L = [-1, -2, -3, -4, -5].
失退 2025-01-22 09:33:55

解决方案 1(常见解决方案):

?- findall(X, between(-2,4,X) , L).
L = [-2,-1,0,1,2,3,4].

解决方案 2(实现内置 Between):

my_between(L, U, X) :-
  L =< U, !,
  (   X = L 
  ;   L1 is L + 1,
      my_between(L1, U, X) ).

?- my_between(-2,4,X).
X = -2 ;
X = -1 ;
X = 0 ;
X = 1 ;
X = 2 ;
X = 3 ;
X = 4 ;
false.;

解决方案 3(遵循您的解决方案):

rList(X, Y ,[]) :- X > Y, !.
rList(X, Y, [X|T]) :-
  N is X + 1,
  rList(N,Y,T).

?- rList(-2, 4, L).
L = [-2,-1,0,1,2,3,4].

?- rList(4, 4, L).
L = [4].

?- rList(5, 4, L).
L = [].

--- 编辑 ---

谢谢@slago,我没有注意到这两个-way 要求,但它可以很容易实现:

my_between2(U, L, X) :-
  L =< U, !,
  (   X = U 
  ;   U1 is U - 1,
      my_between2(U1, L, X) ).


bi_between(L, U, X) :- L =< U, !, my_between(L, U, X).
bi_between(U, L, X) :- my_between2(U, L, X).

?- findall(X, bi_between(-2,4,X) , L).
L = [-2,-1,0,1,2,3,4].

?- findall(X, bi_between(4,-2,X) , L).
L = [4,3,2,1,0,-1,-2].

另外,对于 rList:

bi_rList(X, Y ,L) :- X =< Y, !, rList(X,Y,L).
bi_rList(X, Y, L) :- rList(Y,X,L1), reverse(L1,L).

?- bi_rList(-2, 4, L).
L = [-2,-1,0,1,2,3,4].

?- bi_rList(4, -2, L).
L = [4,3,2,1,0,-1,-2].

Solution 1 (common solution):

?- findall(X, between(-2,4,X) , L).
L = [-2,-1,0,1,2,3,4].

Solution 2 (implement built-in between):

my_between(L, U, X) :-
  L =< U, !,
  (   X = L 
  ;   L1 is L + 1,
      my_between(L1, U, X) ).

?- my_between(-2,4,X).
X = -2 ;
X = -1 ;
X = 0 ;
X = 1 ;
X = 2 ;
X = 3 ;
X = 4 ;
false.;

Solution 3 (follow your solution):

rList(X, Y ,[]) :- X > Y, !.
rList(X, Y, [X|T]) :-
  N is X + 1,
  rList(N,Y,T).

?- rList(-2, 4, L).
L = [-2,-1,0,1,2,3,4].

?- rList(4, 4, L).
L = [4].

?- rList(5, 4, L).
L = [].

--- Edit ---

Thanks @slago, I didn't notice the two-way requirement, but it can be easily implemented:

my_between2(U, L, X) :-
  L =< U, !,
  (   X = U 
  ;   U1 is U - 1,
      my_between2(U1, L, X) ).


bi_between(L, U, X) :- L =< U, !, my_between(L, U, X).
bi_between(U, L, X) :- my_between2(U, L, X).

?- findall(X, bi_between(-2,4,X) , L).
L = [-2,-1,0,1,2,3,4].

?- findall(X, bi_between(4,-2,X) , L).
L = [4,3,2,1,0,-1,-2].

Also, for rList:

bi_rList(X, Y ,L) :- X =< Y, !, rList(X,Y,L).
bi_rList(X, Y, L) :- rList(Y,X,L1), reverse(L1,L).

?- bi_rList(-2, 4, L).
L = [-2,-1,0,1,2,3,4].

?- bi_rList(4, -2, L).
L = [4,3,2,1,0,-1,-2].
土豪我们做朋友吧 2025-01-22 09:33:55

只需一个简单的操作

range(B,B,[B]).
range(A,B,[A|Ns]) :- A < B , A1 is A+1, range(A1,B,Ns) .
range(A,B,[A|Ns]) :- A > B , A1 is A-1, range(A1,B,Ns) .

就可以解决问题。如果你需要保护它,一个简单的装饰器就可以了:

range( A , B , Ns ) :- integer(A), integer(B), range_(A,B,Ns) .

range_( B , B , [B]    ) .
range_( A , B , [A|Ns] ) :- A < B , A1 is A+1, range_(A1,B,Ns) .
range_( A , B , [A|Ns] ) :- A > B , A1 is A-1, range_(A1,B,Ns) .

Just a simple

range(B,B,[B]).
range(A,B,[A|Ns]) :- A < B , A1 is A+1, range(A1,B,Ns) .
range(A,B,[A|Ns]) :- A > B , A1 is A-1, range(A1,B,Ns) .

should do the trick. If you need to guard it, a simple decorator will do:

range( A , B , Ns ) :- integer(A), integer(B), range_(A,B,Ns) .

range_( B , B , [B]    ) .
range_( A , B , [A|Ns] ) :- A < B , A1 is A+1, range_(A1,B,Ns) .
range_( A , B , [A|Ns] ) :- A > B , A1 is A-1, range_(A1,B,Ns) .
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文