如何从给定列表中返回对目标数字进行 mod 0 的数字列表?

发布于 2025-01-17 05:25:20 字数 580 浏览 0 评论 0原文

在我的函数 modded(X,Y,Z) 中,根据给定数字 Y 和给定数字 Z 列表生成一个列表。我想做的是遍历列表 Z 的每个值并查看如果列表中的当前值能整除 Y,(Y/Zz == 0)。我对如何访问每个 Z 的值有点困惑,因为 Prolog 没有传统的迭代器。

modded(X,16,[2,3,4,5,7,8]) 的预期行为将返回 [2,4,8] 列表。只允许完全除数。

modded([],Y,Z):-
    % X is the generated list, Y is the number, Z is a list of given numbers.
    %Base case: Z is empty
    Z =:= [],
    X =:= Z.

modded([Zz|T],Y,[H|T]):-
    %Recursive is Y > 1, Zz is an element of Z
    0 is Y mod Zz,
    Y =< Z - 1,
    Zz is Z + 1,
    % Want to add to a if Y mod Zz == 0
    modded(T,Y,Zz).

In my function modded(X,Y,Z), a list is generated based off of a given number Y and a given list of numbers Z. What I am trying to do is go through the list Z for each of its values and see if the current value in the list will cleanly divide Y, (Y/Zz == 0). I am a bit confused on how to access each of Z's values since Prolog does not have traditional iterators.

Expected behavior would be for modded(X,16,[2,3,4,5,7,8]) to return a list of [2,4,8]. Only complete divisors are allowed.

modded([],Y,Z):-
    % X is the generated list, Y is the number, Z is a list of given numbers.
    %Base case: Z is empty
    Z =:= [],
    X =:= Z.

modded([Zz|T],Y,[H|T]):-
    %Recursive is Y > 1, Zz is an element of Z
    0 is Y mod Zz,
    Y =< Z - 1,
    Zz is Z + 1,
    % Want to add to a if Y mod Zz == 0
    modded(T,Y,Zz).

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

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

发布评论

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

评论(1

勿忘心安 2025-01-24 05:25:20
modded([], _, []).

modded([Zz|T], Y, [Zz|Z]) :- % Case where Zz is a divisor of Y.
    0 =:= Y mod Zz,
    modded(T, Y, Z).

modded(T, Y, [Zz|Z]) :- % Case where Zz is not a divisor of Y.
    0 =\= Y mod Zz,
    modded(T, Y, Z).

然后

?- modded(X,16,[2,3,4,5,7,8]).
X = [2, 4, 8]

基本情况包含输入和输出的空列表。

如果 Zz 是除数并且被添加到结果列表 [Zz|T],则中间情况成立。

如果 Zz 不是除数并且没有添加到结果列表 T 中,则最后一种情况成立

。两种计算情况都向下递归剩余的 Z 列表以填充剩余的结果 T。


如果你不被迫使用递归,你可能会写:

modded(X, Y, Z) :-
    findall(Zz, (member(Zz, Z), 0 =:= Y mod Zz), X).

“找到所有属于 Z 的成员和 Y 的约数的 Zz,并将它们存储在 X 中”。

或者

num_divisor(Y, Zz) :-
    0 =:= Y mod Zz.

modded(X, Y, Z) :-
    include(num_divisor(Y), Z, X).

您可能需要听到但可能不会关心的评论:

如果您使用的是 SWI Prolog,则 https:/ /swish.swi-prolog.org/ 是一个出色的工具,您可以立即尝试一些代码,而无需编辑/保存/重新加载。尝试将一些代码放入其中:

Z =:= []
Type error: `evaluable' expected, found `[]' (an empty_list)

该行永远不会起作用。下一行也不是:

X =:= Z.
Arguments are not sufficiently instantiated
In:
   [1] _1722=:=_1724

modded([Zz|T],Y,[H|T]) 行中,通过在这些位置中使用 T ,您可以表示两个列表的尾部必须相同。这些列表之一是输入,一个是过滤后的输出。那是行不通的。

0 is Y mod Zz 行中,它表示 Zz 除 Y。 modded 的参数不是应该是(结果、数字、输入)吗?因此,使用 modded([Zz|T],Y,[H|T]) 不会是 H 除以 Y,而不是 Zz > 哪个还没有价值?

0 is Y mod Zz 行中,它表示 Zz 除 Y。但是,如果它确实有效并且输入到达 3,则该行将为 false,因为 3 不将 16 均分,这样整个程序就会失败。如果数字不是除数,则无法处理该怎么做。

Y =< Z - 1 也不像其他语言那样工作,=< 不会计算 Z - 1。这几乎是幸运的,因为 Z 在代码中没有值。 (即使有,你不是说它是输入列表吗?Y =< [2,3,4,5,7,8] - 1 会是什么?)

Zz 是 Z + 1 Z 在这里也没有值,但如果有的话也会失败,因为 Zz 与 modded([Zz ) 绑定在顶部,并且它
modded(T,Y,Zz) 不是输入列表 modded 的最后一个参数,为什么它现在是除数?第一个参数是结果,现在它是输入列表的尾部?

是的,您很困惑,在尝试构建基础知识之前,您需要熟悉基础知识。

统一并证明搜索

在 LearnPrologNow 递归向下列表

modded([], _, []).

modded([Zz|T], Y, [Zz|Z]) :- % Case where Zz is a divisor of Y.
    0 =:= Y mod Zz,
    modded(T, Y, Z).

modded(T, Y, [Zz|Z]) :- % Case where Zz is not a divisor of Y.
    0 =\= Y mod Zz,
    modded(T, Y, Z).

Then

?- modded(X,16,[2,3,4,5,7,8]).
X = [2, 4, 8]

The base case holds for an empty list of input and output.

The middle case holds if Zz is a divisor and is added to the result list [Zz|T].

The last case holds if Zz is not a divisor and is not added to the result list T.

Both calculating cases recurse down the remaining Z list to fill in the remaining T of results.


If you weren't forced to use recursion, you might write:

modded(X, Y, Z) :-
    findall(Zz, (member(Zz, Z), 0 =:= Y mod Zz), X).

"Find all the Zzs which are members of Z and divisors of Y, and store them in X".

or

num_divisor(Y, Zz) :-
    0 =:= Y mod Zz.

modded(X, Y, Z) :-
    include(num_divisor(Y), Z, X).

Comments you may need to hear but likely won't care about:

If you are using SWI Prolog then https://swish.swi-prolog.org/ is a brilliant tool you can try bits of code instantly without the edit/saving/reload. Try putting some of your bits of code into it:

Z =:= []
Type error: `evaluable' expected, found `[]' (an empty_list)

That line is never going to work. Nor is the next line:

X =:= Z.
Arguments are not sufficiently instantiated
In:
   [1] _1722=:=_1724

In the line modded([Zz|T],Y,[H|T]) by using T in those to places, you're saying that the tail of both lists must be the same. One of those lists is the input, one is the filtered output. That can't work.

In the line 0 is Y mod Zz it says Zz divides Y. Weren't the arguments to modded supposed to be (Result, Number, Input)? So with modded([Zz|T],Y,[H|T]) wouldn't that be H dividing into Y, not Zz which has no value yet?

In the line 0 is Y mod Zz it says Zz divides Y. But if it did work and the input got to 3 this line would be false, because 3 doesn't divide 16 evenly, so the whole program would fail. There's no handling for what to do if a number isn't a divisor.

The line Y =< Z - 1 doesn't work like other languages either, =< will not calculate Z - 1. Which is almost lucky because Z has no value here in the code. (And even if it had, didn't you say it was the input list? What is Y =< [2,3,4,5,7,8] - 1 going to be?)

Zz is Z + 1 Z also has no value here, but if it had it would fail because Zz is bound at the top with modded([Zz and it
modded(T,Y,Zz) wasn't the last argument of modded the input list, why is it now a divisor? And the first argument was the result, now it's the tail of the input list?

Yes you are confused, you need to get familiar with the basics before trying to build on them.

Unification and proof search

Recursing down lists at LearnPrologNow.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文