jabuci

jabuci

My program eats up the memory and the OS kills it

I’m new to Elixir (started yesterday) and as a first little program, I wanted to solve the Münchausen numbers problem.

“A Münchausen number is a number equal to the sum of its digits raised to each digit’s power. For instance, 3435 is a Münchausen number because 3^3+4^4+3^3+5^5 = 3435. The largest Münchausen number is less than 440 million.”

The problem is that my program eats up all my RAM (16 GB) and the OS kills the process. And I don’t understand what goes on with the garbage collector.

Here is my solution:

#!/usr/bin/env elixir

defmodule Munchausen do
  @cache [0] ++ for n <- 1..9, do: n ** n

  def get_cache(), do: @cache

  def explode(n), do: explode(n, [])

  # int, acc -> list[int]
  def explode(n, acc) when n == 0, do: acc

  def explode(n, acc) do
    digit = rem(n, 10)
    explode(div(n, 10), [digit | acc])
  end

  # int -> bool
  def is_munchausen(n) do
    digits = explode(n)
    li = for x <- digits, do: Enum.at(@cache, x)
    n == Enum.sum(li)
  end
end

defmodule Main do
  # @max 10_000
  @max 440_000_000

  def main() do
    # Munchausen.get_cache() |> IO.inspect
    for n <- 0..@max do
      # :erlang.garbage_collect()
      if rem(n, 1_000_000) == 0 do
        IO.puts("# #{n}")
      end
      if Munchausen.is_munchausen(n) do
        IO.puts(n)
      end
    end
  end
end

Main.main()

I know that it’s not optimal and slow. I’ll work on it.

Now the question is: why does it consume all my memory and how to prevent that? Thanks.

Marked As Solved

al2o3cr

al2o3cr

A for loop like this will return a list containing the results of every evaluation of the do block:

for n <- 0..10 do
  IO.puts(n)
end

Running this in iex produces:

iex(1)> for n <- 0..10 do
...(1)>   IO.puts(n)
...(1)> end
0
1
2
3
4
5
6
7
8
9
10
[:ok, :ok, :ok, :ok, :ok, :ok, :ok, :ok, :ok, :ok, :ok]

Your Main.main function is building up a 440 million element list of :ok and nil, which it then discards when it exits.

Also Liked

tj0

tj0

Also, check out Memoize — memoize v1.4.0 , it makes the caching step trivial. For fibonnaci example:

defmodule Fib do
  use Memoize
  defmemo fibs(0), do: 0
  defmemo fibs(1), do: 1
  defmemo fibs(n), do: fibs(n - 1) + fibs(n - 2)
end
jabuci

jabuci

Thanks. Right, the same thing happens in Python too:

$ python3
Python 3.10.4 (main, Mar 23 2022, 23:05:40) [GCC 11.2.0] on linux
>>> a = list(range(0, 440_000_000))
[1]    216403 killed     python3

So what’s the solution? How to iterate over the numbers from 0 until 440 million?

Update: I found the answer to my question:

Enum.each(0..@max, fn n ->
  if rem(n, 1_000_000) == 0 do
    IO.puts("# #{n}")
  end
  if Munchausen.is_munchausen(n) do
    IO.puts(n)
  end
end)
kokolegorille

kokolegorille

You might use stream to process the list lazily…

https://hexdocs.pm/elixir/1.13/Stream.html

Where Next?

Popular in Questions Top

Fl4m3Ph03n1x
Background Let’s assume I have a typical GenServer that receives messages as requests, does some operation in a DB and returns responses....
New
lastday4you
I wanted to check elixir version in phoenix because i found that my elixir is 1.5 but when i use Enum.chunk_by it said the function is un...
New
yawaramin
In the Dialyzer docs ( http://erlang.org/doc/man/dialyzer.html#requesting-or-suppressing-warnings-in-source-files ), there is a way to tu...
New
LegitStack
I’m hoping you guys can give me some general advice and perhaps code examples if you’re feeling up to it. I’m very interested in Elixir,...
New
romenigld
I am trying to run a deploy with docker and I successfully runned with this command: docker build -t romenigld/blog-prod . but when I t...
New
Kagamiiiii
Student &amp; New to elixir. Nice language. I want to convert a english character, e.g. “a”, which is stored in a variable, to it’s asci...
New
vertexbuffer
Hello, can anybody help here..? I have a list of players and I what to delete an element, but every for loop the list is reverting to ori...
New
mgjohns61585
Could someone help me? I'm making my first elixir program, number guessing game. I can't figure out how to convert the user's guess from ...
New
stefanluptak
Hello everybody, usually, I use a 29" ultra-wide monitor for VSCode which can easily accomodate explorer (files panel) + file with code ...
New
jay1
Why is it that the mnesia database isn’t the most preferred database for use in Elixir/Phoenix?
New

Other popular topics Top

sorentwo
Hello! tl;dr Announcing Oban, an Ecto based job processing library with a focus on reliability and historical observability. After spen...
977 41022 311
New
romenigld
I am trying to run a deploy with docker and I successfully runned with this command: docker build -t romenigld/blog-prod . but when I t...
New
lk-geimfari
What is most correct way to open, read and parse JSON file with poison? For example if we have example.json file in root of some projec...
New
vertexbuffer
Hello, can anybody help here..? I have a list of players and I what to delete an element, but every for loop the list is reverting to ori...
New
chrismccord
As promised, the first release candidate of Phoenix 1.3.0 is out! This release focuses on code generators with improved project structure...
New
mgjohns61585
Could someone help me? I'm making my first elixir program, number guessing game. I can't figure out how to convert the user's guess from ...
New
vonH
When I run the Plug and I recompile I wind up having to use Ctrl C to quit iex and start again. Witht the help of rlwrap I can use the cu...
New
msaraiva
Surface is an experimental library built on top of Phoenix LiveView and its new LiveComponent API that aims to provide a more declarative...
564 42633 214
New
siddhant3030
Hi, I have to write a raw query for one of my project. But till now I have used ecto queries and don’t have much experience writing raw ...
New
jay1
Why is it that the mnesia database isn’t the most preferred database for use in Elixir/Phoenix?
New

We're in Beta

About us Mission Statement