emson/elixirgolf

Elixir Palindrome Detector

Opened this issue · 8 comments

emson commented

Write Elixir code that takes a string from the standard input and outputs a true / false value indicating whether that string is a palindrome or not.

Code will be run from iex, when your code is executed it will prompt for user input and on return will output a true or false value.

iex> --enter your code here--
level
true

Rules

  • Punctuation and whitespace is allowed in the input string of characters, however your program should ignore it, and should not affect whether the string is a palindrome or not.
  • Numbers are valid palindrome characters.
  • The case of the input string should not affect palindrome determination. Therefore “Taco cat” is purrfectly valid.
  • There is no limit on the length of the input string.
  • Only use the ASCII character set.

Finally...

  1. Please add your solutions as comments to this Github issue
  2. Remember to add your Twitter handle (I will link to it if you get a mention)

Many thanks, Ben
When the puzzle is over I'll write them up on http://elixirgolf.com and link back to your Twitter handle

72 characters

import String;s=downcase replace IO.gets(""),~r/[\s,\.]/,"";s==reverse s

It only strips ., as punctuation

I have essentially the same thing, but made it specifically only look at ASCII letters and digits, and assumed IO.puts:

import String;n=replace downcase(IO.gets""),~r/\W|_/,"";IO.puts n==reverse n

76 chars with the puts, 68 without.

EDIT: /[^a-z\d]/ -> /\W|_/

Shocking how similar! I have 110 chars, but it loops on the input.

import String;Enum.each IO.stream(:stdio,:line),fn i->s=downcase replace(i,~r/\W/,"");IO.puts s==reverse s end

I think my regex is in the lead so far ;-)

twitter handle: @gregvaughn

IMHO "A man, a plan, a canal -- Panama!" should be a valid palindrome. Same with "Madam, I'm Adam."

emson commented

@gvaughn I think the rules say you can have case and punctuation, it shouldn't affect the detector. Therefore "Madam, I'm Adam" etc should be fine.

@gvaughn I considered \W but wanted to be quite strict about the input and exclude underscores. But come to think of it, /[^\w_]/ would achieve that with fewer chars than what I did.

Oops, I mean /[\W_]/. Or to shave off one character, /\W|_/.

Just for fun, here is a completely ungolfed palindrome checker without regexps:

defmodule Run do
  def run do
    "abc123ABC!" |> palindrome? |> IO.inspect
    "Taco CAT!?" |> palindrome? |> IO.inspect
  end

  defp palindrome?(string) do
    list = string |> to_char_list |> normalize
    list == :lists.reverse(list)
  end

  defp normalize(char_list), do: char_list |> Enum.map(&normalize_char/1) |> Enum.reject(&(&1 == :ignore))

  defp normalize_char(char) when char in ?a..?z, do: char
  defp normalize_char(char) when char in ?0..?9, do: char
  defp normalize_char(char) when char in ?A..?Z, do: char + ?a - ?A
  defp normalize_char(_char), do: :ignore
end

Run.run

EDIT: No need to loop when we can just compare. 🤦