算数にチャレンジ!(途中)

30分プログラム、その438。算数にチャレンジ!!より。うまくいかなかったけど、一応。

3ケタの整数を、繰り上がり計算がないような2つの整数A、Bの和にすることを考えます。例えば、532という数ならば、「A=111、B=421」や、「A=21、B=511」等が考えられます。(一方、「A=338、B=194」は一の位および十の位の計算の際に繰り上がりがあるので条件に当てはまりません。)

いま、ある3ケタの整数について「A、B」の組が何通りあるかを数えたところ、全部で432通りありました。ただし、AとBが逆になっただけのものも別々に数えました。(532という数なら、「A=111、B=421」と「A=421、B=111」をそれぞれ1通りと数えた、ということです)

では、この3ケタの整数として考えられる数のうち、最も小さいものを答えてください。

Erangだ、わっほい、プロセスを作りまくれ、と思ってspawnしまくってたら、プロセスを作りすぎだって怒られてしまった。続きは、また今度。

=ERROR REPORT==== 15-Dec-2008::23:08:27 ===
Error in process <0.28.0> with exit value: {system_limit,[{erlang,spawn,[erlang,apply,[#Fun<sansu.2.111824317>,[]]]},{erlang,spawn,1},{sansu,'-each_num/2-lc$^1/1-1-',5},{sansu,each_num,2}]}

使い方

$ erl -noshell -run sansu mimimam -run init stop

ソースコード

-module(sansu).
-compile([export_all]).

% convension
% A + B = C

digit_seq(N) ->
    [(N div 100),
     (N div 10) rem 10,
      N rem 100].

plus(A,B) ->
    lists:zipwith(fun (X,Y)->X + Y end,digit_seq(A),digit_seq(B)).

countAB(From,432,Done,Done) ->
    From ! {ok,432};
countAB(From,X,Done,Done) ->
    From ! {ng,X};
countAB(From,Good,Done,All) ->
    receive
	ok ->
	    countAB(From,Good+1,Done+1,All);
	ng ->
	    countAB(From,Good,Done+1,All)
    end.

each_num(From,C) ->
    Self = self(),
    [spawn(fun() ->
		   case plus(A,B) =:= digit_seq(C) of
		       true ->
			   spawn(fun () -> io:format("~p + ~p = ~p~n",[A,B,C]) end),
			   Self ! ok;
		       _ ->
			   spawn(fun () -> io:format("~p + ~p != ~p~n",[A,B,C]) end),
			   Self ! ng
		   end end)
	 || A <- lists:seq(1,C), B <- lists:seq(1,C)],
    countAB(From,0,0,10*10).

mimimam() ->
    Self = self(),
    spawn(fun () -> each_num(Self,532) end),
    receive
	N ->
	    N
    end.