Рекурсия для эрланга не работает. Получение ошибки соответствия функционального предложения - PullRequest
0 голосов
/ 13 апреля 2019

Итак, у меня проблемы с рекурсией.Я получаю ошибку соответствия предложения функции.Рекурсия прекращается, когда каждый ученик получает одинаковое количество конфет.Я уверен, что правильно выполнил условия выхода из рекурсии.Что не так?

-module(assignment3). 
-export([main/0, students/4, givecandy/4, teachergivecandy/4]).

main() ->
    io:fwrite("Hello\n"),
    students(4, 2, 2, 1). %Define how many candy each students get

givecandy(Student1, Student2, Student3, Turn) when (Student1 == Student2) and (Student2 == Student3) -> 1;
% recursivecandy(Student1, Student2, Student3, Turn) when (Student1 /= Student2) and (Student2 /= Student3) -> givecandy().

givecandy(Student1, Student2, Student3, Turn) when (Student1 /= Student2) and (Student2 /= Student3) ->
    io:format("Turn123"),
    Student1Total = (Student1 div 2) + (Student3 div 2),
    Student2Total = (Student2 div 2) + (Student1 div 2),
    Student3Total = (Student3 div 2) + (Student2 div 2),
    TurnCount = Turn + 1,
    teachergivecandy(Student1Total, Student2Total, Student3Total, TurnCount).

students(X, Y, Z, Turn) ->
    Student1 = X,
    Student2 = Y,
    Student3 = Z,
    TurnCount = Turn,
    io:format("Turn: ~p~n" , [TurnCount]),
    io:format("Student 1 Total: ~p~n" , [Student1]),
    io:format("Student 2 Total: ~p~n" , [Student2]),
    io:format("Student 3 Total: ~p~n" , [Student3]),
    givecandy(Student1, Student2, Student3, TurnCount).

teachergivecandy(Student1Total, Student2Total, Student3Total, TurnCount) ->
    io:format("hello1"),
    if 
        Student1Total rem 2 == 1 -> 
            Student1FinalTotal = Student1Total + 1; %Student1FinalTotal = Student1Total + 1,
        true ->
            Student1FinalTotal = Student1Total
    end,
    if 
        Student2Total rem 2 == 1 -> 
            Student2FinalTotal = Student2Total + 1; %Student1FinalTotal = Student1Total + 1,
        true ->
            Student2FinalTotal = Student2Total
    end,
    if 
        Student3Total rem 2 == 1 -> 
            Student3FinalTotal = Student3Total + 1; %Student1FinalTotal = Student1Total + 1,
        true ->
            Student3FinalTotal = Student3Total
    end,
    io:format("Student 1 Total: ~p~n" , [Student1FinalTotal]),
    io:format("Student 2 Total: ~p~n" , [Student2FinalTotal]),
    io:format("Student 3 Total: ~p~n" , [Student3FinalTotal]),
    io:format("Turn: ~p~n" , [TurnCount]),
    givecandy(Student1FinalTotal, Student2FinalTotal, Student3FinalTotal, TurnCount).

Ответы [ 2 ]

3 голосов
/ 13 апреля 2019

Ваш givecandy/4 не соответствует ни одному функциональному предложению.Кажется, вы хотите проверить, что у всех 3 учеников одинаковые конфеты или нет, поэтому вы можете изменить их следующим образом:

givecandy(Student1, Student1, Student1, _Turn) -> 1;
givecandy(Student1, Student2, Student3, Turn) ->
    io:format("Turn123"),
    Student1Total = (Student1 div 2) + (Student3 div 2),
    Student2Total = (Student2 div 2) + (Student1 div 2),
    Student3Total = (Student3 div 2) + (Student2 div 2),
    TurnCount = Turn + 1,
    teachergivecandy(Student1Total, Student2Total, Student3Total, TurnCount).

Результат в оболочке:

1>assignment3:main().
Hello
Turn: 1
Student 1 Total: 4
Student 2 Total: 2
Student 3 Total: 2
Turn123hello1Student 1 Total: 4
Student 2 Total: 4
Student 3 Total: 2
Turn: 2
Turn123hello1Student 1 Total: 4
Student 2 Total: 4
Student 3 Total: 4
Turn: 3
1

У меня маленькийкод для решения этой проблемы ниже:

-module(foo).
-compile(export_all).

start()->
    io:format("A   B   C   Turns~n"),
    d(4, 2, 2, 0).
d(_A, _A, _A, B) ->
    io:format("~p   ~p   ~p   ~p~n",[_A, _A, _A, B]);
d(A, B, C, D)->
    io:format("~p   ~p   ~p   ~p~n", [A, B, C, D]),
    Na = check(A, B),
    Nb = check(B, C),
    Nc = check(C, A),
    d(Na, Nb, Nc, D + 1).

even(X) when X >= 0 -> (X band 1) == 0.
check(A, B)->
    N = trunc((A + B)/2),
    case even(N) of
        true -> N;
        false -> N + 1
    end.

Результат в оболочке:

> foo:start().
A   B   C   Turns
4   2   2   0
4   2   4   1
4   4   4   2
ok
0 голосов
/ 13 апреля 2019

У вас есть два условия для givecandy с условиями охраны (Student1 == Student2) and (Student2 == Student3) и (Student1 /= Student2) and (Student2 /= Student3).Но может случиться так, что оба охранника потерпят неудачу, например givecandy(1,2,2).

Вероятно, один из рекурсивных вызовов выглядит так («вероятно», потому что вы не включаете сообщение об ошибке в вопрос, и оно должно точно сказать, какие функции и аргументы являются проблемой).Таким образом, вам нужно добавить еще один пункт, чтобы обработать это дело или изменить охрану.

Хорошей практикой является, чтобы в последнем пункте не было охранников, чтобы он мог обрабатывать все пропущенные дела.Конечно, это может быть просто выбросить исключение, если нет ничего лучше!

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...