我正在学习一些Erlang并从书中做练习,所以我被困在其中一个上面。如果我引用整个问题然后解释到目前为止我做了什么,那就更好了: “如果重复申请,正数就很高兴 达到了数字1以下的程序。 1.对数字的每个数字进行平方 2.计算所有方块的总和 例如,如果你从19开始:
1 * 1 + 9 * 9 = 1 + 81 = 82
8 * 8 + 2 * 2 = 64 + 4 = 68
6 * 6 + 8 * 8 = 36 + 64 = 100
1 * 1 + 0 * 0 + 0 * 0 = 1 + 0 + 0 = 1
(即19是一个快乐的数字) 你怎么知道一个号码不开心的时候?其实,每个人都不高兴 数字最终将达到周期4,16,37,58,89,145,42,20,4, ...因此,在该周期(例如4)中寻找任何数字就足够了 得出结论,原始数字不满意。 编写函数happy / 1和all_happy / 2,返回 数字是否满意(真或假)和所有快乐数字 分别在N和M之间。 (提示:使用数字化和 和)。 例子:
happy(28) → true
happy(15) → false
happy(5, 25) → [7, 10, 13, 19, 23]"
所以,我创建了一个数字化仪/ 1,给出一个正数N返回该数字中的数字列表:
digitize(N) -> digitize1(N, []).
digitize1(N, Acc) when N > 0 -> digitize1(N div 10, [N rem 10| Acc]);
digitize1(N, Acc) when N == 0 -> Acc.
,和/ 1:
sum(N) when N > 0 -> N + sum(N-1);
sum(0) -> 0.
所以到目前为止我所做的快乐数字是:
happy(N) -> happy1(digitize(N), []).
happy1([], Acc) -> (Acc);
happy1([Head|Tail], Acc1) -> happy1(Tail, [Head * Head|Acc1]).
它对列表中的元素进行了平方,但是我无法想出如何对它们求和并再次递归地再次执行它直到达到1或4.任何帮助或想法? 对于第二部分(all_happy / 2),在我的非主管意见中,我应该使用列表理解,但同样,我不太确定如何实现它。谢谢你的时间。
答案 0 :(得分:2)
我注意到的一件事是你的happy1循环可以直接计算总和,你不需要列表然后添加它们:
calculate([], Total)->
Total;
calculate([First | Rest], Total) ->
calculate(Rest, Total + (First * First)).
对于问题的要点,您可以使用模式匹配来检测您是否已达到不满意的数字,或者您是否已达到1。
我有一个有效的实施方案,但我猜你想为自己弄清楚细节。如果您要我发布,请告诉我。
这是我的解决方案:
-module(happy).
-export([happy/1]).
happy(1) ->
happy;
happy(4) ->
not_happy;
happy(Num) ->
io:format("Current loop: ~p~n", [Num]),
Digits = digitize(Num),
happy(calculate(Digits, 0)).
digitize(N) -> digitize1(N, []).
digitize1(N, Acc) when N > 0 -> digitize1(N div 10, [N rem 10| Acc]);
digitize1(N, Acc) when N == 0 -> Acc.
calculate([], Total)->
Total;
calculate([First | Rest], Total) ->
calculate(Rest, Total + (First * First)).
输出:
3> happy:happy(55).
Current loop: 55
Current loop: 50
Current loop: 25
Current loop: 29
Current loop: 85
Current loop: 89
Current loop: 145
Current loop: 42
Current loop: 20
not_happy
4> happy:happy(4).
not_happy
5> happy:happy(19).
Current loop: 19
Current loop: 82
Current loop: 68
Current loop: 100
happy
6> happy:happy(20).
Current loop: 20
not_happy
7> happy:happy(21).
Current loop: 21
Current loop: 5
Current loop: 25
Current loop: 29
Current loop: 85
Current loop: 89
Current loop: 145
Current loop: 42
Current loop: 20
not_happy
如果您对如何使用列表推导感兴趣,这里是跳过calculate方法的主要子句,并将lists:sum
函数与构建列表一起使用:
happy(Num) ->
io:format("Current loop: ~p~n", [Num]),
Digits = [ X * X || X <- digitize(Num)],
happy(lists:sum(Digits)).
答案 1 :(得分:0)
通过尾递归实现的另一个解决方案:
digitize(N) -> digitize1(N, [],N).
digitize1(N, Acc,M) when N > 0 -> digitize1(N div 10, [N rem 10| Acc],M);
digitize1(N, Acc,M) when N == 0 -> sum_digits(Acc,0,M).
sum_digits([],Acc,N) when Acc == 1 -> {happy,N,Acc};
sum_digits([], Acc,N) when Acc == 4 -> {unhappy,N,Acc};
sum_digits([],Acc,N) -> {digitize,Acc}, digitize1(Acc,[],N);
sum_digits([H|T],Acc,N)-> sum_digits(T,H*H+Acc,N).
使用:
1> c('test.erl').
test.erl:15: Warning: a term is constructed, but never used
{ok,test}
2> c('test.erl').
test.erl:15: Warning: a term is constructed, but never used
{ok,test}
3> c('test.erl').
test.erl:15: Warning: a term is constructed, but never used
{ok,test}
4> test:digitize(55).
{unhappy,55,4}
5> test:digitize(19).
{happy,19,1}
6> test:digitize(5).
{unhappy,5,4}
7> test:digitize(20).
{unhappy,20,4}
8> test:digitize(21).
{unhappy,21,4}