2013-09-24 4 views
1

나는 Erlang을 배우면서 책에서 연습을하고있어, 나는 그 중 하나에 붙어있다. 내가 전체 문제를 인용하고 지금까지 한 일을 설명하면 더 낫다. "숫자 1 아래에있는 절차의 반복 적용으로 에 도달하면 양수가 행복해진다. 1. 각 자릿수를 제곱한다. 당신이 19로 시작하는 경우 2. 계산 모든 제곱의 합 수의 예를 들어, :Erlang의 목록 및 목록 값 조작

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 함수를 작성하여 숫자가 만족한지 여부 (true 또는 false)와 N과 M 사이의 모든 행복한 숫자 을 각각 반환합니다. (힌트 : 기능을 디지털화하고 합계를 사용하십시오). 예 :

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 :

happy(28) → true 
happy(15) → false 
happy(5, 25) → [7, 10, 13, 19, 23]" 

은 그래서, N은 그 번호의 자릿수의 목록을 반환 양수 주어진 디지타이저/1 작성한

happy(N) -> happy1(digitize(N), []). 
happy1([], Acc) -> (Acc); 
happy1([Head|Tail], Acc1) -> happy1(Tail, [Head * Head|Acc1]). 
: 그래서 나는 지금까지 무엇을했는지 행복한 숫자
sum(N) when N > 0 -> N + sum(N-1); 
sum(0) -> 0. 

이있다

그것은 목록의 요소를 사각형으로 만들지 만, 합계하는 방법을 생각해 낼 수 없으며 1 또는 4에 도달 할 때까지 재귀 적으로 다시 할 수 있습니다. 어떤 도움이나 아이디어입니까? 그리고 두 번째 부분 (all_happy/2)에 대해서는 제 권한이없는 의견으로는 목록 이해력을 사용해야하지만 다시 그것을 구현하는 방법은 확실하지 않습니다. 시간 내 줘서 고마워.

calculate([], Total)-> 
    Total; 
calculate([First | Rest], Total) -> 
    calculate(Rest, Total + (First * First)). 

를 질문의 주요 지점에, 당신 : 내가 발견

+1

이 운동은 멋지다 :) 당신은 프로젝트 오일러를 알고 있다면 나도 몰라 ... 그렇지 않은 경우, Erlang (또는 다른 언어)을 훈련하기 위해 이와 같은 많은 다른 작은 연습을 찾을 수 있습니다. – niahoo

답변

2

한가지는 직접 합계를 계산 할 수 happy1 루프, 당신은 추가 후 목록을 만들 필요가 없습니다 것입니다 불행한 숫자에 도달했는지 또는 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 

, 여기에 계산 방법을 건너 뛰고 주요 절이고 빌드 목록에 lists:sum 함수를 사용합니다.

happy(Num) -> 
    io:format("Current loop: ~p~n", [Num]), 
    Digits = [ X * X || X <- digitize(Num)], 
    happy(lists:sum(Digits)). 
꼬리 재귀를 통해 구현
+0

도움 주셔서 감사합니다. 실제로 나는이 문제에 대한 해결책을보고 싶습니다. 왜냐하면 저는 제가 할 수있는 모든 것을 시도했기 때문에, 어떻게해야 하는지를보고 이해하고 싶습니다. 그래서 네, 제발, 가능한 경우 게시하십시오. 다시 한번 감사드립니다. –

+0

나는 나의 대답을 편집했다. 나는 원래의 포스트에서 약간의 부정확성을 가지고 있었다. 나는 그 질문을 잘못 읽었다. 이제는 정확해야합니다. 명확한 설명이 필요하면 알려주세요. – kjw0188

+0

고마워, 이건 더 명확 할 수 없어! 가능하다면 당신의 대답을 N 번 투표 할 것입니다! :) 이해력은 작성되고 제공 될 때 놀라 울 정도로 쉽게 보입니다. –

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}