import
java.util.HashMap;
import
java.util.Stack;
public
class
SingleDigit {
static
int
LIMIT =
10
;
static
HashMap<Integer, Integer> seen
=
new
HashMap<Integer, Integer>();
static
Stack<Character> operators
=
new
Stack<Character>();
static
int
minimum = LIMIT;
static
void
minLevel(
int
total,
int
N,
int
D,
int
level)
{
if
(total == N) {
minimum = Math.min(minimum, level);
return
;
}
if
(level == minimum)
return
;
if
(total % D ==
0
)
minLevel(total / D, N, D, level +
1
);
minLevel(total + D, N, D, level +
1
);
if
(total - D >
0
)
minLevel(total - D, N, D, level +
1
);
minLevel(total * D, N, D, level +
1
);
}
static
boolean
generate(
int
total,
int
N,
int
D,
int
level)
{
if
(total == N)
return
true
;
if
(level == minimum)
return
false
;
if
((seen.containsKey(total)
&& seen.get(total) >= level)
|| !seen.containsKey(total)) {
seen.put(total, level);
int
divide = Integer.MAX_VALUE;
if
(total % D ==
0
) {
divide = total / D;
if
(seen.containsKey(divide))
seen.put(divide, level +
1
);
}
int
addition = total + D;
if
(seen.containsKey(addition))
seen.put(addition, level +
1
);
int
subtraction = Integer.MAX_VALUE;
if
(total - D >
0
) {
subtraction = total - D;
if
(seen.containsKey(subtraction))
seen.put(subtraction, level +
1
);
}
int
multiply = total * D;
if
(seen.containsKey(multiply))
seen.put(multiply, level +
1
);
;
if
(divide != Integer.MAX_VALUE)
if
(generate(divide, N, D, level +
1
)) {
operators.push(
'/'
);
return
true
;
}
if
(generate(addition, N, D, level +
1
)) {
operators.push(
'+'
);
return
true
;
}
if
(subtraction != Integer.MAX_VALUE)
if
(generate(subtraction, N, D,
level +
1
)) {
operators.push(
'-'
);
return
true
;
}
if
(generate(multiply, N, D, level +
1
)) {
operators.push(
'*'
);
return
true
;
}
}
return
false
;
}
static
void
printExpression(
int
N,
int
D)
{
minLevel(D, N, D,
1
);
if
(generate(D, N, D,
1
)) {
String expression =
""
;
if
(!operators.empty()) {
expression = Integer.toString(D)
+ operators.peek();
operators.pop();
}
while
(!operators.empty()) {
if
(operators.peek() ==
'/'
|| operators.peek() ==
'*'
)
expression =
"("
+ expression
+ Integer.toString(D) +
")"
+ operators.peek();
else
expression = expression
+ Integer.toString(D)
+ operators.peek();
operators.pop();
}
expression = expression + Integer.toString(D);
System.out.println(
"Expression: "
+ expression);
}
else
System.out.println(
"Expression not found!"
);
}
public
static
void
main(String[] args)
{
int
N =
7
, D =
4
;
printExpression(N, D);
minimum = LIMIT;
printExpression(
100
,
7
);
minimum = LIMIT;
printExpression(
200
,
9
);
}
}