Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    text
    copied!<p>Example C++ solution:</p> <pre><code>#include &lt;algorithm&gt; #include &lt;iterator&gt; #include &lt;iostream&gt; #include &lt;boost/iterator/counting_iterator.hpp&gt; #include &lt;boost/lexical_cast.hpp&gt; namespace { bool is_palindrome(unsigned int i) { const std::string&amp; s = boost::lexical_cast&lt;std::string&gt;(i); return std::equal(s.begin(), s.end(), s.rbegin()); } const unsigned int stop = 1000000; } int main() { std::remove_copy_if(boost::counting_iterator&lt;unsigned int&gt;(1), boost::counting_iterator&lt;unsigned int&gt;(stop), std::ostream_iterator&lt;unsigned int&gt;(std::cout, "\n"), std::not1(std::ptr_fun(is_palindrome))); } </code></pre> <p>(I used <code>std::remove_copy_if</code> to make up for the lack of <a href="https://stackoverflow.com/questions/1448817/why-there-is-no-stdcopy-if-algorithm"><code>std::copy_if</code></a> which is in C++0x)</p> <p>For completeness sake I implemented a version that generates the palindromes rather than testing candidates against a predicate:</p> <pre><code>#include &lt;boost/lexical_cast.hpp&gt; #include &lt;boost/iterator/counting_iterator.hpp&gt; #include &lt;boost/iterator/transform_iterator.hpp&gt; #include &lt;algorithm&gt; #include &lt;iterator&gt; #include &lt;iostream&gt; #include &lt;cassert&gt; namespace { template &lt;int ver&gt; unsigned int make_palindrome(unsigned int i) { std::string s = boost::lexical_cast&lt;std::string&gt;(i); assert(s.size()); s.reserve(s.size()*2); std::reverse_copy(s.begin(), s.end()-ver, std::back_inserter(s)); return boost::lexical_cast&lt;unsigned int&gt;(s); } } int main() { typedef boost::counting_iterator&lt;unsigned int&gt; counter; std::merge(boost::make_transform_iterator(counter(1), make_palindrome&lt;1&gt;), boost::make_transform_iterator(counter(999), make_palindrome&lt;1&gt;), boost::make_transform_iterator(counter(1), make_palindrome&lt;0&gt;), boost::make_transform_iterator(counter(999), make_palindrome&lt;0&gt;), std::ostream_iterator&lt;unsigned int&gt;(std::cout, "\n")); } </code></pre> <p>(I could have used boost.range I think instead of <code>std::merge</code> for this)</p> <p>The discussion point from this I guess then is "is this a better* way to write it?". The thing I like about writing problems like the palindrome in this style is you get the "if it compiles it's probably correct" heuristic on your side. Even if there is a bug it'll still get handled sensibly at run time (e.g. an exception from <code>lexical_cast</code>).</p> <p>It's a markedly different way of thinking from C programming (but strangely similar to Haskell in some ways). It brings benefits in the form of lots of extra safety, but the compiler error messages can be terrible and shifting the way you think about problems is hard.</p> <p>At the end of it all though what matters is "is it less work for less bugs?". I can't answer that without some metrics to help.</p> <p><code>*</code> For some definition of better.</p>
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload