Birdmansplace Posted May 20, 2015 Share Posted May 20, 2015 What i am after is a round robin table that will sort lets say "cars", "drivers". so if i have 10 cars and 10 drivers i would end up with 10 different combos of cars and there driver. I am looking for ideas how to do this or if someone has code that does this aready. The end game for this round robin is to have all info registered into a mysql database along with it a lap time for around the track. So if car-6 and driver-2 have a lap time of 2 min i need to save this to a database. this would be for every slot in every round. Only idea i have come up with other than figuring out the code for the round robin is enter cars in one table, drivers in another. Use round robin code to generate the rounds and then have that saved to yet another table and from there display that info with functions to enter time. Ideas, code or links would be helpful Thanks Quote Link to comment Share on other sites More sharing options...
Barand Posted May 20, 2015 Share Posted May 20, 2015 If you have 10 cars and 10 drivers there are 100 different combinations, not 10. Table : car (car_id | carname) Table : driver (driver_id | drivername) To get all combinations SELECT carname, drivername FROM car CROSS JOIN driver Quote Link to comment Share on other sites More sharing options...
grissom Posted May 20, 2015 Share Posted May 20, 2015 (edited) If you have 10 cars and 10 drivers then there are 10! (ten factorial) ways of assigning each driver to a car, This is 3628800 different ways. Read all the drivers into an array called $drivers[] Then read all cars into an array called $cars[] Randomly shuffle the arrays by using the PHP shuffle command shuffle($drivers); shuffle($cars); Now put driver[0] with car[0], driver[1] with car[1] etc etc. Edited May 20, 2015 by grissom Quote Link to comment Share on other sites More sharing options...
Barand Posted May 20, 2015 Share Posted May 20, 2015 If you have 10 cars and 10 drivers then there are 10! (ten factorial) ways of assigning each driver to a car, This is 3628800 different ways. (Each of the 10 cars can have each of the 10 drivers. 10 x 10 = 100) 1 Quote Link to comment Share on other sites More sharing options...
grissom Posted May 20, 2015 Share Posted May 20, 2015 (Each of the 10 cars can have each of the 10 drivers. 10 x 10 = 100) The first car has a choice of 10 drivers The second car has a choice of 9 drivers (the first driver has been assigned) So the number of ways of filling the first two cars is 10 X 9 = 90 The number of ways of filling the first three cars is 10 X 9 X 8 possibilities = 720 .. and so on. You make yourself look a complete p**** with your above comment. I suggest you take some night classes in maths before you get cocky and post stupid insulting graphics Quote Link to comment Share on other sites More sharing options...
requinix Posted May 20, 2015 Share Posted May 20, 2015 (edited) There are 10! ways of combining all drivers with all cars. There are 100 ways of combining one driver with one car. You're both right. Edited May 20, 2015 by requinix 1 Quote Link to comment Share on other sites More sharing options...
Barand Posted May 20, 2015 Share Posted May 20, 2015 @grissom, my apologies for the image. Quote Link to comment Share on other sites More sharing options...
Barand Posted May 20, 2015 Share Posted May 20, 2015 Now if the car were a mini-bus with 10 seats and you wanted to know how many different ways you could seat the ten passengers, then I'd agree with you. But that's another problem. Quote Link to comment Share on other sites More sharing options...
Barand Posted May 21, 2015 Share Posted May 21, 2015 Keeping it simple, for the sake of my limited maths knowledge, let's say we have 3 cars (A,B,C) and 3 drivers (1,2,3). The combinations are then A1 B1 C1 A2 B2 C2 A3 B3 C3 which I count to be 9 (ie 3 x 3);Using the Grissom method the count would be 3! (ie 6), so which three would be left out? Quote Link to comment Share on other sites More sharing options...
requinix Posted May 21, 2015 Share Posted May 21, 2015 (edited) Using the Grissom method the count would be 3! (ie 6), so which three would be left out?It's not a counting "method" but a different situation. I'm going to stick with the racing analogy. You're picking one driver and one car at a time (A1). The other drivers and the other cars are irrelevant. This driver+car does a qualifying lap around the track. You then give them a different car (A2), they lap, then lap again with the third car (A3). Repeat that with the other two drivers (B1-3, C1-3) and you have a total of nine qualifying laps. This way you can see a driver's performance change with respect to which car they were driving (A1-3, B1-3, C1-3), or alternatively how different drivers handle the same car (A-C1, A-C2, A-C3). grissom is picking all the drivers and all the cars and putting them into a race all at once. Then the assignments change, except rather than have every driver get a different car, what changes is that somebody (perhaps more than one person) gets a different car. Thus the race lineup as a whole changes, even if some or most (but not all) of the drivers stay in the same car they were just driving. The combinations are 1. A1B2C3 2. A1B3C2 3. A2B1C3 4. A2B3C1 5. A3B1C2 6. A3B2C1 This is more geared towards measuring the performance of a driver with respect to how the other drivers are doing. As is what happens a real race. For example, with races 1 and 2 you can see how driver A (who kept the same car for both) did when B and C changed cars. If you think A's car is the variable, you can compare races 3 and 4 where A used a different car from before (but kept it for both races) and B and C changed. Or races 5 and 6. For driver B you can compare 3+5/1+6/2+4 and for C it's 4+6/2+5/1+3. tldr: you're counting driver+car combinations, grissom is counting driver+car+driver+car+driver+car combinations. Edited May 21, 2015 by requinix 1 Quote Link to comment Share on other sites More sharing options...
Barand Posted May 21, 2015 Share Posted May 21, 2015 @Birdmansplace (if you are still here after that short diversion) I have shown you how to get the combinations for my envisaged scenario using a simple cross join in the SQL. To use the scenario envisaged by grissom then the method is more complex. As it requires a recursive solution then read the data into arrays rather than have queries called recursively. The data (I restricted to 4 of each for brevity of output) $cars = [ 'Audi', 'BMW', 'Chrysler', 'Daewoo' ]; $drivers = [ 'Adam', 'Ben', 'Cathy', 'Diana' ] The code $k = count($cars); $thead = "<tr><th rowspan='2'>Round</th><th colspan='$k'>Cars</th></tr><tr><th>" . join('</th><th>', $cars) . "</th></tr>\n"; $tbody = ''; $results = []; combos($drivers, $results, []); // call the recursive function to get combinations foreach ($results as $k => $names) { $tbody .= "<tr><td>".(++$k)."</td><td>" . join('</td><td>', $names) . "</td></tr>\n"; } function combos($set, &$results, $tmp) { $k = count($set); if ($k==1) { $results[] = array_merge($tmp, $set); } else { // takes each one in turn and call with remaining set members foreach ($set as $k => $x) { $copy = $set; unset($copy[$k]); combos($copy, $results, array_merge($tmp, [$x])); } } } Output 1 Quote Link to comment Share on other sites More sharing options...
Barand Posted May 24, 2015 Share Posted May 24, 2015 Read all the drivers into an array called $drivers[] Then read all cars into an array called $cars[] Randomly shuffle the arrays by using the PHP shuffle command shuffle($drivers); shuffle($cars); Now put driver[0] with car[0], driver[1] with car[1] etc etc. Just in case anyone is tempted to use this "shuffle and pray" shortcut approach to this problem I checked out its validity. I took arrays of N drivers and shuffled them N! times, storing each combination. I then checked to see how many were unique. These are the results ACB BAC BAC BAC CBA CBA 3 drivers: 3 duplicate combinations out of 6 (50%) ABCD ACDB ADBC ADBC ADCB BADC BCAD BCDA BCDA BDCA CABD CABD CBAD CBDA DABC DACB DACB DACB DBAC DBCA DBCA DCAB DCAB DCBA 4 drivers: 7 duplicate combinations out of 24 (29%) ABDCE ABDEC ABECD ABECD ABEDC ABEDC ACBDE ACDBE ACDBE ACDEB ADBEC ADEBC ADECB AEBDC AECBD AECDB AEDCB BACED BADCE BADEC BADEC BCAED BCDEA BCDEA BCEAD BDACE BDACE BDAEC BDAEC BDCAE BDCAE BDEAC BDECA BEDAC BEDAC BEDCA CABDE CABED CABED CAEDB CAEDB CAEDB CBAED CBDAE CBEAD CBEDA CBEDA CDABE CDAEB CDBAE CDBEA CDEAB CDEBA CDEBA CDEBA CDEBA CDEBA CEABD CEADB CEADB CEADB CEBDA CEDAB CEDAB CEDAB CEDBA DABCE DABCE DABCE DAEBC DBAEC DBCAE DBEAC DCABE DCBAE DCBEA DCBEA DCBEA DCEAB DCEBA DCEBA DEACB DEACB DEBAC DEBAC DEBCA DECAB DECAB DECBA DECBA DECBA EADBC EADBC EADBC EADBC EBACD EBACD EBACD EBACD EBCDA EBDCA EBDCA ECABD ECBAD ECBAD ECBDA ECBDA ECDAB ECDBA ECDBA EDABC EDABC EDACB EDACB EDACB EDBCA EDBCA EDCAB EDCBA EDCBA 5 drivers: 46 duplicate combinations out of 120 (38%) 6 drivers: 265 duplicate combinations out of 720 (36%) 7 drivers: 1841 duplicate combinations out of 5040 (36%) 8 drivers: 14761 duplicate combinations out of 40320 (36%) 9 drivers: 327861 duplicate combinations out of 362880 (90%) Verdict: Not fit for purpose. The code used to test: <?php $drivers = ['A','B']; $extra = ['C','D','E','F','G','H','I']; $factorials = [ 3 => 6, 4 => 24, 5 => 120, 6 => 720, 7 => 5040, 8 => 40320, 9 => 362880 ]; foreach ($extra as $e) { $drivers[] = $e; // add to drivers echo countUnique($drivers, $factorials); // test with N drivers } function countUnique($d, $facts) { $combos = []; $k = count($d); $f = $facts[$k]; for ($i=0; $i<$f; $i++) { shuffle($d); // shuffles n! times $str = join('',$d); // and stores each $combos[] = $str; // random combination } // output the smaller shuffled combo arrays to view duplicates if ($k < 6) { sort($combos); $chunks = array_chunk($combos, 12); foreach($chunks as $coms) echo join(' ', $coms)."<br>"; echo '<br>'; } $n = count(array_unique($combos)); // count how many were unique $n1 = $f - $n; // number of duplicate values $n2 = count($combos); // to check that n! were generated return sprintf('%d drivers: %6d duplicate combinations out of %6d (%d%%)<br><br>', count($d), $n1, $n2, $n1*100/$n2 ); } ?> 1 Quote Link to comment Share on other sites More sharing options...
Birdmansplace Posted June 4, 2015 Author Share Posted June 4, 2015 Thanks for the in-put... The way i worded the opening topic was to be able to relate to alot of users to see what i should do. I am building a web based "arena log" for my father inlaws horse arena and they host a few different things. The round robin they do is team round robin and its a roper and a healer (car, driver as stated in opening topic). All healer's compete with one roper. I need to be able to enter into a mysql database these names, roper in one table and healer in another. Then once all the names are there make a round robin table. Once round robin table is made i also need to save a track time with that pair of people for each round. My skills with php are limited and looking for help to literally wright the code. Since I am doing this for him free of charge I am coming to you guys for help. Once everything for this is complete i plan on making it open source for download some where. Thanks Quote Link to comment Share on other sites More sharing options...
requinix Posted June 4, 2015 Share Posted June 4, 2015 Alright, so before things get out of hand again: Let's say you have ropers - Alice - Bob - Cindy and healers - Martin - Nicky - Olivia Exactly what do you want to happen with them? Quote Link to comment Share on other sites More sharing options...
Birdmansplace Posted June 5, 2015 Author Share Posted June 5, 2015 martin nicky and olivia heal for alice then bob and finally cindy. So there would be three rounds and never with the same partner. and for each round i need to be able to log a time per pair per round. Round1 Alice & Martin _time_ Bob & Nicky _time_ Cindy & Olivia _time_ Round2 Alice & Nicky _time_ Bob & Nicky _time_ Cindy & Martin _time_ Step one Enter roper and healer by name to a database Step two Use info from step one to make round robin list and save it. Step three Pull list from step two and be able to save a track time per pair and save again to database. Hope that helps Quote Link to comment Share on other sites More sharing options...
requinix Posted June 5, 2015 Share Posted June 5, 2015 (edited) I assume Round 2 is supposed to have Bob and Olivia? As it so happens, what you're describing wasn't quite covered by grissom or Barand. So that's awesome. Would it be enough to shuffle the list of ropers and the list of healers, pair everyone, and then "rotate" one of the lists? Like it goes M/N/O/P/Q then N/O/P/Q/M then O/P/Q/M/N and so on. The advantage is that it's really, really easy to do, but the disadvantage is that the results aren't random from one round to the next: someone can look at the assignments in one round and tell what the assignments will be in the next round. Edited June 5, 2015 by requinix Quote Link to comment Share on other sites More sharing options...
Barand Posted June 5, 2015 Share Posted June 5, 2015 (edited) You need to the ropers in a consistent sequence and rotate the heelers each round A B C ------ M N O N O M O M N Once allocated the running order can be shuffled. So it would be like this <?php $ropers = [ 'Alice', 'Bob', 'Cindy', 'Dave', 'Emma', 'Fred', 'Gina', 'Henry', 'Imogen', 'Jack' ]; $heelers= [ 'Martin', 'Nicola', 'Oliver', 'Paula', 'Quentin', 'Rosie', 'Steve', 'Tracey', 'Uri', 'Vanessa' ]; $output = ''; for ($round=1; $round<=10; $round++) { $rotated = rotate($heelers, $round-1); $riders = array_combine($ropers, $rotated); $output .= "<table border='1'>\n <tr><th colspan='4'>Round $round</th></tr>\n <tr><th></th><th>Roper</th><th>Heeler</th><th>Time</th></tr>\n"; $turn=1; $rprs = $ropers; // keep ropers in original order shuffle($rprs); foreach ($rprs as $r) { $h = $riders[$r]; // get the heeler allocated to the roper for this round $output .= "<tr><td>$turn</td><td>$r</td><td>$h</td><td></td></tr>\n"; ++$turn; } $output .= "</table>\n"; } function rotate($array, $n) { for ($i=0; $i<$n; $i++) $array[] = array_shift($array); return $array; } ?> <html> <head> <title>Round Robin</title> <style type="text/css"> table { margin: 5px; width: 18%; float: left; } th { color: white; background-color: #369; } td { background-color: white; font-family: sans-serif; font-size: 9pt; } div { background-color: #CCC; } </style> </head> <body> <h1>Round Robin Event</h1> <div> <?=$output?> </div> </body> </html> PS : 100 (10x10) combinations Edited June 5, 2015 by Barand 1 Quote Link to comment Share on other sites More sharing options...
Birdmansplace Posted June 8, 2015 Author Share Posted June 8, 2015 Yes to your first question requinix, and I like your idea because you say its more simple as long as your able to use mysql database. I need to register them in a table and the shuffle them from the table and save it to another table. From that other table i would need to be able to add a time to each pairing and save it back to the table so at the end we can find the winner. Quote Link to comment Share on other sites More sharing options...
Birdmansplace Posted July 16, 2015 Author Share Posted July 16, 2015 Barand I have been messing round with the code you posted and have been trying to do some stuff. I have setup a database called roundrobin in mysql. there is 2 tables RRroper, RRheeler. in each table there is 4 columns sid(auto increm), roper/healer. I am trying to figure out the code needed for $ropers and $heelers= to login and pull names from the database. include("dbinfo.php"); mysql_connect($host,$username,$password); @mysql_select_db($database) or die( "Unable to select database"); // Retrieve data from database $sql="SELECT * FROM roper ORDER BY sid"; $result=mysql_query($sql); while($rows=mysql_fetch_array($result)){ echo $rows['roper']; } this will read the database but can't get it to word in your coding. I have changed $result to $ropers with no luck. removed while($rows.... and the next 2 lines with the same issue. The other issue will be once i pull info from the db if i have more than 10 pairs not all will display for ($round=1; $round<=10; $round++) { so not sure what to do with changing "10" to read the count of how many ropers are in the database. Thanks Quote Link to comment Share on other sites More sharing options...
Birdmansplace Posted July 16, 2015 Author Share Posted July 16, 2015 couldn't save my edited post for some reason. so heres what i was adding: so not sure what to do with changing "10" to read the count of how many ropers are in the database. Once thats figured out i am also going to make a table to save the output to the db so i can save the times for each pair every round. I would like it to display the same way as well if possible. To sum it up: first step would be to enter names to database. step 2 the code you made to display and make sure everything is correct step 3 save displayed output to a table along with a column for time step 4 display saved output with the ability to save round time per pair per round step 5 when all rounds complete view it as your code does with saved times Thanks Quote Link to comment Share on other sites More sharing options...
Barand Posted July 18, 2015 Share Posted July 18, 2015 What is your strategy if you get entries from, say, 12 ropers and 15 heelers? Quote Link to comment Share on other sites More sharing options...
Barand Posted July 19, 2015 Share Posted July 19, 2015 (edited) OK no strategy then, so assuming there are always the same number of each, and given your data looks like this mysql> SELECT sid, roper FROM rrroper; +-----+--------+ | sid | roper | +-----+--------+ | 1 | Alice | | 2 | Bob | | 3 | Cindy | | 4 | Dave | | 5 | Emma | | 6 | Fred | | 7 | Gina | | 8 | Henry | | 9 | Imogen | | 10 | Jack | +-----+--------+ 10 rows in set (0.00 sec) mysql> SELECT sid, heeler FROM rrheeler; +-----+---------+ | sid | heeler | +-----+---------+ | 1 | Martin | | 2 | Nicola | | 3 | Oliver | | 4 | Paula | | 5 | Quentin | | 6 | Rosie | | 7 | Steve | | 8 | Tracey | | 9 | Uri | | 10 | Vanessa | +-----+---------+ 10 rows in set (0.00 sec) CREATE TABLE `result` ( `result_id` int(11) NOT NULL AUTO_INCREMENT, `round_no` int(11) NOT NULL, `roper_id` int(11) NOT NULL, `heeler_id` int(11) NOT NULL, `time` time DEFAULT NULL, PRIMARY KEY (`result_id`) ) this code will generate the rounds for you in a result table for you to record the times (assumes ropers and heelers both have id values 1..N) <?php include("db_inc.php"); // define HOST, USERNAME etc $db = new mysqli(HOST,USERNAME,PASSWORD,'roundrobin'); // // GENERATE THE result TABLE // PAIRING EACH ROPER WITH A // DIFFERENT HEELER FOR EACH ROUND // $res = $db->query("SELECT COUNT(*) FROM rrroper"); list($numRounds) = $res->fetch_row(); for ($r=1; $r<=$numRounds; $r++) { $sql = "INSERT INTO result (round_no, roper_id, heeler_id) SELECT $r as `round` , r.sid as roper , h.sid as heeler FROM rrroper r INNER JOIN rrheeler h ON r.sid = MOD((h.sid + $r),10) + 1"; $db->query($sql); } ?> Edited July 19, 2015 by Barand Quote Link to comment Share on other sites More sharing options...
Barand Posted July 20, 2015 Share Posted July 20, 2015 A couple of corrections required to the above: INNER JOIN rrheeler h ON r.sid = MOD((h.sid + $r),10) + 1"; should be INNER JOIN rrheeler h ON r.sid = MOD((h.sid + $r),$numRounds) + 1"; and the "time" column in result table should be DECIMAL(8,2) Quote Link to comment Share on other sites More sharing options...
Birdmansplace Posted July 21, 2015 Author Share Posted July 21, 2015 there will have to be even amount of ropers and healers to make it fair for everyone. Quote Link to comment Share on other sites More sharing options...
Recommended Posts
Join the conversation
You can post now and register later. If you have an account, sign in now to post with your account.