
ãšã³ããªãŒ
1幎ã¡ãã£ãšåãç§ã¯äººçã§éåžžã«éèŠãªããšãããŸãããMicrosoftIDE Webãµã€ãããVisual StudioãããŠã³ããŒãããC ++ã§ç§ã®äººçã§æåã®ããã°ã©ã ãæžããã®ã§ãã 次ã®6ãæéãç§ã¯Straustrupã®æªåé«ãæ¬ãèªã¿ãC ++ãžã¥ãã¢éçºè ãšããŠä»äºãåŸãŠãPythonã®Luaã§æžã蟌ãããšããŸãããã倧ããªæåãåããŸããã§ãããã¡ã¢ãªã®ãããã®éšåã§ã¯ãªãïŒãšããã§ãåžžã«ã©ããã§ãªãŒã¯ãçºçããŸããïŒãè€æ°ã®ã¹ã¬ããïŒC ++ 11ïŒïŒã䜿çšããããšãããšãã¡ã¢ãªã®ç Žæãšãããããã¯ãçºçããŸããã ã³ãŒããã©ã®ããã«èŠãããã«ã€ããŠé»ã£ãŠããæ¹ãè¯ãã§ãã
ãªãã§ïŒ ç§ã®å人çãªæèŠ/çµéšã§ã¯ãåœä»€åèšèªã¯ããã®ç¹æ§ã®ãããåå¿è éçºè ã«ã¯å®å šã«äžé©åã§ãã ç£æ¥çšããã°ã©ãã³ã°ãã¿ãŒã³ã®ç¥èããªãã¬ãŒãã£ã³ã°ã·ã¹ãã ã®åäœã«é¢ããããã€ãã®æ å ±ãããã³ã³ãŒãã®åºæ¬çãªæåããªããã°ããããã«èããããäœããæžãããšã¯éåžžã«å°é£ã§ãã 圌ãã¯æŸèæãèªè»¢è»ã«èªç±ãšã¹ããŒã¹ãäžããããŸãããæ©èœçãªèšèªã¯éçºè ãå³ããå¶éããããã貧匱ãªã³ãŒããæžãæ©äŒãããŸãäžãããæèãšéçºãäœåãªããããŸãã
çŽ6ãæåãç§ã¯äœããå€ããæã ãšæ°ã¥ããã€ã³ã¿ãŒããããæ€çŽ¢ããŠ30ååŸã«Erlangã®ä»æ§ãèŠã€ããŸããã èšäºã®äžã§ãèè ã¯äžèšã®ãã¹ãŠã®åé¡ãããçŽ æŽãããè¬ããšããŠErlangãæ瀺ããŸããããããŠãäžè¬ã«ã倧éšåã¯åœŒã¯æ£ããã£ãã§ãã ã ããç§ã¯Erlangã§ããã°ã©ãã³ã°ãå§ããããããElixirã§å§ããŸããã
ãšãªã¯ãµãŒèšèª
Elixirã¯Erlangã®äžã«æ§ç¯ãããèšèªã§ãããã³ã³ãã€ã«çµæã¯Erlang VMãã€ãã³ãŒãã§ãã ã·ã³ãã«ãªæ§æãšã¡ã¿ããã°ã©ãã³ã°ã®ããã®åŒ·åãªããŒã«ã«ãããErlangãšæ¯èŒããŠæå©ã§ãïŒLispã«ç²ŸéããŠãã人ã¯ãåŒçšç¬ŠãšéåŒçšç¬Šã®æ§é ãããã«èªèããŸãïŒã ãããã£ãŠããã¹ãŠã®Erlangæ©èœããã®ã¢ãžã¥ãŒã«ããããŠæãéèŠãªã®ã¯OTPãã¬ãŒã ã¯ãŒã¯ã䜿çšå¯èœã§ãã
ããŒã¿åã¯Erlangãšåãã§ãã ããŒã¿ã¯äžå€ã§ããããããã®ã¢ã¯ã·ã§ã³ã®çµæã¯æ°ããããŒã¿ã§ãã Elixirã§ã¯ãå€ãã®é¢æ°åèšèªãšåæ§ã«ãããã¹ãŠãè¡šçŸãã®ååãæ©èœããŸãã åŒã¯å€ãè¿ããŸãã
Elixirã«ã¯ãèšèªãšãšãã«ã€ã³ã¹ããŒã«ãããåªããã€ã³ã¿ãŒããªã¿ãŒããããŸãããã®äžã®äŸãè©Šãããšãã§ããŸãã
åºæ¬çãªããŒã¿å
intãfloat
1 + 1 # => 2 3 / 2 # => 1.5 1.0 + 3 # => 4.0
ãã€ããª
"Hello"<>" World!" # => "Hello World!" "Hello #{World!}" # => "Hello World!" """ hello """ # => "hello\n"
åå
ãã®å€ã®ã¿ãè¡šãå®æ°ã§ããã以äžã®ãã®ã¯ãããŸããã åå¥ã®è«çåã¯ãããŸãããtrueãfalseãnilãã¢ãã ã§ãããèšèªã«ã¯å¯Ÿå¿ããèŠåããããŸãã
is_atom(true) # => true is_atom(:true) # => true is_atom(:hello) # => true
ãªã¹ã
[1,2,3,4,"five"]++[6, "seven"] # => [1, 2, 3, 4, "five", 6, "seven"] [1,1,2,3,4]--[1,2,3,5] # => [1, 4]
æŽå²çãªçç±ã«ãããErlangã®æååã¯ãã€ããªåœ¢åŒã§ã¯ãªããªã¹ã圢åŒã§è¡šãããŸãïŒElixirã§ã¯ãã®éïŒããããã£ãŠããªã¹ãã¯æ¬¡ã®ããã«è¡šãããšãã§ããŸãã
is_list 'this is list' # => true 'lst'++[10000] # => [108, 115, 116, 10000]
ã¿ãã«
ãªã¹ããã¡ã¢ãªå ã®ããŒã¿ã¹ãã¬ãŒãžã®ç·šæã®éããããã«å¿ããŠãããŒã¿ãæäœããããã®ã©ã€ãã©ãªããŒã«ã®ãããªãã®ã
{:hello, "world"}
å°å³
%{2 => 2, :c => {1, 2, 3}, "key1" => 1} # , , %{a: 1, b: 3, c: "qweqwe"}
PID
Erlang VMããã»ã¹ã®èå¥åã ã€ã³ã¿ãŒããªã¿ãŒã®å¯Ÿè©±åã·ã§ã«ãããã»ã¹ã§ãããããåŒã³åºãããããã»ã¹ã®PIDãè¿ãselfé¢æ°ã䜿çšããŸã
self # => #PID<0.95.0> ( )
æ瀺çã«ããã€ãã®åå€æãè¡ãããšã¯å¯èœã§ãã
:erlang.tuple_to_list {1,2,3} # => [1, 2, 3] :erlang.integer_to_binary 123 # => "123" :erlang.binary_to_list "abc" # => :abc
ãŸãããã®èšèªã®å¿«é©ãã®1ã€ã¯ãä»»æã®çšèªãå®å šã«ç¡çã§ãã€ããªã«å€æã§ãããã®éãå¯èœã§ããããšã§ãã 1è¡ã®ããŒã¿ã®ã·ãªã¢ã«åã
res = :erlang.term_to_binary [:hello, {"world", '!!!'}] # => <<131, 108, 0, 0, 0, 2, 100, 0, 5, 104, 101, 108, 108, 111, 104, 2, 109, 0, 0, 0, 5, 119, 111, 114, 108, 100, 107, 0, 3, 33, 33, 33, 106>> :erlang.binary_to_term res # => [:hello, {"world", '!!!'}]
ãã¿ãŒã³ãããã³ã°
ããŒã¿ãå€æ°ã«ããŒã«ã«ã«å²ãåœãŠãããšãã§ããŸãïŒããã«ã¯ã°ããŒãã«å€æ°ãšå ±æã¡ã¢ãªã¯ãªããå²ãåœãŠãããšã¯ã§ããŸããïŒ
x = 1 # => 1 # x c 1 x # => 1 # ( ) x = 1+x # => 2
ãã ãããããè¡ãå¿ èŠã¯ãŸã£ãããããŸããã å€æ°ããŸã£ãã䜿çšããªãå Žåãã³ãŒãã¯ããã·ã³ãã«ã§ãããçŸãããããè¡šçŸåè±ãã§ãã å³å¯ã«èšãã°ãElixirã®æŒç®åã=ãã¯ãåœä»€åèšèªã®éåžžã®æå³ã§ã®å²ãåœãŠã§ã¯ãããŸããã ããã§ãã¿ãŒã³ãããã³ã°ãè¡ãããŸãã ãã®æ¬è³ªã¯äŸã§ç€ºãã®ãç°¡åã§ãã
%{a: x, b: 1} = %{a: 1, b: 1} # => %{a: 1, b: 1} %{a: x, b: 1} = %{a: 1, b: 2} # => ** (MatchError) no match of right hand side value: %{a: 1, b: 2} %{a: x, b: 1} = %{b: 1} # => ** (MatchError) no match of right hand side value: %{b: 1}
åœä»€åèšèªã«é¢ããŠã¯ããã¿ãŒã³ãããã³ã°ã¯æ¯èŒãšå²ãåœãŠã®çµã¿åããã§ããã=ãã®å·ŠåŽã®å€ã«é¢é£ä»ããããæ§é èŠçŽ ã¯ãã=ãã®å³åŽã®å¯Ÿå¿ããæ§é èŠçŽ ãšæ¯èŒãããé¢é£ããŸãã-ãããã¯å³åŽã®æ§é èŠçŽ ã®å¯Ÿå¿ããå€ã«é¢é£ä»ããããŸãã å³åŽã®æ§é ã«ã¯ãå€ã«é¢é£ä»ããããŠããªãèŠçŽ ãå«ããããšã¯ã§ããŸããã æ¯èŒã®ãããããfalseãè¿ãå ŽåãäŸå€ãã¹ããŒãããŸãã
ãã¿ãŒã³ãããã³ã°ã¯ããã€ããªããŒã¿ã§ãå®è¡ã§ããŸãïŒå®è¡ããå¿ èŠããããŸãïŒã
<< a :: binary-size(5), rest :: binary >> = "hello, world" # => "hello, world" a # => "hello" rest # => ", world"
ãšããã§ããã®äŸã«æ³šæããŠãã ããïŒ
x = 1 # => 1 x == 1 # => true %{a: x, b: y} = %{a: 12, b: 1} # => %{a: 12, b: 1} x # => 12
ãã¿ãŒã³ãããã³ã°ãæåããŸãããäŸå€ã¯ãããŸããã ãã®æå³ã§ãElixirã¯ããå³å¯ãªé¢æ°åèšèªïŒErlangãå«ãïŒãšã¯ç°ãªããããé¢æ°å ã§ãã¿ãŒã³ãããã³ã°ã䜿çšãããšæ··ä¹±ãæ··ä¹±ãçããããšããããããŸããã³ãŒã; ããã¯é¿ããã¹ãã§ãã ãã¿ãŒã³ãããã³ã°ã®çã®åšåã¯ãé¢æ°å®£èšãšcaseåŒã§äœ¿çšããå Žåã«ã®ã¿æããããšãã§ããŸãã
é¢æ°ãšã¢ãžã¥ãŒã«
èšèªã¯æ©èœçã§ãããããèšèªã®äž»ãªè¡šçŸæ段ã¯æ©èœã§ãã é¢æ°ã¯ãé¢æ°ãšããŠåŒæ°ãšããŠåãå ¥ããå€ãšããŠè¿ãããšãã§ããŸãã é¢æ°ã¯ã¢ãžã¥ãŒã«å ã§å®çŸ©ãããŸãããã¢ãžã¥ãŒã«ã¯ä»ã®ã¢ãžã¥ãŒã«å ã§ãå®çŸ©ã§ããŸãã
defmodule Some do defp priv_func(arg) do arg<>"Hello from priv_func!" end def pub_func(arg) when is_binary(arg) do arg<>priv_func("Hello from pub_func!\n") end end
ãã®ã¢ãžã¥ãŒã«ã®å€éšã§åŒã³åºãããšãã§ãããããªãã¯é¢æ°ãå®çŸ©ããã«ã¯ãdefã䜿çšããå¿ èŠããããŸãããŸããdefpã䜿çšãããšããã®ã¢ãžã¥ãŒã«å ã§ã®ã¿äœ¿çšå¯èœãªé¢æ°ãããçŽãããšãã§ããŸãïŒErlangãšæ¯ã¹ãŠã©ãã ãç°¡åããåç §ïŒ é¢æ°åãšåŒæ°ã®åŸã«ã¯ãã¬ãŒãåŒãšåŒã°ããåŒããããŸãïŒpub_funcã®å®çŸ©ãåç §ïŒãé¢æ°ã®ç¯å²ãïŒæ°åŠçã«ïŒçããããšãã§ããŸãã
Some.pub_func "Hello from shell!\n" # => "Hello from shell!\nHello from pub_func!\nHello from priv_func!" Some.pub_func 1 # => ** (FunctionClauseError) no function clause matching in Some.pub_func/1 Some.priv_func "Hello" # => ** (UndefinedFunctionError) undefined function: Some.priv_func/1 Some.priv_func("Hello")
Elixir PLã«ã¯ãã©ã ãïŒå¿åé¢æ°ïŒãå®çŸ©ããããã®ã»ãŒåçã®2ã€ã®æ¹æ³ããããŸãã
sum = &(&1+&2) # => &:erlang.+/2 sum.(1,2) # => 3 sum = fn(x,y) -> x + y end # => #Function<12.106461118/2 in :erl_eval.expr/5> sum.(1,2) # => 3
äŸãããããããã«ãã©ã ãã®åŒã³åºãã¯ããããã®ã¿ã§éåžžã®é¢æ°ã®åŒã³åºããšã¯ç°ãªããŸãã é¢æ°ã¯ãã©ã ãã ãã§ãªããéåžžã®é¢æ°ã§ãåŒæ°ãšããŠæž¡ãããšãã§ããŸãã ãããè¡ãã«ã¯ãé¢æ°åã®åã«ãïŒãèšå·ãä»ããŠãã¢ãªãã£ã瀺ããŸãã
defmodule Some do def actor(arg1, arg2, func) do func.(arg1, arg2) end def div(arg1, arg2) do arg1 / arg2 end end sum = &(&1+&2) # => &:erlang.+/2 Some.actor(1,2,sum) # => 3 Some.actor(3,4, &Some.div/2 ) # => 0.75
Elixir YPãšãã®æšæºã¢ãžã¥ãŒã«ã«é¢ãã詳现ãªããã¥ã¡ã³ãã¯ããã§ãErlang / OTPã¯ããã§èªãããšãã§ããŸã ã
ãªã€ã©ãŒéŠ¬åé¡ã®è§£æ±º
C ++ã®å匷ãå§ããã°ããã§ãVMK magistracyã®å ¥åŠè©Šéšã®æºåãããŠãããïŒåœŒãã¯ã¯ãŒã«ãªã³ãŒãã£ã³ã°æ¹æ³ãåŠã¶ãšä¿¡ããŠããŸããïŒãå ¥åŠè©Šéšã®ãªãã·ã§ã³ã®1ã€ã§ãã®ã¿ã¹ã¯ã«åºäŒããŸããã ããããç§ã¯ããã解決ã§ããŸããã§ããã äœããã®çç±ã§ãæšæ¥ãç§ã¯ãããåã³æãåºãã1æéã§æ±ºå®ãæããã®ã§ãç§ã¯ãã®èšäºãæžãããšã«ããŸããã
äžè¬ã«ãæ¬è³ªã¯æ¬¡ã®ãšããã§ãããä»»æã®ãµã€ãºã®æ£æ¹åœ¢ã®ãã§ã¹ç€ããããä»»æã®ã±ãŒãžã§éŠ¬ããã®äžã«ç«ã£ãŠããŸããããŒãã«ã¯ããŒã¹ããããŸããã ãã§ã¹ç€ã®ãã¹ãŠã®ã»ã«ã銬ã§1ã€ãã€æ£ç¢ºã«èšªããåŸããŸãã¯ãããäžå¯èœã§ããããšã蚌æããå¿ èŠããããŸãã
ããŒãã®ãµã€ãºãšéŠ¬ã®åæäœçœ®ã決å®ããç¹å®ã®æ¡ä»¶ã¯ãªãã®ã§ãéå±ã§åççã§ã¯ãªãæœè±¡çãªæ°åŠççµè«ãåºãããšã¯ããªãé£ãããæãæçœãªè§£æ±ºçã¯ç·åœããã§ãã
ãŸããé¢æ°ã§æäœããããŒã¿æ§é ã決å®ããŸãã ããã«ãããããé«ãã¬ãã«ã®æœè±¡åãå®çŸãããœãªã¥ãŒã·ã§ã³ãå€§å¹ ã«ç°¡çŽ åãããŸãã ããã«ããã®æ¹æ³ã§å®çŸ©ãããæ§é ã«ãããã³ãŒãã®æ±ºå®æ§ãé«ãŸããŸãã
# structs of data defmodule Position do defstruct first: 1, second: 1 end defmodule GameState do defstruct current_pos: %Position{}, path: [] end
äœçœ®-ä»»æã®æç¹ã§ã®ããŒãäžã®éšå£«ã®äœçœ®ã ããã§ã¯2次å ã®å ŽåãèããŸãããåŸã§èŠãããã«ãæ©èœã³ãŒãã¯ããã®ãœãªã¥ãŒã·ã§ã³ãä»»æã®æ¬¡å ã®ç©ºéã«å¯ŸããŠéåžžã«ç°¡åã«äžè¬åã§ããããã«é 眮ãããŸãã
GameState-ã²ãŒã ã®çŸåšã®ç¶æ ã¯ãçŸåšã®äœçœ®ãšç§»åãããã¹ã«ãã£ãŠäžæã«æ±ºå®ãããŸãã
ã芧ã®ãšãããæ§é äœãã£ãŒã«ãã®ããã©ã«ãå€ãå®çŸ©ããŠãããããã¯ã©ã¹ã³ã³ã¹ãã©ã¯ã¿ãŒã®ãããªãã®ãåŸãããŸãã Elixirã®æ§é ã¯ãããããŒã¿ã¿ã€ãã«åºã¥ããŠããã䜿çš/æ§æã®æ§é ã«éåžžã«äŒŒãŠããŸãã
defmodule Some do defstruct a: 1, b: nil end res = %Some{} # => %Some{a: 1, b: nil} is_map res # => true Map.keys res # => [:__struct__, :a, :b] Map.values res # => [Some, 1, nil]
次ã«ãäžè¬çãªåœ¢åŒã§ãœãªã¥ãŒã·ã§ã³ãäœæããŸãã init / 1é¢æ°ã¯ãåŒæ°ãšããŠããŒãã®ãšããžïŒãã®å Žåã¯æ£æ¹åœ¢ã®èŸºïŒã®ãµã€ãºãåãã銬ã®åæäœçœ®ïŒãããã£ãŠã²ãŒã ã®ç¶æ ïŒãã©ã³ãã ã«æ±ºå®ããinform_user_about_beginning / 1é¢æ°ã䜿çšããŠããããŠãŒã¶ãŒã«éç¥ãã次ã«game / 2é¢æ°ãåŒã³åºããŸããèããããå€ãã®åé¿çãè¿ãã次ã«show_game_results / 2é¢æ°ãè¿ããŸãããã®é¢æ°ã¯çµæããŠãŒã¶ãŒã«éç¥ããŸãã æŒç®åã|>ãã«æ³šæããŠãã ããã å·ŠåŽã®åŒãæåã®åŒæ°ãšããŠå³åŽã®é¢æ°ã«æž¡ãã ãã§ãã åé¡ã¯è§£æ±ºãããŸãããããŸã å®çŸ©ãããŠããªãé¢æ°ã決å®ããããã«æ®ã£ãŠããŸãã
def init(limit) when (is_integer(limit) and (limit > 0)) do :random.seed(:erlang.now) [ %GameState{ current_pos: %Position{ first: :random.uniform(limit), second: :random.uniform(limit)} |> inform_user_about_beginning } ] |> game(limit) |> show_game_results(limit) end
inform_user_about_beginningé¢æ°ã«ã€ããŠã¯ããã¹ãŠãæ確ã§ãããšæããŸã-åŒæ°ãåãå ¥ããç»é¢ã«è¡šç€ºããŠããããè¿ããŸãã
defp inform_user_about_beginning info do IO.puts "Hello, user, we begin from #{inspect info}" info end
show_game_resultsé¢æ°ã¯ããå°ãè€éã§ãã ã¢ã«ãŽãªãºã ã®çµæãšããŠãèããããåé¿çã®ãªã¹ããååŸããå¿ èŠããããŸãã åœç¶ã空ã®ãªã¹ããšç©ºã§ãªããªã¹ãã«å¯ŸããŠç°ãªãã¡ãã»ãŒãžã衚瀺ããå¿ èŠããããŸãã 1ã€ã®é¢æ°å ã§if-elseãŸãã¯caseåŒã䜿çšãã代ããã«ããã®å Žåã¯ãshow_game_results / 2é¢æ°ã®2ã€ã®å¥åã®å¥ãèšè¿°ããæ¹ãé©åã§ãã ããã«ããã³ãŒããç°¡çŽ åãããèŠèŠçã§èªã¿ããããªããŸãã äžè¬çãªã«ãŒã«ã¯æ¬¡ã®ãšããã§ããé¢æ°ãåŒã³åºããããšãç¹å®ã®é¢æ°ã®å¥ã¯ãã³ãŒãã«èšè¿°ãããŠããé åºã§ç§»åãå§ããŸãã ãã®å Žåããã®å¥ã®é¢æ°ã®ãã¹ãŠã®åŒæ°ãšãå€éšãã転éããã察å¿ããåŒæ°ã®ãã¿ãŒã³ãããã³ã°ãå®è¡ãããŸãã ãã¿ãŒã³ãããã³ã°ãæåããå Žåãé¢æ°ã¯ãã®å¥ã®åŒãè¿ããããã§ãªãå Žåã次ã®å¥ã䜿çšãããŸãã å¥ãçºçããªãå ŽåãäŸå€ãã¹ããŒãããŸãã
defp show_game_results([], limit) do IO.puts "FAIL. This is no any way to go through desk #{limit}x#{limit} from this position." end defp show_game_results([%GameState{current_pos: current_pos, path: path} | rest_way], limit) do """ SUCCESS! There are #{length(rest_way)+1} ways to go through desk #{limit}x#{limit} from this position. Here one of them: """ |> IO.puts Enum.each( path++[current_pos] , &(IO.puts "\t#{inspect &1}") ) end
2çªç®ã®å¥ã«æ³šæããŠãã ããããªã¹ãã®å é ãšæ«å°Ÿãžã®åå²ã䜿çšããŸããããã¯FPã«äžè¬çã§ãã ãã®å Žåããã®ãããªããŒãã£ã·ã§ã³ã®ç®çã¯ãé¢æ°ã®åŒæ°ã§çŽæ¥èŠã€ãã£ããã©ããŒãµã«ãã¹ã®ãªã¹ãããæåã®ãã©ããŒãµã«ãã¹ãååŸããããšã§ããããã«ãããé¢æ°æ¬äœã®ã©ããã§ãããè¡ãå¿ èŠããªããªããŸãã Elixirã§ã¯ãErlangå ãšãªã¹ãã®äž¡æ¹ã§ããªã¹ãã¯ç©ºïŒ[]ïŒã«ããããããããšããŒã«ã«åå²ããããšãã§ããŸãïŒããŒã«ã¯ãªã¹ãã§ãïŒã
lst = [1,2,3] # => [1, 2, 3] [a | rest] = lst # => [1, 2, 3] a # => 1 rest # => [2, 3] lst2 = [0 | lst] # => [0, 1, 2, 3] [first|rest] = [0] # => [0] first # => 0 rest # => []
ãŸãã2çªç®ã®å¥ã®æåŸã«ã¯ãé«éé¢æ°ããããŸãã å®éãããã§ã®Enum.each / 2é¢æ°ã¯ããªã¹ãã®ãã¹ãŠã®èŠçŽ ã調ã¹ãããèªäœã2çªç®ã®åŒæ°ãšããŠãšãé¢æ°ãåèŠçŽ ã«é©çšããŸãïŒãã®å Žåãåã«è¡šç€ºããŸãïŒã ããã«ãããã¹ãã«ã¯Enumã¢ãžã¥ãŒã«ããã®é¢æ°ãããã€ããããŸãã®ã§ãããã«é¢ãã質åã¯ãããŸãããããããã©ã®ããã«æ©èœããããããã«èª¬æããŸãã
Enum.map( lst, func/1 ) # , func(el), el - lst Enum.filter(lst, func/1) # lst, func(el) == true Enum.reduce( lst, res, func/2 ) # Enum.reduce(rest, func(el, res), func/2), [el | rest] = lst, Enum.reduce([], some_res, func/2) == some_res
äžè¶³ããŠããé¢æ°ã²ãŒã / 2ãå®çŸ©ããŸãã å¯èœãªã²ãŒã ç¶æ ã®ç©ºã®ãªã¹ããååŸããå ŽåïŒãããã£ãŠããã€ãã¹ããŸãïŒ-ãããè¿ãããšä»¥å€ã¯äœãããããšãã§ããŸããã ãªã¹ãã空ã§ãªãå Žåããã©ããŒãµã«ãæåŸã«å°éãããã©ããã確èªããããã«å¿ããŠããã©ããŒãµã«ãã¹ã®ãªã¹ããè¿ããããã©ããŒãµã«ãç¶è¡ããŸãã
defp game([], _limit) do [] end defp game(lst, limit) do case game_over?(lst, limit) do true -> lst false -> Enum.map(lst, &(generate_new_list_and_game_next(&1, limit))) |> List.flatten end end defp game_over?([%GameState{path: path}| _rest], limit) do length(path) == (limit*limit - 1) end
game / 2é¢æ°ã®2çªç®ã®ç¯ã«ã¯ãåŒããããŸãã äžèŠãã¹ã€ããã¹ã€ããã«äŒŒãŠããŸãããå®éã«ã¯ããã®æ§è³ªäžãã±ãŒã¹ã¯Elixirã®éåžžã®æ©èœãšã»ãŒåãã§ãã äžçªäžã®è¡ã¯æ¬¡ã®ãšããã§ãã
case (_0) do _1 -> _1 _2 -> _2 ... _n -> _n end
åŒ0ã®å®è¡ããçããæåã®cããéå§ããŠãåå¥ã®é 次ãã¿ãŒã³ãããã³ã°ãå®è¡ãããæåããå Žåãcase-ã³ã³ã¹ãã©ã¯ãã¯ãã®å¥ã«å¯Ÿå¿ããåŒãè¿ããŸãã äžèŽããå¥ããªãå ŽåãäŸå€ãç¶ããŸãã
次ã«ãé¢æ°generate_new_list_and_game_next / 2ãå®çŸ©ããå¿ èŠããããŸãããã®é¢æ°ã¯ãã¹ãããnã§ã²ãŒã ã®ç¶æ ãååŸããã¹ãããn + 1ã§ã²ãŒã ç¶æ ã®ãªã¹ãã«å€æããŸãïŒçµå±ã銬ã¯ä»»æã®ã»ã«ãã0ãã8ã®ç¹å®ã®æ°ã®ã»ã«ã«ç§»åã§ããŸãããæé nïŒã®ç¶æ ã«å¿ããŠããã®ãªã¹ããgame / 2é¢æ°ã«æž¡ããŸãã ãã®é¢æ°ãäœæããã«ã¯ããŸã銬ã®æ©ãæ¹ãç¥ãå¿ èŠããããŸãã åææ¡ä»¶ã«é¢ä¿ãªããã¢ã«ãŽãªãºã ãåäœãéå§ããåã§ãã£ãŠããéšå£«ã®ãã¹ãŠã®å¯èœãªåãã¯ããã£ãŠããŸãïŒããšãã°ã女çã®å Žåãããã¯æ£ãããããŸãã-ãã®å Žåãå€ãã®å¯èœãªåãã¯ããŒãã®ãµã€ãºã«é¢é£ããŠããŸãïŒã ãããã£ãŠããã€ãã®çè«çã«å¯èœãªãã¹ãŠã®åããèšç®ããäœæ¥ã¯ãã³ã³ãã€ã«æã«é 眮ããããšãã§ããŸãïŒãŸãããããã¹ãã§ãïŒã ãããè¡ãã«ã¯ãmake_permutations / 4é¢æ°ãå¥ã®ã¢ãžã¥ãŒã«ã«èšè¿°ããŸãã æåã®defã«ã¯do-endãããã¯ãå«ãŸããŠããããããã©ã«ãã®åŒæ°ãå ¥åããããã«äœ¿çšãããŸãã
defmodule Permutations do def make_permutations( input_set, perm_size, condition, result \\ []) def make_permutations( _input_set, perm_size, condition, result ) when (length(result) == perm_size) do case condition.(result) do true -> List.to_tuple(result) false -> :failed end end def make_permutations( input_set, perm_size, condition, result ) when (length(input_set)+length(result) >= perm_size) do Enum.map( input_set, fn(input_el) -> make_permutations( input_set--[input_el], perm_size, condition, result++[input_el] ) end ) |> List.flatten |> Enum.filter(&(&1 != :failed)) end end
make_permutations / 4é¢æ°ã§ã¯ãæ¡ä»¶æ¡ä»¶ãæºããperm_sizeã®é·ãã§input_setã»ããããèŠçŽ ã®ãã¹ãŠã®é åãååŸããŸãã
ãŸããç¹å®ã®èšç®ã®çµæã䜿çšããã¢ãžã¥ãŒã«ã§ã¯ã次ã®ããã«èšè¿°ããŸãã
@horse_ways Permutations.make_permutations([-1, -2, 1, 2], 2, fn(lst) -> Enum.reduce(lst, 0, &(abs(&1)+&2)) == 3 end )
@-ã¢ãžã¥ãŒã«å±æ§ã®æå®ã ã¢ãžã¥ãŒã«å±æ§ã«ãã£ãŠåãå ¥ããããåŒã¯ããã®ã¢ãžã¥ãŒã«ãã³ã³ãã€ã«ããããšãã«èšç®ãããŸãã
ããã§ãæ¬ èœã³ãŒããäœæããæºåãã§ããŸããã ããã§ã¯ãã¹ãŠãäºçŽ°ãªããšã§ãããé¢æ°ãšåŒæ°ã®ååã¯ããèªäœãç©èªã£ãŠããŸã
defp generate_new_list_and_game_next(game_state = %GameState{current_pos: current_pos}, limit) do @horse_ways |> Enum.map( &(generate_new_position(current_pos, &1)) ) |> Enum.filter(&( can_go_here?(game_state, &1, limit) )) |> Enum.map(&( go_here(game_state, &1) )) |> game(limit) end defp generate_new_position( %Position{first: first, second: second}, {delta1, delta2} ) do %Position{first: (first+delta1), second: (second+delta2)} end defp can_go_here?( %GameState{current_pos: current_pos, path: path}, prompt = %Position{first: first, second: second}, limit ) do not(prompt in [current_pos | path]) and Enum.all?([first, second], &( (&1 <= limit) and (&1 > 0) )) end defp go_here( %GameState{current_pos: current_pos, path: path}, prompt ) do %GameState{current_pos: prompt, path: path++[current_pos]} end
å®å šãªãªã¹ãïŒ
å®å
šãªãªã¹ã
defmodule Permutations do def make_permutations( input_set, perm_size, condition, result \\ []) def make_permutations( _input_set, perm_size, condition, result ) when (length(result) == perm_size) do case condition.(result) do true -> List.to_tuple(result) false -> :failed end end def make_permutations( input_set, perm_size, condition, result ) when (length(input_set)+length(result) >= perm_size) do Enum.map( input_set, fn(input_el) -> make_permutations( input_set--[input_el], perm_size, condition, result++[input_el] ) end ) |> List.flatten |> Enum.filter(&(&1 != :failed)) end end defmodule Horse.Solution do ######################### ### compile-time work ### ######################### @horse_ways Permutations.make_permutations([-1, -2, 1, 2], 2, fn(lst) -> Enum.reduce(lst, 0, &(abs(&1)+&2)) == 3 end ) # structs of data defmodule Position do defstruct first: 1, second: 1 end defmodule GameState do defstruct current_pos: %Position{}, path: [] end #################### ### runtime work ### #################### def init(limit) when (is_integer(limit) and (limit > 0)) do :random.seed(:erlang.now) [ %GameState{current_pos: %Position{ first: :random.uniform(limit), second: :random.uniform(limit)} |> inform_user_about_beginning } ] |> game(limit) |> show_game_results(limit) end defp inform_user_about_beginning info do IO.puts "Hello, user, we begin from #{inspect info}" info end defp game([], _limit) do [] end defp game(lst, limit) do case game_over?(lst, limit) do true -> lst false -> Enum.map(lst, &(generate_new_list_and_game_next(&1, limit))) |> List.flatten end end defp game_over?([%GameState{path: path}| _rest], limit) do length(path) == (limit*limit - 1) end defp generate_new_list_and_game_next(game_state = %GameState{current_pos: current_pos}, limit) do @horse_ways |> Enum.map( &(generate_new_position(current_pos, &1)) ) |> Enum.filter(&( can_go_here?(game_state, &1, limit) )) |> Enum.map(&( go_here(game_state, &1) )) |> game(limit) end defp generate_new_position( %Position{first: first, second: second}, {delta1, delta2} ) do %Position{first: (first+delta1), second: (second+delta2)} end defp can_go_here?( %GameState{current_pos: current_pos, path: path}, prompt = %Position{first: first, second: second}, limit ) do not(prompt in [current_pos | path]) and Enum.all?([first, second], &( (&1 <= limit) and (&1 > 0) )) end defp go_here( %GameState{current_pos: current_pos, path: path}, prompt ) do %GameState{current_pos: prompt, path: path++[current_pos]} end defp show_game_results([], limit) do IO.puts "FAIL. This is no any way to go through desk #{limit}x#{limit} from this position." end defp show_game_results([%GameState{current_pos: current_pos, path: path} | rest_way], limit) do """ SUCCESS! There are #{length(rest_way)+1} ways to go through desk #{limit}x#{limit} from this position. Here one of them: """ |> IO.puts Enum.each( path++[current_pos] , &(IO.puts "\t#{inspect &1}") ) end end
å®è¡ããŠã¿ãŸãããã 次ã®ãããªãã®ãåŸãããã¯ãã§ãã

ãŸãã¯ãåææ¡ä»¶ã«äžéãªå ŽåïŒ

5x5ããŒãã®çµæã¯ã©ã®ãããã®éãã§åŸãããŸãããïŒ 6x6ã¯ã©ãã§ããïŒ ããã»ã©éããããŸããã topã瀺ãããã«ãErlang VMã¯1ã€ã®ã³ã¢ã®ã¿ãããŒãããŸãã

èšç®ã䞊ååããæéã
䞊åã¿ã¹ã¯ãœãªã¥ãŒã·ã§ã³ã®æé©å
Erlang VMã§æ°ããããã»ã¹ãäœæããã®ã¯ç°¡åã§ãã spawnããã³spawn_linké¢æ°ã¯ãæ°ããããã»ã¹ã§é¢æ°ãéå§ããŸããããã¯åŒæ°ãšããŠååŸãããåããã»ã¹ã®PIDãè¿ããŸãã ãã®é¢æ°ãå€ãè¿ããåŸãããã»ã¹ã¯çµäºããŸãã ãã®å Žåãåããã»ã¹ã§äŸå€ãçºçããå Žåãspawn_linkã䜿çšãããšã芪ããã»ã¹ã«è»¢éãããéã®å Žåãåæ§ã§ããããã«ãããããã°ã©ã ã®å®è¡ããã決å®çã«ãªããŸãã
spawn_link fn() -> IO.puts "hello from #{inspect self}" end # => #PID<0.80.0> spawn_link fn() -> 109 / 0 end # => ** (EXIT from #PID<0.76.0>) an exception was raised spawn fn() -> 109 / 0 end # => #PID<0.85.0>
æé©åããããã®æãããªå Žæã¯ãã³ãŒãå ã®Enum.map/2é¢æ°ã§ãããªã¹ãã®åèŠçŽ ãåå¥ã®ããã»ã¹ã§åŠçããåãåã£ãå€ããæ°ãããªã¹ããåéããã ãã§ãã ãããèšèªã®ã³ã¢ã«çŽæ¥å®è£ ãããŠããªãã®ã¯ãªãã§ããïŒ
èããããæåã®çç±ã¯ãäžè¬çãªå ŽåãçŽç²ãªé¢æ°ãEnum.mapã«æž¡ãããããšã誰ãä¿èšŒããªãããšã§ãã æ²ããããªãããã¯èšç®ãè¡ãé åºã§åé¡ã«ãªãããšããããŸãã ãã®ãããªãæ±ããé¢æ°ã¯ããã®çµæãïŒã°ããŒãã«ãªæå³ã§ïŒåŒæ°ã«äŸåããã ãã§ãªããåé¿ãããã¹ãã§ãããåé¿ã§ããªãå Žåã¯ãå°ãªããšãäœããã®åœ¢ã§ããŒã«ã©ã€ãºãããŸãã
èãããã2çªç®ã®çç±ã¯ãããã»ã¹æ°ã®å¶éã§ãã ãã®ãããªä»®æ³çãªäžŠåå®è¡Enum.mapãäœããã®åœ¢ã§ååž°çã«åŒã³åºããããšä»®å®ãããšãããã»ã¹ã®æ°ã¯éªåŽ©ã®ããã«å¢å ãå§ããŸãã ãã®ç¹ã§ã¯ãErlangä»®æ³ãã·ã³ã¯éåžžã«å®å®ããŠãããããã»ã¹èªäœã¯éåžžã«å®äŸ¡ã§ãã ãããããã®äžçã®ãã¹ãŠã«ã¯éçããããŸãã
ããã«ãããããããä»ã®ãšããã䞊è¡ããŠïŒåæã«æ£ããïŒåäœããEnum.mapãç¬èªã«èšè¿°ããŸãïŒãã ããEnum.mapã«è»¢éãããé¢æ°ã®çŽåºŠã¯ãããã䜿çšãã人ã®è¯å¿ã«ãšã©ãŸããŸãïŒã
æ£åŒã«ã¯ãErlang VMã®ããã»ã¹ã¯å ±æããŒã¿ãæãããå®å šã«åé¢ãããŠãããäºãã«éåæã§ã®ã¿ã¡ãã»ãŒãžãéä¿¡ã§ããŸãã ã¡ãã»ãŒãžã«ã¯ãä»»æã®ã¢ãŒã©ã³çšèªã䜿çšã§ããŸãã ã¡ãã»ãŒãžã¯send / 2é¢æ°ã«ãã£ãŠéä¿¡ãããcaseåŒã«éåžžã«é¡äŒŒããåä¿¡åŒã䜿çšããŠåä¿¡ãããŸãã éãã¯ãåä¿¡åŒã«é©åãªå¥ããªãå ŽåïŒã€ãŸããã¡ãŒã«ããã¯ã¹ã«äºæ³ãããã¿ã€ãã®ã¡ãã»ãŒãžããªãå ŽåïŒ-äŸå€ã¯ã¹ããŒããããé©åãªã¡ãã»ãŒãžãå°çãããŸã§åŒãããã³ã°ãããããšã§ãïŒã¿ã€ã ã¢ãŠããèšå®ããããšãå¯èœã§ãïŒ ïŒ
defmodule Some do def receiver do receive do "hello" -> IO.puts "hello from receiver" receiver "please, die" -> IO.puts "OK ... " end end end child = spawn_link &Some.receiver/0 # => #PID<0.182.0> send child, "hello" # => hello from receiver send child, "some message" # => send child, "hello" # => hello from receiver send child, "please, die" # => OK ...
ã芧ã®ãšããããã¹ãŠãéåžžã«ç°¡åã§ãã ããããç§ãã¡ããã§ã«è©±ããããããããšãããã®ã1ã€ãããŸããErlang VMã¯ãæ°åãæ°åãæ°åäžãã®ããã»ã¹ãåæã«ãµããŒãã§ããŸãããã ãããã®æ°ã¯ãŸã æéã§ããããããèæ ®ããå¿ èŠããããŸãããã®ãããªã¢ã«ãŠã³ãã£ã³ã°ã§ã¯ãErlang VMå šäœã«å¯ŸããŠ1ã€ã®ã«ãŠã³ã¿ãŒããã»ã¹ãå¿ èŠã§ããããã¯éåžžã«åçŽã«é 眮ãããŠããŸã-ä»ã®ããã»ã¹ããã®å¯Ÿå¿ããã¡ãã»ãŒãžãåãå ¥ãã1å¢å ã1æžå°ããŸãã¯ãã®å€ãèŠæ±ããããã»ã¹ã«å€ãéä¿¡ã§ããå¿ èŠããããŸããå ±æã¡ã¢ãªãšã°ããŒãã«å€æ°ããªãé¢æ°åèšèªã§æœè±¡ãªããžã§ã¯ãã®ç¶æ ãä¿åããæ¹æ³ã¯ïŒæ£è§£ã¯ååž°ã§ãã
def parallel_enum_control_system number \\ 1 do receive do %{ from: sender, query: :get_number} -> send sender, number parallel_enum_control_system number :increment -> parallel_enum_control_system number+1 :decrement -> parallel_enum_control_system number-1 some -> IO.puts "WARNING! Unexpected message in parallel_enum_control_system: #{inspect some}" parallel_enum_control_system number end end
ãã ããã«ãŠã³ã¿ãŒããã»ã¹ã®PIDããã«ãŠã³ã¿ãŒããã»ã¹ã«ã¡ãã»ãŒãžãéä¿¡ããåããã»ã¹ã«æž¡ãããšã¯äžäŸ¿ã§ããç¹ã«ãParallelEnum.mapãéæ¥çã«èªåèªèº«ãååž°çã«åŒã³åºãããšãã§ããããšãèæ ®ããŸãïŒãã®å Žåã¯ãããªããŸãïŒã PIDãç¹å®ã®ååïŒãšã€ãªã¢ã¹ïŒã§ç»é²ãããšã€ãªã¢ã¹ã䜿çšããŠã¡ãã»ãŒãžãéä¿¡ããŸãã以äžã®ãªã¹ãã¯ãParallelEnum.mapãåŒã³åºããããšãã«äœãèµ·ãããã瀺ããŠããŸããã«ãŠã³ã¿ãŒããã»ã¹ã®ååã®ããã»ã¹ãç»é²ãããŠããªãå Žåã¯ããããéå§ããŠç»é²ããŸãã倧æåå°æåã®ä»£ããã«ifã䜿çšããŠããã®å Žåã¯ãã®åŒãè¿ãçµæã¯éèŠã§ã¯ãªããåŒã¯å¯äœçšã®ããã ãã«å®è¡ãããããšã匷調ããŠããŸãã spawn_linkã®ä»£ããã«spawnãããã§äœ¿çšãããããšã«ã泚æããŠãã ãããããã¯å¶ç¶ã§ã¯ãããŸãããäºå®ã¯æåã¯ãParallelEnum.map / 2é¢æ°ãã©ãã§ããã€ã誰ã«ãã£ãŠäœ¿çšããããã«ã€ããŠäœãä»®å®ããŠããŸããã§ããã Erlang VM 2ã®ã©ããã§ParallelEnum.map/2é¢æ°ãåæã«å®è¡ããããã®ãã¡ã®1ã€ãäœããã®çç±ã§äŸå€ãã¹ããŒããå Žåãã«ãŠã³ã¿ãŒããã»ã¹ãäœäžããäºæž¬ã§ããªãåäœãšãå¥å šãªãããã®æãããªåææ¡ä»¶ãäœæããŸãçŸæç¹ã§ParallelEnum.map/2é¢æ°ãå®è¡ããããšãã§ããªãã£ãããã»ã¹ããã®ãããã«ãŠã³ã¿ãŒããã»ã¹ãä»ã®ããã»ã¹ã«ãªã³ã¯ããªãã§ãã ãããäºæž¬äžå¯èœãªåäœãšãå¥å šãªãããã»ã¹ã®ããã®æ確ãªåææ¡ä»¶ãäœæããŸãããããã¯ãçŸæç¹ã§é¢æ°ParallelEnum.map/2ãå®è¡ããã ãã®å¹žéã§ã¯ãããŸããã§ããããã®ãããã«ãŠã³ã¿ãŒããã»ã¹ãä»ã®ããã»ã¹ã«ãªã³ã¯ããªãã§ãã ãããäºæž¬äžå¯èœãªåäœãšãå¥å šãªãããã»ã¹ã®ããã®æ確ãªåææ¡ä»¶ãäœæããŸãããããã¯ãçŸæç¹ã§é¢æ°ParallelEnum.map/2ãå®è¡ããã ãã®å¹žéã§ã¯ãããŸããã§ããããã®ãããã«ãŠã³ã¿ãŒããã»ã¹ãä»ã®ããã»ã¹ã«ãªã³ã¯ããªãã§ãã ããã
def map lst, func, limit \\ 2 do if (:erlang.whereis(@controller) == :undefined ) do :erlang.register( @controller, spawn(ParallelEnum, :parallel_enum_control_system, [1]) ) end Enum.map(lst, &(try_make_child(&1, func, limit))) |> Enum.map( &collect_results/1 ) end
ParallelEnum.map/2é¢æ°ã®æ¬äœã®if-expressionã®åŸã«ãå€å žçãªmap-reduceããããŸãïŒäžéšã®ç®èãªãæ£åŒã«ã¯map-mapã¯ããã«ãããŸãããçµè«ã«æ¥ããªãã§ãã ããïŒããããã£ãŠããŠã£ãããã£ã¢ã«ãããšããã®ãã¿ãŒã³ã¯2ã€ã®ã¹ãããã§æ§æãããŠããŸãã
ãããã¹ããã
Mapã¹ãããã§ã¯ãã«ãŠã³ã¿ãŒããã»ã¹ã«åŸã£ãŠParallelEnumã«é¢é£ããå®è¡äžã®ããã»ã¹ã®æ°ã確èªããŸããããã»ã¹æ°ã®æå®ãããå¶éãè¶ ããŠããªãå Žåãåããã»ã¹ãäœæããPIDãæž¡ããŠïŒçµæãè¿ãããšãã§ããããã«ïŒãã¯ãŒã¯ãããŒãå®è¡ããåŒæ°ãæã€é¢æ°ãæž¡ããŸããå¶éãè¶ ããå Žåã芪ããã»ã¹ã¯ããèªäœã§åŒãå®è¡ããŸãã
IntermediateResultæ§é äœã䜿çšããçç±ã«ã€ããŠå°ã説æããŸããããã»ã¹ã®æ°ã«å¶éããªãå Žåãåããã»ã¹ã®PIDã®ãªã¹ããåéããããããçµæã§å¿çããã®ãåŸ ã€ããšãã§ããŸããããããå¶éã«ãããå Žåã«ãã£ãŠã¯èŠªããã»ã¹ãäœæ¥ãè¡ãå¿ èŠããããŸãããã®æ§é ã¯ãåããã»ã¹ããã®çµæãæåŸ ãããã©ãããç解ããããã®çž®å°ã¹ãããã§åœ¹ç«ã¡ãŸãã
defmodule IntermediateResult do defstruct child_pid: nil, my_own_result: nil end defp try_make_child(arg, func, limit) do case (get_number_of_processes < limit) do false -> %IntermediateResult{child_pid: nil, my_own_result: func.(arg)} # in this case do work yourself haha true -> %IntermediateResult{child_pid: spawn_link(ParallelEnum, :worker, [self, func, arg]), my_own_result: nil} end end defp get_number_of_processes do send @controller, %{ from: self, query: :get_number } receive do num when is_integer(num) -> num end end
äœæ¥ããã»ã¹
è€éãªããšã¯ãŸã£ãããããŸãããéå§çŽåŸã«å¢åä¿¡å·ãã«ãŠã³ã¿ãŒã«éä¿¡ããé¢æ°ãå®è¡ããŠçµæãçæããã»ã¹ã«éä¿¡ããå®äºåã«æžåä¿¡å·ãã«ãŠã³ã¿ãŒã«éä¿¡ããŸãã
def worker(daddy, func, arg) do send @controller, :increment send daddy, %{ from: self, result: func.(arg)} send @controller, :decrement end
ã¹ããããæžãã
ããã§ãããã¹ãŠãéåžžã«éæã§ããmapã¹ãããã®åŸã«ååŸããIntermediateResultæ§é ã¯ãreduceã¹ãããã§äœãããå¿ èŠãããããæ確ã«ç€ºããŠããŸã-å®æããçµæïŒèŠªããã»ã¹ãäœæ¥ãè¡ã£ãå ŽåïŒãååŸããããåããã»ã¹ããã®çµæãå«ãã¡ãã»ãŒãžãåŸ ã¡ãŸãã
defp collect_results( %IntermediateResult{child_pid: nil, my_own_result: result}) do result end defp collect_results( %IntermediateResult{child_pid: pid, my_own_result: nil}) do receive do %{ from: incoming_pid, result: result} when (incoming_pid == pid) -> result end end
ããã§ãããšãã°ã²ãŒã é¢æ°å ã§ãEnum.mapé¢æ°ãParallelEnum.mapé¢æ°ã«çœ®ãæããããšãã§ããäœæ¥ã¯å®äºã§ããã³ãŒãã®æçµããŒãžã§ã³ã¯ããã§èŠãããŸãã
æ§èœè©Šéš
ãããã£ãŠãããªã€ã©ãŒéŠ¬ãã®åé¡ã¯è§£æ±ºããããœãªã¥ãŒã·ã§ã³ãæé©åãããŸããçŸåšããã¹ãŠãè¿ éã«åäœãããã¹ãŠã®ããã»ããµã³ã¢ãæ倧éã«ããŒãããŸãã

ãã¹ãã®æéã䞊åæé©åã®è°è«ã®äžã§ãç¹å®ã®ã¿ã¹ã¯ã®ããã»ã¹æ°ã®å¶éã«ã€ããŠæ£ç¢ºã«ã¯äœãèšãããŠããŸããã§ãããHorse.Solutionã¢ãžã¥ãŒã«ã®é¢æ°ããããã«å€æŽããŠãå¿ èŠãªããã»ã¹æ°ãšéŠ¬ã®åæäœçœ®ãäžæã«èšå®ã§ããããã«ããŸãïŒæ確ã«ããããïŒã5x5ããŒãã®Horse.Solution.inité¢æ°ã®å®è¡æéã1.1ã®åæäœçœ®ãããã³ãã®é¢æ°ã䜿çšããããã»ã¹ã®æ倧æ°ã®ç°ãªãå€ããã¹ãããŸãã
def test_of_performance do Enum.each( 1..25, fn(num) -> test_of_performance_process(num) end ) Enum.each( [50, 75, 100, 150, 200, 250, 500, 1000], fn(num) -> test_of_performance_process(num) end ) # to test this, add +P 100000000 flag when starting iex Enum.each( [10000, 50000, 100000, 500000, 1000000, 5000000, 10000000], fn(num) -> test_of_performance_process(num) end ) end defp test_of_performance_process(num) do {res, _} = :timer.tc( fn() -> init(5, num, %Position{}) end ) File.write "./test_results", "#{num} #{res}\n", [:append] end
枬å®ã«ãããäœæ¥ããã»ã¹æ°24ã®æå°æéïŒæ倧çç£æ§ïŒã瀺ãããŸããã

ãªããããªã«ãããã
çµå±ã®ãšãããããŒã«ã«ãã·ã³ã®ã³ã¢ã¯ã¯ããã«å°ãªãã§ããErlang VMããã»ã¹ã¯ãéåžžã®æå³ã§ã®OSããã»ã¹ã§ã¯ãªãããã§ããã¹ã¬ããã§ã¯ãããŸãããä»®æ³ãã·ã³ã¯ããããå®å šã«ã«ãã»ã«åããããã»ããµã³ã¢å šäœã«è² è·ãåçã«åæ£ããŸãïŒå¯èœãªå ŽåïŒã
ãªããããªã«å°ãªã
Erlang VMããã»ã¹ã®ãªãœãŒã¹ã¯ãããããã§ãããã³ã¹ãã¯ããããŸããããã»ã¹æ°ã®å¢å ã«äŒŽããç·ãªãŒããŒãããã³ã¹ããå¢å ããããã«ãçŽ24ã®ããã»ã¹ã§ããã»ããµã³ã¢ã«è² è·ãåçã«åæ£ããŸããä»®æ³ãã·ã³ã¯è² è·ãããã«åçã«åæ£ã§ããŸãããããã§ã¯ãå®éã®ããã»ããµã®ç©ççãªå¶éã«äŸåããŸãã
ç§ãã¡ã®ç¹å®ã®ã±ãŒã¹ã§ã¯ãã«ãŠã³ã¿ãŒããã»ã¹ã«ã€ããŠèŠããŠãã䟡å€ããããŸãã芪ããã»ã¹ã¯ãåããã»ã¹ãäœæããã®ãããããšãäœæ¥ãè¡ãã®ãã決å®ãããšãã«ãæ¢ã«å®è¡äžã®ããã»ã¹ã®æ°ãã«ãŠã³ãããã»ã¹ã«èŠæ±ããŸããããã§ã圌ã¯ã«ãŠã³ã¿ãŒã«ã¡ãã»ãŒãžãéä¿¡ããã ãã§ãªãã圌ããã®åçãåŸ ã€å¿ èŠããããŸããããã»ã¹ã¯1ã€ã®ã«ãŠã³ã¿ãŒã§ããæ°åäžã®äœæ¥ããã»ã¹ãããã§ã¯ãã¹ãŠãæ確ã ãšæããŸãã
1,000,000åã®ããã»ã¹ãããŒã¯ããåŸã«çç£æ§ãåã³äžæãå§ããçç±ã¯ãç§ã«ã¯è¬ã§ãã
ãããã«
Erlangã¯ããã«ãã¹ã¬ããããã°ã©ãã³ã°ã®äžçã§å¯äžã®çŸè±¡ã§ãã 1987幎ããŸã JavaããååšãããC ++ã§ã®åçŽãªãã«ãã¹ã¬ããããã°ã©ãã³ã°ã«ã€ããŠå€¢ãèŠãããšãã§ãããšãããšãªã¯ãœã³ã®éçºè ã¯ãã§ã«éä¿¡æ¥çã§äœ¿çšãããã©ãŒã«ããã¬ã©ã³ãããã°ã©ã ãäœæããŠããŸããã Erlangèšèªãšãã®ä»®æ³ãã·ã³ã¯ãç¹å®ã®ãã¬ã³ã ã¿ã¹ã¯ã解決ããããã«å°ãå®çšçãªç®çã®ããã«äœæãããŸãã;é·å¹Žã«ããã£ãŠããã®èšèªã¯å®éã®ã¿ã¹ã¯ïŒHaskellãªã©ãšã¯ç°ãªããŸãïŒã§é²åããŸãããéçºã®éçšã§ãå€ãã®ãããããã°ããææžåãããã©ã€ãã©ãªã§ãæé·ãããOTPïŒOpen Telecom PlatformïŒãã¬ãŒã ã¯ãŒã¯ãç»å ŽããŸããã Erlangã®OTPã¯ãããšãã°C ++ã®Qt以äžã®ãã®ã§ããéåä¿¡åŒãèŠããŠããŸããïŒ Erlang VMã«ã¯å®éã«ã¯ããã»ã¹éã®éåæã¡ãã»ãŒãžã³ã°ãããããŸããã倧èŠæš¡ãããžã§ã¯ãã§ãã®ãããªäœã¬ãã«ã®ã³ãŒããæžãã®ã¯ããŸã䟿å©ã§ã¯ãããŸãããOTPã«ã¯äœã¬ãã«ã®è©³çŽ°ãã«ãã»ã«åããéåžžã«ã·ã³ãã«ã§äŸ¿å©ã§çŽæçãªã€ã³ã¿ãŒãã§ã€ã¹ãæäŸããããŒã«ããããŸã-éåæ亀æã ãã§ãªããããšãã°åæéä¿¡ããšã©ãŒåŠçããŒã«/æ»ãªã©ããã®èšäºã§ã¯ãå¥ã®å€§ããªèšäºã®ãããã¯ã§ãããšããçç±ã ãã§OTPã䜿çšããŸããã§ããã Erlang VMã®å®å®æ§ãšèé害æ§ã¯åçã§ã¯ãããŸãããç°ãªãããã»ã¹æ°ã§ããã©ãŒãã³ã¹ããã¹ããããšããæåŸã®å€ã¯10,000,000ã§ãããåæã«ãããã©ãŒãã³ã¹ã¯ãã¡ãã24ã«æ¯ã¹ãŠäœäžããŸããããå®å šã«èŽåœçã§ã¯ãããŸãããã¯ããErlang VMã®æŒç®ã¯ãå°ããã€ããã®ã§ããããã圌ããèšãããã«ãé«éãªç®è¡æŒç®ãå¿ èŠãªå Žåã¯ãFortranãå¿ èŠã§ãããã®å³ã§ã¯ãErlang VMã®å Žåãåæã«ä¿å®ããå¿ èŠãããããã°ã©ã ãäœæã§ãããšèšãããã ãã§ããæ¬åœã«ããããã®ããã»ã¹ãäŸãšããŠãWebãµãŒããŒãŸãã¯åæ§ã®ãã®ãããã«æãæµ®ãã³ãŸããããã«ãErlang VMã®ããã©ãŒãã³ã¹ã¯æªããªããååãšããŠãœãããªã¢ã«ã¿ã€ã ã§ããäžè¬ã«ãErlang / Elixir + OTPã¯ãå®å®ããåæ£ãããéåžžã«ä¿¡é Œæ§ã®é«ãããã°ã©ã ãäœæããããã®äžå¯æ¬ ãªã¢ã·ã¹ã¿ã³ãã«ãªãããšãã§ããŸãã
UPDïŒLispããŒãžã§ã³
æ°æ¥åãç§ã¯LispãšJVMãåæã«åå ãããClojureã§ãã®ã¿ã¹ã¯ãæžãçŽãããšã«ããŸãããå®éãã³ãŒãã®åªé ã/èªã¿ãããã«ã€ããŠã¯è°è«ã®äœå°ããããŸãããããã§ã®äœæ¥ã®é床ãéåžžã«èš±å®¹ã§ãããšããäºå®ã§ãã

ã³ãŒãã¯ãã¡ãã§ãã
Elixirãå®éã«è¶³ã䌞ã°ããŠããå ŽæããŸã ç解ããã人ã®ããã«-Lispã®æ¹èšã«ç²Ÿéããããšããå§ãããŸãã