Skip to content

Instantly share code, notes, and snippets.

@torazuka
Created November 14, 2012 12:25
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save torazuka/4071826 to your computer and use it in GitHub Desktop.
Save torazuka/4071826 to your computer and use it in GitHub Desktop.
第五回オフラインリアルタイムどう書く の解答(Java) ref: http://qiita.com/items/f2f721dfb2bb03cf5812
import static org.junit.Assert.assertEquals;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Set;
import org.junit.Test;
class Card implements Comparable<Card> {
String suit;
String rank;
Card(char s, char r) {
suit = String.valueOf(s);
rank = String.valueOf(r);
}
public boolean isStrong(int rank) {
int n = this.convertRank();
if (rank < n) {
return true;
}
return false;
}
@Override
public String toString() {
return suit + rank;
}
public int convertRank() {
if (rank.equals("T")) {
return 10;
}
if (rank.equals("J")) {
return 11;
}
if (rank.equals("Q")) {
return 12;
}
if (rank.equals("K")) {
return 13;
}
if (rank.equals("A")) {
return 14;
}
if (rank.equals("2")) {
return 15;
}
if (rank.equals("o")) {
return 16;
}
return Integer.valueOf(rank);
}
@Override
public int compareTo(Card o) {
int n = this.convertRank();
int m = o.convertRank();
if (m < n) {
return 1;
}
if (n < m) {
return -1;
}
return 0;
}
@Override
public boolean equals(Object obj) {
if (obj instanceof Card) {
Card c = (Card) obj;
if (rank.equals(c.rank) && suit.equals(c.suit)) {
return true;
}
}
return false;
}
}
/**
* 問題: http://nabetani.sakura.ne.jp/hena/ord5dahimi/
*/
public class Dahimi {
protected String solve(String input) {
String[] split = input.split(",");
if (split.length < 2) {
return "-";
}
List<Card> spaceList = getCards(split[0]);
List<Card> hand = getCards(split[1]);
int spaceNum = spaceList.size();
int spaceRank = getMinRank(spaceList).convertRank();
Map<Integer, List<String>> available = getAvailable(spaceRank,
spaceNum, hand);
if (0 == available.size()) {
return "-";
}
return createResult(available, spaceNum);
}
protected Card getMinRank(List<Card> space) {
if (hasJoker(space)) {
if (space.size() == 1) {
return new Card('J', 'o');
}
space.remove(new Card('J', 'o'));
}
return Collections.min(space);
}
// ランクごとにコンビネーションを作成する
protected String createResult(Map<Integer, List<String>> available, int num) {
StringBuilder result = new StringBuilder();
Set<Integer> rankSet = available.keySet();
Iterator<Integer> ite = rankSet.iterator();
for (; ite.hasNext();) {
List<String> list = available.get(ite.next());
result.append(createCombination(list, num));
result.append(",");
}
return new String(result).substring(0, result.length() - 1);
}
protected String createCombination(List<String> list, int target) {
StringBuilder result = new StringBuilder();
List<String> loop = loop(list, target);
for (String cards : loop) {
result.append(cards);
result.append(',');
}
return new String(result).substring(0, result.length() - 1);
}
// c.f. http://d.hatena.ne.jp/ibaza/20080303/1204476552
protected List<String> loop(List<String> list, int r) {
List<String> result = new ArrayList<>();
int n = list.size();
// n = r のとき、選び方は1つなので、リストをそのまま1つのリストにして返す
if (n == r) {
StringBuilder sb = new StringBuilder();
for (String card : list) {
sb.append(card);
}
result.add(new String(sb));
return result;
}
// r = 1 のとき、選び方はn通りあるので、リストの要素をそれぞれリストにして返す
if (r == 1) {
for (String card : list) {
result.add(card);
}
return result;
}
// r = 0 または r がリストの要素数より大きいとき、空リストを返す
if (r == 0 || n < r) {
return result;
}
// 「リストの先頭要素を除いたリストからr-1個を選ぶ組合せのそれぞれに先頭要素を加えたもの
// と、 リストの先頭要素を除いたリストからr個を選ぶ組合せ」の合計
List<String> paraList = new ArrayList<>(list);
String removed = paraList.remove(0);
List<String> looped = loop(paraList, r - 1);
for (int i = 0; i < looped.size(); i++) {
String str = looped.get(i);
looped.set(i, str + removed);
}
List<String> looped2 = loop(paraList, r);
for (String card : looped2) {
looped.add(card);
}
return looped;
}
protected Map<Integer, List<String>> getAvailable(int spaceRank,
int spaceNum, List<Card> hand) {
Map<Integer, List<String>> result = new HashMap<>();
// ワイルドカードとして使わないJokerを持っていたら捨てる
boolean hasWildcard = hasJoker(hand) && 1 < spaceNum;
if (hasWildcard == false) {
hand.remove(new Card('J', 'o'));
}
for (Card card : hand) {
if (card.isStrong(spaceRank) && card.convertRank() != 16) {
List<String> list = result.get(card.convertRank());
if (list == null) {
list = new ArrayList<>();
}
list.add(card.toString());
result.put(card.convertRank(), list);
}
}
// ワイルドカードとしてJokerを使う
if (hasWildcard) {
addWildcard(result);
}
// 場札の枚数よりも少ないとき、削除
Set<Integer> keySet = result.keySet();
List<Integer> removeIdx = new ArrayList<>();
for (Integer integer : keySet) {
List<String> list = result.get(integer);
if (list.size() < spaceNum) {
removeIdx.add(integer);
}
}
for (Integer integer : removeIdx) {
result.remove(integer);
}
return result;
}
protected void addWildcard(Map<Integer, List<String>> result) {
Set<Integer> keySet = result.keySet();
for (Integer integer : keySet) {
List<String> tmpList = result.get(integer);
tmpList.add(new Card('J', 'o').toString());
result.put(integer, tmpList);
}
}
protected boolean hasJoker(List<Card> hand) {
return 0 < Collections.frequency(hand, new Card('J', 'o')) ? true
: false;
}
protected List<Card> getCards(String hand) {
List<Card> result = new ArrayList<>();
for (int i = 0; i < hand.length(); i += 2) {
Card c = new Card(hand.charAt(i), hand.charAt(i + 1));
result.add(c);
}
return result;
}
public static void main(String[] args) {
Dahimi dahimi = new Dahimi();
System.out.println(dahimi.solve("JoC8,H6D7C5S9CQH9STDTCAD9S5DAS2CT"));
}
// テストのための処理。解答や期待値の文字列をソートする
protected String answerSort(String string) {
String result = "";
String[] split = string.split(",");
if (split.length == 0) {
// カンマがない場合は'-'、あるいは1枚だけ
return string;
}
List<String> tmpOuter = new ArrayList<>();
int innerUnit = split[0].length() / 2;
for (String str : split) {
List<String> tmpInner = new ArrayList<>();
for (int i = 0; i < innerUnit * 2; i += 2) {
String s = new Card(str.charAt(i), str.charAt(i + 1))
.toString();
tmpInner.add(s);
}
Collections.sort(tmpInner);
StringBuilder inner = new StringBuilder();
for (String s : tmpInner) {
inner.append(s);
}
tmpOuter.add(new String(inner));
}
Collections.sort(tmpOuter);
Iterator<String> ite = tmpOuter.iterator();
if (ite.hasNext()) {
result += ite.next() + ",";
}
return result.substring(result.length() - 1);
}
protected void test(String problem, String expect) {
String expectSort = answerSort(expect);
Dahimi dahimi = new Dahimi();
String answer = dahimi.solve(problem);
String answerStr = answerSort(answer);
assertEquals(expectSort, answerStr);
}
@Test
public void testSolve() throws Exception {
/* #1 */test("DJ,", "-");
/* #2 */test("H7,HK", "HK");
/* #3 */test("S3,D4D2", "D4,D2");
/* #4 */test("S9,C8H4", "-");
/* #5 */test("S6,S7STCK", "CK,ST,S7");
/* #6 */test("H4,SAS8CKH6S4", "S8,CK,H6,SA");
/* #7 */test("ST,D6S8JoC7HQHAC2CK", "Jo,C2,CK,HA,HQ");
/* #8 */test("SA,HAD6S8S6D3C4H2C5D4CKHQS7D5", "H2");
/* #9 */test("S2,D8C9D6HQS7H4C6DTS5S6C7HAD4SQ", "-");
/* #10 */test("Jo,HAC8DJSJDTH2", "-");
/* #11 */test("S4Jo,CQS6C9DQH9S2D6S3", "DQCQ,D6S6,H9C9");
/* #12 */test("CTDT,S9C2D9D3JoC6DASJS4", "JoC2,SJJo,DAJo");
/* #13 */test("H3D3,DQS2D6H9HAHTD7S6S7Jo",
"JoHA,JoD6,JoH9,D6S6,D7S7,JoS6,HTJo,JoDQ,S2Jo,JoD7,JoS7");
/* #14 */test("D5Jo,CQDAH8C6C9DQH7S2SJCKH5", "CQDQ");
/* #15 */test("C7H7,S7CTH8D5HACQS8JoD6SJS5H4",
"HAJo,JoSJ,H8S8,H8Jo,CQJo,CTJo,JoS8");
/* #16 */test("SAHA,S7SKCTS3H9DJHJH7S5H2DKDQS4", "-");
/* #17 */test("JoC8,H6D7C5S9CQH9STDTCAD9S5DAS2CT",
"CTDT,H9D9,S9D9,DACA,CTST,H9S9,DTST");
/* #18 */test("HTST,SJHJDJCJJoS3D2",
"DJCJ,SJDJ,JoHJ,CJHJ,SJJo,HJSJ,DJJo,JoCJ,JoD2,SJCJ,DJHJ");
/* #19 */test("C7D7,S8D8JoCTDTD4CJ",
"D8S8,JoS8,CTJo,DTJo,JoCJ,CTDT,D8Jo");
/* #20 */test("DJSJ,DTDKDQHQJoC2", "JoDK,HQDQ,DQJo,C2Jo,JoHQ");
/* #21 */test("C3H3D3,CKH2DTD5H6S4CJS5C6H5S9CA", "S5H5D5");
/* #22 */test("D8H8S8,CQHJCJJoHQ", "JoCQHQ,JoHJCJ");
/* #23 */test("H6D6S6,H8S8D8C8JoD2H2",
"D2H2Jo,D8JoS8,D8S8C8,C8D8H8,JoC8S8,H8JoC8,S8H8C8,JoS8H8,C8JoD8,D8H8S8,D8JoH8");
/* #24 */test("JoD4H4,D3H3S3C3CADASAD2", "DACASA");
/* #25 */test("DJHJSJ,SQDQJoHQCQC2CA",
"SQJoCQ,DQCQJo,JoSQHQ,SQCQHQ,DQHQSQ,HQDQCQ,HQDQJo,SQDQCQ,CQJoHQ,SQJoDQ");
/* #26 */test("H3D3Jo,D4SKH6CTS8SAS2CQH4HAC5DADKD9", "HASADA");
/* #27 */test("C3JoH3D3,S2S3H7HQCACTC2CKC6S7H5C7", "-");
/* #28 */test("H5C5S5D5,C7S6D6C3H7HAH6H4C6HQC9", "C6D6S6H6");
/* #29 */test("H7S7C7D7,S5SAH5HAD5DAC5CA", "SADACAHA");
/* #30 */test(
"D4H4S4C4,S6SAH6HAD6DAC6CAJo",
"C6H6S6D6,SAJoDACA,S6H6C6Jo,SACAJoHA,HADASAJo,HADAJoCA,CADAHASA,D6C6JoH6,S6D6C6Jo,H6JoS6D6");
/* #31 */test("DTCTSTHT,S3SQH3HQD3DQC3CQJo",
"HQSQJoDQ,SQCQDQJo,DQCQHQJo,SQHQJoCQ,CQDQHQSQ");
/* #32 */test("JoS8D8H8,S9DTH9CTD9STC9CAC2", "H9C9D9S9");
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment