与えた条件を満たす候補
Posted feedbacks - Java
起動パラメータで条件を与えます。 and and and を与えれば、出力は (true, true, true, true) となり、 not and not and not and not を与えると、 (false, false, false, false) になります。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 | public class Sample {
interface Command {
boolean operate(boolean org, boolean para);
}
private static Command[] cmd = new Command[4];
private Command[] exp = new Command[4];
private static final int AND = 0;
private static final int OR = 1;
private static final int NOT = 2;
static {
cmd[AND] = new Command() {
public boolean operate(boolean org, boolean para) {
return (org && para);
}
};
cmd[OR] = new Command() {
public boolean operate(boolean org, boolean para) {
return (org || para);
}
};
cmd[AND | NOT] = new Command() {
public boolean operate(boolean org, boolean para) {
return (org && !para);
}
};
cmd[OR | NOT] = new Command() {
public boolean operate(boolean org, boolean para) {
return (org || !para);
}
};
}
public Sample(String[] args) {
int lastCommand = AND;
int n = 0;
for (int i = 0; i < args.length; i++) {
if (args[i].equalsIgnoreCase("NOT")) {
lastCommand += NOT;
} else {
exp[n++] = cmd[lastCommand];
if (args[i].equalsIgnoreCase("AND")) {
lastCommand = AND;
} else if (args[i].equalsIgnoreCase("OR")) {
lastCommand = OR;
}
}
}
exp[n++] = cmd[lastCommand];
}
public boolean eval(boolean[] x) {
boolean val = true;
for (int i = 0; i < x.length; i++) {
val = exp[i].operate(val, x[i]);
}
return val;
}
public void work(boolean... x) {
if (eval(x)) {
System.out.printf("(%b, %b, %b, %b)%n", x[0], x[1], x[2], x[3]);
}
}
public static void main(String[] args) {
Sample s = new Sample(args);
for (int i = 0; i < 16; i++) {
s.work((i & 8) > 0, (i & 4) > 0, (i & 2) > 0, (i & 1) > 0);
}
}
}
|
だいぶ長くなってしまいましたけどJavaなのでその辺りは多めに見てもらって、ちゃんと対応版を書いてみました。 それと無駄に、enumやIteratorを使ってみました。
でも、eval関数が DRY原則に反してるのがイケてない・・・。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 | import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
public class Answer43 {
public enum BoolOperator {
not(1) {
@Override
public boolean operate(boolean... bs) {
return !bs[0];
}
},
and(2) {
@Override
public boolean operate(boolean... bs) {
return bs[0] && bs[1];
}
},
or(2) {
@Override
public boolean operate(boolean... bs) {
return bs[0] || bs[1];
}
};
private int count_;
private BoolOperator(int count) {
count_ = count;
}
public int operateCount() {
return count_;
}
public abstract boolean operate(boolean... bs);
}
public static class BooleanArrayIterator implements Iterator<boolean[]> {
private long counter_;
private final int arrayLength_;
public BooleanArrayIterator(int arrayLength) {
arrayLength_ = arrayLength;
counter_ = (long) (Math.pow(2, arrayLength) - 1);
}
public boolean hasNext() {
return counter_ > 0;
}
public boolean[] next() {
boolean[] bs = new boolean[arrayLength_];
for (int index = 0; index < arrayLength_; index++) {
bs[index] = (counter_ & (1 << index)) > 0;
}
counter_--;
return bs;
}
public void remove() {
throw new UnsupportedOperationException();
}
}
public static List<boolean[]> searchTrueList(BoolOperator[] boolOperators) {
if (boolOperators.length == 0) return new ArrayList<boolean[]>();
int resultLength = getResultLength(boolOperators);
BooleanArrayIterator iterator = new BooleanArrayIterator(resultLength);
List<boolean[]> result = new ArrayList<boolean[]>();
while (iterator.hasNext()) {
boolean[] bs = iterator.next();
if (eval(boolOperators, bs)) {
result.add(bs);
}
}
return result;
}
private static int getResultLength(BoolOperator[] boolOperators) {
int length = 1;
for (BoolOperator op: boolOperators) {
length += (op.operateCount() - 1);
}
return length;
}
private static boolean eval(BoolOperator[] boolOperators, boolean[] bs) {
int index = 0;
boolean result = bs[0];
BoolOperator op = boolOperators[index];
if (op.operateCount() == 1) {
while (index < boolOperators.length - 1) {
BoolOperator opNext = boolOperators[++index];
if (opNext.operateCount() > 1) break;
result = opNext.operate(result);
}
result = op.operate(result);
}
for (int bIndex = 1; bIndex < bs.length; bIndex++) {
boolean x = bs[bIndex];
op = boolOperators[index];
while (index < boolOperators.length - 1) {
BoolOperator opNext = boolOperators[++index];
if (opNext.operateCount() > 1) break;
x = opNext.operate(x);
}
result = op.operate(result, x);
}
return result;
}
public static void print(String... args) {
List<BoolOperator> ops = new ArrayList<BoolOperator>();
for (String str: args) {
try {
BoolOperator op = BoolOperator.valueOf(str);
ops.add(op);
} catch (IllegalArgumentException ex) {
}
System.out.print(str);
System.out.print(", ");
}
System.out.println();
List<boolean[]> result = searchTrueList(ops.toArray(new BoolOperator[0]));
for (boolean[] bs: result) {
System.out.print('(');
for (int index = 0; index < bs.length; index++) {
if (index > 0) System.out.print(", ");
System.out.print(bs[index]);
}
System.out.print(')');
System.out.println();
}
System.out.println();
}
public static void main(String[] args) {
print("and");
print("or");
print("not");
print("not", "not");
print("not", "not", "not");
print("and", "or", "not", "and");
}
}
|


にしお
#3399()
Rating0/0=0.00
元ネタの 充足可能性問題 - Wikipedia は、 同じリテラル(x1とかnot x2とか)が複数回出てくることを想定しているので、 今回の問題のようにそれぞれ別の変数でだと乗法標準形 - Wikipediaにした場合に、答えが…と色々悩みどころでした。
[ reply ]