{"id":29,"date":"2013-03-27T17:58:54","date_gmt":"2013-03-27T17:58:54","guid":{"rendered":"https:\/\/www.mattbusche.org\/blog\/?p=29"},"modified":"2014-05-04T21:46:18","modified_gmt":"2014-05-04T21:46:18","slug":"partition-intro","status":"publish","type":"post","link":"https:\/\/www.mattbusche.org\/blog\/article\/partition-intro\/","title":{"rendered":"Tracking the States of a Set of Objects by Partition<span class=\"h1sub\">An Introduction to the Partition Container<\/span>"},"content":{"rendered":"<p><img decoding=\"async\" src=\"\/images\/partition-intro\/partition.png\" class=\"graphic\"\nalt=\"Partition of the numbers 1 through 6 into 3 groups.\"\/><\/p>\n<p>In this post I share a useful programming technique I first saw used<br \/>\ntwenty-some years ago while reading through some C code.  The technique<br \/>\ncombined aspects of an array and a linked-list into a single data construct.<br \/>\nI&#8217;ve here abstracted the technique into a reusable container I call a<br \/>\npartition.  (If someone knows of some library in some language that offers a<br \/>\nsimilar container I&#8217;d appreciate a reference.)<\/p>\n<p>A partition is a high performance container that organizes<br \/>\na set of N sequential integer IDs (which together are called the domain) into<br \/>\nan arbitrary number of non-overlapping groups. (I.e., each ID of the<br \/>\ndomain can be in at most one group.)  The functionality of a partition<br \/>\nincludes these constant time operations:<\/p>\n<ol>\n<li>\n    Given an ID, determine the group to which the ID belongs (if any).\n<\/li>\n<li>\n    Given a group, find an ID in that group (if any).\n<\/li>\n<li>\n    Given an ID, move that ID to a particular group (simultaneously removing<br \/>\n    it from the group with which it was previously a member if any).\n<\/li>\n<\/ol>\n<p>None of the above operations use the heap and are each considerably faster<br \/>\nthan even a single push to standard implementations of a doubly linked list.<\/p>\n<p>A partition has not one, but two fundamental classes:  Domain and Group.<br \/>\nThe set of sequential IDs in a partition are defined by a Domain<br \/>\nobject; and a Group is a list of IDs from a Domain.  Domain and Group each<br \/>\nhave two templatization parameters M and V.  IDs can be bound to a<br \/>\nuser-defined <i>member<\/i> object of type M and Groups can be bound to a user<br \/>\ndefined <i>value<\/i> object of type V.  Together these associations enable<br \/>\nmappings from objects of type M (with known IDs) to objects of type V, and<br \/>\nconversely from objects of type V (with known Groups) to a list of objects<br \/>\nof type M.<\/p>\n<p>The partition is potentially useful any time objects need to be<br \/>\norganized into groups; and that happens all the time!  In this post, I show<br \/>\nhow you can use a partition to track the states of a set of like objects.<br \/>\nThis is just one possible usage of a partition and is intended only as a<br \/>\ntutorial example of how you can use this versatile storage class.<\/p>\n<p><!--more--><\/p>\n<h2>Contents<\/h2>\n<div class=\"outline\">\n<div class=\"i2\"><a href=\"#motivation\">Motivation<\/a><\/div>\n<div class=\"i2\"><a href=\"#example\">An Example<\/a><\/div>\n<div class=\"i3\"><a href=\"#problem\">The Problem<\/a><\/div>\n<div class=\"i3\"><a href=\"#solution\">A Solution<\/a><\/div>\n<div class=\"i2\"><a href=\"#conclusions\">Conclusions<\/a><\/div>\n<div class=\"i2\"><a href=\"#software\">Software Downloads and Documentation<\/a><\/div>\n<\/div>\n<div style=\"width:900px;\">\n<a name=\"motivation\"><\/a><\/p>\n<h2>Motivation<\/h2>\n<p>Suppose you have a set of N objects of some common type each having an<br \/>\nindependent state variable.  Perhaps you have hardware monitoring the<br \/>\nbit-error-rates on N communications ports and it is your job to categorize<br \/>\nthem into signal quality states of CLEAR, DEGRADED or FAILED.  Or perhaps<br \/>\nyou are tracking the BUSY-IDLE states of N processors in a massively<br \/>\nparallel computer processing environment.  Or you might be tracking<br \/>\nthe activity of N threads in a thread pool.  Obviously, such problems abound.<\/p>\n<p>A common use-case for such systems is to find one or more objects in a<br \/>\nparticular state.  For example, you may need to find one port in the<br \/>\nCLEAR state for allocation to some new network communications service; or<br \/>\nyou may want to find and list all processors in the BUSY state to<br \/>\nperform an audit.  If the number of objects is small, you could simply<br \/>\niterate over them all until you find the objects with the desired<br \/>\nstate; but if you have many objects, this approach can be highly inefficient.<br \/>\nTo solve such problems for large sets, you will naturally use containers to<br \/>\nhold objects that share a common state; but what type of container should<br \/>\nyou use?<\/p>\n<p>For C++ you might group your objects into standard STL maps.<br \/>\nSimilarly, for Java you could use HashMaps from the java.util package.<br \/>\nThese classes provide convenient solutions, but such heavy-weight<br \/>\ncontainers may be prohibitively slow for some applications.<\/p>\n<p>A lighter-weight alternative is to use linked-lists, but then a state<br \/>\nchange of, for example, a circuit from CLEAR to DEGRADED now requires you<br \/>\nfirst find the circuit in the CLEAR list so that it can be removed from that<br \/>\nlist before adding it to the DEGRADED list; this search can again be slow for<br \/>\nlarge sets.  In the C++ domain you can remedy this by giving each circuit<br \/>\nobject an iterator that tracks its own location in the linked-list of which it<br \/>\nis currently a member.  This is actually an effective (if slightly cumbersome)<br \/>\nsolution.  In the Java domain, such an approach is not possible if you restrict<br \/>\nyourself to standard library containers which suffer from the limitation that<br \/>\niterators point between two members and are in any case necessarily invalidated<br \/>\nwhenever the container they reference is updated.  (Oh, the horror!  I need a<br \/>\nProzac!)<\/p>\n<p>The partition container is specialized to handle exactly this type of problem<br \/>\nand is both easier to use and faster than any of the above alternatives.<\/p>\n<p><a name=\"example\"><\/a><\/p>\n<h2>An Example<\/h2>\n<p><a name=\"problem\"><\/a><\/p>\n<h3>The problem<\/h3>\n<p>A partition is often useful for solving resource management problems.  For our working example, we&#8217;ll track the state of a box of eight crayons being shared by my two girls Becky and Cate to draw pictures.  (This is not the most compelling resource management problem, but it is at least easy to understand and certainly doesn&#8217;t look like any proprietary software I&#8217;ve ever written.)  I want to show how you might model a resource that has multiple states, so we&#8217;ll give each crayon both a <code>User<\/code> state (which can be one of <code>BECKY<\/code>, <code>CATE<\/code>, or <code>BOX<\/code>), and a <code>Quality<\/code> state (which can be one of <code>SHARP<\/code> or <code>DULL<\/code>).  The programming problem is merely to efficiently keep track of this state information for all eight crayons and support a variety of use cases, like &#8220;find a sharp crayon in the box&#8221;, &#8220;get the state of the red crayon&#8221;, or &#8220;return all of Cate&#8217;s crayons to the box&#8221;.<\/p>\n<p><a name=\"solution\"><\/a><\/p>\n<h3>A solution<\/h3>\n<p><script type=\"text\/javascript\" src=\"\/js\/typewriter.js\"><\/script><br \/>\n<script type=\"text\/javascript\">\n\/\/<![CDATA[\n\nvar step = 0;\nvar numStep = 17;\nvar tw = new TypeWriter();\n\nfunction getSections(name) {\n    var a = document.getElementsByName(name);\n    return a;\n}\n\nfunction showStep(s) {\n\n    tw.finish();\n\n    if(s != step) {\n\n        if(step > 0) {\n            tw.unhighlight(getSections('step_' + step));\n            tw.unhighlight([document.getElementById('button_' + step)]);\n        }\n\n        for(var i = 1; i <= numStep; ++i) {\n            if(i < s)\n                tw.show(getSections('step_' + i));\n            else\n                tw.hide(getSections('step_' + i));\n        }\n\n        tw.highlight(getSections('step_' + s));\n        tw.highlight([document.getElementById('button_' + s)], '#fff');\n\n        step = s;\n        tw.write(getSections('step_' + s));\n    }\n}\n\n\/\/]]>\n<\/script><\/p>\n<div style=\"width: 520px; float:right;\">\n<pre>\r\n<span name=\"step_4\">#include \"partition.hpp\"<\/span><span name=\"step_1\">\r\n#include &lt;string&gt;\r\n#include &lt;iostream&gt;\r\n#include &lt;iomanip&gt;\r\n\r\nusing namespace std;<\/span><span name=\"step_4\">\r\nusing namespace partition;\r\n<\/span><span name=\"step_1\">\r\nenum Color { NONE_AVAILABLE = -1, RED, ORANGE, YELLOW, GREEN, BLUE,\r\n                                  VIOLET, BROWN, BLACK, NUM_CRAYONS };\r\nstring crayonName[] = { \"red\", \"orange\", \"yellow\", \"green\", \"blue\",\r\n                        \"violet\", \"brown\", \"black\" };<\/span><span name=\"step_2\">\r\n\r\nenum User { BOX, CATE, BECKY, NUM_USER };\r\nstring userName[] = { \"Box\", \"Cate\", \"Becky\" };\r\n\r\nenum Quality { SHARP, DULL, NUM_QUALITY };\r\nstring qualityName[] = { \"Sharp\", \"Dull\" };<\/span><span name=\"step_3\">\r\n\r\nclass CrayonState {\r\n    private:\r\n        User user;\r\n        Quality quality;\r\n    public:\r\n        CrayonState() {}\r\n        CrayonState(User user, Quality quality)\r\n            :   user(user), quality(quality) {\r\n        }\r\n        User getUser() const { return user; }\r\n        Quality getQuality() const { return quality; }\r\n        friend ostream& operator &lt;&lt; (ostream& os, const CrayonState& cs);\r\n};\r\n\r\ninline ostream& operator &lt;&lt; (ostream& os, const CrayonState& cs) {\r\n    return os &lt;&lt; \"(\" &lt;&lt; setw(5) &lt;&lt; userName[cs.user] &lt;&lt; \", \" &lt;&lt;\r\n                 setw(5) &lt;&lt; qualityName[cs.quality] &lt;&lt; \")\";\r\n}<\/span><span name=\"step_5\">\r\n\r\ntypedef Group&lt;string,CrayonState&gt; CrayonGroup;<\/span><span name=\"step_15\">\r\n\r\ninline ostream& operator &lt;&lt; (ostream& os, const CrayonGroup& g) {\r\n    os &lt;&lt; g.getValue() &lt;&lt; \":\";\r\n    for(CrayonGroup::ConstIterator i = g.front(); !i.isAfterBack(); ++i)\r\n        os &lt;&lt; \" \" &lt;&lt; (*i).member;\r\n    return os;\r\n}<\/span><span name=\"step_4\">\r\n\r\nclass CrayonManager {\r\n    private:\r\n        Domain&lt;string,CrayonState&gt; crayons;<\/span><span name=\"step_5\">\r\n        CrayonGroup state[NUM_USER][NUM_QUALITY];\r\n<\/span><span name=\"step_6\">\r\n    public:\r\n        CrayonManager() {\r\n            for(int i = 0; i &lt; NUM_CRAYONS; ++i)\r\n                crayons.addEntry(i, crayonName[i]);<\/span><span name=\"step_7\">\r\n            for(int u = 0; u &lt; NUM_USER; ++u) {\r\n                for(int q = 0; q &lt; NUM_QUALITY; ++q) {\r\n                    state[u][q].setDomain(crayons);\r\n                    state[u][q].setValue(CrayonState(User(u),Quality(q)));\r\n                }\r\n            }<\/span><span name=\"step_8\">\r\n            state[BOX][SHARP].addAll();<\/span><span name=\"step_6\">\r\n        }<\/span><span name=\"step_9\">\r\n\r\n        const CrayonState& getState(Color c) const {\r\n            return crayons.getValue(c);\r\n        }\r\n\r\n        User getUser(Color c) const {\r\n            return crayons.getValue(c).getUser();\r\n        }\r\n\r\n        Quality getQuality(Color c) const {\r\n            return crayons.getValue(c).getQuality();\r\n        }\r\n<\/span><span name=\"step_10\">\r\n        void setState(Color c, User u, Quality q) {\r\n            if(c != NONE_AVAILABLE)<\/span><span name=\"step_15\"> {\r\n                cout &lt;&lt; CrayonState(u,q) &lt;&lt; \" &lt;- \" &lt;&lt; getState(c) &lt;&lt;\r\n                    \": \" &lt;&lt; crayonName[c] &lt;&lt; endl;<\/span><span name=\"step_10\">\r\n                state[u][q].addBack(c);<\/span><span name=\"step_15\">\r\n            }<\/span><span name=\"step_10\">\r\n        }\r\n\r\n        void setUser(Color c, User u) {\r\n            if(c != NONE_AVAILABLE)\r\n                setState(c, u, getQuality(c));\r\n        }\r\n\r\n        void setQuality(Color c, Quality q) {\r\n            if(c != NONE_AVAILABLE)\r\n                setState(c, getUser(c), q);\r\n        }<\/span><span name=\"step_11\">\r\n\r\n        Color find(Quality q, User u = BOX) const {\r\n            if(state[u][q].size() > 0)\r\n                return (Color) state[u][q].peekFront().id;\r\n            else\r\n                return NONE_AVAILABLE;\r\n        }<\/span><span name=\"step_12\">\r\n\r\n        Color findPreferred(Quality q = SHARP, User u = BOX) const {\r\n            if(state[u][q].size() > 0)\r\n                return (Color) state[u][q].peekFront().id;\r\n            else\r\n                return find(q == SHARP ? DULL : SHARP, u);\r\n        }<\/span><span name=\"step_13\">\r\n\r\n        Color findPreferred(Color c, Quality q=SHARP, User u=BOX) const {\r\n            if(getUser(c) == u)\r\n                return c;\r\n            else\r\n                return findPreferred(q, u);\r\n        }<\/span><span name=\"step_14\">\r\n\r\n        void moveAll(User from, User to, Quality q) {<\/span><span name=\"step_15\">\r\n            cout &lt;&lt; CrayonState(to, q) &lt;&lt; \" &lt;- \" &lt;&lt; state[from][q] &lt;&lt; endl;<\/span><span name=\"step_14\">\r\n            state[to][q].addBack(state[from][q]);\r\n        }\r\n\r\n        void moveAll(User from, User to) {\r\n            for(int q = 0; q &lt; NUM_QUALITY; ++q)\r\n                moveAll(from, to, Quality(q));\r\n        }<\/span><span name=\"step_15\">\r\n\r\n        friend ostream& operator &lt;&lt; (ostream& os, const CrayonManager& cm);<\/span><span name=\"step_4\">\r\n};<\/span><span name=\"step_15\">\r\n\r\ninline ostream& operator &lt;&lt; (ostream& os, const CrayonManager& cm) {\r\n    for(int u = 0; u &lt; NUM_USER; ++u)\r\n        for(int q = 0; q &lt; NUM_QUALITY; ++q)\r\n            os &lt;&lt; cm.state[u][q] &lt;&lt; endl;\r\n    return os;\r\n}<\/span><span name=\"step_16\">\r\n\r\nint main(int argc, char** argv) {\r\n    CrayonManager manager;\r\n\r\n    Color c;\r\n\r\n    \/\/ Becky grabs three crayons, preferrably orange, blue, and a sharp.\r\n    \/\/ She dulls the first two.\r\n    \/\/\r\n    c = manager.findPreferred(ORANGE);\r\n    manager.setState(c, BECKY, DULL);\r\n\r\n    c = manager.findPreferred(BLUE);\r\n    manager.setState(c, BECKY, DULL);\r\n\r\n    c = manager.findPreferred();\r\n    manager.setUser(c, BECKY);\r\n\r\n    \/\/ Cate grabs two crayons, preferrably blue and green.\r\n    \/\/ She dulls the first one.\r\n    \/\/\r\n    c = manager.findPreferred(BLUE);\r\n    manager.setState(c, CATE, DULL);\r\n\r\n    c = manager.findPreferred(GREEN);\r\n    manager.setUser(c, CATE);\r\n\r\n    \/\/ Becky returns all her crayons to the box...\r\n    \/\/\r\n    manager.moveAll(BECKY, BOX);\r\n\r\n    \/\/ ...and then grabs a sharp one...\r\n    \/\/\r\n    c = manager.find(SHARP);\r\n    manager.setUser(c, BECKY);\r\n\r\n    \/\/ ...and makes it dull...\r\n    \/\/\r\n    manager.setQuality(c, DULL);\r\n\r\n    \/\/ Cate returns her dullest crayon to the box.\r\n    \/\/\r\n    c = manager.findPreferred(DULL, CATE);\r\n    manager.setUser(c, BOX);\r\n\r\n    \/\/ Cate notices the sharp ones are disappearing fast,\r\n    \/\/ so she grabs all the remaining sharp ones...\r\n    \/\/\r\n    manager.moveAll(BOX, CATE, SHARP);\r\n\r\n    \/\/ Becky gets mad and shows dad.\r\n    \/\/\r\n    cout &lt;&lt; \"\\\\nFinal States:\\\\n\" &lt;&lt; manager &lt;&lt; endl;\r\n\r\n    return 0;\r\n}<\/span>\r\n<\/pre>\n<\/div>\n<div style=\"width:360px; margin-right: auto;\">\n<p style=\"font-size:70%;color:#444;\">Note:  bypass animation by double-clicking the step buttons.<\/p>\n<p><a id=\"button_1\" class=\"awesome stepButton\" onclick=\"showStep(1);\">STEP 1<\/a><\/p>\n<p>Define an enum for the 8 crayon colors.  The enum values of these crayons (from 0 to 7) will<br \/>\nform the ids of the Domain.  Also define a string array that maps each crayon to its string<br \/>\nname.<\/p>\n<div style=\"clear:left;\"><\/div>\n<p><a id=\"button_2\" class=\"awesome stepButton\" onclick=\"showStep(2);\">STEP 2<\/a><\/p>\n<p>Likewise, define enums and string arrays for the User and Quality state variables.<\/p>\n<div style=\"clear:left;\"><\/div>\n<p><a id=\"button_3\" class=\"awesome stepButton\" onclick=\"showStep(3);\">STEP 3<\/a><\/p>\n<p>Define a simple class to bind the two state variables together into a single compound state.  One of these will be bound to each Group.  They won&#8217;t change value, so we won&#8217;t need any setters.<\/p>\n<div style=\"clear:left;\"><\/div>\n<p><a id=\"button_4\" class=\"awesome stepButton\" onclick=\"showStep(4);\">STEP 4<\/a><\/p>\n<p>Now create a class CrayonManager to track the crayon states.  Start by giving CrayonManager a Domain to hold the crayons.  We&#8217;ll use the partition to map from a crayon color to a CrayonState; accordingly, the Domain has templatization parameters string and CrayonState.  Alternatively, we could have defined two Domains (one to map crayons to user state, and another to map crayons to quality state), but it turns out to be more useful to have a single Domain that maps to a multi-valued state.<\/p>\n<div style=\"clear:left;\"><\/div>\n<p><a id=\"button_5\" class=\"awesome stepButton\" onclick=\"showStep(5);\">STEP 5<\/a><\/p>\n<p>Next we&#8217;ll need some Groups.  Each Group will hold all the crayons in a particular compound state, so we define a double-array of Groups indexed by user state and quality state.<\/p>\n<div style=\"clear:left;\"><\/div>\n<p><a id=\"button_6\" class=\"awesome stepButton\" onclick=\"showStep(6);\">STEP 6<\/a><\/p>\n<p>Initialize the domain by loading up all the crayon ids (zero through seven) and mapping each to its color string.<\/p>\n<div style=\"clear:left;\"><\/div>\n<p><a id=\"button_7\" class=\"awesome stepButton\" onclick=\"showStep(7);\">STEP 7<\/a><\/p>\n<p>Initialize each Group by binding it to the Domain object and setting its value to the CrayonState it represents.<\/p>\n<div style=\"clear:left;\"><\/div>\n<p><a id=\"button_8\" class=\"awesome stepButton\" onclick=\"showStep(8);\">STEP 8<\/a><\/p>\n<p>The last initialization step is to give all the crayons an initial state.  We&#8217;ll start with them all sharp and in the box.<\/p>\n<div style=\"clear:left;\"><\/div>\n<p><a id=\"button_9\" class=\"awesome stepButton\" onclick=\"showStep(9);\">STEP 9<\/a><\/p>\n<p>Add a method to get the current compound state of a crayon.  Remember that the state of a crayon is defined by its Group membership.  The Domain&#8217;s getValue() method finds the Group of the given crayon, and returns the user-assigned value of that Group (which is just the CrayonState object we set above).  I&#8217;ve also added a couple of convenience methods to return just the crayon&#8217;s User state and Quality state.<\/p>\n<div style=\"clear:left;\"><\/div>\n<p><a id=\"button_10\" class=\"awesome stepButton\" onclick=\"showStep(10);\">STEP 10<\/a><\/p>\n<p>The setState method sets a crayon&#8217;s full compound state by moving that crayon to the Group representing the given state.  Note that we only have to add the crayon to its new Group &mdash; the crayon is removed from its previous Group automatically.  I&#8217;ve also provided convenience methods for setting each component of a crayon&#8217;s state independently.  For simplicity, I&#8217;ll largely be ignoring exceptional conditions, but here I at least go to the effort to ignore attempts to set the state of the NONE_AVAILABLE crayon.<\/p>\n<div style=\"clear:left;\"><\/div>\n<p><a id=\"button_11\" class=\"awesome stepButton\" onclick=\"showStep(11);\">STEP 11<\/a><\/p>\n<p>Add a method to find a crayon with a particular quality and user state; if no crayon with that compound state exists, return NONE_AVAILABLE.<\/p>\n<div style=\"clear:left;\"><\/div>\n<p><a id=\"button_12\" class=\"awesome stepButton\" onclick=\"showStep(12);\">STEP 12<\/a><\/p>\n<p>findPreferred will try to find a crayon with the requested quality and user state.  If none exists, it will look for a crayon with the opposite quality but that same user state.  If the user has no crayons at all, it returns NONE_AVAILABLE.<\/p>\n<div style=\"clear:left;\"><\/div>\n<p><a id=\"button_13\" class=\"awesome stepButton\" onclick=\"showStep(13);\">STEP 13<\/a><\/p>\n<p>Add an overloaded version of findPreferred that first looks for a particular color in the given user state, but if that fails, it works just like the first version of findPreferred above.<\/p>\n<div style=\"clear:left;\"><\/div>\n<p><a id=\"button_14\" class=\"awesome stepButton\" onclick=\"showStep(14);\">STEP 14<\/a><\/p>\n<p>Add a method to transfer all crayons of a particular quality from one user to another, and another method to move all crayons (independent of quality) from one user to another.<\/p>\n<div style=\"clear:left;\"><\/div>\n<p><a id=\"button_15\" class=\"awesome stepButton\" onclick=\"showStep(15);\">STEP 15<\/a><\/p>\n<p>So we can see what&#8217;s going on, update the state setters to print the state changes that are taking effect, and define a streaming operator for the crayon manager itself that prints the current state of all crayons.<\/p>\n<div style=\"clear:left;\"><\/div>\n<p><a id=\"button_16\" class=\"awesome stepButton\" onclick=\"showStep(16);\">STEP 16<\/a><\/p>\n<p>Finally, add a main routine to exercise things.  To do it right, I&#8217;d have to define what to do when any of the find methods return NONE_AVAILABLE, but for this tutorial I just pass these failures onto the state setters which ignore them.<\/p>\n<div style=\"clear:left;\"><\/div>\n<p><a id=\"button_17\" class=\"awesome stepButton\" onclick=\"showStep(17);\">RUN IT<\/a><\/p>\n<p>Compile the program and run it.<\/p>\n<div style=\"clear:left;\"><\/div>\n<pre>\r\n&gt; <span name=\"step_17\">g++ -o crayons -I ..\/src crayons.cpp\r\n&gt; .\/crayons\r\n(Becky,  Dull) &lt;- (  Box, Sharp): orange\r\n(Becky,  Dull) &lt;- (  Box, Sharp): blue\r\n(Becky, Sharp) &lt;- (  Box, Sharp): red\r\n( Cate,  Dull) &lt;- (  Box, Sharp): yellow\r\n( Cate, Sharp) &lt;- (  Box, Sharp): green\r\n(  Box, Sharp) &lt;- (Becky, Sharp): red\r\n(  Box,  Dull) &lt;- (Becky,  Dull): orange blue\r\n(Becky, Sharp) &lt;- (  Box, Sharp): violet\r\n(Becky,  Dull) &lt;- (Becky, Sharp): violet\r\n(  Box,  Dull) &lt;- ( Cate,  Dull): yellow\r\n( Cate, Sharp) &lt;- (  Box, Sharp): brown black red\r\n\r\nFinal States:\r\n(  Box, Sharp):\r\n(  Box,  Dull): orange blue yellow\r\n( Cate, Sharp): green brown black red\r\n( Cate,  Dull):\r\n(Becky, Sharp):\r\n(Becky,  Dull): violet\r\n\r\n&gt;\r\n<\/span><\/pre>\n<div style=\"clear:both;\"><\/div>\n<\/div>\n<p><script type=\"text\/javascript\">showStep(1);<\/script><\/p>\n<p><a name=\"conclusions\"><\/a><\/p>\n<h2>Conclusions<\/h2>\n<p>A software partition is an exceptionally fast container useful for organizing a set of<br \/>\nlike objects into groups.  Applicable programming problems are common:  I personally have<br \/>\nused a partition-based approach to achieve elegant solutions to circuit state modeling<br \/>\nproblems, problems in graph theory, and others.  If you too are a software developer,<br \/>\nI suspect you&#8217;ll find uses for Partition as well if you only look for them.<\/p>\n<p><a name=\"software\"><\/a><\/p>\n<h2>Software Downloads and Documentation<\/h2>\n<p>This software is protected by the GNU general public license version 3.  This is free software (as defined by the License), but I&#8217;d very much appreciate it if you leave a comment to let me know if and\/or how you&#8217;ve found the software useful.<\/p>\n<p>I have not gone to the effort to put together a commercial license, but if someone is interested, I&#8217;ll make one available.<\/p>\n<p>Although I&#8217;ve used partition programming techniques at multiple companies during my software career, this design and implementation is new and should be considered experimental.  I&#8217;m not sure I&#8217;m satisfied with the public interface (particularly due to arguably cumbersome method names that resulted from the decision to not include a reverse iterator).  Future versions may not be backwards compatible.  This software has been extensively unit-tested, but only with gcc version 4.4.3 on Ubuntu 10.04.4.  Please, please contact me if you discover platform compatibility problems; bugs; design deficiencies; and\/or documentation errors (including misspellings or grammatical errors).  Thanks!<\/p>\n<table class=\"text\">\n<tr>\n<td><\/td>\n<td style=\"text-align:center;\"><strong>Downloads<\/strong><\/td>\n<td><strong>Documentation<\/strong><\/td>\n<\/tr>\n<tr>\n<td rowspan=\"2\"><strong>C++<\/strong><\/td>\n<td><a href=\"\/projects\/partition\/c++\/downloads\/partition_c++_0.1.1.tgz\">partition_c++_0.1.1.tgz<\/a><\/td>\n<td rowspan=\"2\" style=\"text-align:center;\"><a href=\"\/projects\/partition\/c++\/doc\/0.1.1\/\">0.1.1<\/a><\/td>\n<\/tr>\n<tr>\n<td><a href=\"\/projects\/partition\/c++\/downloads\/partition_c++_0.1.zip\">partition_c++_0.1.1.zip<\/a><\/td>\n<\/tr>\n<tr>\n<td rowspan=\"2\"><strong>Java<\/strong><\/td>\n<td><a href=\"\/projects\/partition\/java\/downloads\/partition_java_0.1.tgz\">partition_java_0.1.tgz<\/a><\/td>\n<td rowspan=\"2\" style=\"text-align:center;\"><a href=\"\/projects\/partition\/java\/doc\/0.1\/\">0.1<\/a><\/td>\n<\/tr>\n<tr>\n<td><a href=\"\/projects\/partition\/java\/downloads\/partition_java_0.1.zip\">partition_java_0.1.zip<\/a><\/td>\n<\/tr>\n<\/table>\n<\/div>\n","protected":false},"excerpt":{"rendered":"<p>In this post I share a useful programming technique I first saw used twenty-some years ago while reading through some C code. The technique combined aspects of an array and a linked-list into a single data construct. I&#8217;ve here abstracted &hellip; <a href=\"https:\/\/www.mattbusche.org\/blog\/article\/partition-intro\/\">Continue reading <span class=\"meta-nav\">&rarr;<\/span><\/a><\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[1],"tags":[],"_links":{"self":[{"href":"https:\/\/www.mattbusche.org\/blog\/wp-json\/wp\/v2\/posts\/29"}],"collection":[{"href":"https:\/\/www.mattbusche.org\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.mattbusche.org\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.mattbusche.org\/blog\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/www.mattbusche.org\/blog\/wp-json\/wp\/v2\/comments?post=29"}],"version-history":[{"count":1,"href":"https:\/\/www.mattbusche.org\/blog\/wp-json\/wp\/v2\/posts\/29\/revisions"}],"predecessor-version":[{"id":30,"href":"https:\/\/www.mattbusche.org\/blog\/wp-json\/wp\/v2\/posts\/29\/revisions\/30"}],"wp:attachment":[{"href":"https:\/\/www.mattbusche.org\/blog\/wp-json\/wp\/v2\/media?parent=29"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.mattbusche.org\/blog\/wp-json\/wp\/v2\/categories?post=29"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.mattbusche.org\/blog\/wp-json\/wp\/v2\/tags?post=29"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}