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 🙂