Skip to content

Instantly share code, notes, and snippets.

@pazworld
Last active August 29, 2015 14:06
Show Gist options
  • Save pazworld/2f2bc9871508d1e49063 to your computer and use it in GitHub Desktop.
Save pazworld/2f2bc9871508d1e49063 to your computer and use it in GitHub Desktop.
「上と左の合計」をErlangで(横へな22) その2 ref: http://qiita.com/pazworld/items/03a9d342025961e6e9ff
-module ( irrpas2 ).
-compile ( export_all ).
solve ( DataString ) ->
[ { Width, Height } | ConcatCells ] = parse_input_string ( DataString ),
TargetCellValueWithMemo = get_value ( Width - 1, Height - 1, ConcatCells, [] ),
get_right_two_digit ( element ( 1, TargetCellValueWithMemo ) ).
parse_input_string ( InputString ) ->
NumberStrings = string:tokens ( lists:delete ( $x, InputString ), ":," ),
[ list_to_tuple ( [ N - $0 || N <- M ] ) || M <- NumberStrings ].
get_right_two_digit ( X ) -> string:right ( "0" ++ integer_to_list ( X ), 2 ).
get_value ( 0, 0, _ConcatCells, ValueMemo ) -> { 1, ValueMemo };
get_value ( X, Y, _ConcatCells, ValueMemo ) when X < 0 orelse Y < 0 -> { 0, ValueMemo };
get_value ( X, Y, ConcatCells, ValueMemo ) ->
{ NX, NY } = normalize_position ( X, Y, ConcatCells ),
case lists:keyfind ( { NX, NY }, 1, ValueMemo ) of
{ _XY, Value } -> { Value, ValueMemo };
_Otherwise ->
LeftAndUpperCells = get_left_and_upper_cells ( NX, NY, ConcatCells ),
UniqueLeftAndUpperCells = lists:usort (
[ normalize_position ( CX, CY, ConcatCells ) || { CX, CY } <- LeftAndUpperCells ] ),
SumCellValueFunction = get_sum_cell_value_function ( ConcatCells ),
lists:foldl ( SumCellValueFunction, { 0, ValueMemo }, UniqueLeftAndUpperCells )
end.
get_sum_cell_value_function ( ConcatCells ) ->
fun ( { X, Y }, { SumValue, ValueMemo } ) ->
{ CellValue, ValueMemo2 } = get_value ( X, Y, ConcatCells, ValueMemo ),
{ SumValue + CellValue, [ { { X, Y }, CellValue } | ValueMemo2 ] }
end.
get_left_and_upper_cells ( X, Y, ConcatCells ) ->
IsInsideFunction = get_is_inside_function ( X, Y ),
case lists:filter ( IsInsideFunction, ConcatCells ) of
[ { _X, _Y, Width, Height } ] -> get_left_and_upper_cells ( X, Y, Width, Height );
_Otherwise -> get_left_and_upper_cells ( X, Y, 1, 1 )
end.
get_left_and_upper_cells ( X, Y, Width, Height ) ->
[ { X - 1, LeftCellY } || LeftCellY <- lists:seq ( Y, Y + Height - 1 )] ++
[ { UpperCellX, Y - 1 } || UpperCellX <- lists:seq ( X, X + Width - 1 ) ].
normalize_position ( X, Y, ConcatCells ) ->
IsInsideFunction = get_is_inside_function ( X, Y ),
case lists:filter ( IsInsideFunction, ConcatCells ) of
[ { FoundRangeX, FoundRangeY, _Width, _Height } ] -> { FoundRangeX, FoundRangeY };
_Otherwise -> { X, Y }
end.
get_is_inside_function ( X, Y ) ->
fun ( { RangeX, RangeY, RangeWidth, RangeHeight } ) ->
RangeX =< X andalso X < RangeX + RangeWidth andalso
RangeY =< Y andalso Y < RangeY + RangeHeight
end.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment