{"id":26304,"date":"2020-02-10T11:36:45","date_gmt":"2020-02-10T16:36:45","guid":{"rendered":"https:\/\/www.dannyadam.com\/blog\/?p=26304"},"modified":"2023-07-20T10:57:57","modified_gmt":"2023-07-20T14:57:57","slug":"revdoor","status":"publish","type":"post","link":"https:\/\/www.dannyadam.com\/blog\/2020\/02\/revdoor\/","title":{"rendered":"revdoor"},"content":{"rendered":"\n<p><code>revdoor<\/code> is a single-file C++ library for visiting <em>revolving door<\/em> <a href=\"https:\/\/en.wikipedia.org\/wiki\/Combination\">combinations<\/a>.<\/p>\n\n\n\n<p>The <em>combinations without replacement<\/em> generator implements Algorithm R from TAOCP 7.2.1.3 [<a href=\"https:\/\/www.dannyadam.com\/blog\/2020\/02\/revdoor\/#references\">1<\/a>]. The <em>combinations with replacement<\/em> generator implements the same algorithm, modified to support replacement.<\/p>\n\n\n\n<p>The algorithms visit combinations by indicating at most two pairs of items to swap in and out on each iteration.<\/p>\n\n\n\n<p>The source code is available on GitHub:<br><a href=\"https:\/\/github.com\/dstein64\/revdoor\">https:\/\/github.com\/dstein64\/revdoor<\/a><a href=\"https:\/\/github.com\/dstein64\/revdoor\"><\/a><\/p>\n\n\n<p><!--more--><\/p>\n\n\n<h4 class=\"wp-block-heading\"><strong><span style=\"text-decoration: underline;\">Example<\/span><\/strong><\/h4>\n\n\n\n<p>The following example program\u2014that uses the <code>revdoor<\/code> single-file header library\u2014visits combinations by indicating the replacement for each iteration. For the purpose of illustration, the full set of combination items is tracked and printed on each iteration.<\/p>\n\n\n\n<figure class=\"wp-block-embed\"><div class=\"wp-block-embed__wrapper\">\n<style>.gist table { margin-bottom: 0; }<\/style><div style=\"tab-size: 8\" id=\"gist101123989\" class=\"gist\">\n    <div class=\"gist-file\" translate=\"no\" data-color-mode=\"light\" data-light-theme=\"light\">\n      <div class=\"gist-data\">\n        \n<div class=\"js-gist-file-update-container js-task-list-container\">\n      <div id=\"file-revdoor-cpp\" class=\"file my-2\">\n    \n    <div itemprop=\"text\"\n      class=\"Box-body p-0 blob-wrapper data type-c  \"\n      style=\"overflow: auto\" tabindex=\"0\" role=\"region\"\n      aria-label=\"revdoor.cpp content, created by dstein64 on 04:26PM on February 10, 2020.\"\n    >\n\n        \n<div class=\"js-check-hidden-unicode js-blob-code-container blob-code-content\">\n\n  <template class=\"js-file-alert-template\">\n  <div data-view-component=\"true\" class=\"flash flash-warn flash-full d-flex flex-items-center\">\n  <svg aria-hidden=\"true\" data-component=\"Octicon\" height=\"16\" viewBox=\"0 0 16 16\" version=\"1.1\" width=\"16\" data-view-component=\"true\" class=\"octicon octicon-alert\">\n    <path d=\"M6.457 1.047c.659-1.234 2.427-1.234 3.086 0l6.082 11.378A1.75 1.75 0 0 1 14.082 15H1.918a1.75 1.75 0 0 1-1.543-2.575Zm1.763.707a.25.25 0 0 0-.44 0L1.698 13.132a.25.25 0 0 0 .22.368h12.164a.25.25 0 0 0 .22-.368Zm.53 3.996v2.5a.75.75 0 0 1-1.5 0v-2.5a.75.75 0 0 1 1.5 0ZM9 11a1 1 0 1 1-2 0 1 1 0 0 1 2 0Z\"><\/path>\n<\/svg>\n    <span>\n      This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.\n      <a class=\"Link--inTextBlock\" href=\"https:\/\/github.co\/hiddenchars\" target=\"_blank\">Learn more about bidirectional Unicode characters<\/a>\n    <\/span>\n\n\n  <div data-view-component=\"true\" class=\"flash-action\">        <a href=\"{{ revealButtonHref }}\" data-view-component=\"true\" class=\"btn-sm btn\">    Show hidden characters\n<\/a>\n<\/div>\n<\/div><\/template>\n<template class=\"js-line-alert-template\">\n  <span aria-label=\"This line has hidden Unicode characters\" data-view-component=\"true\" class=\"line-alert tooltipped tooltipped-e\">\n    <svg aria-hidden=\"true\" data-component=\"Octicon\" height=\"16\" viewBox=\"0 0 16 16\" version=\"1.1\" width=\"16\" data-view-component=\"true\" class=\"octicon octicon-alert\">\n    <path d=\"M6.457 1.047c.659-1.234 2.427-1.234 3.086 0l6.082 11.378A1.75 1.75 0 0 1 14.082 15H1.918a1.75 1.75 0 0 1-1.543-2.575Zm1.763.707a.25.25 0 0 0-.44 0L1.698 13.132a.25.25 0 0 0 .22.368h12.164a.25.25 0 0 0 .22-.368Zm.53 3.996v2.5a.75.75 0 0 1-1.5 0v-2.5a.75.75 0 0 1 1.5 0ZM9 11a1 1 0 1 1-2 0 1 1 0 0 1 2 0Z\"><\/path>\n<\/svg>\n<\/span><\/template>\n\n  <table data-hpc class=\"highlight tab-size js-file-line-container\" data-tab-size=\"4\" data-paste-markdown-skip data-tagsearch-path=\"revdoor.cpp\">\n        <tr>\n          <td id=\"file-revdoor-cpp-L1\" class=\"blob-num js-line-number js-blob-rnum\" data-line-number=\"1\"><\/td>\n          <td id=\"file-revdoor-cpp-LC1\" class=\"blob-code blob-code-inner js-file-line\">#include &lt;cassert&gt;<\/td>\n        <\/tr>\n        <tr>\n          <td id=\"file-revdoor-cpp-L2\" class=\"blob-num js-line-number js-blob-rnum\" data-line-number=\"2\"><\/td>\n          <td id=\"file-revdoor-cpp-LC2\" class=\"blob-code blob-code-inner js-file-line\">#include &lt;cstdlib&gt;<\/td>\n        <\/tr>\n        <tr>\n          <td id=\"file-revdoor-cpp-L3\" class=\"blob-num js-line-number js-blob-rnum\" data-line-number=\"3\"><\/td>\n          <td id=\"file-revdoor-cpp-LC3\" class=\"blob-code blob-code-inner js-file-line\">#include &lt;iostream&gt;<\/td>\n        <\/tr>\n        <tr>\n          <td id=\"file-revdoor-cpp-L4\" class=\"blob-num js-line-number js-blob-rnum\" data-line-number=\"4\"><\/td>\n          <td id=\"file-revdoor-cpp-LC4\" class=\"blob-code blob-code-inner js-file-line\">#include &lt;set&gt;<\/td>\n        <\/tr>\n        <tr>\n          <td id=\"file-revdoor-cpp-L5\" class=\"blob-num js-line-number js-blob-rnum\" data-line-number=\"5\"><\/td>\n          <td id=\"file-revdoor-cpp-LC5\" class=\"blob-code blob-code-inner js-file-line\">#include &lt;string&gt;<\/td>\n        <\/tr>\n        <tr>\n          <td id=\"file-revdoor-cpp-L6\" class=\"blob-num js-line-number js-blob-rnum\" data-line-number=\"6\"><\/td>\n          <td id=\"file-revdoor-cpp-LC6\" class=\"blob-code blob-code-inner js-file-line\">#include &lt;vector&gt;<\/td>\n        <\/tr>\n        <tr>\n          <td id=\"file-revdoor-cpp-L7\" class=\"blob-num js-line-number js-blob-rnum\" data-line-number=\"7\"><\/td>\n          <td id=\"file-revdoor-cpp-LC7\" class=\"blob-code blob-code-inner js-file-line\">\n<\/td>\n        <\/tr>\n        <tr>\n          <td id=\"file-revdoor-cpp-L8\" class=\"blob-num js-line-number js-blob-rnum\" data-line-number=\"8\"><\/td>\n          <td id=\"file-revdoor-cpp-LC8\" class=\"blob-code blob-code-inner js-file-line\">#include &quot;revdoor.hpp&quot;<\/td>\n        <\/tr>\n        <tr>\n          <td id=\"file-revdoor-cpp-L9\" class=\"blob-num js-line-number js-blob-rnum\" data-line-number=\"9\"><\/td>\n          <td id=\"file-revdoor-cpp-LC9\" class=\"blob-code blob-code-inner js-file-line\">\n<\/td>\n        <\/tr>\n        <tr>\n          <td id=\"file-revdoor-cpp-L10\" class=\"blob-num js-line-number js-blob-rnum\" data-line-number=\"10\"><\/td>\n          <td id=\"file-revdoor-cpp-LC10\" class=\"blob-code blob-code-inner js-file-line\">using namespace std;<\/td>\n        <\/tr>\n        <tr>\n          <td id=\"file-revdoor-cpp-L11\" class=\"blob-num js-line-number js-blob-rnum\" data-line-number=\"11\"><\/td>\n          <td id=\"file-revdoor-cpp-LC11\" class=\"blob-code blob-code-inner js-file-line\">\n<\/td>\n        <\/tr>\n        <tr>\n          <td id=\"file-revdoor-cpp-L12\" class=\"blob-num js-line-number js-blob-rnum\" data-line-number=\"12\"><\/td>\n          <td id=\"file-revdoor-cpp-LC12\" class=\"blob-code blob-code-inner js-file-line\">void print_set(const set&lt;int&gt;&amp; s) {<\/td>\n        <\/tr>\n        <tr>\n          <td id=\"file-revdoor-cpp-L13\" class=\"blob-num js-line-number js-blob-rnum\" data-line-number=\"13\"><\/td>\n          <td id=\"file-revdoor-cpp-LC13\" class=\"blob-code blob-code-inner js-file-line\">  set&lt;int&gt;::iterator it = s.begin();<\/td>\n        <\/tr>\n        <tr>\n          <td id=\"file-revdoor-cpp-L14\" class=\"blob-num js-line-number js-blob-rnum\" data-line-number=\"14\"><\/td>\n          <td id=\"file-revdoor-cpp-LC14\" class=\"blob-code blob-code-inner js-file-line\">  while (it != s.end()) {<\/td>\n        <\/tr>\n        <tr>\n          <td id=\"file-revdoor-cpp-L15\" class=\"blob-num js-line-number js-blob-rnum\" data-line-number=\"15\"><\/td>\n          <td id=\"file-revdoor-cpp-LC15\" class=\"blob-code blob-code-inner js-file-line\">    if (it != s.begin()) cout &lt;&lt; &quot;,&quot;;<\/td>\n        <\/tr>\n        <tr>\n          <td id=\"file-revdoor-cpp-L16\" class=\"blob-num js-line-number js-blob-rnum\" data-line-number=\"16\"><\/td>\n          <td id=\"file-revdoor-cpp-LC16\" class=\"blob-code blob-code-inner js-file-line\">    cout &lt;&lt; *(it++);<\/td>\n        <\/tr>\n        <tr>\n          <td id=\"file-revdoor-cpp-L17\" class=\"blob-num js-line-number js-blob-rnum\" data-line-number=\"17\"><\/td>\n          <td id=\"file-revdoor-cpp-LC17\" class=\"blob-code blob-code-inner js-file-line\">  }<\/td>\n        <\/tr>\n        <tr>\n          <td id=\"file-revdoor-cpp-L18\" class=\"blob-num js-line-number js-blob-rnum\" data-line-number=\"18\"><\/td>\n          <td id=\"file-revdoor-cpp-LC18\" class=\"blob-code blob-code-inner js-file-line\">  cout &lt;&lt; endl;<\/td>\n        <\/tr>\n        <tr>\n          <td id=\"file-revdoor-cpp-L19\" class=\"blob-num js-line-number js-blob-rnum\" data-line-number=\"19\"><\/td>\n          <td id=\"file-revdoor-cpp-LC19\" class=\"blob-code blob-code-inner js-file-line\">}<\/td>\n        <\/tr>\n        <tr>\n          <td id=\"file-revdoor-cpp-L20\" class=\"blob-num js-line-number js-blob-rnum\" data-line-number=\"20\"><\/td>\n          <td id=\"file-revdoor-cpp-LC20\" class=\"blob-code blob-code-inner js-file-line\">\n<\/td>\n        <\/tr>\n        <tr>\n          <td id=\"file-revdoor-cpp-L21\" class=\"blob-num js-line-number js-blob-rnum\" data-line-number=\"21\"><\/td>\n          <td id=\"file-revdoor-cpp-LC21\" class=\"blob-code blob-code-inner js-file-line\">int main(int argc, char* argv[]) {<\/td>\n        <\/tr>\n        <tr>\n          <td id=\"file-revdoor-cpp-L22\" class=\"blob-num js-line-number js-blob-rnum\" data-line-number=\"22\"><\/td>\n          <td id=\"file-revdoor-cpp-LC22\" class=\"blob-code blob-code-inner js-file-line\">  assert(argc == 3);<\/td>\n        <\/tr>\n        <tr>\n          <td id=\"file-revdoor-cpp-L23\" class=\"blob-num js-line-number js-blob-rnum\" data-line-number=\"23\"><\/td>\n          <td id=\"file-revdoor-cpp-LC23\" class=\"blob-code blob-code-inner js-file-line\">  int n = stoi(argv[1]);<\/td>\n        <\/tr>\n        <tr>\n          <td id=\"file-revdoor-cpp-L24\" class=\"blob-num js-line-number js-blob-rnum\" data-line-number=\"24\"><\/td>\n          <td id=\"file-revdoor-cpp-LC24\" class=\"blob-code blob-code-inner js-file-line\">  int t = stoi(argv[2]);<\/td>\n        <\/tr>\n        <tr>\n          <td id=\"file-revdoor-cpp-L25\" class=\"blob-num js-line-number js-blob-rnum\" data-line-number=\"25\"><\/td>\n          <td id=\"file-revdoor-cpp-LC25\" class=\"blob-code blob-code-inner js-file-line\">  revdoor::combinations combs(n, t);<\/td>\n        <\/tr>\n        <tr>\n          <td id=\"file-revdoor-cpp-L26\" class=\"blob-num js-line-number js-blob-rnum\" data-line-number=\"26\"><\/td>\n          <td id=\"file-revdoor-cpp-LC26\" class=\"blob-code blob-code-inner js-file-line\">  vector&lt;int&gt; init_state = combs.state();<\/td>\n        <\/tr>\n        <tr>\n          <td id=\"file-revdoor-cpp-L27\" class=\"blob-num js-line-number js-blob-rnum\" data-line-number=\"27\"><\/td>\n          <td id=\"file-revdoor-cpp-LC27\" class=\"blob-code blob-code-inner js-file-line\">  set&lt;int&gt; state(init_state.begin(), init_state.end());<\/td>\n        <\/tr>\n        <tr>\n          <td id=\"file-revdoor-cpp-L28\" class=\"blob-num js-line-number js-blob-rnum\" data-line-number=\"28\"><\/td>\n          <td id=\"file-revdoor-cpp-LC28\" class=\"blob-code blob-code-inner js-file-line\">  cout &lt;&lt; &quot;init: &quot;;<\/td>\n        <\/tr>\n        <tr>\n          <td id=\"file-revdoor-cpp-L29\" class=\"blob-num js-line-number js-blob-rnum\" data-line-number=\"29\"><\/td>\n          <td id=\"file-revdoor-cpp-LC29\" class=\"blob-code blob-code-inner js-file-line\">  print_set(state);<\/td>\n        <\/tr>\n        <tr>\n          <td id=\"file-revdoor-cpp-L30\" class=\"blob-num js-line-number js-blob-rnum\" data-line-number=\"30\"><\/td>\n          <td id=\"file-revdoor-cpp-LC30\" class=\"blob-code blob-code-inner js-file-line\">  int in, out;<\/td>\n        <\/tr>\n        <tr>\n          <td id=\"file-revdoor-cpp-L31\" class=\"blob-num js-line-number js-blob-rnum\" data-line-number=\"31\"><\/td>\n          <td id=\"file-revdoor-cpp-LC31\" class=\"blob-code blob-code-inner js-file-line\">  while (combs.step(&amp;out, &amp;in)) {<\/td>\n        <\/tr>\n        <tr>\n          <td id=\"file-revdoor-cpp-L32\" class=\"blob-num js-line-number js-blob-rnum\" data-line-number=\"32\"><\/td>\n          <td id=\"file-revdoor-cpp-LC32\" class=\"blob-code blob-code-inner js-file-line\">    cout &lt;&lt; &quot;out: &quot; &lt;&lt; out &lt;&lt; &quot;, in: &quot; &lt;&lt; in &lt;&lt; &quot; state: &quot;;<\/td>\n        <\/tr>\n        <tr>\n          <td id=\"file-revdoor-cpp-L33\" class=\"blob-num js-line-number js-blob-rnum\" data-line-number=\"33\"><\/td>\n          <td id=\"file-revdoor-cpp-LC33\" class=\"blob-code blob-code-inner js-file-line\">    state.erase(out);<\/td>\n        <\/tr>\n        <tr>\n          <td id=\"file-revdoor-cpp-L34\" class=\"blob-num js-line-number js-blob-rnum\" data-line-number=\"34\"><\/td>\n          <td id=\"file-revdoor-cpp-LC34\" class=\"blob-code blob-code-inner js-file-line\">    state.insert(in);<\/td>\n        <\/tr>\n        <tr>\n          <td id=\"file-revdoor-cpp-L35\" class=\"blob-num js-line-number js-blob-rnum\" data-line-number=\"35\"><\/td>\n          <td id=\"file-revdoor-cpp-LC35\" class=\"blob-code blob-code-inner js-file-line\">    print_set(state);<\/td>\n        <\/tr>\n        <tr>\n          <td id=\"file-revdoor-cpp-L36\" class=\"blob-num js-line-number js-blob-rnum\" data-line-number=\"36\"><\/td>\n          <td id=\"file-revdoor-cpp-LC36\" class=\"blob-code blob-code-inner js-file-line\">  }<\/td>\n        <\/tr>\n        <tr>\n          <td id=\"file-revdoor-cpp-L37\" class=\"blob-num js-line-number js-blob-rnum\" data-line-number=\"37\"><\/td>\n          <td id=\"file-revdoor-cpp-LC37\" class=\"blob-code blob-code-inner js-file-line\">  return EXIT_SUCCESS;<\/td>\n        <\/tr>\n        <tr>\n          <td id=\"file-revdoor-cpp-L38\" class=\"blob-num js-line-number js-blob-rnum\" data-line-number=\"38\"><\/td>\n          <td id=\"file-revdoor-cpp-LC38\" class=\"blob-code blob-code-inner js-file-line\">}<\/td>\n        <\/tr>\n  <\/table>\n<\/div>\n\n\n    <\/div>\n\n  <\/div>\n\n<\/div>\n\n      <\/div>\n      <div class=\"gist-meta\">\n        <a href=\"https:\/\/gist.github.com\/dstein64\/c7b98d4846b4090aafb0274fe26f8d82\/raw\/3bbe6e68ee8ec300b8f08e9738b0de945c449f07\/revdoor.cpp\" style=\"float:right\" class=\"Link--inTextBlock\">view raw<\/a>\n        <a href=\"https:\/\/gist.github.com\/dstein64\/c7b98d4846b4090aafb0274fe26f8d82#file-revdoor-cpp\" class=\"Link--inTextBlock\">\n          revdoor.cpp\n        <\/a>\n        hosted with &#10084; by <a class=\"Link--inTextBlock\" href=\"https:\/\/github.com\">GitHub<\/a>\n      <\/div>\n    <\/div>\n<\/div>\n\n<\/div><\/figure>\n\n\n\n<p>An example usage is shown below.<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">$ .\/example 5 3\ninit: 0,1,2\nout: 1, in: 3 state: 0,2,3\nout: 0, in: 1 state: 1,2,3\nout: 2, in: 0 state: 0,1,3\nout: 1, in: 4 state: 0,3,4\nout: 0, in: 1 state: 1,3,4\nout: 1, in: 2 state: 2,3,4\nout: 3, in: 0 state: 0,2,4\nout: 0, in: 1 state: 1,2,4\nout: 2, in: 0 state: 0,1,4<\/pre>\n\n\n\n<h4 class=\"wp-block-heading\" id=\"references\"><strong><span style=\"text-decoration: underline;\">References<\/span><\/strong><\/h4>\n\n\n\n<p>[1] Donald Knuth, The Art of Computer Programming, Volume 4, Fascicle 3: Generating All Combinations and Partitions (Addison-Wesley Professional, 2005).<\/p>\n","protected":false},"excerpt":{"rendered":"<p>revdoor is a single-file C++ library for visiting revolving door combinations. The combinations without replacement generator implements Algorithm R from TAOCP 7.2.1.3 [1]. The combinations with replacement generator implements the same algorithm, modified to support replacement. The algorithms visit combinations by indicating at most two pairs of items to swap in and out on each [&hellip;]<\/p>\n","protected":false},"author":3,"featured_media":0,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"jetpack_post_was_ever_published":false,"_jetpack_newsletter_access":"","_jetpack_dont_email_post_to_subs":false,"_jetpack_newsletter_tier_id":0,"_jetpack_memberships_contains_paywalled_content":false,"_jetpack_memberships_contains_paid_content":false,"footnotes":"","jetpack_publicize_message":"","jetpack_publicize_feature_enabled":true,"jetpack_social_post_already_shared":true,"jetpack_social_options":{"image_generator_settings":{"template":"highway","default_image_id":0,"font":"","enabled":false},"version":2}},"categories":[1],"tags":[77,82,84,83,85],"class_list":["post-26304","post","type-post","status-publish","format-standard","hentry","category-uncategorized","tag-c","tag-combinations","tag-combinatorics","tag-revolving-door","tag-taocp"],"jetpack_publicize_connections":[],"jetpack_featured_media_url":"","jetpack_shortlink":"https:\/\/wp.me\/s1sCC6-revdoor","jetpack_sharing_enabled":true,"_links":{"self":[{"href":"https:\/\/www.dannyadam.com\/blog\/wp-json\/wp\/v2\/posts\/26304","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.dannyadam.com\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.dannyadam.com\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.dannyadam.com\/blog\/wp-json\/wp\/v2\/users\/3"}],"replies":[{"embeddable":true,"href":"https:\/\/www.dannyadam.com\/blog\/wp-json\/wp\/v2\/comments?post=26304"}],"version-history":[{"count":17,"href":"https:\/\/www.dannyadam.com\/blog\/wp-json\/wp\/v2\/posts\/26304\/revisions"}],"predecessor-version":[{"id":26932,"href":"https:\/\/www.dannyadam.com\/blog\/wp-json\/wp\/v2\/posts\/26304\/revisions\/26932"}],"wp:attachment":[{"href":"https:\/\/www.dannyadam.com\/blog\/wp-json\/wp\/v2\/media?parent=26304"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.dannyadam.com\/blog\/wp-json\/wp\/v2\/categories?post=26304"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.dannyadam.com\/blog\/wp-json\/wp\/v2\/tags?post=26304"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}