16 Jul 2013, 02:25
Dave_gnome_head_isolated_pragsmall

Dave Thomas (339 posts)

  • Write a function that takes a list of dqs and prints each on a separate line, centered in a column which is the width of the longest. Make sure it works with UTF characters.

    iex> center(["cat", "zebra", "elephant"])
      cat
     zebra
    elephant
    

A Possible Solution</summary>

defmodule MyString do

  def center(strings) do
    strings 
    |> Enum.map_reduce(0, accumulate_max_length(&1, &2))
    |> center_strings_in_field
    |> Enum.each(IO.puts(&1))
  end

  # We jump through this hoop to avoid calculating the string length twice.
  # Here, we build a tuple containing the length and the string, and
  # nest it in a tuple containing the maximum length seen so far
  defp accumulate_max_length(string, max_length_so_far) do
    l = String.length(string)
    { {string, l}, max(l, max_length_so_far) }
  end

  defp center_strings_in_field({strings, field_width}) do
    strings |> Enum.map(center_one_string(field_width, &1))
  end

  defp center_one_string(field_width, {string, length}) do
    %b[#{String.duplicate(" ", div(field_width - length, 2))}#{string}]
  end
end

MyString.center %w{ cat zebra elephant }

</details>

31 Oct 2013, 15:24
Mac 128k logic board 96x96_pragsmall

Roger Turner (7 posts)


  def center(strings) do
    strings 
    |> center_strings 
    |> Enum.each &IO.puts/1
  end

  def center_strings(strings) do
    max_length = strings |> Enum.map(&String.length/1) |> Enum.max
    in_width = fn (string) ->
      l = String.length string
      div(max_length - l, 2) + l
    end
    strings |> Enum.map &(String.rjust(&1, in_width.(&1)))
  end

14 Jan 2014, 01:41
Generic-user-small

Daniel Ashton (7 posts)

defmodule Binaries do

  import Enum, only: [max: 1, map: 2, each: 2]
  import String, only: [length: 1, duplicate: 2]
  import Kernel, except: [length: 1]

  def center(str_list) do
    max_len = str_list |> map(&(length &1)) |> max
    str_list |> each &(IO.puts duplicate(" ", div(max_len - length(&1), 2)) <> &1)
  end

end
16 Jun 2014, 02:51
Generic-user-small

Luke Imhoff (6 posts)

I found that Erlang has a :string library, but confusingly, there strings are character lists, but since we’re just calling IO.puts and it doesn’t care, you can use :string.centre (note British English spelling even though the docs will say ‘center’ in the description).

defmodule DoubleQuotedStrings do
  def center(list_of_strings) do
    max_length = list_of_strings
                 |> Enum.map(&String.length/1)
                 |> Enum.max
    list_of_strings
    |> Enum.map(&String.to_char_list/1)
    |> Enum.map(&(:string.centre(&1, max_length)))
    |> Enum.map(&IO.puts/1)
  end
end
14 Aug 2014, 09:54
Generic-user-small

Jeremy Ozog (1 post)

  def center(strings) do
    maxlength = strings |> Enum.max_by(&String.length/1) |> String.length
    Enum.map(strings, &(display_padded_string(&1, maxlength)))
  end
  defp display_padded_string(str, maxlength), do: IO.puts String.rjust(str, get_padding(str, maxlength))
  defp get_padding(str, maxlength), do: String.length(str) + div(maxlength-String.length(str), 2)
22 Aug 2014, 09:27
Generic-user-small

Peng Xiang (1 post)

It seems I still don’t get the sprit of functional programming…

defmodule StringList do
  def center string_list do
    max_length = string_list |> Enum.map(&String.length/1) |> Enum.max
    Enum.each string_list, fn str ->
      IO.puts String.rjust str, div(max_length+String.length(str),2)
    end
  end
end

StringList.center ["hello", "world", "Hahahahaha"]
21 Sep 2014, 17:11
Blacksad-cov_sq_pragsmall

Porco Wong (3 posts)

defmodule MyStr do

  def center(strList) do
    mlen = maxLen strList
    Enum.each strList, fn str ->
      l = String.length str
      str
        |> String.rjust(div((mlen - l), 2) + l)
        |> IO.puts
    end
  end

  defp maxLen(strList) do
    List.foldl strList, 0, fn (x, acc) ->
      xlen = String.length x
      cond do
        xlen > acc -> xlen
        true -> acc
      end
    end
  end

end
12 Nov 2014, 05:11
Generic-user-small

Elliot Finley (11 posts)

Here is my version. I try for code that is easy to reason about even if it is a little more verbose:

defmodule MyString do
  def center(list_of_strings) do
    max_length = list_of_strings
    |> Enum.max_by(&String.length/1)
    |> String.length

    list_of_strings
    |> Enum.each(&(print_centered(&1, max_length)))
  end

  defp print_centered(string, max_length) do
    padding = String.duplicate(" ", div(max_length-String.length(string),2))
    IO.write padding
    IO.puts string
  end
end
05 Dec 2014, 21:15
9863_pragsmall

Suraj Kurapati (15 posts)

I didn’t take the shortcut of padding only the left-hand side of each string because, although it works for the purpose of printing these strings to stdout, it would produce unwanted alignment if these strings were printed side-by-side on a single line.

defmodule MyString do
  def center(strings) do
    lengths = strings |> Enum.map(&String.length/1)
    max_len = lengths |> Enum.max
    for {str, len} <- Enum.zip(strings, lengths) do
      pad(str, max_len - len)
    end
  end

  defp pad(string, amount, using\\" ") do
    pad_left = String.duplicate(using, div(amount, 2))
    pad_right = String.duplicate(using, rem(amount, 2)) <> pad_left
    pad_left <> string <> pad_right
  end
end

For example:

iex(131)> MyString.center ~W[ cat zebra elephant ]
["  cat   ", " zebra  ", "elephant"]
11 Dec 2014, 01:43
5971263675_f01d667f5b_z_pragsmall

Stuart Blair (3 posts)

By comparison, mine is a little verbose. I suspect there’s actually a way to remove the duplication with the two justify functions by using a reference to the named functions rjust and ljust and just pass them as parameters to the function. Ah well, I’m sure I’ll get to that later in the book.

defmodule WordList do
  def center(words) do
    Enum.each(words, fn(word) -> formatWord(word, inTheContextOfThe(words)) end)
  end

  defp inTheContextOfThe(words) do
    fn(word) ->
      div(longestWordLength(words) - String.length(word), 2)
    end
  end

  defp longestWordLength(words) do
    Enum.max Enum.map(words, fn(word) -> String.length(word) end)
  end

  defp formatWord(word, paddingFor) do
    IO.puts leftJustifiedWord(rightJustifiedWord(word, paddingFor), paddingFor)
  end

  defp rightJustifiedWord(word, paddingFor) do
    String.rjust(word, String.length(word) + paddingFor.(word))
  end

  defp leftJustifiedWord(word, paddingFor) do
    String.ljust(word, String.length(word) + paddingFor.(word))
  end
end

Example:

WordList.center(["cat", "zebra", "José Ørstüd", "elephant"])
    cat
   zebra
José Ørstüd
 elephant
29 Dec 2014, 10:51
Generic-user-small

Pierre Sugar (55 posts)

defmodule MyString do
  def center(words) do
    max_length = (for x <- words, do: String.length(x))
                 |> Enum.max
    for x <- words, do: IO.puts center_word(x, max_length)
  end

  def center_word(word, length) do
    filler = String.duplicate(" ", div(length - String.length(word),2))
    filler <> word <> filler
  end
end
  You must be logged in to comment