<?xml version='1.0' encoding='UTF-8'?><?xml-stylesheet href="http://www.blogger.com/styles/atom.css" type="text/css"?><feed xmlns='http://www.w3.org/2005/Atom' xmlns:openSearch='http://a9.com/-/spec/opensearchrss/1.0/' xmlns:georss='http://www.georss.org/georss' xmlns:gd='http://schemas.google.com/g/2005' xmlns:thr='http://purl.org/syndication/thread/1.0'><id>tag:blogger.com,1999:blog-24682001</id><updated>2011-12-14T18:40:36.627-08:00</updated><title type='text'>Blog Summaries</title><subtitle type='html'>Simple is elegant.</subtitle><link rel='http://schemas.google.com/g/2005#feed' type='application/atom+xml' href='http://blogsummaries.blogspot.com/feeds/posts/default'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/24682001/posts/default?max-results=100'/><link rel='alternate' type='text/html' href='http://blogsummaries.blogspot.com/'/><link rel='hub' href='http://pubsubhubbub.appspot.com/'/><author><name>Blog Summaries</name><uri>http://www.blogger.com/profile/01198627526772585776</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><generator version='7.00' uri='http://www.blogger.com'>Blogger</generator><openSearch:totalResults>1</openSearch:totalResults><openSearch:startIndex>1</openSearch:startIndex><openSearch:itemsPerPage>100</openSearch:itemsPerPage><entry><id>tag:blogger.com,1999:blog-24682001.post-114323115789305242</id><published>2006-03-24T12:00:00.000-08:00</published><updated>2006-03-24T13:56:58.286-08:00</updated><title type='text'>Solution to the NexTag card shuffle problem</title><content type='html'>I found the &lt;a href="http://www.nextag.com/serv/main/about/jobs/java.jsp"&gt;NexTag card shuffle problem&lt;/a&gt; from &lt;a href="http://www.reddit.com"&gt;Reddit&lt;/a&gt; interesting enough to solve as it reminded me of the problems from &lt;a href="http://www.ioinformatics.org/"&gt;IOI&lt;/a&gt; and &lt;a href="http://icpc.baylor.edu/icpc/"&gt;ACM&lt;/a&gt; competitions from long ago.&lt;br /&gt;&lt;br /&gt;The problem is the following:&lt;br /&gt;&lt;blockquote&gt;&lt;br /&gt;Given a deck of nCards unique cards, cut the deck iCut cards from top and perform a perfect shuffle. A perfect shuffle begins by putting down the bottom card from the top portion of the deck followed by the bottom card from the bottom portion of the deck followed by the next card from the top portion, etc., alternating cards until one portion is used up. The remaining cards go on top. The problem is to find the number of perfect shuffles required to return the deck to its original order. Your function should be declared as "static long shuffles(int nCards,int iCut);".&lt;br /&gt;&lt;/blockquote&gt;&lt;br /&gt;&lt;br /&gt;Spoilers follow.&lt;br /&gt;&lt;br /&gt;Each card has a position and each shuffle takes each card and transfers it to a different position. The number of transfers during which one particular card ends up in its initial position is the cycle length for that card. The number of shufles for reaching the starting position is the &lt;a href="http://en.wikipedia.org/wiki/Least_common_multiple"&gt;least common multiple&lt;/a&gt; of all the cycle lengths.&lt;br /&gt;&lt;br /&gt;Code follows (runs in less than 10 milliseconds):&lt;br /&gt;&lt;pre id=cj_831604 class=ColorJava_block&gt;&lt;pre class=ColorJava_innerPre&gt;&lt;span class=j_eclipse_keyword&gt;package&lt;/span&gt; &lt;span class=j_eclipse_pkgname&gt;com&lt;/span&gt;.&lt;span class=j_eclipse_pkgname&gt;blogsummaries&lt;/span&gt;;&lt;br /&gt;&lt;br /&gt;&lt;span class=j_eclipse_comment&gt;/**&lt;br /&gt; * &lt;span class=j_eclipse_jdtagat&gt;@&lt;/span&gt;&lt;span class=j_eclipse_jdtag&gt;author&lt;/span&gt; http://blogsummaries.blogspot.com/&lt;br /&gt; *&lt;/span&gt;/&lt;br /&gt;&lt;span class=j_eclipse_keyword&gt;public&lt;/span&gt; &lt;span class=j_eclipse_keyword&gt;class&lt;/span&gt; &lt;span class=j_eclipse_classname&gt;BlogSummariesShuffle&lt;/span&gt; {&lt;br /&gt;  &lt;span class=j_eclipse_keyword&gt;public&lt;/span&gt; &lt;span class=j_eclipse_keyword&gt;static&lt;/span&gt; &lt;span class=j_eclipse_typekeyw&gt;void&lt;/span&gt; &lt;span class=j_eclipse_methname&gt;main&lt;/span&gt;(&lt;span class=j_eclipse_classname&gt;String&lt;/span&gt;[] &lt;span class=j_eclipse_varname&gt;args&lt;/span&gt;) {&lt;br /&gt;    &lt;span class=j_eclipse_keyword&gt;final&lt;/span&gt; &lt;span class=j_eclipse_typekeyw&gt;int&lt;/span&gt; &lt;span class=j_eclipse_varname&gt;cardCount&lt;/span&gt; = 1002;&lt;br /&gt;    &lt;span class=j_eclipse_keyword&gt;final&lt;/span&gt; &lt;span class=j_eclipse_typekeyw&gt;int&lt;/span&gt; &lt;span class=j_eclipse_varname&gt;cutSize&lt;/span&gt; = 101;&lt;br /&gt;    &lt;br /&gt;    &lt;span class=j_eclipse_keyword&gt;final&lt;/span&gt; &lt;span class=j_eclipse_typekeyw&gt;long&lt;/span&gt; &lt;span class=j_eclipse_varname&gt;startTime&lt;/span&gt; = &lt;span class=j_eclipse_classname&gt;System&lt;/span&gt;.currentTimeMillis();&lt;br /&gt;    &lt;span class=j_eclipse_typekeyw&gt;long&lt;/span&gt; &lt;span class=j_eclipse_varname&gt;result&lt;/span&gt; = shuffles(cardCount, cutSize);&lt;br /&gt;    &lt;span class=j_eclipse_keyword&gt;final&lt;/span&gt; &lt;span class=j_eclipse_typekeyw&gt;long&lt;/span&gt; &lt;span class=j_eclipse_varname&gt;endTime&lt;/span&gt; = &lt;span class=j_eclipse_classname&gt;System&lt;/span&gt;.currentTimeMillis();&lt;br /&gt;    &lt;span class=j_eclipse_keyword&gt;final&lt;/span&gt; &lt;span class=j_eclipse_typekeyw&gt;long&lt;/span&gt; &lt;span class=j_eclipse_varname&gt;totalTime&lt;/span&gt; = endTime - startTime;&lt;br /&gt;    &lt;br /&gt;    &lt;span class=j_eclipse_classname&gt;System&lt;/span&gt;.out.println(&lt;span class=j_eclipse_string&gt;"shuffles("&lt;/span&gt; + cardCount + &lt;br /&gt;        &lt;span class=j_eclipse_string&gt;", "&lt;/span&gt; + cutSize + &lt;span class=j_eclipse_string&gt;") = "&lt;/span&gt; + result + &lt;br /&gt;        &lt;span class=j_eclipse_string&gt;" ("&lt;/span&gt; + totalTime + &lt;span class=j_eclipse_string&gt;" ms)"&lt;/span&gt;);&lt;br /&gt;  }&lt;br /&gt;  &lt;br /&gt;  &lt;span class=j_eclipse_keyword&gt;private&lt;/span&gt; &lt;span class=j_eclipse_keyword&gt;static&lt;/span&gt; &lt;span class=j_eclipse_typekeyw&gt;long&lt;/span&gt; &lt;span class=j_eclipse_methname&gt;shuffles&lt;/span&gt;(&lt;span class=j_eclipse_typekeyw&gt;int&lt;/span&gt; &lt;span class=j_eclipse_varname&gt;nCards&lt;/span&gt;, &lt;span class=j_eclipse_typekeyw&gt;int&lt;/span&gt; &lt;span class=j_eclipse_varname&gt;iCut&lt;/span&gt;) {&lt;br /&gt;    &lt;span class=j_eclipse_comment&gt;// in which position will the card end up &lt;/span&gt;&lt;br /&gt;    &lt;span class=j_eclipse_comment&gt;// after one shuffle&lt;/span&gt;&lt;br /&gt;    &lt;span class=j_eclipse_keyword&gt;final&lt;/span&gt; &lt;span class=j_eclipse_typekeyw&gt;int&lt;/span&gt;[] &lt;span class=j_eclipse_varname&gt;pointers&lt;/span&gt; = &lt;span class=j_eclipse_keyword&gt;new&lt;/span&gt; &lt;span class=j_eclipse_typekeyw&gt;int&lt;/span&gt;[&lt;span class=j_eclipse_varname&gt;nCards&lt;/span&gt;]; &lt;br /&gt;    &lt;br /&gt;    if (2*iCut &amp;lt; nCards) { &lt;span class=j_eclipse_comment&gt;// cut is less than at half &lt;/span&gt;&lt;br /&gt;      &lt;span class=j_eclipse_keyword&gt;final&lt;/span&gt; &lt;span class=j_eclipse_typekeyw&gt;int&lt;/span&gt; &lt;span class=j_eclipse_varname&gt;midPortion&lt;/span&gt; = nCards - 2*iCut;&lt;br /&gt;      &lt;br /&gt;      &lt;span class=j_eclipse_keyword&gt;for&lt;/span&gt; (&lt;span class=j_eclipse_typekeyw&gt;int&lt;/span&gt; &lt;span class=j_eclipse_varname&gt;i&lt;/span&gt; = 0; i &amp;lt; pointers.length; i++) {&lt;br /&gt;        if (i &amp;lt; iCut) &lt;span class=j_eclipse_comment&gt;// cut&lt;/span&gt;&lt;br /&gt;          pointers[i] = midPortion + i*2 + 1;&lt;br /&gt;        else if (i &amp;lt; nCards - iCut) &lt;span class=j_eclipse_comment&gt;// midportion&lt;/span&gt;&lt;br /&gt;          pointers[i] = i - iCut;&lt;br /&gt;        else &lt;span class=j_eclipse_comment&gt;// bottom&lt;/span&gt;&lt;br /&gt;          pointers[i] = midPortion + &lt;br /&gt;            (i - iCut - midPortion)*2;&lt;br /&gt;      }&lt;br /&gt;    } else { &lt;span class=j_eclipse_comment&gt;// cut is at more than a halfpoint&lt;/span&gt;&lt;br /&gt;      &lt;span class=j_eclipse_keyword&gt;final&lt;/span&gt; &lt;span class=j_eclipse_typekeyw&gt;int&lt;/span&gt; &lt;span class=j_eclipse_varname&gt;topPortion&lt;/span&gt; = nCards - 2*(nCards - iCut);&lt;br /&gt;      &lt;br /&gt;      &lt;span class=j_eclipse_keyword&gt;for&lt;/span&gt; (&lt;span class=j_eclipse_typekeyw&gt;int&lt;/span&gt; &lt;span class=j_eclipse_varname&gt;i&lt;/span&gt; = 0; i &amp;lt; pointers.length; i++) {&lt;br /&gt;        if (i &amp;lt; topPortion) &lt;span class=j_eclipse_comment&gt;// top&lt;/span&gt;&lt;br /&gt;          pointers[i] = i;&lt;br /&gt;        else if (i &amp;lt; iCut) &lt;span class=j_eclipse_comment&gt;// midportion&lt;/span&gt;&lt;br /&gt;          pointers[i] = topPortion + &lt;br /&gt;            2*(i - topPortion) + 1;&lt;br /&gt;        else &lt;span class=j_eclipse_comment&gt;// bottom&lt;/span&gt;&lt;br /&gt;          pointers[i] = topPortion + 2*(i - iCut);&lt;br /&gt;      }   &lt;br /&gt;    }&lt;br /&gt;    &lt;br /&gt;    &lt;span class=j_eclipse_comment&gt;// how many shuffles will it take for the card &lt;/span&gt;&lt;br /&gt;    &lt;span class=j_eclipse_comment&gt;// to end up in the starting position&lt;/span&gt;&lt;br /&gt;    &lt;span class=j_eclipse_keyword&gt;final&lt;/span&gt; &lt;span class=j_eclipse_typekeyw&gt;long&lt;/span&gt;[] &lt;span class=j_eclipse_varname&gt;cycleLength&lt;/span&gt; = &lt;span class=j_eclipse_keyword&gt;new&lt;/span&gt; &lt;span class=j_eclipse_typekeyw&gt;long&lt;/span&gt;[&lt;span class=j_eclipse_varname&gt;pointers&lt;/span&gt;.length];  &lt;br /&gt;    &lt;span class=j_eclipse_keyword&gt;for&lt;/span&gt; (&lt;span class=j_eclipse_typekeyw&gt;int&lt;/span&gt; &lt;span class=j_eclipse_varname&gt;i&lt;/span&gt; = 0; i &amp;lt; pointers.length; i++) {&lt;br /&gt;      &lt;span class=j_eclipse_typekeyw&gt;int&lt;/span&gt; &lt;span class=j_eclipse_varname&gt;current&lt;/span&gt; = pointers[i];&lt;br /&gt;      cycleLength[i] = 1;&lt;br /&gt;      &lt;span class=j_eclipse_keyword&gt;while&lt;/span&gt; (current != i) {&lt;br /&gt;        current = pointers[current];&lt;br /&gt;        cycleLength[i]++;&lt;br /&gt;      }&lt;br /&gt;    }&lt;br /&gt;    &lt;br /&gt;    &lt;span class=j_eclipse_comment&gt;// the LCM of all the cycle lengths is the number &lt;/span&gt;&lt;br /&gt;    &lt;span class=j_eclipse_comment&gt;// of shuffles needed for ALL the cards to end up &lt;/span&gt;&lt;br /&gt;    &lt;span class=j_eclipse_comment&gt;// in their initial places&lt;/span&gt;&lt;br /&gt;    &lt;span class=j_eclipse_typekeyw&gt;long&lt;/span&gt; &lt;span class=j_eclipse_varname&gt;lcm&lt;/span&gt; = cycleLength[0];  &lt;br /&gt;    &lt;span class=j_eclipse_keyword&gt;for&lt;/span&gt; (&lt;span class=j_eclipse_typekeyw&gt;int&lt;/span&gt; &lt;span class=j_eclipse_varname&gt;i&lt;/span&gt; = 1; i &amp;lt; cycleLength.length; i++) {&lt;br /&gt;      lcm = lcm(lcm, cycleLength[i]);&lt;br /&gt;    }&lt;br /&gt;    &lt;br /&gt;    &lt;span class=j_eclipse_keyword&gt;return&lt;/span&gt; lcm;&lt;br /&gt;  }&lt;br /&gt;  &lt;br /&gt;  &lt;span class=j_eclipse_keyword&gt;private&lt;/span&gt; &lt;span class=j_eclipse_keyword&gt;static&lt;/span&gt; &lt;span class=j_eclipse_typekeyw&gt;long&lt;/span&gt; &lt;span class=j_eclipse_methname&gt;lcm&lt;/span&gt;(&lt;span class=j_eclipse_typekeyw&gt;long&lt;/span&gt; &lt;span class=j_eclipse_varname&gt;a&lt;/span&gt;, &lt;span class=j_eclipse_typekeyw&gt;long&lt;/span&gt; &lt;span class=j_eclipse_varname&gt;b&lt;/span&gt;) {&lt;br /&gt;    &lt;span class=j_eclipse_keyword&gt;return&lt;/span&gt; (a*b) / gcd(a, b);&lt;br /&gt;  }&lt;br /&gt;  &lt;br /&gt;  &lt;span class=j_eclipse_keyword&gt;private&lt;/span&gt; &lt;span class=j_eclipse_keyword&gt;static&lt;/span&gt; &lt;span class=j_eclipse_typekeyw&gt;long&lt;/span&gt; &lt;span class=j_eclipse_methname&gt;gcd&lt;/span&gt;(&lt;span class=j_eclipse_typekeyw&gt;long&lt;/span&gt; &lt;span class=j_eclipse_varname&gt;a&lt;/span&gt;, &lt;span class=j_eclipse_typekeyw&gt;long&lt;/span&gt; &lt;span class=j_eclipse_varname&gt;b&lt;/span&gt;) {&lt;br /&gt;    &lt;span class=j_eclipse_keyword&gt;return&lt;/span&gt; (b == 0) ? a : gcd(b, a % b);&lt;br /&gt;  }&lt;br /&gt;}&lt;/pre&gt;&lt;/pre&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/24682001-114323115789305242?l=blogsummaries.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://blogsummaries.blogspot.com/feeds/114323115789305242/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=24682001&amp;postID=114323115789305242' title='27 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/24682001/posts/default/114323115789305242'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/24682001/posts/default/114323115789305242'/><link rel='alternate' type='text/html' href='http://blogsummaries.blogspot.com/2006/03/solution-to-nextag-card-shuffle.html' title='Solution to the NexTag card shuffle problem'/><author><name>Blog Summaries</name><uri>http://www.blogger.com/profile/01198627526772585776</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>27</thr:total></entry></feed>
