// 6. hét – Halmaz logikai vektorral (és bitmaszkkal) ábrázolva
// Futtatás: java BitVectorSet.java
public class BitVectorSet {

    // Az alaphalmaz (univerzum): a hét napjai. A halmaz egy n hosszú logikai vektor:
    // in[i] igaz, ha az univerzum i-edik eleme benne van a halmazban.
    static final String[] DAYS = { "H", "K", "Sze", "Cs", "P", "Szo", "V" };
    final boolean[] in = new boolean[DAYS.length];

    static BitVectorSet of(int... idx) {
        BitVectorSet s = new BitVectorSet();
        for (int i : idx) s.in[i] = true;
        return s;
    }

    boolean contains(int i) { return in[i]; }   // eleme-e? – O(1)

    BitVectorSet union(BitVectorSet o) {          // O(|U|)
        BitVectorSet r = new BitVectorSet();
        for (int i = 0; i < in.length; i++) r.in[i] = in[i] || o.in[i];
        return r;
    }

    BitVectorSet intersection(BitVectorSet o) {
        BitVectorSet r = new BitVectorSet();
        for (int i = 0; i < in.length; i++) r.in[i] = in[i] && o.in[i];
        return r;
    }

    BitVectorSet difference(BitVectorSet o) {
        BitVectorSet r = new BitVectorSet();
        for (int i = 0; i < in.length; i++) r.in[i] = in[i] && !o.in[i];
        return r;
    }

    // Részhalmaza-e? A ⊆ B, ha nincs olyan elem, ami A-ban benne van, B-ben nincs.
    boolean subsetOf(BitVectorSet o) {
        for (int i = 0; i < in.length; i++) if (in[i] && !o.in[i]) return false;
        return true;
    }

    int size() {
        int c = 0;
        for (boolean b : in) if (b) c++;
        return c;
    }

    public String toString() {
        StringBuilder sb = new StringBuilder("{");
        for (int i = 0; i < in.length; i++) {
            if (in[i]) sb.append(sb.length() > 1 ? ", " : "").append(DAYS[i]);
        }
        return sb.append("}").toString();
    }

    // ----- Ugyanez bitmaszkkal: egy int i-edik bitje jelzi az i-edik elemet -----
    static String maskToString(int m) {
        StringBuilder sb = new StringBuilder("{");
        for (int i = 0; i < DAYS.length; i++) {
            if ((m & (1 << i)) != 0) sb.append(sb.length() > 1 ? ", " : "").append(DAYS[i]);
        }
        return sb.append("}").toString();
    }

    public static void main(String[] args) {
        BitVectorSet a = of(0, 2, 3, 5); // H, Sze, Cs, Szo
        BitVectorSet b = of(1, 2, 3);    // K, Sze, Cs
        System.out.println("A = " + a + ", B = " + b);
        System.out.println("A ∪ B = " + a.union(b));
        System.out.println("A ∩ B = " + a.intersection(b));
        System.out.println("A \\ B = " + a.difference(b));
        System.out.println("Sze ∈ A? " + a.contains(2) + ", |A| = " + a.size());
        System.out.println("A ∩ B ⊆ A? " + a.intersection(b).subsetOf(a));

        // Bitmaszk: egy gépi utasítás a teljes halmazműveletre (legfeljebb 32/64 elemű univerzum)
        int ma = 0b0101101; // H(0), Sze(2), Cs(3), Szo(5)
        int mb = 0b0001110; // K(1), Sze(2), Cs(3)
        System.out.println("\nBitmaszkkal:");
        System.out.println("A | B  = " + maskToString(ma | mb));
        System.out.println("A & B  = " + maskToString(ma & mb));
        System.out.println("A & ~B = " + maskToString(ma & ~mb));
        System.out.println("|A| = Integer.bitCount(A) = " + Integer.bitCount(ma));
        System.out.println("A ⊆ B? " + ((ma & ~mb) == 0));
    }
}
