学籍番号の末尾4個の数字を,順序を変えずに使用する
演算記号は,四則演算(+, -, *, /) と括弧のみを使用する
除算は最終的に,割り切れなければならない
0〜20の整数作成を目指す
例
0 = 201 * 0
1 = 2 - 01 + 0
2 = 20 / 10
3 = 2 + 01 + 0
8 = -2 + 010
10 = 20 - 10
12 = 2 + 010
19 = 20 - 1 + 0
20 = 2 * 010
他はできない
Digit count:
4
Digit data(ex. 2 0 1 0):
2
0
1
0
All Expressions Count: 5936
0 = ( 2 * ( 0 * ( 1 + 0 ) ) ) [1188 patterns]
1 = ( 2 - ( 0 + ( 1 + 0 ) ) ) [240 patterns]
2 = ( 2 * ( 0 + ( 1 + 0 ) ) ) [730 patterns]
3 = ( 2 + ( 0 + ( 1 + 0 ) ) ) [176 patterns]
4 = (Impossible)
5 = (Impossible)
6 = (Impossible)
7 = (Impossible)
8 = ( (-2) + ( 0 + 10 ) ) [18 patterns]
9 = (Impossible)
10 = ( ( 2 * 0 ) + 10 ) [10 patterns]
11 = (Impossible)
12 = ( 2 + ( 0 + 10 ) ) [18 patterns]
13 = (Impossible)
14 = (Impossible)
15 = (Impossible)
16 = (Impossible)
17 = (Impossible)
18 = (Impossible)
19 = ( 20 - ( 1 + 0 ) ) [16 patterns]
20 = ( 20 * ( 1 + 0 ) ) [58 patterns]
import java.io.IOException;
import java.util.ArrayDeque;
import java.util.ArrayList;
import java.util.Deque;
import java.util.List;
import java.util.Scanner;
public class AlgoTask {
private static int PRINT_MIN = 0;
private static int PRINT_MAX = 20;
private static class Entry {
private double result;
private String expr;
public Entry(double result, String expr) {
this.result = result;
this.expr = expr;
}
public Entry(int i) {
this.result = i;
this.expr = String.valueOf(i);
}
public Entry connect(Entry rh) {
return new Entry(result * 10 + rh.result, expr + rh.expr);
}
public Entry negative() {
return new Entry(-result, "(-" + expr + ")");
}
public Entry add(Entry rh) {
return new Entry(result + rh.result, "( " + expr + " + " + rh.expr
+ " )");
}
public Entry sub(Entry rh) {
return new Entry(result - rh.result, "( " + expr + " - " + rh.expr
+ " )");
}
public Entry mul(Entry rh) {
return new Entry(result * rh.result, "( " + expr + " * " + rh.expr
+ " )");
}
public Entry div(Entry rh) {
return new Entry(result / rh.result, "( " + expr + " / " + rh.expr
+ " )");
}
@Override
public String toString() {
return result + ": " + expr;
}
}
ビット列の中から1の数を返す。
@param bits
@return
private static int count1(int bits) {
int count = 0;
while (bits != 0) {
if ((bits & 0x1) == 0x1) {
count++;
}
bits >>>= 1;
}
return count;
}
数列に対してスタック命令列を試す。
@param nums
@param insts
@return
private static List<Entry> processInsts(List<Entry> nums, int insts) {
Deque<Entry> input = new ArrayDeque<Entry>(nums);
Deque<List<Entry>> stack = new ArrayDeque<List<Entry>>();
int instsLen = nums.size() * 2 - 1;
for (int i = 0; i < instsLen; i++) {
boolean inst = (insts & 0x01) == 0x01;
insts >>>= 1;
if (inst) {
Entry in = input.removeFirst();
List<Entry> list = new ArrayList<Entry>();
list.add(in);
list.add(in.negative());
stack.push(list);
} else {
if (stack.size() < 2) {
return new ArrayList<Entry>();
}
List<Entry> rh = stack.pop();
List<Entry> lh = stack.pop();
List<Entry> popResult = new ArrayList<Entry>();
for (Entry re : rh) {
for (Entry le : lh) {
popResult.add(le.add(re));
popResult.add(le.sub(re));
popResult.add(le.mul(re));
popResult.add(le.div(re));
}
}
stack.push(popResult);
}
}
return stack.pop();
}
数字のあらゆる連結方法を試す。
@param digits
private static void tryNumbers(List<Integer> digits) {
List<Entry> result = new ArrayList<Entry>();
int patternLen = digits.size() - 1;
for (int pat = 0; pat < (1 << patternLen); pat++) {
List<Entry> nums = new ArrayList<Entry>();
nums.add(new Entry(digits.get(0)));
for (int i = 1; i < digits.size(); i++) {
if ((pat >>> (i - 1) & 0x1) == 0) {
nums.add(new Entry(digits.get(i)));
} else {
Entry last = nums.remove(nums.size() - 1);
nums.add(last.connect(new Entry(digits.get(i))));
}
}
int instsLen = nums.size() * 2 - 1;
for (int i = 0; i < (1 << instsLen) - 1; i++) {
if (count1(i) == nums.size()) {
result.addAll(processInsts(nums, i));
}
}
}
System.out.printf("All Expressions Count: %d%n", result.size());
for (int i = PRINT_MIN; i <= PRINT_MAX; i++) {
int find = 0;
String example = null;
for (Entry e : result) {
if (Math.abs(e.result - i) < 1e-10) {
find++;
if (example == null) {
example = e.expr;
}
}
}
if (example == null) {
System.out.printf("%4d = (Impossible)%n", i);
} else {
System.out.printf("%4d = %s [%d patterns]%n", i, example, find);
}
}
}
public static void main(String[] args) throws IOException {
Scanner in = new Scanner(System.in);
System.out.println("Digit count: ");
int count = in.nextInt();
System.out.println(count);
List<Integer> digits = new ArrayList<Integer>();
System.out.println("Digit data(ex. 2 0 1 0): ");
for (int i = 0; i < count; i++) {
int digit = in.nextInt();
System.out.println(digit);
if (digit < 0 || digit > 9)
throw new RuntimeException("Digit must be 0<=d<=9.");
digits.add(digit);
}
tryNumbers(digits);
}
}