I have a text file with only +'s and blank spaces. i have to find a target within this file that looks like a spaceship. but the spaceship does not have to be perfect.
thanks in advance
this is the text file with the targets, a smaller version. there is at least 1 target in this.
+ ++ + + + + + + + +++ +
+ ++ + + ++ + + ++ ++ + +
+ + + + ++ + + ++++ ++
+ + ++++ + ++ + ++ +
+ + + + ++ + ++ + +
+ + + + ++ + + + +
+ + ++ + + +++ ++ +++
+ + + + ++ + ++ ++ + ++
+ + + + + ++ + + + + ++ + +
+ ++ + + ++ ++ +++ +
+ ++ + ++ + + + + ++ ++ +
+ + ++ ++ + + + + +
+ + + + + ++ + +
this is the target
+
+
+++
+++++++
++ ++
++ + ++
++ +++ ++
++ + ++
++ ++
+++++++
+++
I have tried Regex pattern reading but the file is too big so i decided to go against that. I do not know any other way to solve this.
I don't think you can or need to do anything really fancy here.
You can start by encoding your patterns. In this case, you could:
Encode every line as a string, and the lines themselves in an array: String[]
Encode every line as a string, and the lines themselves in an List: List<String>
Encode every line as a char[], and the lines themselves in an array: char[][]
Number 3 has the benefit that you can easily index it as a matrix:
char[][] matrix = ...;
char ch = matrix[row][column];
So you have:
char[][] search = new char[searchRows][searchColumns];
char[][] target = new char[targetRows][targetColumns];
You algorithm could be:
For every possible position that target could occur in search, calculate how many characters are equal
The position with the highest amount of equal characters wins
Get a percentage by dividing this amount of equal characters by the total amount of characters in target and you get a percentage
If the percentage is over a certain threshold, it's a match
Step1:
The maximum row or column is the total number of rows or columns in the search pattern minus the rows or columns in the target pattern.
int maxMatch = 0;
int maxMatchRow = -1;
int maxMatchColumn = -1;
for (int row = 0; row <= searchRows - targetRows; row++) {
for (int column = 0; columns <= searchColumns - targetColumns; column++) {
int match = calculateMatch(search, target, row, column);
if (match > maxMatch) {
maxMatchRow = row;
maxMatchColumn = column;
}
}
}
And to calculate matches in method calculateMatch, just add one if the characters in search and target are the same (but add offset row and column when you check search, not when you check target)
I think you should be able to finish it from there.
Related
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.
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.
System.out.println(7 + 5 + " ");
This prints out 12, but in another order
System.out.println(" " + 5 + 7);
it prints out 57. Why is this?
Firstly, this has nothing to do with System.out.println. You'll see exactly the same effect if you use:
String x = 7 + 5 + "";
String y = " " + 5 + 7;
It's got everything to do with associativity. The + operator is left-associative, so the above two statements are equivalent to:
String x = (7 + 5) + "";
String y = (" " + 5) + 7;
Now look at the results of the first expression in each case: 7 + 5 is just 12, as int... whereas " " + 5 is "5" (a string).
Or to break it down further:
int x1 = 7 + 5; // 12 (integer addition)
String x = x1 + ""; // "12" (conversion to string, then string concatenation)
String y1 = " " + 5; // "5" (conversion to string, then string concatenation)
String y = y1 + 7; // "57" (conversion to string, then string concatenation)
Justification: JLS 15.18 (additive operators):
The additive operators have the same precedence and are syntactically left-associative (they group left-to-right).
Easy. System.out.println(7 + 5 + " ") is viewed as a mathematical equation, whereas System.out.println(" " + 5 + 7) whereas having the space beforehand, Java (I'm assuming) views it as a string. Thus 'concatenating' the two.
String secondLine = ...E......E..E.E;
String failures = "E";
String passed = ".";
int i = 0;
while ((i = (secondLine.indexOf(failures, i) + 1)) > 0) {
System.out.println(i);
feedbackString += "<strong style='color: red;'><li>Failed: </strong><strong>" + i + "</strong> - " + "out of " + resultString.length() + " tests.<br>";
}
The total number of the tests is the sum of the dots which is = 12. and the E's are the failures which in this case = 4.
The dots are the passes and the E's are the failures. Whenever this is ran and there is a failure, it adds an 'E' in front of the dot which becomes'.E'. I can get the E's on its own but I want a statement that says given a dot comes before the E and then it should print the '.E' and pass it into a variable called failedTest.
The code above has an output of: 4, 11, 14, 16 which is not what I want as its considering each character separately but I want it to consider '.E' as one that is if an E comes after a dot then it should consider it as one. if this should be ran considering the '.E' as failure, the expected output should be 3, 9, 11, 12. Thanks :)
I understand your problem better now: if i am right, you print a ., ran the test and if it do not pass, you will print an E.
The point if the final length of secondLine is the number of test plus the number of error, so the if the first error is the test T-i, the T-i dot would be at the position T-i, its E would be at the position (T-1) + 1. The following test would be displaced one position: the dot of the test T-(i+1) would be at the position (T-i) + 2. Do you see the point?
So, this is my suggestion
String secondLine = "...E......E..E.E";
String failures = "E";
String passed = ".";
int detectedErrors = 0;
int i = 0;
while ((i = (secondLine.indexOf(failures, i) + 1)) > 0) {
System.out.println(i);
feedbackString += "<strong style='color: red;'><li>Failed: </strong><strong>"
+ (i - detectedErrors) // here
+ "</strong> - " + "out of " + resultString.length() + " tests.<br>";
detectedErrors += 1; // and here
}
You need to keep track of the number of extra characters in the secondLine and subtract them from the match position. Also change your failure String to ".E"
String secondLine = "...E......E..E.E";
String failures = ".E";
String passed = ".";
int n = 0;
int i = 0;
while ((i = (secondLine.indexOf(failures, i) + 1)) > 0) {
System.out.println(i-n);
n++;
feedbackString += "<strong style='color: red;'><li>Failed: </strong><strong>" + (i-n) + "</strong> - " + "out of " + resultString.length() + " tests.<br>";
I am trying to convert an integer to a binary number using an integer array. The first conversion is toBinaryString where I get the proper conversion "11111111" then the next step to convert to an array. This is where it goes wrong and I think its the getChar line.
int x = 255;
string=(Integer.toBinaryString(x));
int[] array = new int[string.length()];
for (int i=0; i< string.length(); i++){
array[i] = string.getChar(i);
Log.d("TAG", " Data " + array[1] "," + array[2] + "," + array[3]);
Log displays ( Data 0,0,0 ) the results I am looking for is ( Data 1,1,1 )
Here is the final code and it works.
// NEW
int x = 128;
string=(Integer.toBinaryString(x));
int[] array = new int[string.length()];
for (int i=0; i < string.length(); i++) {
array[i] = Integer.parseInt(string.substring(i,i+1));
}
Log.d("TAG", "Data " + array[0] + "" + array[1]+ "" + array[2] + "" + array[3]+ " " + array[4]+ "" + array[5] + "" + array[6] + "" + array[7]);
// Take your input integer
int x = 255;
// make an array of integers the size of Integers (in bits)
int[] digits = new Integer[Integer.SIZE];
// Iterate SIZE times through that array
for (int j = 0; j < Integer.SIZE; ++j) {
// mask of the lowest bit and assign it to the next-to-last
// Don't forget to subtract one to get indicies 0..(SIZE-1)
digits[Integer.SIZE-j-1] = x & 0x1;
// Shift off that bit moving the next bit into place
x >>= 1;
}
how about :
array[i] = Integer.parseInt(string.substring(i,i+1));
First of all, an array starts from the index of 0 instead of 1, so change the following line of code:
Log.d("TAG", " Data " + array[1] "," + array[2] + "," + array[3]);
To:
Log.d("TAG", " Data " + array[0] "," + array[1] + "," + array[2]);
Next, the following line of code:
array[i] = string.getChar(i);
You are trying to get a character value to an Integer array, you may want to try the following instead and parse the value into an Integer (also, the "getChar" function does not exist):
array[i] = Integer.parseInt(String.valueOf(string.charAt(i)));
I hope I've helped.
P.S - Thanks to Hyrum Hammon for pointing out about the String.valueOf.