编写一个程序,输出所有可能放置+或 - 或之间的任何内容 数字1,2,...,9(按此顺序),结果如此 总是100.例如:1 + 2 + 34 - 5 + 67 - 8 + 9 = 100.
我用Python解决了这个问题,以获得 11个答案:
import itertools
for operator in [p for p in itertools.product(['+','-',''], repeat=8)]:
values = zip([str(x) for x in range(1, length+1)], operator) + ['9']
code = ''.join(itertools.chain(*values))
if 100 == eval(code):
print "%s = %d" % (code, eval(code))
这是我的第二个Python代码(https://gist.github.com/prosseek/41201d6508f01cf1643e):
[1, 2, 34, -5, 67, -8, 9]
[1, 23, -4, 56, 7, 8, 9]
[12, 3, -4, 5, 67, 8, 9]
[123, -4, -5, -6, -7, 8, -9]
[1, 23, -4, 5, 6, 78, -9]
[12, 3, 4, 5, -6, -7, 89]
[12, -3, -4, 5, -6, 7, 89]
[123, -45, -67, 89]
[123, 45, -67, 8, -9]
[1, 2, 3, -4, 5, 6, 78, 9]
[123, 4, -5, 67, -89]
我还在Prolog中找到了一个建议的解决方案 (http://www.reddit.com/r/programming/comments/358tnp/five_programming_problems_every_software_engineer/cr2dvsz):
sum([Head|Tail],Signs,Result) :-
sum(Head,Tail,Signs,Result).
sum(X,[],[],X).
sum(First,[Second|Tail],['+'|Signs],Result) :-
Head is First + Second,
sum(Head,Tail,Signs,Result).
sum(First,[Second|Tail],['-'|Signs],Result) :-
Head is First - Second,
sum(Head,Tail,Signs,Result).
sum(First,[Second|[Third|Tail]],['+'|[''|Signs]],Result) :-
C is Second*10+Third,
Head is First + C,
sum(Head,Tail,Signs,Result).
sum(First,[Second|[Third|Tail]],['-'|[''|Signs]],Result) :-
C is Second*10+Third,
Head is First - C,
sum(Head,Tail,Signs,Result).
然而,这提供了仅4个解决方案(不是11,正如预期的那样):
?- sum([1,2,3,4,5,6,7,8,9],X,100).
X = [+, +, -,+, +, +,'',+] ;
X = [+, +,'',-, + '', -,+] ;
X = [+,'', -,+, +, +,'',-] ;
X = [+,'', -,+ '', +, +,+] ;
false.
这是因为''
不会显示为第一个列表项。因此,系统会跳过解决方案[12,...]
和[123,...]
。
我尝试添加sum(First,[Second|Tail],[''|Signs],Result) :- Head is First*10 + Second, sum(Head,Tail,Signs,Result).
,
但这样做会返回 15个解决方案,而不是11个。
解释说明1+23
到((1)+2)*10+3
的解释错误。
?- sum([1,2,3], [+,''], Result).
Result = 33.
然后,如何在Prolog中解决这个问题?在这个例子中,如何教授Prolog 1 + 23
是24
?
答案 0 :(得分:2)
使用dcg,我们首先定义nonterminal sep//0
:
sep --> "+" | "-" | "".
然后,我们运行以下查询(使用phrase/2
,sep//0
,read_from_codes/2
和(=:=)/2
):
?- set_prolog_flag(double_quotes,chars).
true.
?- phrase(("1",sep,"2",sep,"3",sep,"4",sep,"5",sep,"6",sep,"7",sep,"8",sep,"9"),Cs),
read_from_codes(Cs,Expr),
Expr =:= 100.
Cs = [1,+,2,+,3,-,4,+,5,+,6,+,7,8,+,9], Expr = 1+2+3-4+5+6+78+9
; Cs = [1,+,2,+,3,4,-,5,+,6,7,-,8,+,9], Expr = 1+2+34-5+67-8+9
; Cs = [1,+,2,3,-,4,+,5,+,6,+,7,8,-,9], Expr = 1+23-4+5+6+78-9
; Cs = [1,+,2,3,-,4,+,5,6,+,7,+,8,+,9], Expr = 1+23-4+56+7+8+9
; Cs = [1,2,+,3,+,4,+,5,-,6,-,7,+,8,9], Expr = 12+3+4+5-6-7+89
; Cs = [1,2,+,3,-,4,+,5,+,6,7,+,8,+,9], Expr = 12+3-4+5+67+8+9
; Cs = [1,2,-,3,-,4,+,5,-,6,+,7,+,8,9], Expr = 12-3-4+5-6+7+89
; Cs = [1,2,3,+,4,-,5,+,6,7,-,8,9], Expr = 123+4-5+67-89
; Cs = [1,2,3,+,4,5,-,6,7,+,8,-,9], Expr = 123+45-67+8-9
; Cs = [1,2,3,-,4,-,5,-,6,-,7,+,8,-,9], Expr = 123-4-5-6-7+8-9
; Cs = [1,2,3,-,4,5,-,6,7,+,8,9], Expr = 123-45-67+89
; false.
答案 1 :(得分:1)
与CapelliC的解决方案完全相同,但适用于SWI-Prolog和模块lambda:
:- use_module(library(lambda)).
sum_100(Atom) :-
L = [1,2,3,4,5,6,7,8,9],
O = [_A,_B,_C,_D,_E,_F,_G,_H,' '],
maplist(\X^member(X, [+,-,' ']), O),
foldl(\X^Y^Z^T^(Y = ' '
-> append(Z,[X], T)
; append(Z,[X,Y], T)), L, O, [], Expr),
atomic_list_concat(Expr, Atom),
term_to_atom(Term, Atom),
Term =:= 100.
示例查询:
?- sum_100(X).
X = '1+2+3-4+5+6+78+9' ;
X = '1+2+34-5+67-8+9' ;
X = '1+23-4+5+6+78-9' ;
X = '1+23-4+56+7+8+9' ;
X = '12+3+4+5-6-7+89' ;
X = '12+3-4+5+67+8+9' ;
X = '12-3-4+5-6+7+89' ;
X = '123+4-5+67-89' ;
X = '123+45-67+8-9' ;
X = '123-4-5-6-7+8-9' ;
X = '123-45-67+89' ;
false.