Chemiczny konkurs od DZone – rozwiązanie w Elixirze

O ile rozwiązanie w Javie możecie sobie podejrzeć w repozytorium, a jego omówienie będzie w przyszłym tygodniu, to dziś pokażę, jak można rozwiązać zadanie w Elixirze.

W praktyce całość sprowadza się do kilku (dokładnie 22) linii kodu:

Listing 1. Rozwiązanie w Elixirze

defmodule Chemicals do
  import Enum, only: [map: 2, uniq: 1, min: 1, member?: 2]
  import String, only: [downcase: 1, split: 3 ]
  
  def main(args) do
      {_, [name|t], _} = OptionParser.parse(args)
      symbols = name |> downcase |> split("", trim: true )|> generateValidSymbols
      IO.puts member?(symbols, t|> List.first |> downcase )
      IO.puts length(symbols)
      IO.puts min(symbols)
  end

  def generateValidSymbols([head|tail]) when length(tail) == 1 do
      tail|> map( &(head  <> &1))
  end

  def generateValidSymbols([head |tail]) do
      symb = tail |> map( &(head  <> &1))
      uniq(symb ++ generateValidSymbols(tail))
  end

end

Kluczem są funkcje generateValidSymbols, które zwracają listę wszystkich poprawnych symboli dla podanej nazwy. To samo napisane w Javie (z zachowaniem tej samej logiki) to zdecydowanie więcej kodu. Co tu się dzieje?

Funkcja przyjmuje jako parametr listę liter z nazwy pierwiastka i od razu dzieli ją na pierwszy element (potocznie głowę – head) i resztę (ogon – tail). Jeżeli ogon ma długość 1, co weryfikuje strażnik, to elementy są łączone. Inaczej dla każdego elementu ogona tworzony jest symbol, a lista tak wygenerowanych symboli jest łączona z listą symboli wygenerowanych z ogona. Z tak powstałej listy usuwane są duplikaty. Następnie za pomocą kilku prostych testów sprawdzamy, czy symbol, podany jako drugi parametr, znajduje się na liście, jak duża jest lista, który symbol jest pierwszy w kolejności alfabetycznej.

A najwięcej czasu zajęło mi sprawdzenie jak to cholerstwo uruchomić, bo nie jest to takie oczywiste 🙂

Napisz odpowiedź

Twój adres email nie zostanie opublikowany. Pola, których wypełnienie jest wymagane, są oznaczone symbolem *

To create code blocks or other preformatted text, indent by four spaces:

    This will be displayed in a monospaced font. The first four 
    spaces will be stripped off, but all other whitespace
    will be preserved.
    
    Markdown is turned off in code blocks:
     [This is not a link](http://example.com)

To create not a block, but an inline code span, use backticks:

Here is some inline `code`.

For more help see http://daringfireball.net/projects/markdown/syntax