#include <iostream>
#include <vector>
#include <functional>
#include <cmath>
#include <iterator>
#include <string>
#include <stdexcept>

#include <boost/math/common_factor_rt.hpp>
#include <boost/lexical_cast.hpp>

class rational_t
{
  int n_, d_;
  double r_;

  public:
  rational_t(int numerator, int denominator)
    : n_(numerator), d_(denominator),
    r_(static_cast<double>(n_)/static_cast<double>(d_)) {}

  double real() const
  { return r_; }
  bool isnan() const
  { return std::isnan(r_); }

  int numerator() const
  { return n_; }
  int denominator() const
  { return d_; }
};
std::ostream&
operator<<(std::ostream& os, const rational_t& r)
{
  return (os << r.numerator() << "/" << r.denominator());
}

class compare_near_to
: public std::binary_function<bool, rational_t, rational_t>
{
  double g_;
  public:
  compare_near_to(double goal) : g_(goal) {}

  bool operator()(
      const rational_t& lhs,
      const rational_t& rhs
      )
  {
    return std::fabs(g_-lhs.real()) < std::fabs(g_-rhs.real());
  }
};

rational_t
find_rational(
    double  goal,
    int     denominator
    )
{
  double min_diff = goal;

  rational_t rat(0, denominator);
  for ( int n = 1; ; ++n ) {
    rational_t rat_(n, denominator);
    double diff = std::fabs(goal - rat_.real());

    if ( diff > min_diff ) break;

    min_diff = diff;
    rat = rat_;
  }
  if ( boost::math::gcd(rat.numerator(), rat.denominator()) != 1 )
    return rational_t(0,0); // causes real is NaN
  return rat;
}

int main(int c, char** v)
{
  if ( c != 2 ) {
    std::cout << v[0] << " <real number|rational number>\n";
    return 0;
  }
  double goal;
  try {
    std::string val(v[1]);
    std::string::size_type idx;
    if ( (idx = val.find("/")) != std::string::npos )
      goal = boost::lexical_cast<double>(val.substr(0,idx)) /
            boost::lexical_cast<double>(val.substr(idx+1,val.length()-(idx+1)));
    else
      goal = boost::lexical_cast<double>(v[1]);

    if ( goal <= 0.0 )
      throw std::runtime_error("input number must be positive");
  }
  catch (const std::exception& e) {
    std::cerr << e.what() << "\n";
    return -1;
  }

  std::vector<rational_t> rationals;
  for ( int i = 1; i < 10; ++i )
    rationals.push_back(find_rational(goal, i));

  rationals.erase(
      std::remove_if(
        rationals.begin(),
        rationals.end(),
        std::mem_fun_ref(&rational_t::isnan) ),
      rationals.end());
  std::sort(
      rationals.begin(),
      rationals.end(),
      compare_near_to(goal) );

  std::copy(
      rationals.begin(),
      rationals.end(),
      std::ostream_iterator<rational_t>(std::cout, ", ") );

  return 0;
}