best pattern to translate nested loops into FP

306 views
Skip to first unread message

eksperimental

unread,
Aug 16, 2015, 12:47:29 PM8/16/15
to elixir-l...@googlegroups.com
I'm trying to port this code to Elixir,
https://luckytoilet.wordpress.com/2010/04/18/the-sieve-of-sundaram/

```
for(ll i=0; i<m; i++)
sieve[i] = 1;

for(ll i=1; i<m; i++)
for(ll j=i; j<=(m-i)/(2*i+1); j++)
sieve[i+j+2*i*j] = 0;
```

What is the pattern to translate a nested loop into Elixir code.?

Thank you

Peter Hamilton

unread,
Aug 16, 2015, 1:55:45 PM8/16/15
to elixir-l...@googlegroups.com

for comprehension syntax supports iterating over multiple variables. It's essentially equivalent to a combination of flat_map and map.


--
You received this message because you are subscribed to the Google Groups "elixir-lang-talk" group.
To unsubscribe from this group and stop receiving emails from it, send an email to elixir-lang-ta...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/elixir-lang-talk/20150816234717.1b46ff6d.eksperimental%40autistici.org.
For more options, visit https://groups.google.com/d/optout.

eksperimental

unread,
Aug 16, 2015, 3:04:56 PM8/16/15
to elixir-l...@googlegroups.com
Thanks for the advice.
I cannot get this to work though,

n = 100
m = div(n, 2)
numbers = 1..n |> Enum.map &(&1)
result = for i <- 1..m-1 do
for j <- i..m, j <= div(m-i, 2*i+1) do
i+j+2*i*j
end
end |> List.flatten
primes = numbers -- result
IO.inspect(primes)

I'm not getting the right results.
:-(
and got stuck for a while already

José Valim

unread,
Aug 16, 2015, 3:20:04 PM8/16/15
to elixir-l...@googlegroups.com
Here is a translation of the algorithm (not of the C code):

n = 100
m = 50

all = Enum.to_list(1..100)

remove =
  for i <- 1..(m - 1),
      j <- i..div(m - 1, 2 * i + 1),
      do: i + j + 2 * i * j

IO.inspect Enum.map(all -- remove, &(2 * &1 + 1))

There are likely more efficient ways of running this. Maybe put all numbers in a map and remove them as you go. But this is definitely the simplest implementation.



José Valim
Skype: jv.ptec
Founder and Director of R&D

eksperimental

unread,
Aug 17, 2015, 1:09:29 AM8/17/15
to elixir-l...@googlegroups.com
Thank you very much for the code Jose,
that helped me understand how to write a lot cleaner and better
performant code.

I was overlooking the fact that the algorithm specified that the
remaining integers had to be multiplied by 2 and added 1. That's why i
was getting wrong numbers, and that C code sample was just counting up
how many prime numbers.

I would like to implement the idea with the map,
but how can I keep the state over the iterations?

Cheers,

On Sun, 16 Aug 2015 21:19:40 +0200
José Valim <jose....@plataformatec.com.br> wrote:

> Here is a translation of the algorithm (not of the C code):
>
> n = 100
> m = 50
>
> all = Enum.to_list(1..100)
>
> remove =
> for i <- 1..(m - 1),
> j <- i..div(m - 1, 2 * i + 1),
> do: i + j + 2 * i * j
>
> IO.inspect Enum.map(all -- remove, &(2 * &1 + 1))
>
>
> There are likely more efficient ways of running this. Maybe put all
> numbers in a map and remove them as you go. But this is definitely
> the simplest implementation.
>
>
>
> *José Valim*

José Valim

unread,
Aug 17, 2015, 6:02:48 AM8/17/15
to elixir-l...@googlegroups.com
I would like to implement the idea with the map,
but how can I keep the state over the iterations?

You will need to call Enum.reduce two times, passing the map as accumulator each time.

Ed W

unread,
Aug 17, 2015, 1:25:52 PM8/17/15
to elixir-l...@googlegroups.com
On 17/08/2015 06:09, eksperimental wrote:

> I would like to implement the idea with the map,
> but how can I keep the state over the iterations?

I would also comment that even more than with "non functional
languages", the readability goes up a lot if you introduce smaller
functions. 2 nested maps as you want here can easily look quite clunky,
but if you introduce a named function to say wrap the inner, then you
can quickly introduce some very readable code.

Good luck!

Ed W

Reply all
Reply to author
Forward
0 new messages