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

-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).
-1
Slay 13 Апр 2019 в 01:24

2 ответа

Лучший ответ

Ваш 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
3
bxdoan 13 Апр 2019 в 06:02

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

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

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

0
Alexey Romanov 13 Апр 2019 в 06:02