It's a poker game with bluetooth and I encounter some difficulties to redistribute the side pots. Does someone have any experiences with that?
for(int k = 0; k < numberOfPlayer; k++)
{
canWinSidePotUpTo[k] = -1;
}
for(int i = 0 ; i < sidePot.size(); i++) {
if (sideTempToRaiseListSorted.get(i) != sideTempToRaiseListSorted.get(i + 1)) {
for (int k = 0; k < numberOfPlayer; k++) {
print("All in ToRaiseList[" + k + "] = " + toRaiseList[k]);
print("All in TempToRaise[" + k + "] = " + tempToRaise[k]);
if (sideTempToRaiseListSorted.get(i) == max(toRaiseList) - max(tempToRaise)) {
continue;
}
if (sideTempToRaiseListSorted.get(i) == (toRaiseList[k] - tempToRaise[k])) {
canWinSidePotUpTo[k] = j;
}
if (sideTempToRaiseListSorted.get(i + 1) == (toRaiseList[k] - tempToRaise[k])) {
canWinSidePotUpTo[k] = j;
}
print("All In canWinSidePotUpTo[" + k + "] " + canWinSidePotUpTo[k] + " + i = " + i);
}
print("All In sideTempToRaiseListSorted.get(" + i + ") " + sideTempToRaiseListSorted.get(i) + " + i = " + i);
print("All In sideTempToRaiseListSorted.get(" + (i + 1) + ") " + sideTempToRaiseListSorted.get(i + 1) + " + i + 1 = " + i + 1);
}
j++;
}
The expected result is to be able to set the array canWinSidePotUpTo[player]
for each player.
The side pot start at index 0 and if the player can win only the pot then canWinSidePotUpTo[player] = -1. All player which are allin have canWinSidePotUpTo[player] = -1 and then canWinSidePotUpTo[player] should be set according to the stack at allin...
the actual result is:
All In canWinSidePotUpTo[0] -1 + i = 1
All In canWinSidePotUpTo[1] 1 + i = 1
All In canWinSidePotUpTo[2] 1 + i = 1
All In canWinSidePotUpTo[3] -1 + i = 1
That the result for:
player:hand:stack allin
0:AA:900
1:KK:1100
2:QQ:1300
3:JJ:1500
pot = 3600
sidepot(0)= 600
sidepot(1) = 400
Flop:AKQJ9
Any help would be welcome!
In software, I think it's simpler to do it in the opposite order from how a live-game dealer would. In a casino, the side-pots are awarded first, then the main--mainly because the pots are consolidated during betting and sometimes that's the only way to do it.
But in software, you can keep track during betting of each player's total contribution to the pot, including antes and blinds, as the betting happens. You don't have to calculate it after-the-fact. So to award the pots, then, you just start with the best hand. Award him his contribution, plus up to that amount from each of the other players, then remove him (and any other players with no contribution left) from the list. Then repeat: find the best remaining hand, award him his remaining contribution plus up to that amount from each of the others, then remove from list, etc.
I've been answering a variety of these questions, because often they come with clues and nothing super concrete. If you'd like to see the algorithm I wrote, assuming you still care, I'm linking to the code here:
https://dotnetfiddle.net/P0wgR5
It doesn't care about bets, it's at the point where everyone's committment has been tallied and it's time to distribute to the winners. It handles folded hands, all-ins/overbets, and I haven't found a bug yet.
Related
I need to print the factors of a perfect number. Here's the gist of my main class:
ArrayList<Integer> perfNums = new ArrayList<>();
Scanner in = new Scanner(System.in);
System.out.print("Enter the upperbound: ");
upperbound = in.nextInt();
for (int i = 1; i <= upperbound; i++) {
if (isPerfect(i)) { //boolean to check if number is a perfect number
perfNums.add(i);
}
}
System.out.println("Perfect numbers between 1 and " + upperbound + " are:");
for (int i = 0; i < perfNums.size(); i++) {
System.out.print(perfNums.get(i) + " = ");
printFactor((int)perfNums.get(i));
System.out.println();
}
Here's the printFactor class.
private static void printFactor(int number){
int factor = 1;
while(factor < number){
if (number%factor == 0) System.out.print(factor+ " + ");
//I don't know how to print the + sign otherwise.
factor++;
}
}
And here's a sample output:
Enter the upperbound: 10000
Perfect numbers between 1 and 10000 are:
6 = 1 + 2 + 3 +
28 = 1 + 2 + 4 + 7 + 14 +
496 = 1 + 2 + 4 + 8 + 16 + 31 + 62 + 124 + 248 +
8128 = 1 + 2 + 4 + 8 + 16 + 32 + 64 + 127 + 254 + 508 + 1016 + 2032 + 4064 +
I've got the main gist of it but I've struggled with an output issue. Due to the restrictions of my online submission system, my output needs to fit exact specifications.
My question is how do I go about printing all the factors of my perfect number but removing the + sign at the end? (e.g)6 = 1 + 2 + 3
I'm not too sure of many methods to print from a while loop. Would a for-loop be better for my goals? Or are there alternative methods to print the factors of a number?
The least amount of change to address this might be something like this:
private static void printFactor(int number)
System.out.print(1);
int factor = 2;
while (factor<number) {
if (number%factor == 0) System.out.print(" + " + factor);
factor++;
}
}
1 is always a factor, so you can print that before the loop and then prepend + to every subsequent factor.
You should cache the output you want to print into a StringBuilder. Then you are able to remove the last plus sign before you print the whole String. It also has a better performance.
private static void printFactor(int number)
{
StringBuilder output = new StringBuilder();
int factor = 1;
while (factor < number)
{
if (number % factor == 0)
output.append(factor + " + ");
factor++;
}
// remove last plus sign
output.deleteCharAt(output.length() - 1);
// print the whole string
System.out.print(output.toString());
}
Since factor starts from value 1 and number % 1 == 0 will always be true, you might print 1 first and then flip factor and + in System.out.print. Like this:
private static void printFactor(int number) {
if(number > 0) {
System.out.print(1);
}
int factor = 2;
while (factor<number) {
if (number % factor == 0) {
System.out.print(" + " + factor);
}
factor++;
}
}
Not the best solution, but it will do the job.
Try to create a variable String numb and use substring method like this:
String numb ="";
while(factor<number){
if(number%factor == 0)
numb= numb + factor+ " + ";
factor++;
}
System.out.print(numb.substring(0, numb.trim().length()-1));
Just for the sake of using Java 8 :)
private static void printFactor(int number){
System.out.println(IntStream.range(1, number)
.filter(p -> number % p == 0)
.mapToObj(i -> String.valueOf(i))
.collect(Collectors.joining(" + ")));
}
Thanks everyone for the quick response. You all have been a lifesaver, and I managed to pick up some new things to consider when I code in the future.
Anyway, while waiting for a reply I was fiddling with the code and came up with a rather inelegant solution, if anybody's interested. Here's the changes to the main class:
System.out.println("Perfect numbers between 1 and " + upperbound + " are:");
for(int i=0; i<perfNums.size(); i++){
System.out.print(perfNums.get(i) + " = ");
outputString = printFactor2(perfNums.get(i));
if(outStr.endsWith(" + ")) outStr = outStr.substring(0, outStr.length()-3);
//because the submission system would cry foul with even a single extra space
System.out.println(outStr);
}
And here's the changes to the printFactor class:
private static String printFactor2(int number){
String out = "";
int factor = 1;
while(factor<number){
if(number%factor == 0) out += factor + " + ";
factor++;
}
return out;
}
Basically, what I did was append the factors to a string, then removing the trailing + sign using the substring method. On hindsight, I probably should've called the substring method inside the printFactor class instead. Something like return out.substring(0, out.length()-3); perhaps?
Nevertheless, thanks everyone!
I know my code can be simpler and more efficient... My code is supposed to grab the biggest set of 5 digits. It works, except it only is grabbing 3 digits, what would i need to modify to change that?
public class thousandDigits {
public static void main(String[] args) {
int greatest = 0;
String num = ("73167176531330624919225119674426574742355349194934"
+ "96983520312774506326239578318016984801869478851843"
+ "85861560789112949495459501737958331952853208805511"
+ "12540698747158523863050715693290963295227443043557"
+ "66896648950445244523161731856403098711121722383113"
+ "62229893423380308135336276614282806444486645238749"
+ "30358907296290491560440772390713810515859307960866"
+ "70172427121883998797908792274921901699720888093776"
+ "65727333001053367881220235421809751254540594752243"
+ "52584907711670556013604839586446706324415722155397"
+ "53697817977846174064955149290862569321978468622482"
+ "83972241375657056057490261407972968652414535100474"
+ "82166370484403199890008895243450658541227588666881"
+ "16427171479924442928230863465674813919123162824586"
+ "17866458359124566529476545682848912883142607690042"
+ "24219022671055626321111109370544217506941658960408"
+ "07198403850962455444362981230987879927244284909188"
+ "84580156166097919133875499200524063689912560717606"
+ "05886116467109405077541002256983155200055935729725"
+ "71636269561882670428252483600823257530420752963450");
for (int n = 0; n < num.length() - 5; n++) {
greatest = ((num.charAt(n)) + (num.charAt(n+1)) + (num.charAt(n+2)) + (num.charAt(n+3))
+ (num.charAt(n+4)));
if (greatest > n) {
n = greatest;
}
}
System.out.print(greatest);
}
}
OUTPUT:
357
I think you want to use String.substring(int, int) to iterate all possible 5 character substrings, and then you might use Math.max(int, int) to update greatest. Something like
int greatest = Integer.MIN_VALUE;
for (int i = 0; i < num.length() - 4; i++) {
// int value = Integer.parseInt(num.substring(i, i + 5));
int value = Integer.parseInt(String.valueOf(num.charAt(i))
+ num.charAt(1 + i) + num.charAt(2 + i) + num.charAt(3 + i)
+ num.charAt(4 + i));
greatest = Math.max(greatest, value);
}
System.out.println(greatest);
I get 99890.
I think you are trying to add 5 consecutive characters to get sum, and store starting index of highest sum.
But you should be using Character.getNumricValue(char) to convert (num.charAt(n)) to numeric value and then add.
greatest = Character.getNumericValue((num.charAt(n)) + Character.getNumericValue((num.charAt(n+1)) + Character.getNumericValue((num.charAt(n+2)) +
Character.getNumericValue((num.charAt(n+3)) +
Character.getNumericValue((num.charAt(n+4));
You need a valirable to store old value to compare and index
if(greatest > oldGreatest) {
index = n;
}
Then finally print using index out side loop:
System.out.print((num.charAt(index)) + (num.charAt(index+1) + (num.charAt(index +2)) + (num.charAt(index +3)) + (num.charAt(index +)));
Although #ElliottFrisch and #dave provides more elegant answer, I tried to modify from your original version and here is my code (I have tested it):
public class ThousandDigits {
public static void main(String[] args) {
int greatest = 0;
String num = ("73167176531330624919225119674426574742355349194934"
+ "96983520312774506326239578318016984801869478851843"
+ "85861560789112949495459501737958331952853208805511"
+ "12540698747158523863050715693290963295227443043557"
+ "66896648950445244523161731856403098711121722383113"
+ "62229893423380308135336276614282806444486645238749"
+ "30358907296290491560440772390713810515859307960866"
+ "70172427121883998797908792274921901699720888093776"
+ "65727333001053367881220235421809751254540594752243"
+ "52584907711670556013604839586446706324415722155397"
+ "53697817977846174064955149290862569321978468622482"
+ "83972241375657056057490261407972968652414535100474"
+ "82166370484403199890008895243450658541227588666881"
+ "16427171479924442928230863465674813919123162824586"
+ "17866458359124566529476545682848912883142607690042"
+ "24219022671055626321111109370544217506941658960408"
+ "07198403850962455444362981230987879927244284909188"
+ "84580156166097919133875499200524063689912560717606"
+ "05886116467109405077541002256983155200055935729725"
+ "71636269561882670428252483600823257530420752963450");
int max = -1;
for (int n = 0; n < num.length() - 4; n++) {
greatest = ((num.charAt(n) - '0') * 10000 + (num.charAt(n + 1) - '0') * 1000
+ (num.charAt(n + 2) - '0') * 100 + (num.charAt(n + 3) - '0') * 10 + (num.charAt(n + 4) - '0'));
if (max < greatest) {
max = greatest;
}
}
System.out.print(max);
}
}
I think you'll find it's not grabbing three digits, but rather the sum of the six characters you are pulling out is a 3-digit number.
If you're after the largest five digit number, you need to extract five digits (not six) as you do and assign them a weight. So the first digit must be multiplied by 10,000, the second by 1,000 and so on.
But there's more: you're are getting the character at an index within your string. This is not what you want as it is not the same as the numeric value of that character. For that you need:
num.charAt(n) - '0'
These changes should allow you to correct your algorithm as it stands.
A more efficient approach would be to extract 5-digit sub-strings and convert them to integers. The first one would be:
Integer.parseInt(num.subString(0, 5));
You can iterate to get each one to find the greatest.
This is the question:
There are N boys and N girls. Only a boy and a girl can form a dancing pair (i.e. no same sex dancing pairs are allowed). The only other condition in making pairs is that their absolute difference in height should be less than or equal to K.
Find the maximum number of pairs that can be formed so that everyone has a unique partner.
I want to improve my algorithm to take less time..
first see the code:
//k is the maximum difference between pairs
int k = 5;
ArrayList<Integer> ArrBoys = new ArrayList<>(Arrays.asList(new Integer[]{28, 16, 22}));
ArrayList<Integer> ArrGirls = new ArrayList<>(Arrays.asList(new Integer[]{13, 10, 14}));
//sorting all arrays
Collections.sort(ArrBoys);
Collections.sort(ArrGirls);
System.out.println("After Sorting");
//printing arrays after sorting
for (Integer ArrBoy : ArrBoys) {
System.out.print(ArrBoy + " ");
}
System.out.println("");
for (Integer ArrGirl : ArrGirls) {
System.out.print(ArrGirl + " ");
}
System.out.println("");
//algorithm used to find the number of pairs
int count = 0;
for (Iterator<Integer> iteB = ArrBoys.iterator(); iteB.hasNext();) {
Integer ArrBoy = iteB.next();
for (Iterator<Integer> iteG = ArrGirls.iterator(); iteG.hasNext();) {
{
Integer ArrGirl = iteG.next();
int dif = (int) Math.abs(ArrBoy - ArrGirl);
if (dif <= k) {
System.out.println("we took " + ArrBoy + " from boys with "
+ ArrGirl + " from girls, thier dif < " + k);
ArrBoys.remove(ArrBoy);
ArrGirls.remove(ArrGirl);
iteB = ArrBoys.iterator();
count++;
break;
} else {
System.out.println("we try " + ArrBoy + " from boys with " + ArrGirl + " from grils but thier dif > " + (int) k);
//ArrGirls.remove(ArrGirl);
}
}
}
}
System.out.println("the number of pairs we can take is "+count);
the output of this code is:
As you see this algorithm inefficient since we don't need to start comparing the height from the first girl for the second boy, we should go to the girl which come after the previous girl we took as pair.
For example:
in the boy with 22 height, the algorithm must start comparing the boys'height with the girl with 14 height, because we already sort them, if the first boy (shorter) cant make a pair with the first girl so definitely the second boy (longer) cant also, we waste the time if we compare from the first girl.
We can solve this problem by two choices, either by making the iterator start with the girl after the previous boy has been stopped (i don't know how to do it with iterator), or by removing the girl from the arraylist once if it's not satisfy the condition and let the loop start with first girl (i tried this but it gives me an exception)
Solve it by these two ways if you can...
You have to add more conditions. Here it is, there are three options :
abs(dif) <= k : they can dance together
dif > k : even the current boy (the smallest) is too tall for her, no one can dance with her, exclude her
dif < -k : the first girl is far too tall for him, exclude him
Here is the code:
int count = 0;
int gLimit = 0;
for (int b = 0; b<ArrBoys.size();b++) {
if(gLimit == ArrGirls.size()) {
System.out.println("no more girl for boy " + ArrBoys.get(b));
}
for (int g = gLimit; g<ArrGirls.size();g++) {
{
int dif = ArrBoys.get(b) - ArrGirls.get(g);
if (Math.abs(dif) <= k) {
System.out.println("we took " + ArrBoys.get(b) + " from boys with "
+ ArrGirls.get(g) + " from girls, thier dif < " + k);
gLimit++;
count++;
break;
} else if (dif > k) {
System.out.println("we try " + ArrBoys.get(b) + " from boys with " + ArrGirls.get(g) + " from grils but thier dif > " + (int) k + ", girl too small, excluded");
gLimit++;
} else if (dif < -k) {
System.out.println("we try " + ArrBoys.get(b) + " from boys with " + ArrGirls.get(g) + " from grils but thier dif > " + (int) k + ", boy too small, excluded");
break;
}
}
}
}
I used get index for more maniability on lists content
Here is the ouput
After Sorting
16 22 28
10 13 14
we try 16 from boys with 10 from grils but thier dif > 5, girl too small, excluded
we took 16 from boys with 13 from girls, thier dif < 5
we try 22 from boys with 14 from grils but thier dif > 5, girl too small, excluded
no more girl for boy 28
the number of pairs we can take is 1
I have this method:
I am trying to assign picture of a card into their iconCards[][] profiles. Pictures are located in images/ folder as e.g. images/AS.gif (Ace of Spades), images/AD.gif (Ace of Diamonds) etc.
static void loadCardIcons(){
int l =0;
int k =0;
while (k < 14){
for (l = 0; l < 4; l++){
String card = "images/" + Character.toString(valueRanks[k]) + "C.gif";
iconCards[k][l] = new ImageIcon(card);
System.out.println(k + " " + l + " " + card);
card = "images/" + Character.toString(valueRanks[k]) + "D.gif";
iconCards[k][l++] = new ImageIcon(card);
System.out.println(k + " " + l + " " + card);
card = "images/" + Character.toString(valueRanks[k]) + "H.gif";
iconCards[k][l++] = new ImageIcon(card);
System.out.println(k + " " + l + " " + card);
card = "images/" + Character.toString(valueRanks[k]) + "S.gif";
iconCards[k][l++] = new ImageIcon(card);
System.out.println(k + " " + l + " " + card);
k++;
}
}
iconBack = new ImageIcon("images/BK.gif");
}
...12 3 images/KS.gif
13 0 images/XC.gif
13 1 images/XD.gif
13 2 images/XH.gif
13 3 images/XS.gif
*13
2
images/XS.gif*
You can see that value = 13 and suit = 2. According to output above the card should be images/XH (JokerHearts), but it prints me XS. Why? Here's the method that runs it. Can't find out what's going on for weeks.
static public Icon getIcon(Card card){
loadCardIcons();
return iconCards[valueAsInt(card)][suitAsInt(card)];
}
Problem is here
iconCards[k][l++] = new ImageIcon(card);
l++ is the post increment operator on l. Therefore given l = 0 and k = 0, you would access
iconCards[0][0]
and then l would go to 1. You might want to use the pre increment ++l version.
So your l (as an index to iconCards) only goes up to value 2 (for images/XH.gif), not 3 (for images/XS.gif).
See the Oracle tutorial here on increment/decrement operators for an explanation on their use.
Perhaps most of you know the Send + More = Money. Well, I'm currently learning java and one of the exercises is I have to solve HES + THE = BEST.
Now, so far I can/should use if-for-while-do loops, nothing else. Although I'm sure there are different methods to solve it, that's not the point of the exercise I'm going through. I have to be able to use if-for-while-do loops the most efficient way.
My problem? I can't seem to think of an efficient way to solve it! I've come up with this, which solves the puzzle, but is perhaps the worst efficient way to do so:
public class Verbalarithmetics {
public static void main (String args[]) {
// Countint Variables
int index_h = 0;
int index_e = 0;
int index_s = 0;
int index_t = 0;
int index_b = 0;
// Start with h = 1 and increase until the else-if statement is true
for(int h = 1; h <= 9; h++) { // h = 1, because first Symbol can't be zero
index_h++;
// Increase e so long until e equals h
for(int e = 0; e <= 9; e++) {
index_e++;
if (e == h) {
continue;
}
// Increase s so long until s equals h or e
for(int s = 0; s <= 9; s++) {
index_s++;
if (s == h || s == e) {
continue;
}//end if
// Increase t so long until t equals h or e or s.
for(int t = 1; t <= 9; t++) { // t = 1, because 1st Symbol cant be zero
index_t++;
if(t == h || t == e || t == s) {
continue;
}// end if
// Increase b so long until b equals h, e, s or t.
for(int b = 1; b <= 9; b++) { // b = 1, weil das 1. Symbol nicht für eine 0 stehen darf
index_b++;
if (b == h || b == e || b == s || b == t) {
continue;
}// end if
// x = 100*h + 10*e + s
// y = 100*t + 10*h + e
// z = 1000*b + 100*e + 10*s + t
// Check if x+y=z, if true -> Print out Solution, else continue with the upper most loop
else
if (100*h + 10*e + s + 100*t + 10*h + e == 1000*b + 100*e +10*s + t) {
System.out.println("HES + THE = BEST => " + h + e + s + " + " + t + h + e + " = " + b + e + s + t);
System.out.println("With H=" + h + ", E=" + e + ", S=" + s + ", T=" + t + ", und B=" + b + ".");
System.out.println("It took " + index_h +
" Loop-Cycles to find 'h' !");
System.out.println("It took " + index_e +
" Loop-Cycles to find 'e' !");
System.out.println("It took " + index_s +
" Loop-Cycles to find 's' !");
System.out.println("It took " + index_t +
" Loop-Cycles to find 't' !");
System.out.println("It took " + index_b +
" Loop-Cycles to find 'b' !");
System.out.println("This is a total of " + (index_h + index_e + index_s + index_t + index_b) +
" Loop-Cycles");
}// end else if
}//end for
}//end for
}//end for
}//end for
}//end for
}
}
It takes about 15000 odd loop-cycles in total to solve this puzzle. That's a lot in my opinion. Any pointers, please?
The big question here is: can you (do you want to) logically deduce certain constraints and apply them to your algorithm or do you want to brute-force it? Assuming the former, some of them are pretty obvious:
B = 1
T can't be 0 (because it's first in THE), thus neither S nor E can be 0 either.
T = E + S % 10
Thus you have S, E, H to loop through giving you at most 9 * 8 * 8 combinations which is 576. Add to that the fact that H + T must be greater or equal to 9 and you'll reduce this even further.
Update Here's a quick and ugly solution. It's based only on 3 constraints listed above.
public class Puzzle {
public static void main(String[] args) {
for (int S = 1; S<10; S++) {
for (int E = 1; E<10; E++) {
if (S==E) continue; // all letters stand for different digits
for (int H = 1; H<10; H++) {
if (H==E || H==S) continue; // all letters stand for different digits
checkAndPrint(S, E, H);
}
} // for
} // for
} // main
private static boolean checkAndPrint(int S, int E, int H) {
int T = (S + E) % 10;
int S1 = (E + H) + (S + E) / 10; // calculates value for 'S' in 'BEST' (possibly + 10)
if (S1 % 10 != S) return false;
int E1 = H + T + S1 / 10; // calculates value for 'E' in 'BEST' (possibly + 10)
if (E1 % 10 != E) return false;
System.out.println(H + "" + E + "" + S + " + " + T + "" + H + "" + E + " = 1" + E + "" + S + "" + T);
return true;
}
}
Maybe you might want to look this repository : it is a solution to solve verbal-arithmetic problems using JavaFX. Firefly Algorithm for Verbal-arithmetics problem [GitHub]
Instead of looping through all values of the letters, loop through the possible values for S, E, and T. S + E % 10 should be T. Once you have a set of potential S,E,T solutions, find the loop through the possible E+H+(0 or 1, depending on if S+E is greater than 9)=S solutions...and so on, and so on.
I am not an expert, but it could be worth looking at languages which manage constraints such as Prolog. There's a very similar problem here:
Compute a list of distinct odd numbers (if one exists), such that their sum is equal to a given number
Prolog is a different type of language but if you are doing this for your own education then it will certainly exercise your brain :-)
It will be possible to code general approaches to alphametics - not just the rather simple one here.
An alternative - which is not guaranteed to give a result - is to use an optimisation technique such as genetic algorithms. Guess a number of solutions, and compute how close they are to the correct solution, and then adjust them. You may get partial solutions by this method.
Efficiency goes out the window if the standard approach is to brute force it, as suggested here. The most efficient way that only uses loops probably involves calculating the exhaustive set of possibilities, storing them, then iterating through each one to see if it works.
uhm you could do a lot in the form of optimisation in your approach.
first of all, get the maximum value for "BEST".
assume "HES" has the highest possible value, 987, then "THE" would be X98 so the highest value for "THE" is 698 which gives 987+698=1685.
if "THE" has the highest value, THE would be 987 and HES would be 876 -> 876+987=1863, which is higher than 1685, so 1863 is an upper bound for "best". So you could have your program adjust the upper bound for "B" to 1 (which in this case already yields you the first digit..).
the lower bound for BEST is easy, as it's 1023.
then you do something like this:
for(i=102;i<=987;i++)
{
for(j=1023-i;j<=(1863-i < 987 ? 1863-i:987);j++)
{
//check if the solution matches and doesn't have duplicate digits
}
}
this way you discard a lot of impossible combinations right away through the values in the inner for loop.
and I bet there are similar ways to constrain the space of possible solutions more.
And the program is way less complex this way.
That class of problem is the poster child for query optimisation. Java isn't for that.
If you have fewer than a few tens of billion states, brute force it. It will take much less time to run a brute force search than it would to create an optimising query engine.