# How to make a program that prints number from 1 to N starting in 1 without an accumulator?

I want to make a program to prints number from 1 to N starting in 1 without an accumulator.

``````defmodule Recursion do
def print_multiple_times(n) when n <= 1 do
IO.puts n
end

def print_multiple_times( n) do
IO.puts n
print_multiple_times( n - 1)
end
end
``````

I want to do something like this, but instead of going from n to 1 (n - 1) going from 1 to n, but without an accumulator I can’t find any solution.

``````iex> for n <- 1..10, do: IO.puts n
``````

or

``````defmodule Recursion do
def print_multiple_times(n) when n >= 10 do
IO.puts n
end

def print_multiple_times( n) do
IO.puts n
print_multiple_times( n + 1)
end
end
``````

but in this case, You set n as starting point. You could pass m value as the end point.

1 Like

Thanks it worked, I thought there wasn’t for loops on Elixir

It’s not a loop, it’s a list comprehension

3 Likes

Other esoteric ways, just for fun:

`Enum.each(1..10, &IO.puts/1)`

`Stream.iterate(0, & (&1 + 1)) |> Stream.take(10) |> Enum.join(" ") |> IO.puts`

`Stream.iterate(0, & (&1 + 1)) |> Stream.map(&IO.puts/1) |> Enum.take(10)`

2 Likes

This is not esoteric, but the only true way, as all the other versions actually create a list that we are not interested in. Since we are only interested in the side effects of printing, actually only `Enum.each/2` or some stream that is piped into `Stream.run/1` are valid answers.

Yes, perhaps “esoteric” was not my best choice of words. I get the feeling the original poster was trying various approaches out and there was no strict constraint. If there was a constraint to not create a list, then I apologize for my irrelevant post. At least I didn’t use an accumulator Why?

Additional parameters are a legitimate technique for controlling recursion. With tail recursion (without side effects like `IO.puts`) one parameter is used to managing the data that is left on the call stack with body recursion.

``````defmodule Demo do
def multi(n),
do: multi(1, n, [])

defp multi(i, n, list) when i > n,
do: list

defp multi(i, n, rest) when i <= n,
do: multi(i + 1, n, [i | rest])
end

result = Demo.multi(10)
IO.puts("#{inspect(result, charlists: :as_lists)}")

r = :lists.reverse(result)
IO.puts("#{inspect(r, charlists: :as_lists)}")
``````
``````\$ elixir demo.exs
[10, 9, 8, 7, 6, 5, 4, 3, 2, 1]
[1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
\$
``````
1 Like

I didn’t mean to scare you away, sorry if I did. I’m not sure if the original poster needed a list, but from the example code, the `Enum.each/2` is closest.

Because it sometimes can help understanding the language if one sees a couple different ways to achieve the same or similar observable behaviour?

1 Like
``````1..n |> Enum.map(&to_string/1) |> Enum.intersperse("\n") |> IO.puts()
``````

I was driving towards the realization that the original code has in fact a hardcoded limit - as demonstrated by @kokolegorille.

So going the other way doesn’t actually need an additional parameter. It’s just that the original code left one out by hardcoding it.

``````defmodule Recursion do
def print_multiple_times(n, m) when n <= m do
IO.puts(n)
end

def print_multiple_times(n, m) do
IO.puts(n)
print_multiple_times(n - 1, m)
end

def print_multiple_times_r(n, m) when n >= m do
IO.puts(n)
end

def print_multiple_times_r(n, m) do
IO.puts(n)
print_multiple_times_r(n + 1, m)
end

def multi(n, m) when n >= m,
do: print_multiple_times(n, m)

def multi(n, m),
do: print_multiple_times_r(n, m)
end

Recursion.multi(10, 1)
Recursion.multi(1, 10)
Recursion.multi(10, 10)
``````

Yeah, the `Enum.each/2` was closest, but honestly, I like @kokolegorille 's example for comprehension most. As I learned from José’s Advent of Code videos, a for comprehension that is not assigned to a variable does not generate the intermediate list either.