A Binary Palindrom is a positive integer for which the binary representation is a palindrom. See the Weekly challange.

This is a solution in the Crystal programming language.

Directory layout

.
├── spec
│   └── palindrome_spec.cr
└── src
    ├── palindrome.cr
    └── use_palindrome.cr

Implementation

examples/crystal/binary_palindrome/src/palindrome.cr

def palindrome?(n : Int32)
  raise ArgumentError.new("Negative number not accepted") if n < 0
  binary = sprintf("%b", n)
  return binary == binary.reverse
end

In Crystal you can have ? as the last character of a function name. It is often used for functions that return a boolean value.

The original requets was for returning 1 and 0, but most likely it was defined that way because Perl does not have a special boolean type. In the Crystal solution I opted to return true or false respectively as that's the right way to do it in Crystal.

Functions in Crystal return the value of the last statement so the return keyword is optional, but I prefer to have it explicitely.

Extra: If the function is called with a negative value an ArgumentError exception is raised.

Usage

A simple Crystal program that will accept one or more numbers on the command line and will print Yes or No for each number:

$ crystal src/use_palindrome.cr 3 4 5
3 Yes
4 No
5 Yes

examples/crystal/binary_palindrome/src/use_palindrome.cr

require "./palindrome"

if ARGV.size == 0
  puts "Usage: #{PROGRAM_NAME} [NUMBERs]"
  exit 1
end

ARGV.each {|number|
  puts %[#{number} #{palindrome?(number.to_i) ? "Yes" : "No"}]
}

  • ARGV is an array of string containing the values from the command line
  • #{} is interpolation of variables and expressions inside a string
  • A string can be delimitered using double-quotes " or this construct: %[] where you can use any type of brackets.
  • ARGV.each iterates over the elements of ARGV and on each iteration the current value is assigned to the "number" variable.
  • to_i converts a string to an integer.
  • ?: is just the conditional operator (aka. the ternary operator)

Spec tests

I also included a test script.

examples/crystal/binary_palindrome/spec/palindrome_spec.cr

require "spec"
require "../src/palindrome"

describe "Palindrome" do
  it "verify" do
    palindrome?(5).should be_true
    palindrome?(4).should be_false
    palindrome?(15).should be_true
    palindrome?(14).should be_false
    palindrome?(0).should be_true
    expect_raises(ArgumentError, "Negative number not accepted") do
      palindrome?(-1)
    end
  end
end

In order to run the tests install Crystal, re-created the directory layout with the two files. (You can clone the repository and cd to examples/crystal/binary_palindrome/) Then run

crystal spec