2015-06-02 14 views
11

Ho armeggiato con Elixir per le ultime settimane. Mi sono appena imbattuto in questo succinto combinations algorithm in Erlang, che ho provato a riscrivere in Elixir ma sono rimasto bloccato. VersioneCome riscrivere l'algoritmo delle combinazioni di Erlang in elisir?

Erlang:

comb(0,_) -> 
    [[]]; 
comb(_,[]) -> 
    []; 
comb(N,[H|T]) -> 
    [[H|L] || L <- comb(N-1,T)]++comb(N,T). 

versione Elixir mi si avvicinò con questo, ma non è corretto:

def combination(0, _), do: [[]] 
def combination(_, []), do: [] 
def combination(n, [x|xs]) do 
    for y <- combination(n - 1, xs), do: [x|y] ++ combination(n, xs) 
end 

Esempio di utilizzo, con risultati non corretti:

iex> combination(2, [1,2,3]) 
[[1, 2, [3], [2, 3]]] 

qualsiasi puntatori su cosa sto facendo male?

Grazie!
Sean

risposta

13

È necessario avvolgere l'espressione for in parentesi come il codice Erlang.

def combination(n, [x|xs]) do 
    (for y <- combination(n - 1, xs), do: [x|y]) ++ combination(n, xs) 
end 

Demo:

iex(1)> defmodule Foo do 
...(1)> def combination(0, _), do: [[]] 
...(1)> def combination(_, []), do: [] 
...(1)> def combination(n, [x|xs]) do 
...(1)>  (for y <- combination(n - 1, xs), do: [x|y]) ++ combination(n, xs) 
...(1)> end 
...(1)> end 
{:module, Foo, 
<<70, 79, 82, 49, 0, 0, 6, 100, 66, 69, 65, 77, 69, 120, 68, 99, 0, 0, 0, 137, 131, 104, 2, 100, 0, 14, 101, 108, 105, 120, 105, 114, 95, 100, 111, 99, 115, 95, 118, 49, 108, 0, 0, 0, 2, 104, 2, ...>>, 
{:combination, 2}} 
iex(2)> Foo.combination 2, [1, 2, 3] 
[[1, 2], [1, 3], [2, 3]] 
+0

Eccellente! Grazie. :) – seanomlor