8) { $total_odds_value = $newhand_value = $newhand_suits = $test_suits = $test_value = $hand_suits = $hand_values = array(); $deck_keys = array_keys($deck); for ($i = 0; $i < 5; $i++) { $hand_suits[] = $deck_suits[$deck_keys[$i]]; $hand_values[] = $deck_values[$deck_keys[$i]]; unset($deck_suits[$deck_keys[$i]]);unset($deck_values[$deck_keys[$i]]);unset($deck[$deck_keys[$i]]); } $hand = array_join($hand_suits,$hand_values,','); for ($i = 0; $i < 32; $i++) { for ($j = 0; $j < 5; $j++) { if ($i & pow(2,$j)) { $test_suits[$i][] = $hand_suits[$j]; $test_value[$i][] = $hand_values[$j]; } else { $test_suits[$i][] = '*'; $test_value[$i][] = '*'; } } get_odds($test_value[$i],$test_suits[$i]); } arsort($total_odds_value); $keys = array_keys($total_odds_value); $count = 0; $deck_keys = array_keys($deck); for ($i = 0; $i < 5; $i++) { if ($test_value[$keys[0]][$i]) { $newhand_value[$i] = $test_value[$keys[0]][$i]; $newhand_suits[$i] = $test_suits[$keys[0]][$i]; } else { $newhand_suits[$i] = $deck_suits[$deck_keys[$count]]; $newhand_value[$i] = $deck_values[$deck_keys[$count]]; unset($deck_suits[$deck_keys[$count]]);unset($deck_values[$deck_keys[$count]]);unset($deck[$deck_keys[$count]]); $count++; } } $final_points += $final_hands[] = get_points($newhand_value,$newhand_suits); } $keys = array_keys($deck); $file = fopen("output.txt",'w'); $final_hands = array_count_values($final_hands); $total_hands = 0; $total_points = 0; foreach (array( //0 => 'ZERO_HAND', TWO_KIND => 'TWO_KIND', TWO_PAIR => 'TWO_PAIR', THREE_KIND => 'THREE_KIND', STRAIGHT => 'STRAIGHT', FLUSH => 'FLUSH', FULL_HOUSE => 'FULL_HOUSE', FOUR_KIND => 'FOUR_KIND', STRAIGHT_FLUSH => 'STRAIGHT_FLUSH', ) as $id => $name) { $final_hands[$id] += 1-1; fwrite($file,$name.': '.$final_hands[$id]."n"); $total_hands += $final_hands[$id]; $total_points += $final_hands[$id]*$id; } fwrite($file,$total_hands."n".($total_points/$total_hands)."n".$total_points); fclose($file); } function get_deck_file() { global $suits,$cards,$deck_suits,$deck_values,$deck; $suits = array('d','c','s','h'); $cards = array(2,3,4,5,6,7,8,9,10,11,12,13,14); $file = file("input.txt"); foreach ($file as $card) { $deck_values[] = str_replace(array('T','J','Q','K','A'),array(10,11,12,13,14),substr($card,0,1)); $deck_suits[] = strtolower(substr($card,1,1)); } $deck = array_join($deck_suits,$deck_values,''); } function get_odds(&$values,&$suits) { global $deck,$total_odds_value,$total_odds; for ($i = 0; $i < 5; $i++) if ($values[$i] == '*') { unset($values[$i]);unset($suits[$i]); } if (sizeof($values) < 2 && !in_array(14,$values)) {$total_odds_value[] = ''; return false;} // odds for a straight-flush $odds += get_odds_straightflush($values,$suits) * STRAIGHT_FLUSH; // odds for a flush $odds += get_odds_flush($suits) * FLUSH; // odds for a straight $odds += get_odds_straight($values) * STRAIGHT; // odds for 4-kind $odds += get_odds_xkind($values,4) * FOUR_KIND; // odds for full house $odds += get_odds_fullhouse($values) * FULL_HOUSE; // odds for 3-kind $odds += get_odds_xkind($values,3) * THREE_KIND; // odds for 2-pair $odds += get_odds_twopair($values) * TWO_PAIR; // odds for 2-kind $odds += get_odds_xkind($values,2) * TWO_KIND; $total_odds_value[] = $odds; return $odds; } function get_points(&$values,&$suits) { // points for a straight-flush if (get_points_straightflush($values,$suits)) return STRAIGHT_FLUSH; // points for a flush elseif (get_points_flush($suits)) return FLUSH; // points for a straight elseif (get_odds_straight($values)) return STRAIGHT; // points for 4-kind elseif (get_points_xkind($values,4)) return FOUR_KIND; // points for full house elseif (get_points_fullhouse($values)) return FULL_HOUSE; // points for 3-kind elseif (get_points_xkind($values,3)) return THREE_KIND; // points for 2-pair elseif (get_points_twopair($values)) return TWO_PAIR; // points for 2-kind elseif (get_points_xkind($values,2)) return TWO_KIND; else return 0; } function get_odds_straightflush($values,$suits) { global $deck,$deck_values,$total_odds; if (array_max($values,0) > 1 || array_max($suits,0) != sizeof($suits)) return 0; asort($values); $keys = array_keys($values); $lo = $values[$keys[0]]; $hi = $values[$keys[sizeof($values)-1]]; if ($hi - $lo >= 5) return 0; if (sizeof($hand) == 5) return 1; $deck_count = array_count_values($deck); for ($i = $lo-4; $i <= $lo; $i++) { if ($i < $hi-4 || $i < 2 || $i+4 > 14) continue; $temp = 1; for ($j = 0; $j < 5; $j++) { if (in_array($j+$i,$values)) continue; $temp *= $deck_count[$suits[$keys[0]].($j+$i)]/(sizeof($deck)-$count); } $odds += $temp*factorial(5-sizeof($values)); } return $odds; } function get_odds_xkind($values,$amount) { global $deck_values,$deck,$total_odds; $left = array_count_values($deck_values); $numleft = array_count_values($left); // odds of getting x of a kind using one of the cards already in hand foreach (array_count_values($values) as $key => $count) { $numleft[4-$count]--; if ($amount == $count) return 1; elseif ($amount < $count) return 0; elseif ($amount - $count > 5 - sizeof($values)) continue; $temp = choose($left[$key],$amount-$count)*choose(sizeof($deck_values)-$left[$key],5-sizeof($values)-($amount-$count)); $odds += $temp; } // odds of getting x of a kind with a card not currently in your hand if ($amount <= 5-sizeof($values)) { for ($i = 4; $i >= $amount; $i--) { $odds += choose($numleft[$i],1)*choose($i,$amount); } } return $odds / choose(sizeof($deck),5-sizeof($values)); } function get_odds_fullhouse($values) { global $deck_values,$deck,$total_odds; $cards = array_count_values($values); if (sizeof($cards) > 2) return 0; $keys = array_keys($cards); $left = array_count_values($deck_values); foreach ($left as $key => $value) { if ($cards[$key]) continue; $numleft[$value]++; } if (sizeof($cards) == 1) { for ($j = 4; $j > 1; $j--) { if (!$numleft[$j]) continue; $odds += choose($left[$keys[0]],3-$cards[$keys[0]])*choose($numleft[$j],1)*choose($j,2) + choose($left[$keys[0]],2-$cards[$keys[0]])*choose($numleft[$j],1)*choose($j,3); } } else { $odds = choose($left[$keys[0]],3-$cards[$keys[0]])*choose(1,1)*choose($cards[$keys[1]],2)+ choose($left[$keys[1]],3-$cards[$keys[1]])*choose(1,1)*choose($cards[$keys[0]],2); } return $odds / choose(sizeof($deck),5-sizeof($values)); } function get_odds_twopair($values) { global $deck_values,$deck,$total_odds; $cards = array_count_values($values); if (sizeof($cards) > 3) return 0; arsort($cards); $keys = array_keys($cards); if (array_max($values,0) == 2 && array_max($values,1) == 2) return 1; $left = array_count_values($deck_values); foreach ($left as $key => $value) { if ($cards[$key]) continue; $numleft[$value]++; } if ($cards[$keys[0]] == 2) { for ($i = 1; $i < sizeof($cards); $i++) { $odds += choose($left[$keys[$i]],1)*choose(sizeof($deck)-$left[$keys[0]]-$left[$keys[$i]],5-sizeof($values)-1); } if (2 <= 5-sizeof($values)) { for ($i = 4; $i >= 2; $i--) { $odds += choose($numleft[$i],1)*choose($i,2)*choose(sizeof($deck)-$left[$keys[0]]-$i,5-sizeof($values)-2); } } } else { for ($i = 0; $i < sizeof($cards); $i++) { for ($j = 4; $j >= 2; $j--) { $odds += choose($left[$keys[$i]],1)*choose($numleft[$j],1)*choose($j,2)*choose(sizeof($deck)-$left[$keys[$i]]-$j,5-sizeof($values)-3); } foreach ($values as $key => $value) { if ($values[$keys[$i]] == $value) continue; $odds += choose($left[$keys[$j]],1)*choose($left[$keys[$j]],1)*choose(sizeof($deck)-$left[$keys[$j]]-$left[$key],5-sizeof($values)-2); } } } return $odds / choose(sizeof($deck),5-sizeof($values)); } function get_odds_flush($values) { global $deck_suits,$total_odds; if (sizeof(array_count_values($values)) != 1) return 0; if (sizeof($values) == 5) return 1; $left = array_count_values($deck_suits); $keys = array_keys($values); return choose($left[$values[$keys[0]]],5-sizeof($values))/choose(sizeof($deck_suits),5-sizeof($values)); } function get_odds_straight($values) { global $deck,$deck_values; if (sizeof(array_count_values($values)) != sizeof($values)) return 0; asort($values); $keys = array_keys($values); $lo = $values[$keys[0]]; $hi = $values[$keys[sizeof($values)-1]]; if ($hi - $lo >= 5) return 0; if (sizeof($values) == 5) return 1; $deck_count = array_count_values($deck_values); for ($i = $lo-4; $i <= $lo; $i++) { if ($i < $hi-4 || $i < 2 || $i+4 > 14) continue; $temp = 1; for ($j = 0; $j < 5; $j++) { if (in_array($j+$i,$values)) continue; $temp *= $deck_count[$j+$i]/(sizeof($deck)-$count); } $odds += $temp*factorial(5-sizeof($values)); } return $odds; } function get_points_straightflush(&$values,&$suits) { if (array_max($values,0) == 1 && array_max($suits,0) == 5) { arsort($values); $keys = array_keys($values); if ($values[$keys[0]] - $values[$keys[4]] == 4) return true; } return false; } function get_points_flush(&$suits) { if (array_max($suits,0) == 5) return true; return false; } function get_points_straight(&$values) { if (array_max($values,0) == 1) { arsort($values); $keys = array_keys($values); if ($values[$keys[0]] - $values[$keys[4]] == 4) return true; } return false; } function get_points_xkind($values,$amount) { if (array_max($values,0) == $amount) return true; return false; } function get_points_fullhouse(&$values) { if (array_max($values,0) == 3 && array_max($values,1) == 2) return true; return false; } function get_points_twopair(&$values) { if (array_max($values,0) == 2 && array_max($values,1) == 2) return true; return false; } function choose($a=0,$b=0) { if ($b > $a || $a < 0 || $b < 0) return 0; $temp = 1; for ($i = $a; $i > $a - $b; $i--) $temp *= $i; return $temp / factorial($b); } function factorial($start) { global $cache; if ($start < 1) return 1; if ($cache[$start]) return $cache[$start]; $output = 1; for ($i = 1; $i <= $start; $i++) $output *= $i; $cache[$start] = $output; return $output; } function array_join($one,$two,$join) { if (sizeof($one) != sizeof($two)) return false; foreach ($one as $id => $key) $new[$id] = $one[$id].$join.$two[$id]; return $new; } function array_max($array,$offset = 0) { $count = array_count_values($array); arsort($count); $keys = array_keys($count); return $count[$keys[$offset]]; } function array_multiply($keys) { $output = 1; foreach ($keys as $val) $output *= $val; return $output; } ?>