Skip to content

Instantly share code, notes, and snippets.

@allansideas
Last active February 27, 2017 09:54
Show Gist options
  • Save allansideas/aebc90812e82ce407e0ce08a1ddf7cb8 to your computer and use it in GitHub Desktop.
Save allansideas/aebc90812e82ce407e0ce08a1ddf7cb8 to your computer and use it in GitHub Desktop.
Marios Pyramid
defmodule Pyramid.Plans do
defstruct height: nil, layers: nil
end
defmodule Pyramid do
@moduledoc """
Mario's Pyramid problem solution
"""
def main(height) do
#How to validate that input is > 0 without if?
plans = %Pyramid.Plans{height: height}
plans
|> build_layers
|> print_out
end
def print_out(%Pyramid.Plans{layers: layers}) do
# Say I didn't want a newline at the very end, would the best way be to just
# delete the last element of the flattened list?
#IO.puts(layers) (is far more performant - the flatten, and join are not required thanks to IO lists (see comment)
List.flatten(layers)
|> Enum.join("")
|> IO.puts
end
@doc """
Builds a list consisting of the carachters needed for the layer of the Pyramid
`blocks` is the number of blocks in the layer
`height` is used to calculate the left padding
## Examples
iex> Pyramid.build_layer(3, 5)
[" ", " ", "#", "#", "#", "\\n"]
"""
def build_layer(blocks, height) do
# Generally speaking is this method too messy? Should I extract the Enum.maps
# into more descriptive smaller methods i.e pad_layer(layer), add_blocks_to_layer(layer)?
left_pad = height - blocks
# How to avoid having to trim the list (why does 0..0 iterate once) i.e.
# Enum.map(0..0, fn(pos)-> pos end)
# [0]
padding = Enum.map(0..left_pad, fn(pos)-> " " end)
padding_plus_blocks = padding ++ Enum.map(1..blocks, fn(pos)-> "#" end)
trimmed = List.delete_at(padding_plus_blocks, 0)
trimmed ++ ["\n"]
end
@doc """
Builds a List of lists with each layer's representation in strings i.e.
[[" ", "#", "\n"], ["#", "#", "\n"]]
"""
def build_layers(%Pyramid.Plans{height: height} = plans) do
block_counts = Enum.to_list(1..height)
layers =
block_counts
# Can I do an (&build_layer/2) with args here instead of the full fn inside
# the map?, should this somehow be done with recursion?
|> Enum.map(fn(blocks_in_layer)-> build_layer(blocks_in_layer, height) end)
%Pyramid.Plans{plans | layers: layers}
end
end
@allansideas
Copy link
Author

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment