:- dynamic(cost_from_index/2).
:- dynamic(current_min/1).

main :-
	read_num(N),
	read_n_num_list(N, Jumps),
        findall(Cost, find_min_cost(Jumps, Cost), CostList),
        min_list(CostList, MinCost),
	write(MinCost),
	nl,
	halt.


find_min_cost(L, Cost) :-
        jump(1, L, 0, Cost).

jump(_Index, [_], Sum, Sum) :-
        write_min(Sum).

jump(Index, [H1, H2|R], Acc, AllCost) :-
        Cost is abs(H1 - H2),
        NewAcc is Cost + Acc,
        NewIndex is Index + 1,
        is_need_more_search(NewAcc),
        is_need_overwrite_index_cost(NewIndex, NewAcc),
        write_index_cost(NewIndex, NewAcc),
        jump(NewIndex, [H2|R], NewAcc, AllCost).
        
        
jump(Index, [H1, _H2, H3|R], Acc, AllCost) :-
        Cost is abs(H1 - H3),
        NewAcc is Cost + Acc,
        NewIndex is Index + 2,
        is_need_more_search(NewAcc),
        is_need_overwrite_index_cost(NewIndex, NewAcc),
        write_index_cost(NewIndex, NewAcc),
        assert(cost_from_index(NewIndex, NewAcc)),
        jump(NewIndex, [H3|R], NewAcc, AllCost).

write_index_cost(Index, NewCost) :-
        cost_from_index(Index, OldCost),
        integer(OldCost) ->
        (
         retract(cost_from_index(Index, OldCost)),
         assert(cost_from_index(Index, NewCost))
        )
        ;
        assert(cost_from_index(Index, NewCost)).

write_min(Min) :-
        current_min(OldMinTotalCost),
        integer(OldMinTotalCost) ->
        (
            Min < OldMinTotalCost,
            retract(current_min(OldMinTotalCost)),    
         assert(current_min(Min))
        )
        ;     
        assert(current_min(Min)).

is_need_overwrite_index_cost(Index, NewCost) :-
        cost_from_index(Index, OldCost),
        integer(OldCost) ->
        NewCost < OldCost
        ;         
        true.
        

is_need_more_search(Cost) :-
        current_min(OldMinTotalCost),
        integer(OldMinTotalCost) ->
        Cost < OldMinTotalCost
        ;
        true.

read_n_num_list(Num, List) :-
	read_n_num_list_aux(Num, [], List),
	!.
read_n_num_list_aux(0, List, List).
read_n_num_list_aux(Num, Old, Accum) :-
	read_num(NewItem),
	NewNum is Num - 1,
	append(Old, [NewItem], NewList),
	read_n_num_list_aux(NewNum, NewList, Accum).

read_str(S) :-
        read_string(current_input, ' \n', '', _, S).

read_num(N) :-
	read_str(S),
	number_string(N, S).

:- main.
