• Advanced set solution by mserrano
  • 5 years ago
  • Download | Raw
import java.util.*;
import java.io.*;

import java.math.BigInteger;

class CombinationGenerator {

  private int[] a;
  private int n;
  private int r;
  private BigInteger numLeft;
  private BigInteger total;

  //------------
  // Constructor
  //------------

  public CombinationGenerator (int n, int r) {
    if (r > n) {
      throw new IllegalArgumentException ();
    }
    if (n < 1) {
      throw new IllegalArgumentException ();
    }
    this.n = n;
    this.r = r;
    a = new int[r];
    BigInteger nFact = getFactorial (n);
    BigInteger rFact = getFactorial (r);
    BigInteger nminusrFact = getFactorial (n - r);
    total = nFact.divide (rFact.multiply (nminusrFact));
    reset ();
  }

  //------
  // Reset
  //------

  public void reset () {
    for (int i = 0; i < a.length; i++) {
      a[i] = i;
    }
    numLeft = new BigInteger (total.toString ());
  }

  //------------------------------------------------
  // Return number of combinations not yet generated
  //------------------------------------------------

  public BigInteger getNumLeft () {
    return numLeft;
  }

  //-----------------------------
  // Are there more combinations?
  //-----------------------------

  public boolean hasMore () {
    return numLeft.compareTo (BigInteger.ZERO) == 1;
  }

  //------------------------------------
  // Return total number of combinations
  //------------------------------------

  public BigInteger getTotal () {
    return total;
  }

  //------------------
  // Compute factorial
  //------------------

  private static BigInteger getFactorial (int n) {
    BigInteger fact = BigInteger.ONE;
    for (int i = n; i > 1; i--) {
      fact = fact.multiply (new BigInteger (Integer.toString (i)));
    }
    return fact;
  }

  //--------------------------------------------------------
  // Generate next combination (algorithm from Rosen p. 286)
  //--------------------------------------------------------

  public int[] getNext () {

    if (numLeft.equals (total)) {
      numLeft = numLeft.subtract (BigInteger.ONE);
      return a;
    }

    int i = r - 1;
    while (a[i] == n - r + i) {
      i--;
    }
    a[i] = a[i] + 1;
    for (int j = i + 1; j < r; j++) {
      a[j] = a[i] + j - i;
    }

    numLeft = numLeft.subtract (BigInteger.ONE);
    return a;

  }
}

public class THM {
    static class Hand {
        static class Card implements Comparable<Card> {
            enum Suit {
                HEARTS, DIAMONDS, CLUBS, SPADES
            }
            enum Rank {
                TWO, THREE, FOUR, FIVE, SIX, SEVEN, EIGHT, NINE,
                TEN, JACK, QUEEN, KING, ACE
            }

            public final Suit suit;
            public final Rank rank;

            public Card(String st) {
                char s = st.charAt(1);
                char r = st.charAt(0);
                switch (r) {
                    case '2': rank = Rank.TWO; break;
                    case '3': rank = Rank.THREE; break;
                    case '4': rank = Rank.FOUR; break;
                    case '5': rank = Rank.FIVE; break;
                    case '6': rank = Rank.SIX; break;
                    case '7': rank = Rank.SEVEN; break;
                    case '8': rank = Rank.EIGHT; break;
                    case '9': rank = Rank.NINE; break;
                    case 'T': rank = Rank.TEN; break;
                    case 'J': rank = Rank.JACK; break;
                    case 'Q': rank = Rank.QUEEN; break;
                    case 'K': rank = Rank.KING; break;
                    case 'A': rank = Rank.ACE; break;
                    default: System.out.println("Unknown rank " + r); rank = Rank.KING; System.exit(1); break;
                }
                switch (s) {
                    case 'd': suit = Suit.DIAMONDS; break;
                    case 'h': suit = Suit.HEARTS; break;
                    case 'c': suit = Suit.CLUBS; break;
                    case 's': suit = Suit.SPADES; break;
                    default: System.out.println("Unknown suit " + s); suit = Suit.SPADES; System.exit(1); break;
                }
            }

            public int compareTo(Card c) {
                return rank.compareTo(c.rank);
            }
        }
        private Card[] cards;
        public Hand(String v) {
            String[] cs = v.split(" ");
            cards = new Card[cs.length];
            for (int c = 0; c < cs.length; c++) {
                cards[c] = new Card(cs[c]);
            }
        }

        private static int getRank(List<Card> l) {
            Collections.sort(l);
            boolean isFlush = true;
            Card.Suit s = l.get(0).suit;
            for (Card c : l) {
                if (c.suit != s) { isFlush = false; break; }
            }
            boolean isStraight = false;
            boolean isLowStraight = false;
            boolean hasUniques = true;
            for (int i = 0; i < l.size() - 1; i++) {
                if (l.get(i).rank == l.get(i + 1).rank) { hasUniques = false; break; }
            }
            isStraight = hasUniques && (l.get(4).rank.ordinal() - l.get(0).rank.ordinal() == 4);
            if (    l.get(0).rank == Card.Rank.TWO &&
                    l.get(1).rank == Card.Rank.THREE &&
                    l.get(2).rank == Card.Rank.FOUR &&
                    l.get(3).rank == Card.Rank.FIVE &&
                    l.get(4).rank == Card.Rank.ACE) {
                isLowStraight = true;
//                System.out.println("Low straight!\n");
            }
            int mag = l.get(4).rank.ordinal();

            int[] count = new int[Card.Rank.ACE.ordinal() + 1];
            for (int i = 0; i < count.length; i++) count[i] = 0;
            for (Card c : l) {
                count[c.rank.ordinal()]++;
            }
            boolean isPair = false, isThree = false, isTwoPair = false, isFour = false;
            int twoPairMag, threeMag, fourMag, pairMag;
            twoPairMag = threeMag = fourMag = pairMag = 0;
            for (int i = 0; i < count.length; i++) {
                int c = count[i];
                if (c == 2) {
                    if (isPair) { isTwoPair = true; twoPairMag = i; }
                    else { isPair = true; pairMag = i;  }
                }
                else if (c == 3) { isThree = true; threeMag = i; }
                else if (c == 4) { isFour = true; fourMag = i; }
            }
            boolean isFullHouse = (isThree && isPair);
            if (isPair && pairMag == mag) { mag = l.get(2).rank.ordinal(); }
            if (isThree && threeMag == mag) { mag = l.get(1).rank.ordinal(); }
            if (isFour && fourMag == mag) { mag = l.get(0).rank.ordinal(); }

            if (isStraight && isFlush) {
                int base = 0x800000;
                for (int i = 0; i < l.size(); i++) {
                    base |= l.get(i).rank.ordinal() << (i * 4);
                }
                return base;
            }
            if (isLowStraight && isFlush) {
                int base = 0x800000;
                for (int i = 0; i < l.size() - 1; i++) {
                    base |= l.get(i).rank.ordinal() << ((i + 1) * 4);
                }
                base |= l.get(l.size() - 1).rank.ordinal();
                return base;
            }

            if (isFour) {
                int base = 0x700000;
                base |= mag;
                for (int i = 1; i <= 4; i++) {
                    base |= fourMag << (i * 4);
                }
                return base;
            }

            if (isFullHouse) {
                int base = 0x600000;
                for (int i = 0; i < 2; i++) {
                    base |= pairMag << (i * 4);
                }
                for (int i = 2; i < 5; i++) {
                    base |= threeMag << (i * 4);
                }
                return base;
            }

            if (isFlush) {
                int base = 0x500000;
                for (int i = 0; i < l.size(); i++) {
                    base |= l.get(i).rank.ordinal() << (i * 4);
                }
                return base;
            }

            if (isStraight) {
                int base = 0x400000;
                for (int i = 0; i < l.size(); i++) {
                    base |= l.get(i).rank.ordinal() << (i * 4);
                }
                return base;
            }
            if (isLowStraight) {
                int base = 0x400000;
                for (int i = 0; i < l.size() - 1; i++) {
                    base |= l.get(i).rank.ordinal() << ((i + 1) * 4);
                }
                base |= l.get(l.size() - 1).rank.ordinal();
                return base;
            }

            if (isThree) {
                int base = 0x300000;
                for (int i = 0, j = 0; i < l.size(); i++) {
                    int rn = l.get(i).rank.ordinal();
                    if (rn != threeMag) {
                        base |= rn << (j * 4);
                        j++;
                    }
                }
                for (int i = 2; i < 5; i++) {
                    base |= threeMag << (i * 4);
                }
                return base;
            }

            if (isTwoPair) {
                int base = 0x200000;
                for (int i = 0; i < l.size(); i++) {
                    int rn = l.get(i).rank.ordinal();
                    if (rn != pairMag && rn != twoPairMag) {
                        base |= rn;
                        break;
                    }
                }
                int smaller = (pairMag > twoPairMag) ? pairMag : twoPairMag;
                int larger = (pairMag == smaller) ? twoPairMag : pairMag;
                base |= (smaller << (1 * 4)) | (smaller << (2 * 4));
                base |= (larger << (3 * 4)) | (smaller << (4 * 4));
                return base;
            }

            if (isPair) {
                int base = 0x100000;
                for (int i = 0, j = 0; i < l.size(); i++) {
                    int rn = l.get(i).rank.ordinal();
                    if (rn != pairMag) {
                        base |= rn << (j << 2);
                        j++;
                        if (j == 3) break;
                    }
                }
                base |= (pairMag << (3 * 4)) | (pairMag << (4 * 4));
                return base;
            }

            int base = 0x000000;
            for (int i = 0; i < l.size(); i++) {
                base |= l.get(i).rank.ordinal() << (i << 2);
            }
            return base;
        }

        public int rank() {
            // okay. Generate all permutations.
            CombinationGenerator gen = 
                new CombinationGenerator(cards.length, 5);
            int bestRank = 0;
            while (gen.hasMore()) {
                List<Card> l = new ArrayList<Card>();
                int[] indices = gen.getNext();
                for (int index : indices) {
                    l.add(cards[index]);
                }
                int rank = getRank(l);
                if (rank > bestRank) bestRank = rank;
            }
            return bestRank;
        }
    }

    public static void main(String[] args) {
        Scanner console = new Scanner(System.in);
        int numCases = Integer.parseInt(console.nextLine());
        for (int c = 0; c < numCases; c++) {
            int numPlayers = Integer.parseInt(console.nextLine());
            String community = console.nextLine();
            String[] players = new String[numPlayers];
            for (int p = 0; p < numPlayers; p++)
                players[p] = console.nextLine();
            // okay
            for (int p = 0; p < numPlayers; p++) {
                players[p] = community + " " + players[p];
            }
            Hand[] hands = new Hand[numPlayers];
            int[] ranks = new int[numPlayers];
            int bestRank = 0;
            for (int p = 0; p < numPlayers; p++) {
                hands[p] = new Hand(players[p]);
                ranks[p] = hands[p].rank();
                if (ranks[p] > bestRank) bestRank = ranks[p];
            }
            String s = "";
            for (int p = 0; p < numPlayers; p++) {
                if (ranks[p] == bestRank)
                    s += p + " ";
            }
            s = s.substring(0, s.length() - 1);
            System.out.println(s);
        }
    }
}


Scoreboard

lzm bas adv bon 200
sirpengi bas adv bon 200
sixthgear bas adv bon 190
mserrano bas adv bon 190
robbinsr bas adv bon 190
synx bas adv bon 50

What do?

  1. Write your program according to the problem description
  2. Download the basic input set. The timer will start.
  3. Feed the input file to your program and save the output.
  4. Upload the output file along with your source code. If it is correct, you will receive points. If not you may try again until the timer expires.
  5. If the timer expires. You may try again, but a new input file will be generated.
  6. Repeat fot each set.

Note: The input sets use unix line endings (\n) and the verifier expects them as well.


Come Chat!

Join channel ##proggit on freenode.

Bugs

Having issues with the the site? Let us know.