001package ball.riddler538.ant.taskdefs; 002/*- 003 * ########################################################################## 004 * Solutions for the 538 Riddler 005 * %% 006 * Copyright (C) 2015 - 2022 Allen D. Ball 007 * %% 008 * Licensed under the Apache License, Version 2.0 (the "License"); 009 * you may not use this file except in compliance with the License. 010 * You may obtain a copy of the License at 011 * 012 * http://www.apache.org/licenses/LICENSE-2.0 013 * 014 * Unless required by applicable law or agreed to in writing, software 015 * distributed under the License is distributed on an "AS IS" BASIS, 016 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 017 * See the License for the specific language governing permissions and 018 * limitations under the License. 019 * ########################################################################## 020 */ 021import ball.game.card.Card; 022import ball.game.card.poker.Deck; 023import ball.game.card.poker.Evaluator; 024import ball.game.card.poker.Ranking; 025import ball.swing.table.SimpleTableModel; 026import ball.util.ant.taskdefs.AntTask; 027import java.util.Arrays; 028import java.util.Collections; 029import java.util.List; 030import java.util.LinkedList; 031import java.util.TreeMap; 032import lombok.Getter; 033import lombok.NoArgsConstructor; 034import lombok.Setter; 035import lombok.ToString; 036import org.apache.tools.ant.BuildException; 037 038/** 039 * {@link.uri http://ant.apache.org/ Ant} {@link org.apache.tools.ant.Task} 040 * to solve 041 * {@link.uri https://fivethirtyeight.com/features/hark-two-holiday-puzzles/ Riddler Express} 042 * <p> 043 * From Jeffrey Hope, open up your junk drawer and pull out those decks of 044 * cards: 045 * </p> 046 * <p> 047 * Your challenge is to take any 50 cards from a standard 52-card deck and 048 * arrange them into 10 poker hands, one of each type from a royal flush 049 * down to a lowly high card.2 The hands you build always rank as the 050 * highest type of hand possible,3 and a card may not be reused across the 051 * hands. (This means, for example, that a four-of-a-kind better than four 052 * nines is impossible because it’d use a card you’d need to make a royal 053 * flush.) As in actual poker, it doesn’t matter what order the cards are 054 * arranged within a hand. 055 * </p> 056 * <p> 057 * Sounds easy enough, and indeed there is more than one solution. But: 058 * Exactly how many solutions are there? 059 * </p> 060 * 061 * {@ant.task} 062 * 063<pre> 064Ranking Hand 065---------------------------------------- 066RoyalFlush [A-♤, K-♤, Q-♤, J-♤, 10-♤] 067StraightFlush [K-♡, Q-♡, J-♡, 10-♡, 9-♡] 068FourOfAKind [8-♤, 8-♡, 8-♢, 8-♧, J-♧] 069FullHouse [A-♡, A-♢, A-♧, K-♢, K-♧] 070Flush [Q-♢, J-♢, 10-♢, 9-♢, 7-♢] 071Straight [7-♤, 6-♤, 5-♤, 4-♤, 3-♤] 072ThreeOfAKind [6-♡, 6-♢, 6-♧, 10-♧, 5-♧] 073TwoPair [9-♤, 9-♧, 7-♡, 7-♧, 4-♡] 074Pair [5-♡, 5-♢, 4-♢, 4-♧, 3-♡] 075HighCard [Q-♧, 3-♢, 3-♧, 2-♤, 2-♡] 076Remaining [2-♢, 2-♧] 077</pre> 078 * 079 * @author {@link.uri mailto:ball@hcf.dev Allen D. Ball} 080 */ 081@AntTask("solve-express-2017-12-22") 082@NoArgsConstructor @ToString 083public class SolveExpress20171222Task extends AbstractTask { 084 @Override 085 public void execute() throws BuildException { 086 super.execute(); 087 088 try { 089 SimpleTableModel model = new SimpleTableModel(new Object[][] { }, "Ranking", "Hand"); 090 TreeMap<Ranking,List<Card>> map = new TreeMap<>(); 091 List<Card> deck = new Deck(); 092 093 deck.sort(Evaluator.CARD); 094 Collections.reverse(deck); 095 096 List<Ranking> rankings = Arrays.asList(Ranking.values()); 097 098 Collections.reverse(rankings); 099 100 for (Ranking ranking : rankings) { 101 List<Card> hand = ranking.find(deck); 102 103 if (! hand.isEmpty()) { 104 hand = hand.subList(0, ranking.required()); 105 106 map.put(ranking, hand); 107 108 deck.removeAll(hand); 109 } 110 } 111 112 for (Ranking ranking : rankings) { 113 List<Card> hand = map.get(ranking); 114 115 if (hand != null) { 116 if (hand.size() < 5) { 117 hand = new LinkedList<>(hand); 118 119 List<Card> draw = deck.subList(0, 5 - hand.size()); 120 121 hand.addAll(draw); 122 draw.clear(); 123 } 124 125 model.row(ranking, hand); 126 } 127 } 128 129 model.row("Remaining", deck); 130 131 log(model); 132 } catch (BuildException exception) { 133 throw exception; 134 } catch (Throwable throwable) { 135 throwable.printStackTrace(); 136 throw new BuildException(throwable); 137 } 138 } 139}