public
anonymous / gist:4695766
Created

Balance Parenthesis

  • Download Gist
gistfile1.txt
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117
/*
CC0 1.0 Universal (CC0 1.0)
Public Domain
https://creativecommons.org/publicdomain/zero/1.0/
*/
 
#include <string>
#include <vector>
#include <algorithm>
#include <iostream>
#include <fstream>
#include <stdexcept>
#include <boost/xpressive/xpressive.hpp>
 
 
namespace bxpr = boost::xpressive;
 
 
struct message
{
message(std::string const& s);
bool has_balanced_parentheses() const;
std::string value_;
};
 
 
message::message
(std::string const& s): value_ (s)
{
if ((s.length() < 1) || (s.length() > 100)) {
throw std::runtime_error ("Your message is too damn long!");
}
}
 
 
bool
message::has_balanced_parentheses
() const
{
static bxpr::sregex msg_chars = bxpr::alpha | ' ' | ':';
static bxpr::sregex smilies = bxpr::as_xpr(":)") | ":(";
static bxpr::sregex bal_msg;
static bool bal_msg_init = false;
 
if (value_.empty())
return true;
 
/* Small optimisation. We can't forward declare *and* statically initialise a local for our
* reference, so we check to see if we've init'd the regex using a flag instead.
*/
if (!bal_msg_init) {
bal_msg = *(msg_chars | smilies | ('(' >> bxpr::by_ref(bal_msg) >> ')'));
bal_msg_init = true;
}
 
return bxpr::regex_match (value_.begin(), value_.end(), bal_msg);
}
 
 
std::vector<message>
get_n_messages
(std::istream& is, unsigned long n_messages)
{
std::vector<message> messages;
 
if ((n_messages < 5) || (n_messages > 50))
throw std::range_error ("Number of messages out of range 5 <= m <= 50");
 
messages.reserve (n_messages);
auto msg_inserter = std::back_inserter (messages);
 
std::generate_n (msg_inserter, n_messages,
[&is]() -> std::string {
std::string s;
std::getline(is, s);
return s;
});
 
return messages;
}
 
 
int main
(int const argc, char* argv[])
{
std::ifstream src_file;
unsigned long n_messages = 0;
 
src_file.exceptions (std::ifstream::failbit | std::ifstream::badbit);
 
if (argc < 2)
return EXIT_FAILURE;
 
try {
std::string n_messages_str;
 
src_file.open (argv[1]);
std::getline (src_file, n_messages_str);
n_messages = std::stoul (n_messages_str);
 
std::vector<message> messages = get_n_messages (src_file, n_messages);
 
unsigned int i = 1;
std::for_each (messages.begin(), messages.end(),
[&i](message const& msg) -> void
{ std::cout << "Case #" << i++ << ": "
<< (msg.has_balanced_parentheses() ? "YES" : "NO") << std::endl; });
 
return EXIT_SUCCESS;
}
catch (std::exception& e) {
std::cerr << e.what() << std::endl;
return EXIT_FAILURE;
}
 
return EXIT_FAILURE;
}

Please sign in to comment on this gist.

Something went wrong with that request. Please try again.