📄 calc24.java
字号:
/*
By qjpseu
yahqjp@yahoo.com.cn
/j 可以选择是否交换运算参数顺序(不同顺序的加法或乘法)
/k 可以选择是否根据运算符号的前后关系确定是否添加括号
/s 可以选择随机产生四个数字
自动排除重复的计算表达式
*/
import java.text.NumberFormat;
import java.text.ParseException;
import java.io.IOException;
public class calc24 {
public calc24() {
exg = prn = false;
}
public boolean input() {
System.out.print(getHead());
for (int i = 0; i < 4; ) {
System.out.print(getPrompt(i));
byte bytes[] = new byte[16];
try {
System.in.read(bytes, 0, 16);
String s = new String(bytes);
for (int l = 0; l >= 0; ) {
s = s.trim();
try {
NumberFormat nf = NumberFormat.getNumberInstance();
idata[i] = nf.parse(s).intValue();
if (i < 4 && (idata[i] < 1 || idata[i] > 13)){
System.out.print("无效输入!\n" + getHead());
for (int j = 0; j < i; j++)
System.out.println(getPrompt(i) + idata[j]);
}
else i++;
} catch (ParseException e) {
if (s.isEmpty()) return false;
if (s.charAt(0) == '/') {
char c = (char)(s.charAt(1) | ('a' ^ 'A'));
if (c == 's')
while (i < 4) System.out.println(idata[i++] = (int)(Math.random() * 13) + 1);
else if (c == 'j') exg ^= true;
else if (c == 'k') prn ^= true;
}
}
if ((l = s.indexOf(' ')) > 0) s = s.substring(l);
}
} catch (IOException e) {
e.printStackTrace();
return false;
}
}
return true;
}
public void calcAll() {
float df[] = new float[4];
String ds[] = new String[4]; //float and string to hold the current array and extra two data of d1,d0
hold = "";
cnt[0] = cnt[1] = 0;
for (int m = 6; m-- > 0; calcNested(3, -(m < 3 ? 1 : 0) - 1, -1, df, df[3], ds, ds[3])) //create 6 arrays from 4 data
for (int i = 4, j; i-- > 0; df[i] = (float)j, ds[i] = String.valueOf(j)) {
j = idata[(m + (m > 4 ? 1 : 0) + i) % 4 ^ (((m % 5 > 0) || ((m == 0) ^ (i % 3 > 0))) ? 0 : 3)]; //j=(0,1,2,3,1,0), then shift and swap data: m==0,swap(d1,d2); m==5,swap(d0,d3)
}
System.out.print("\n总共" + cnt[0] + "种算法, 其中有" + cnt[1] + "种不同的算式:\n" + hold + "(Solutions: " + cnt[1] + "/" + cnt[0] + ")\n");
}
private float calc(int plr, int j, float x, float y) {
return plr > 0 ? calc(0, j, y, x) : j == 0 ? x + y : j == 1 ? x - y : j == 2 ? x * y : (float)(y == 0.0 ? 1e9 : (x / y));
}
private void calcNested(int n, int op1, int op2, float[] dt, float da, String[] ds, String dc) {
n--;
for (int j = 4; j-- > 0; )
for (int i = (exg || (j & 1) > 0) ? 2 : 1; i-- > 0; ) {
float f = calc(i, j, dt[n], da);
String s = expr(i, j, ds[n], dc, op1, op2);
if (n == 2) {
for (int k = (-op1 & 2) << 1; k-- > 0; ) //d0+d1,d1+d0; d0-d1,d1-d0; d0xd1,d1xd0; d0/d1,d1/d0
for (int m = (exg || (k & 1) > 0) ? 2 : 1; m-- > 0; ) //swap 2 pairs: (axb)x(cxd)=>(cxd)x(axb)
calcNested(1, k, j, new float[] { calc(m, k, dt[0], dt[1]) }, f, new String[] { expr(m, k, ds[0], ds[1], -1, -1) }, s); //j,k;dt,da;ds,dc swaped
calcNested(2, -1, j, new float[] { dt[1], dt[0] }, f, new String[] { ds[1], ds[0] }, s); //swap(dt[0],dt[1]); swap(ds[0],ds[1]);
}
if (n > 0) calcNested(n, -1, j, dt, f, ds, s);
else if (f == 24) {
cnt[0]++;
if (hold.indexOf(s) < 0) {
cnt[1]++;
hold += s + "\n";
}
}
}
}
private String getHead() {
final String onoff[] = { "开启", "关闭" }, state[] = { "尽量少", "尽量多" };
return "\n当前状态:\n\t交换顺序 -- " + state[exg ? 1 : 0] + ".\n\t添加括号 -- " + state[prn ? 1 : 0]
+ ".\n选项开关:\n\t/j -- 用于\"" + onoff[exg ? 1 : 0] + "\"参数的前后顺序交换开关!\n\t/k -- 用于\"" + onoff[prn ? 1 : 0]
+ "\"括号添加开关!\n\t/s -- 自动输入四个随机数!\n请输入选项或4个数字(可以在一行内输入以空格分隔的所有数据).\n";
}
private String getPrompt(int i) {
return "选项或第" + (char)('1' + i) + "个数字(1-13): ";
}
private String lr(int plr, int pos, int opC, int opP) {
return parenthese[(opP >= 0 && (prn || (((opC + plr) > 1) && (opP < 2)) || (plr > 0 && (opC > 2)))) ? pos + 1 : 0];
}
private String expr(int plr, int op0, String d1, String d2, int op1, int op2) { //calculation expression
String c = "", c7[] ={ lr(plr, 0, op0, op1), d1, lr(plr, 1, op0, op1), cs[op0], lr(plr ^ 1, 0, op0, op2), d2, lr(plr ^ 1, 1, op0, op2) };
for (int k = 0; k < 7; c += c7[(k + ((plr > 0 && (k != 3)) ? 4 : 0)) % 8], k++) ;
return c; //(a)x(b) or (b)x(a)
}
private boolean exg, prn; //exg=0:3240 calculations, exg=1:7680 calculations
private int idata[] = new int[4], cnt[] = new int[2]; //count of calculations
private String hold; //string to hold the calculation expressions
private static String cs[] = { " + ", " - ", " * ", " / " }, parenthese[] = { "", "(", ")" }; //plr=parenthese(0_1)=>[left,right], position(0_1), opCurr +-*/, opPrev +-*/
public static void main(String[] args) {
calc24 c = new calc24();
while (c.input())
c.calcAll();
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -