{"action":"opened","issue":{"url":"https://api.github.com/repos/jeanluct/braidlab/issues/113","labels_url":"https://api.github.com/repos/jeanluct/braidlab/issues/113/labels{/name}","comments_url":"https://api.github.com/repos/jeanluct/braidlab/issues/113/comments","events_url":"https://api.github.com/repos/jeanluct/braidlab/issues/113/events","html_url":"https://github.com/jeanluct/braidlab/issues/113","id":53338679,"number":113,"title":"Possible simplification of braid.compact","user":{"login":"jeanluct","id":3310622,"avatar_url":"https://avatars.githubusercontent.com/u/3310622?v=3","gravatar_id":"","url":"https://api.github.com/users/jeanluct","html_url":"https://github.com/jeanluct","followers_url":"https://api.github.com/users/jeanluct/followers","following_url":"https://api.github.com/users/jeanluct/following{/other_user}","gists_url":"https://api.github.com/users/jeanluct/gists{/gist_id}","starred_url":"https://api.github.com/users/jeanluct/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/jeanluct/subscriptions","organizations_url":"https://api.github.com/users/jeanluct/orgs","repos_url":"https://api.github.com/users/jeanluct/repos","events_url":"https://api.github.com/users/jeanluct/events{/privacy}","received_events_url":"https://api.github.com/users/jeanluct/received_events","type":"User","site_admin":false},"labels":[{"url":"https://api.github.com/repos/jeanluct/braidlab/labels/enhancement","name":"enhancement","color":"84b6eb"}],"state":"open","locked":false,"assignee":null,"milestone":null,"comments":0,"created_at":"2015-01-04T15:07:44Z","updated_at":"2015-01-04T15:07:44Z","closed_at":null,"body":"In writing a free word class for `ttauto`, I wanted to use STL-style generic algorithms.  To reduce a free word, one needs to go through and cancel adjacent elements.  I ended up writing [this](https://github.com/jeanluct/ttauto/blob/ff44146/include/freeword.hpp) algorithm, `adjacent_remove_if`:\r\n```c++\r\n// Remove from container adjacent elements satisfying a comparison function.\r\n// Similar to unique (http://www.cplusplus.com/reference/algorithm/unique/)\r\ntemplate <class ForwardIterator, class BinaryPredicate>\r\nForwardIterator\r\nadjacent_remove_if(ForwardIterator first, ForwardIterator last, BinaryPredicate pred)\r\n{\r\n  if (first == last) return last;\r\n\r\n  ForwardIterator result = first;\r\n  while (++first != last)\r\n    {\r\n      if (!pred(*result,*first))\r\n\t{\r\n\t  // The elements are not equal, so copy to result and move on.\r\n\t  *(++result) = std::move(*first);\r\n\t}\r\n      else\r\n\t{\r\n\t  // The elements are equal.\r\n\t  // Point the the next element (after the elements to be cancelled).\r\n\t  // If we're at the end of the container, we're done.\r\n\t  if (++first == last) return result;\r\n\t  // Copy the next element after the cancelled ones.\r\n\t  *result = std::move(*first);\r\n\t}\r\n    }\r\n  return ++result;\r\n}\r\n```\r\nI can then reduce a free word by repeatedly running this algo until nothing changes:\r\n```c++\r\n// Reduce a word by canceling adjacent inverses.\r\ntemplate<class T>\r\ninline free_word<T>& free_word<T>::reduce()\r\n{\r\n  // Elements are \"equal\" if they are inverses of each other.\r\n  struct IsInv {\r\n    bool operator() (const T& a, const T& b) { return (a == -b); }\r\n  } isinv;\r\n\r\n  while (true)\r\n    {\r\n      auto i = adjacent_remove_if(this->begin(),this->end(),isinv);\r\n      if (i == this->end()) break;\r\n      this->erase(i,this->end());\r\n    }\r\n\r\n  return *this;\r\n}\r\n```\r\nThis kind of algo could be used to greatly simplify `braid.compact`.  But it's much less obvious to see how to implement the `121==212` relation.  Is it worth implementing?"}}