Erlang Almost Magic Square
-module(almost_magic_square).
-export([almost_magic_square/1]).

almost_magic_square(A) ->
    Rows = chunk3(A),
    RowSums = [lists:sum(R) || R <- Rows],
    ColSums = [lists:sum([lists:nth(C, R) || R <- Rows]) || C <- [1, 2, 3]],
    MaxSum = lists:max(RowSums ++ ColSums),
    FinalRows = balance(0, 0, RowSums, ColSums, Rows, MaxSum),
    lists:append(FinalRows).

chunk3([]) -> [];
chunk3(List) ->
    {Row, Rest} = lists:split(3, List),
    [Row | chunk3(Rest)].

balance(I, J, RowSums, ColSums, Rows, MaxSum) when I < 3, J < 3 ->
    RowSumI = lists:nth(I + 1, RowSums),
    ColSumJ = lists:nth(J + 1, ColSums),
    Diff = min(MaxSum - RowSumI, MaxSum - ColSumJ),
    Rows1 = add_at(Rows, I, J, Diff),
    RowSums1 = add_at_list(RowSums, I, Diff),
    ColSums1 = add_at_list(ColSums, J, Diff),
    NextI = case lists:nth(I + 1, RowSums1) of MaxSum -> I + 1; _ -> I end,
    NextJ = case lists:nth(J + 1, ColSums1) of MaxSum -> J + 1; _ -> J end,
    balance(NextI, NextJ, RowSums1, ColSums1, Rows1, MaxSum);
balance(_, _, _, _, Rows, _) ->
    Rows.

add_at(Rows, I, J, Diff) ->
    [case Idx of
         I -> [case Jdx of J -> V + Diff; _ -> V end
               || {Jdx, V} <- lists:zip(lists:seq(0, length(Row) - 1), Row)];
         _ -> Row
     end || {Idx, Row} <- lists:zip(lists:seq(0, length(Rows) - 1), Rows)].

add_at_list(List, Idx0, Diff) ->
    [case I of Idx0 -> V + Diff; _ -> V end
     || {I, V} <- lists:zip(lists:seq(0, length(List) - 1), List)].

This adjusts the matrix toward a matching target sum so the rows and columns line up more like a magic square.