我是Prolog的新手,并决定尝试解决一个问题,其中我有一系列符号,每个符号的值为1或-1。我需要的是将它们全部加在一起,一次一个元素,并提取哪个索引,第一次的总和降到0以下。因为我来自一个命令背景,我想象一个计数变量和一个for-loop,但显然我不能在Prolog中做到这一点。
value('(', 1).
value(')', -1).
main(R) :- readFile("input", R), ???
readFile(Path, R) :-
open(Path, read, File),
read_string(File, _, Str),
stringToCharList(Str, Xs),
maplist(value, Xs, R).
stringToCharList(String, Characters) :-
name(String, Xs),
maplist(toChar, Xs, Characters ).
toChar(X, Y) :- name(Y, [X]).
正如您所看到的,到目前为止我真正管理的所有内容都是读取包含序列的文件,并将其转换为1s和-1s。我不知道从哪里开始。我想这个问题有三个方面:
有什么建议吗?我可以以某种方式切断列表,其中迭代将总和降低到零以下,并返回长度?
答案 0 :(得分:4)
我将在辅助变量的Prolog中使用一个原则作为计数器,直到条件达到我们想要的为止。然后辅助计数器与基本情况中该点的变量统一。
我盲目地假设您的代码按照规定运行。我没有测试它(这取决于你)。
user
main(IndexAtZeroSum) :- readFile("input", R), index_at_zero_sum(R, IndexAtZeroSum).
readFile(Path, R) :-
open(Path, read, File),
read_string(File, _, Str),
stringToCharList(Str, Xs),
maplist(value, Xs, R).
stringToCharList(String, Characters) :-
name(String, Xs),
maplist(toChar, Xs, Characters ).
toChar(X, Y) :- name(Y, [X]).
% The following predicate assumes indexing starting at 0
index_at_zero_sum([V|Vs], IndexAtZeroSum) :-
index_at_zero_sum(Vs, V, 0, IndexAtZeroSum).
% When sum is zero, Index is what we want
index_at_zero_sum(_, 0, Index, Index).
index_at_zero_sum([V|Vs], Sum, CurIndex, Index) :-
S is Sum + V,
NextIndex is CurIndex + 1,
index_at_zero_sum(Vs, S, NextIndex, Index).
提供给定列表的索引,其中总和变为零。它通过使用辅助谓词index_at_zero_sum/2
来实现,从第一个值的和开始(总和是值本身)和从0开始的当前索引。所以第二个参数是索引0处的和。对index_at_zero_sum/4
的后续调用会递增索引并累加总和,直到总和变为0.此时,基本情况成功并将第4个参数与当前索引统一。如果在列表变空之前总和永远不会变为0,则谓词将失败。
index_at_zero_sum/4
:来避免阅读整个文件并创建数字列表
get_char/2