How to resolve the algorithm Nonoblock step by step in the Elixir programming language

Published on 12 May 2024 09:40 PM

How to resolve the algorithm Nonoblock step by step in the Elixir programming language

Table of Contents

Problem Statement

Nonoblock is a chip off the old Nonogram puzzle.

Given a row of five cells and a block of two cells followed by a block of one cell - in that order, the example could be shown as: And would expand to the following 3 possible rows of block positions:

Note how the sets of blocks are always separated by a space. Note also that it is not necessary for each block to have a separate letter. Output approximating This: This would also work:

(This is the algorithm used in the Nonoblock#Python solution).

Let's start with the solution:

Step by Step solution about How to resolve the algorithm Nonoblock step by step in the Elixir programming language

Source code in the elixir programming language

defmodule Nonoblock do
  def solve(cell, blocks) do
    width = Enum.sum(blocks) + length(blocks) - 1
    if cell < width do
      raise "Those blocks will not fit in those cells"
    else
      nblocks(cell, blocks, "")
    end
  end
  
  defp nblocks(cell, _, position) when cell<=0, do:
    display(String.slice(position, 0..cell-1))
  defp nblocks(cell, blocks, position) when length(blocks)==0 or hd(blocks)==0, do:
    display(position <> String.duplicate(".", cell))
  defp nblocks(cell, blocks, position) do
    rest = cell - Enum.sum(blocks) - length(blocks) + 2
    [bl | brest] = blocks
    Enum.reduce(0..rest-1, 0, fn i,acc ->
      acc + nblocks(cell-i-bl-1, brest, position <> String.duplicate(".", i) <> String.duplicate("#",bl) <> ".")
    end)
  end
  
  defp display(str) do
    IO.puts nonocell(str)
    1                           # number of positions
  end
  
  def nonocell(str) do                  # "##.###..##" -> "|A|A|_|B|B|B|_|_|C|C|"
    slist = String.to_char_list(str) |> Enum.chunk_by(&(&1==?.)) |> Enum.map(&List.to_string(&1))
    chrs = Enum.map(?A..?Z, &List.to_string([&1]))
    result = nonocell_replace(slist, chrs, "")
             |> String.replace(".", "_")
             |> String.split("") |> Enum.join("|")
    "|" <> result
  end
  
  defp nonocell_replace([], _, result), do: result
  defp nonocell_replace([h|t], chrs, result) do
    if String.first(h) == "#" do
      [c | rest] = chrs
      nonocell_replace(t, rest, result <> String.replace(h, "#", c))
    else
      nonocell_replace(t, chrs, result <> h)
    end
  end
end

conf = [{ 5, [2, 1]},
        { 5, []},
        {10, [8]},
        {15, [2, 3, 2, 3]},
        { 5, [2, 3]}       ]
Enum.each(conf, fn {cell, blocks} ->
  try do
    IO.puts "Configuration:"
    IO.puts "#{Nonoblock.nonocell(String.duplicate(".",cell))} # #{cell} cells and #{inspect blocks} blocks"
    IO.puts "Possibilities:"
    count = Nonoblock.solve(cell, blocks)
    IO.puts "A total of #{count} Possible configurations.\n"
  rescue
    e in RuntimeError -> IO.inspect e
  end
end)


  

You may also check:How to resolve the algorithm Polynomial regression step by step in the Kotlin programming language
You may also check:How to resolve the algorithm Array length step by step in the Potion programming language
You may also check:How to resolve the algorithm Stirling numbers of the second kind step by step in the Wren programming language
You may also check:How to resolve the algorithm Sum multiples of 3 and 5 step by step in the Phix programming language
You may also check:How to resolve the algorithm Window creation step by step in the mIRC Scripting Language programming language