How to find 2x3 pattern in matrix Java - java

This algorithm has me stumped. I'm pretty novice to data structures and alogithms, I understand what the code needs to do, but can't wrap my brain on how to actually code it.
The problem is as follows:
Determines whether the matrix includes a golden ticket. A golden ticket consists of 6 upper-case 'G' where three pairs of Gs are right above each other as shown below. Note that I left out the single quotes to improve readability.
G G
G G
G G
E.g.,
[A b - - C d m]
[- G G Z G G -]
[H o - r G G D] this matrix returns true
[H o - r G G D]
E.g.,
[R g G - C d m W]
[- G G Z G G - r] this matrix returns false
[o G G G r G G D] because the Gs are not in the specified position
[S t C - G G a -] relative to each other
The matrix should be 'rectangular', which means, all rows should have the same number of elements. If that is not the case, an IllegalArgumentException should be thrown.
This is what I have written:
public static boolean goldenTicket(char[][] matrix) {
if (matrix == null) return false;
if (matrix.length == 0) return false;
char char1, char2;
int matchCount = 0;
int indexOne = 0, indexTwo = 0, prevIndex1 = 0,prevIndex2 = 0;
int rows = matrix.length;
int columns = matrix[0].length;
for (int i = 0; i < rows; i++) {
if (matrix[i].length != columns)
throw new IllegalArgumentException("Length of row doesn't match");
if (matrix[i].length == 0) return false;
if (matchCount == 3) return true;
for (int j = 1; j < columns; j++) {
if (matrix[i][j] == 'G' && matrix[i][j - 1] == 'G') {
if (prevIndex1 == 0 && prevIndex2 == 0) {
indexOne = j - 1;
indexTwo = j;
matchCount++;
} else {
prevIndex1 = j - 1;
prevIndex2 = j;
matchCount++;
}
}
}
if (prevIndex1 == indexOne && prevIndex2 == indexTwo) {
matchCount++;
}
}
return false;
}
However, the problem is the code passes both example one and two as above, instead of only passing example 1.
I've already turned in the assignment with only passing 24/25 tests, I just really want to understand how this should work and maybe a better way to code it for future reference.
Thanks in advance!

This is the type of problem where divide and conquer can help simplify the code.
The task is to find a 2 x 3 matrix of the letter "G" in a larger matrix.
So, we write a method to check each 2 x 3 matrix within a larger matrix.
Here are the results of one of my tests.
[a, G, G, a]
[a, G, G, a]
[a, G, a, a]
[a, a, a, a]
false
[a, G, G, a]
[a, G, G, a]
[a, G, G, a]
[a, a, a, a]
true
[a, a, a, a]
[a, a, G, G]
[a, a, G, G]
[a, a, G, G]
true
I wrote two methods.
The goldenTicket method checks to see if the matrix is null, less than a 2 x 3 matrix, or if the column lengths are the same. The last code block goes through the matrix looking for the golden ticket.
The isTicket method checks to see if the current 2 x 3 section of the matrix consists of all "G" letters.
Breaking up the code into two methods makes each method smaller and easier to read, and hides somewhat the fact that it takes 4 nested for loops to solve the task correctly.
Here's the complete runnable code.
import java.lang.reflect.Array;
import java.util.Arrays;
public class GoldenTicketExample {
public static void main(String[] args) {
char[][] matrix1 = { { 'a', 'G', 'G', 'a' }, { 'a', 'G', 'G', 'a' },
{ 'a', 'G', 'a', 'a' }, { 'a', 'a', 'a', 'a' } };
displayOutput(matrix1);
char[][] matrix2 = { { 'a', 'G', 'G', 'a' }, { 'a', 'G', 'G', 'a' },
{ 'a', 'G', 'G', 'a' }, { 'a', 'a', 'a', 'a' } };
displayOutput(matrix2);
char[][] matrix3 = { { 'a', 'a', 'a', 'a' }, { 'a', 'a', 'G', 'G' },
{ 'a', 'a', 'G', 'G' }, { 'a', 'a', 'G', 'G' } };
displayOutput(matrix3);
}
private static void displayOutput(char[][] matrix) {
for (char[] row : matrix) {
System.out.println(Arrays.toString(row));
}
System.out.println(goldenTicket(matrix));
}
public static boolean goldenTicket(char[][] matrix) {
if (matrix == null) {
return false;
}
if (matrix.length < 3) {
return false;
}
int columns = matrix[0].length;
if (columns < 2) {
return false;
}
for (int row = 1; row < matrix.length; row++) {
if (matrix[row].length != columns) {
throw new IllegalArgumentException(
"Length of row doesn't match");
}
}
for (int row = 0; row < matrix.length - 2; row++) {
for (int column = 0; column < matrix[row].length - 1; column++) {
if (isTicket(matrix, row, column)) {
return true;
}
}
}
return false;
}
private static boolean isTicket(char[][] matrix, int row, int column) {
for (int r = row; r < row + 3; r++) {
for (int c = column; c < column + 2; c++) {
if (matrix[r][c] != 'G') {
return false;
}
}
}
return true;
}
}

It could be solved with O(ncol*nrow), where ncol is the number of columns and nrow is the number of rows.
You should generate a matrix with the same rows and columns as your original matrix, and for each item you consider a pair of number which first element represent number of sequential G's including this item in the row, and second element represent number of sequential G's including this item in the column.
To fill this matrix(I named it onlyGMatrix) we check if item (i,j) is G, if not we simply put pair (0,0) otherwise for i>0 and j>0 we put min {onlyGMatrix(i-1,j)[0] , onlyGMatrix(i,j-1)[0]} + 1 as first element and min {onlyGMatrix(i-1,j)[1] , onlyGMatrix(i,j-1)[1]} + 1 as the second element.
Using your first matrix we would reach the below onlyGMatrix:
(0,0) (0,0) (0,0) (0,0) (0,0) (0,0) (0,0)
(0,0) (0,0) (0,0) (0,0) (1,1) (2,1) (0,0)
(0,0) (0,0) (0,0) (0,0) (2,1) (2,2) (0,0)
(0,0) (0,0) (0,0) (0,0) (3,1) (3,2) (0,0)
And for your second matrix we would have:
(0,0) (0,0) (1,1) (0,0) (0,0) (0,0) (0,0) (0,0)
(0,0) (1,1) (2,2) (0,0) (1,1) (2,1) (0,0) (0,0)
(0,0) (1,2) (2,3) (3,1) (0,0) (1,2) (2,1) (0,0)
(0,0) (0,0) (0,0) (0,0) (1,1) (2,1) (0,0) (0,0)
now your algorithm simply would end successfully when you see pair (3,2) when you building this onlyGMatrix, and if you reach the last element of matrix and you didn't see this pair then you should return false.

Related

How do I generate all combinations of integers from zero to value [duplicate]

I want to write a function that takes an array of letters as an argument and a number of those letters to select.
Say you provide an array of 8 letters and want to select 3 letters from that. Then you should get:
8! / ((8 - 3)! * 3!) = 56
Arrays (or words) in return consisting of 3 letters each.
Art of Computer Programming Volume 4: Fascicle 3 has a ton of these that might fit your particular situation better than how I describe.
Gray Codes
An issue that you will come across is of course memory and pretty quickly, you'll have problems by 20 elements in your set -- 20C3 = 1140. And if you want to iterate over the set it's best to use a modified gray code algorithm so you aren't holding all of them in memory. These generate the next combination from the previous and avoid repetitions. There are many of these for different uses. Do we want to maximize the differences between successive combinations? minimize? et cetera.
Some of the original papers describing gray codes:
Some Hamilton Paths and a Minimal Change Algorithm
Adjacent Interchange Combination Generation Algorithm
Here are some other papers covering the topic:
An Efficient Implementation of the Eades, Hickey, Read Adjacent Interchange Combination Generation Algorithm (PDF, with code in Pascal)
Combination Generators
Survey of Combinatorial Gray Codes (PostScript)
An Algorithm for Gray Codes
Chase's Twiddle (algorithm)
Phillip J Chase, `Algorithm 382: Combinations of M out of N Objects' (1970)
The algorithm in C...
Index of Combinations in Lexicographical Order (Buckles Algorithm 515)
You can also reference a combination by its index (in lexicographical order). Realizing that the index should be some amount of change from right to left based on the index we can construct something that should recover a combination.
So, we have a set {1,2,3,4,5,6}... and we want three elements. Let's say {1,2,3} we can say that the difference between the elements is one and in order and minimal. {1,2,4} has one change and is lexicographically number 2. So the number of 'changes' in the last place accounts for one change in the lexicographical ordering. The second place, with one change {1,3,4} has one change but accounts for more change since it's in the second place (proportional to the number of elements in the original set).
The method I've described is a deconstruction, as it seems, from set to the index, we need to do the reverse – which is much trickier. This is how Buckles solves the problem. I wrote some C to compute them, with minor changes – I used the index of the sets rather than a number range to represent the set, so we are always working from 0...n.
Note:
Since combinations are unordered, {1,3,2} = {1,2,3} --we order them to be lexicographical.
This method has an implicit 0 to start the set for the first difference.
Index of Combinations in Lexicographical Order (McCaffrey)
There is another way:, its concept is easier to grasp and program but it's without the optimizations of Buckles. Fortunately, it also does not produce duplicate combinations:
The set that maximizes , where .
For an example: 27 = C(6,4) + C(5,3) + C(2,2) + C(1,1). So, the 27th lexicographical combination of four things is: {1,2,5,6}, those are the indexes of whatever set you want to look at. Example below (OCaml), requires choose function, left to reader:
(* this will find the [x] combination of a [set] list when taking [k] elements *)
let combination_maccaffery set k x =
(* maximize function -- maximize a that is aCb *)
(* return largest c where c < i and choose(c,i) <= z *)
let rec maximize a b x =
if (choose a b ) <= x then a else maximize (a-1) b x
in
let rec iterate n x i = match i with
| 0 -> []
| i ->
let max = maximize n i x in
max :: iterate n (x - (choose max i)) (i-1)
in
if x < 0 then failwith "errors" else
let idxs = iterate (List.length set) x k in
List.map (List.nth set) (List.sort (-) idxs)
A small and simple combinations iterator
The following two algorithms are provided for didactic purposes. They implement an iterator and (a more general) folder overall combinations.
They are as fast as possible, having the complexity O(nCk). The memory consumption is bound by k.
We will start with the iterator, which will call a user provided function for each combination
let iter_combs n k f =
let rec iter v s j =
if j = k then f v
else for i = s to n - 1 do iter (i::v) (i+1) (j+1) done in
iter [] 0 0
A more general version will call the user provided function along with the state variable, starting from the initial state. Since we need to pass the state between different states we won't use the for-loop, but instead, use recursion,
let fold_combs n k f x =
let rec loop i s c x =
if i < n then
loop (i+1) s c ##
let c = i::c and s = s + 1 and i = i + 1 in
if s < k then loop i s c x else f c x
else x in
loop 0 0 [] x
In C#:
public static IEnumerable<IEnumerable<T>> Combinations<T>(this IEnumerable<T> elements, int k)
{
return k == 0 ? new[] { new T[0] } :
elements.SelectMany((e, i) =>
elements.Skip(i + 1).Combinations(k - 1).Select(c => (new[] {e}).Concat(c)));
}
Usage:
var result = Combinations(new[] { 1, 2, 3, 4, 5 }, 3);
Result:
123
124
125
134
135
145
234
235
245
345
Short java solution:
import java.util.Arrays;
public class Combination {
public static void main(String[] args){
String[] arr = {"A","B","C","D","E","F"};
combinations2(arr, 3, 0, new String[3]);
}
static void combinations2(String[] arr, int len, int startPosition, String[] result){
if (len == 0){
System.out.println(Arrays.toString(result));
return;
}
for (int i = startPosition; i <= arr.length-len; i++){
result[result.length - len] = arr[i];
combinations2(arr, len-1, i+1, result);
}
}
}
Result will be
[A, B, C]
[A, B, D]
[A, B, E]
[A, B, F]
[A, C, D]
[A, C, E]
[A, C, F]
[A, D, E]
[A, D, F]
[A, E, F]
[B, C, D]
[B, C, E]
[B, C, F]
[B, D, E]
[B, D, F]
[B, E, F]
[C, D, E]
[C, D, F]
[C, E, F]
[D, E, F]
May I present my recursive Python solution to this problem?
def choose_iter(elements, length):
for i in xrange(len(elements)):
if length == 1:
yield (elements[i],)
else:
for next in choose_iter(elements[i+1:], length-1):
yield (elements[i],) + next
def choose(l, k):
return list(choose_iter(l, k))
Example usage:
>>> len(list(choose_iter("abcdefgh",3)))
56
I like it for its simplicity.
Lets say your array of letters looks like this: "ABCDEFGH". You have three indices (i, j, k) indicating which letters you are going to use for the current word, You start with:
A B C D E F G H
^ ^ ^
i j k
First you vary k, so the next step looks like that:
A B C D E F G H
^ ^ ^
i j k
If you reached the end you go on and vary j and then k again.
A B C D E F G H
^ ^ ^
i j k
A B C D E F G H
^ ^ ^
i j k
Once you j reached G you start also to vary i.
A B C D E F G H
^ ^ ^
i j k
A B C D E F G H
^ ^ ^
i j k
...
Written in code this look something like that
void print_combinations(const char *string)
{
int i, j, k;
int len = strlen(string);
for (i = 0; i < len - 2; i++)
{
for (j = i + 1; j < len - 1; j++)
{
for (k = j + 1; k < len; k++)
printf("%c%c%c\n", string[i], string[j], string[k]);
}
}
}
The following recursive algorithm picks all of the k-element combinations from an ordered set:
choose the first element i of your combination
combine i with each of the combinations of k-1 elements chosen recursively from the set of elements larger than i.
Iterate the above for each i in the set.
It is essential that you pick the rest of the elements as larger than i, to avoid repetition. This way [3,5] will be picked only once, as [3] combined with [5], instead of twice (the condition eliminates [5] + [3]). Without this condition you get variations instead of combinations.
Short example in Python:
def comb(sofar, rest, n):
if n == 0:
print sofar
else:
for i in range(len(rest)):
comb(sofar + rest[i], rest[i+1:], n-1)
>>> comb("", "abcde", 3)
abc
abd
abe
acd
ace
ade
bcd
bce
bde
cde
For explanation, the recursive method is described with the following example:
Example: A B C D E
All combinations of 3 would be:
A with all combinations of 2 from the rest (B C D E)
B with all combinations of 2 from the rest (C D E)
C with all combinations of 2 from the rest (D E)
I found this thread useful and thought I would add a Javascript solution that you can pop into Firebug. Depending on your JS engine, it could take a little time if the starting string is large.
function string_recurse(active, rest) {
if (rest.length == 0) {
console.log(active);
} else {
string_recurse(active + rest.charAt(0), rest.substring(1, rest.length));
string_recurse(active, rest.substring(1, rest.length));
}
}
string_recurse("", "abc");
The output should be as follows:
abc
ab
ac
a
bc
b
c
In C++ the following routine will produce all combinations of length distance(first,k) between the range [first,last):
#include <algorithm>
template <typename Iterator>
bool next_combination(const Iterator first, Iterator k, const Iterator last)
{
/* Credits: Mark Nelson http://marknelson.us */
if ((first == last) || (first == k) || (last == k))
return false;
Iterator i1 = first;
Iterator i2 = last;
++i1;
if (last == i1)
return false;
i1 = last;
--i1;
i1 = k;
--i2;
while (first != i1)
{
if (*--i1 < *i2)
{
Iterator j = k;
while (!(*i1 < *j)) ++j;
std::iter_swap(i1,j);
++i1;
++j;
i2 = k;
std::rotate(i1,j,last);
while (last != j)
{
++j;
++i2;
}
std::rotate(k,i2,last);
return true;
}
}
std::rotate(first,k,last);
return false;
}
It can be used like this:
#include <string>
#include <iostream>
int main()
{
std::string s = "12345";
std::size_t comb_size = 3;
do
{
std::cout << std::string(s.begin(), s.begin() + comb_size) << std::endl;
} while (next_combination(s.begin(), s.begin() + comb_size, s.end()));
return 0;
}
This will print the following:
123
124
125
134
135
145
234
235
245
345
static IEnumerable<string> Combinations(List<string> characters, int length)
{
for (int i = 0; i < characters.Count; i++)
{
// only want 1 character, just return this one
if (length == 1)
yield return characters[i];
// want more than one character, return this one plus all combinations one shorter
// only use characters after the current one for the rest of the combinations
else
foreach (string next in Combinations(characters.GetRange(i + 1, characters.Count - (i + 1)), length - 1))
yield return characters[i] + next;
}
}
Simple recursive algorithm in Haskell
import Data.List
combinations 0 lst = [[]]
combinations n lst = do
(x:xs) <- tails lst
rest <- combinations (n-1) xs
return $ x : rest
We first define the special case, i.e. selecting zero elements. It produces a single result, which is an empty list (i.e. a list that contains an empty list).
For n > 0, x goes through every element of the list and xs is every element after x.
rest picks n - 1 elements from xs using a recursive call to combinations. The final result of the function is a list where each element is x : rest (i.e. a list which has x as head and rest as tail) for every different value of x and rest.
> combinations 3 "abcde"
["abc","abd","abe","acd","ace","ade","bcd","bce","bde","cde"]
And of course, since Haskell is lazy, the list is gradually generated as needed, so you can partially evaluate exponentially large combinations.
> let c = combinations 8 "abcdefghijklmnopqrstuvwxyz"
> take 10 c
["abcdefgh","abcdefgi","abcdefgj","abcdefgk","abcdefgl","abcdefgm","abcdefgn",
"abcdefgo","abcdefgp","abcdefgq"]
And here comes granddaddy COBOL, the much maligned language.
Let's assume an array of 34 elements of 8 bytes each (purely arbitrary selection.) The idea is to enumerate all possible 4-element combinations and load them into an array.
We use 4 indices, one each for each position in the group of 4
The array is processed like this:
idx1 = 1
idx2 = 2
idx3 = 3
idx4 = 4
We vary idx4 from 4 to the end. For each idx4 we get a unique combination
of groups of four. When idx4 comes to the end of the array, we increment idx3 by 1 and set idx4 to idx3+1. Then we run idx4 to the end again. We proceed in this manner, augmenting idx3,idx2, and idx1 respectively until the position of idx1 is less than 4 from the end of the array. That finishes the algorithm.
1 --- pos.1
2 --- pos 2
3 --- pos 3
4 --- pos 4
5
6
7
etc.
First iterations:
1234
1235
1236
1237
1245
1246
1247
1256
1257
1267
etc.
A COBOL example:
01 DATA_ARAY.
05 FILLER PIC X(8) VALUE "VALUE_01".
05 FILLER PIC X(8) VALUE "VALUE_02".
etc.
01 ARAY_DATA OCCURS 34.
05 ARAY_ITEM PIC X(8).
01 OUTPUT_ARAY OCCURS 50000 PIC X(32).
01 MAX_NUM PIC 99 COMP VALUE 34.
01 INDEXXES COMP.
05 IDX1 PIC 99.
05 IDX2 PIC 99.
05 IDX3 PIC 99.
05 IDX4 PIC 99.
05 OUT_IDX PIC 9(9).
01 WHERE_TO_STOP_SEARCH PIC 99 COMP.
* Stop the search when IDX1 is on the third last array element:
COMPUTE WHERE_TO_STOP_SEARCH = MAX_VALUE - 3
MOVE 1 TO IDX1
PERFORM UNTIL IDX1 > WHERE_TO_STOP_SEARCH
COMPUTE IDX2 = IDX1 + 1
PERFORM UNTIL IDX2 > MAX_NUM
COMPUTE IDX3 = IDX2 + 1
PERFORM UNTIL IDX3 > MAX_NUM
COMPUTE IDX4 = IDX3 + 1
PERFORM UNTIL IDX4 > MAX_NUM
ADD 1 TO OUT_IDX
STRING ARAY_ITEM(IDX1)
ARAY_ITEM(IDX2)
ARAY_ITEM(IDX3)
ARAY_ITEM(IDX4)
INTO OUTPUT_ARAY(OUT_IDX)
ADD 1 TO IDX4
END-PERFORM
ADD 1 TO IDX3
END-PERFORM
ADD 1 TO IDX2
END_PERFORM
ADD 1 TO IDX1
END-PERFORM.
Another C# version with lazy generation of the combination indices. This version maintains a single array of indices to define a mapping between the list of all values and the values for the current combination, i.e. constantly uses O(k) additional space during the entire runtime. The code generates individual combinations, including the first one, in O(k) time.
public static IEnumerable<T[]> Combinations<T>(this T[] values, int k)
{
if (k < 0 || values.Length < k)
yield break; // invalid parameters, no combinations possible
// generate the initial combination indices
var combIndices = new int[k];
for (var i = 0; i < k; i++)
{
combIndices[i] = i;
}
while (true)
{
// return next combination
var combination = new T[k];
for (var i = 0; i < k; i++)
{
combination[i] = values[combIndices[i]];
}
yield return combination;
// find first index to update
var indexToUpdate = k - 1;
while (indexToUpdate >= 0 && combIndices[indexToUpdate] >= values.Length - k + indexToUpdate)
{
indexToUpdate--;
}
if (indexToUpdate < 0)
yield break; // done
// update combination indices
for (var combIndex = combIndices[indexToUpdate] + 1; indexToUpdate < k; indexToUpdate++, combIndex++)
{
combIndices[indexToUpdate] = combIndex;
}
}
}
Test code:
foreach (var combination in new[] {'a', 'b', 'c', 'd', 'e'}.Combinations(3))
{
System.Console.WriteLine(String.Join(" ", combination));
}
Output:
a b c
a b d
a b e
a c d
a c e
a d e
b c d
b c e
b d e
c d e
Here is an elegant, generic implementation in Scala, as described on 99 Scala Problems.
object P26 {
def flatMapSublists[A,B](ls: List[A])(f: (List[A]) => List[B]): List[B] =
ls match {
case Nil => Nil
case sublist#(_ :: tail) => f(sublist) ::: flatMapSublists(tail)(f)
}
def combinations[A](n: Int, ls: List[A]): List[List[A]] =
if (n == 0) List(Nil)
else flatMapSublists(ls) { sl =>
combinations(n - 1, sl.tail) map {sl.head :: _}
}
}
If you can use SQL syntax - say, if you're using LINQ to access fields of an structure or array, or directly accessing a database that has a table called "Alphabet" with just one char field "Letter", you can adapt following code:
SELECT A.Letter, B.Letter, C.Letter
FROM Alphabet AS A, Alphabet AS B, Alphabet AS C
WHERE A.Letter<>B.Letter AND A.Letter<>C.Letter AND B.Letter<>C.Letter
AND A.Letter<B.Letter AND B.Letter<C.Letter
This will return all combinations of 3 letters, notwithstanding how many letters you have in table "Alphabet" (it can be 3, 8, 10, 27, etc.).
If what you want is all permutations, rather than combinations (i.e. you want "ACB" and "ABC" to count as different, rather than appear just once) just delete the last line (the AND one) and it's done.
Post-Edit: After re-reading the question, I realise what's needed is the general algorithm, not just a specific one for the case of selecting 3 items. Adam Hughes' answer is the complete one, unfortunately I cannot vote it up (yet). This answer's simple but works only for when you want exactly 3 items.
I had a permutation algorithm I used for project euler, in python:
def missing(miss,src):
"Returns the list of items in src not present in miss"
return [i for i in src if i not in miss]
def permutation_gen(n,l):
"Generates all the permutations of n items of the l list"
for i in l:
if n<=1: yield [i]
r = [i]
for j in permutation_gen(n-1,missing([i],l)): yield r+j
If
n<len(l)
you should have all combination you need without repetition, do you need it?
It is a generator, so you use it in something like this:
for comb in permutation_gen(3,list("ABCDEFGH")):
print comb
https://gist.github.com/3118596
There is an implementation for JavaScript. It has functions to get k-combinations and all combinations of an array of any objects. Examples:
k_combinations([1,2,3], 2)
-> [[1,2], [1,3], [2,3]]
combinations([1,2,3])
-> [[1],[2],[3],[1,2],[1,3],[2,3],[1,2,3]]
Lets say your array of letters looks like this: "ABCDEFGH". You have three indices (i, j, k) indicating which letters you are going to use for the current word, You start with:
A B C D E F G H
^ ^ ^
i j k
First you vary k, so the next step looks like that:
A B C D E F G H
^ ^ ^
i j k
If you reached the end you go on and vary j and then k again.
A B C D E F G H
^ ^ ^
i j k
A B C D E F G H
^ ^ ^
i j k
Once you j reached G you start also to vary i.
A B C D E F G H
^ ^ ^
i j k
A B C D E F G H
^ ^ ^
i j k
...
function initializePointers($cnt) {
$pointers = [];
for($i=0; $i<$cnt; $i++) {
$pointers[] = $i;
}
return $pointers;
}
function incrementPointers(&$pointers, &$arrLength) {
for($i=0; $i<count($pointers); $i++) {
$currentPointerIndex = count($pointers) - $i - 1;
$currentPointer = $pointers[$currentPointerIndex];
if($currentPointer < $arrLength - $i - 1) {
++$pointers[$currentPointerIndex];
for($j=1; ($currentPointerIndex+$j)<count($pointers); $j++) {
$pointers[$currentPointerIndex+$j] = $pointers[$currentPointerIndex]+$j;
}
return true;
}
}
return false;
}
function getDataByPointers(&$arr, &$pointers) {
$data = [];
for($i=0; $i<count($pointers); $i++) {
$data[] = $arr[$pointers[$i]];
}
return $data;
}
function getCombinations($arr, $cnt)
{
$len = count($arr);
$result = [];
$pointers = initializePointers($cnt);
do {
$result[] = getDataByPointers($arr, $pointers);
} while(incrementPointers($pointers, count($arr)));
return $result;
}
$result = getCombinations([0, 1, 2, 3, 4, 5], 3);
print_r($result);
Based on https://stackoverflow.com/a/127898/2628125, but more abstract, for any size of pointers.
Here you have a lazy evaluated version of that algorithm coded in C#:
static bool nextCombination(int[] num, int n, int k)
{
bool finished, changed;
changed = finished = false;
if (k > 0)
{
for (int i = k - 1; !finished && !changed; i--)
{
if (num[i] < (n - 1) - (k - 1) + i)
{
num[i]++;
if (i < k - 1)
{
for (int j = i + 1; j < k; j++)
{
num[j] = num[j - 1] + 1;
}
}
changed = true;
}
finished = (i == 0);
}
}
return changed;
}
static IEnumerable Combinations<T>(IEnumerable<T> elements, int k)
{
T[] elem = elements.ToArray();
int size = elem.Length;
if (k <= size)
{
int[] numbers = new int[k];
for (int i = 0; i < k; i++)
{
numbers[i] = i;
}
do
{
yield return numbers.Select(n => elem[n]);
}
while (nextCombination(numbers, size, k));
}
}
And test part:
static void Main(string[] args)
{
int k = 3;
var t = new[] { "dog", "cat", "mouse", "zebra"};
foreach (IEnumerable<string> i in Combinations(t, k))
{
Console.WriteLine(string.Join(",", i));
}
}
Hope this help you!
Another version, that forces all the first k to appear firstly, then all the first k+1 combinations, then all the first k+2 etc.. It means that if you have sorted array, the most important on the top, it would take them and expand gradually to the next ones - only when it is must do so.
private static bool NextCombinationFirstsAlwaysFirst(int[] num, int n, int k)
{
if (k > 1 && NextCombinationFirstsAlwaysFirst(num, num[k - 1], k - 1))
return true;
if (num[k - 1] + 1 == n)
return false;
++num[k - 1];
for (int i = 0; i < k - 1; ++i)
num[i] = i;
return true;
}
For instance, if you run the first method ("nextCombination") on k=3, n=5 you'll get:
0 1 2
0 1 3
0 1 4
0 2 3
0 2 4
0 3 4
1 2 3
1 2 4
1 3 4
2 3 4
But if you'll run
int[] nums = new int[k];
for (int i = 0; i < k; ++i)
nums[i] = i;
do
{
Console.WriteLine(string.Join(" ", nums));
}
while (NextCombinationFirstsAlwaysFirst(nums, n, k));
You'll get this (I added empty lines for clarity):
0 1 2
0 1 3
0 2 3
1 2 3
0 1 4
0 2 4
1 2 4
0 3 4
1 3 4
2 3 4
It's adding "4" only when must to, and also after "4" was added it adds "3" again only when it must to (after doing 01, 02, 12).
Array.prototype.combs = function(num) {
var str = this,
length = str.length,
of = Math.pow(2, length) - 1,
out, combinations = [];
while(of) {
out = [];
for(var i = 0, y; i < length; i++) {
y = (1 << i);
if(y & of && (y !== of))
out.push(str[i]);
}
if (out.length >= num) {
combinations.push(out);
}
of--;
}
return combinations;
}
Clojure version:
(defn comb [k l]
(if (= 1 k) (map vector l)
(apply concat
(map-indexed
#(map (fn [x] (conj x %2))
(comb (dec k) (drop (inc %1) l)))
l))))
Algorithm:
Count from 1 to 2^n.
Convert each digit to its binary representation.
Translate each 'on' bit to elements of your set, based on position.
In C#:
void Main()
{
var set = new [] {"A", "B", "C", "D" }; //, "E", "F", "G", "H", "I", "J" };
var kElement = 2;
for(var i = 1; i < Math.Pow(2, set.Length); i++) {
var result = Convert.ToString(i, 2).PadLeft(set.Length, '0');
var cnt = Regex.Matches(Regex.Escape(result), "1").Count;
if (cnt == kElement) {
for(int j = 0; j < set.Length; j++)
if ( Char.GetNumericValue(result[j]) == 1)
Console.Write(set[j]);
Console.WriteLine();
}
}
}
Why does it work?
There is a bijection between the subsets of an n-element set and n-bit sequences.
That means we can figure out how many subsets there are by counting sequences.
e.g., the four element set below can be represented by {0,1} X {0, 1} X {0, 1} X {0, 1} (or 2^4) different sequences.
So - all we have to do is count from 1 to 2^n to find all the combinations. (We ignore the empty set.) Next, translate the digits to their binary representation. Then substitute elements of your set for 'on' bits.
If you want only k element results, only print when k bits are 'on'.
(If you want all subsets instead of k length subsets, remove the cnt/kElement part.)
(For proof, see MIT free courseware Mathematics for Computer Science, Lehman et al, section 11.2.2. https://ocw.mit.edu/courses/electrical-engineering-and-computer-science/6-042j-mathematics-for-computer-science-fall-2010/readings/ )
short python code, yielding index positions
def yield_combos(n,k):
# n is set size, k is combo size
i = 0
a = [0]*k
while i > -1:
for j in range(i+1, k):
a[j] = a[j-1]+1
i=j
yield a
while a[i] == i + n - k:
i -= 1
a[i] += 1
All said and and done here comes the O'caml code for that.
Algorithm is evident from the code..
let combi n lst =
let rec comb l c =
if( List.length c = n) then [c] else
match l with
[] -> []
| (h::t) -> (combi t (h::c))#(combi t c)
in
combi lst []
;;
Here is a method which gives you all combinations of specified size from a random length string. Similar to quinmars' solution, but works for varied input and k.
The code can be changed to wrap around, ie 'dab' from input 'abcd' w k=3.
public void run(String data, int howMany){
choose(data, howMany, new StringBuffer(), 0);
}
//n choose k
private void choose(String data, int k, StringBuffer result, int startIndex){
if (result.length()==k){
System.out.println(result.toString());
return;
}
for (int i=startIndex; i<data.length(); i++){
result.append(data.charAt(i));
choose(data,k,result, i+1);
result.setLength(result.length()-1);
}
}
Output for "abcde":
abc abd abe acd ace ade bcd bce bde cde
Short javascript version (ES 5)
let combine = (list, n) =>
n == 0 ?
[[]] :
list.flatMap((e, i) =>
combine(
list.slice(i + 1),
n - 1
).map(c => [e].concat(c))
);
let res = combine([1,2,3,4], 3);
res.forEach(e => console.log(e.join()));
Another python recusive solution.
def combination_indicies(n, k, j = 0, stack = []):
if len(stack) == k:
yield list(stack)
return
for i in range(j, n):
stack.append(i)
for x in combination_indicies(n, k, i + 1, stack):
yield x
stack.pop()
list(combination_indicies(5, 3))
Output:
[[0, 1, 2],
[0, 1, 3],
[0, 1, 4],
[0, 2, 3],
[0, 2, 4],
[0, 3, 4],
[1, 2, 3],
[1, 2, 4],
[1, 3, 4],
[2, 3, 4]]
I created a solution in SQL Server 2005 for this, and posted it on my website: http://www.jessemclain.com/downloads/code/sql/fn_GetMChooseNCombos.sql.htm
Here is an example to show usage:
SELECT * FROM dbo.fn_GetMChooseNCombos('ABCD', 2, '')
results:
Word
----
AB
AC
AD
BC
BD
CD
(6 row(s) affected)
Here is my proposition in C++
I tried to impose as little restriction on the iterator type as i could so this solution assumes just forward iterator, and it can be a const_iterator. This should work with any standard container. In cases where arguments don't make sense it throws std::invalid_argumnent
#include <vector>
#include <stdexcept>
template <typename Fci> // Fci - forward const iterator
std::vector<std::vector<Fci> >
enumerate_combinations(Fci begin, Fci end, unsigned int combination_size)
{
if(begin == end && combination_size > 0u)
throw std::invalid_argument("empty set and positive combination size!");
std::vector<std::vector<Fci> > result; // empty set of combinations
if(combination_size == 0u) return result; // there is exactly one combination of
// size 0 - emty set
std::vector<Fci> current_combination;
current_combination.reserve(combination_size + 1u); // I reserve one aditional slot
// in my vector to store
// the end sentinel there.
// The code is cleaner thanks to that
for(unsigned int i = 0u; i < combination_size && begin != end; ++i, ++begin)
{
current_combination.push_back(begin); // Construction of the first combination
}
// Since I assume the itarators support only incrementing, I have to iterate over
// the set to get its size, which is expensive. Here I had to itrate anyway to
// produce the first cobination, so I use the loop to also check the size.
if(current_combination.size() < combination_size)
throw std::invalid_argument("combination size > set size!");
result.push_back(current_combination); // Store the first combination in the results set
current_combination.push_back(end); // Here I add mentioned earlier sentinel to
// simplyfy rest of the code. If I did it
// earlier, previous statement would get ugly.
while(true)
{
unsigned int i = combination_size;
Fci tmp; // Thanks to the sentinel I can find first
do // iterator to change, simply by scaning
{ // from right to left and looking for the
tmp = current_combination[--i]; // first "bubble". The fact, that it's
++tmp; // a forward iterator makes it ugly but I
} // can't help it.
while(i > 0u && tmp == current_combination[i + 1u]);
// Here is probably my most obfuscated expression.
// Loop above looks for a "bubble". If there is no "bubble", that means, that
// current_combination is the last combination, Expression in the if statement
// below evaluates to true and the function exits returning result.
// If the "bubble" is found however, the ststement below has a sideeffect of
// incrementing the first iterator to the left of the "bubble".
if(++current_combination[i] == current_combination[i + 1u])
return result;
// Rest of the code sets posiotons of the rest of the iterstors
// (if there are any), that are to the right of the incremented one,
// to form next combination
while(++i < combination_size)
{
current_combination[i] = current_combination[i - 1u];
++current_combination[i];
}
// Below is the ugly side of using the sentinel. Well it had to haave some
// disadvantage. Try without it.
result.push_back(std::vector<Fci>(current_combination.begin(),
current_combination.end() - 1));
}
}
Here is a code I recently wrote in Java, which calculates and returns all the combination of "num" elements from "outOf" elements.
// author: Sourabh Bhat (heySourabh#gmail.com)
public class Testing
{
public static void main(String[] args)
{
// Test case num = 5, outOf = 8.
int num = 5;
int outOf = 8;
int[][] combinations = getCombinations(num, outOf);
for (int i = 0; i < combinations.length; i++)
{
for (int j = 0; j < combinations[i].length; j++)
{
System.out.print(combinations[i][j] + " ");
}
System.out.println();
}
}
private static int[][] getCombinations(int num, int outOf)
{
int possibilities = get_nCr(outOf, num);
int[][] combinations = new int[possibilities][num];
int arrayPointer = 0;
int[] counter = new int[num];
for (int i = 0; i < num; i++)
{
counter[i] = i;
}
breakLoop: while (true)
{
// Initializing part
for (int i = 1; i < num; i++)
{
if (counter[i] >= outOf - (num - 1 - i))
counter[i] = counter[i - 1] + 1;
}
// Testing part
for (int i = 0; i < num; i++)
{
if (counter[i] < outOf)
{
continue;
} else
{
break breakLoop;
}
}
// Innermost part
combinations[arrayPointer] = counter.clone();
arrayPointer++;
// Incrementing part
counter[num - 1]++;
for (int i = num - 1; i >= 1; i--)
{
if (counter[i] >= outOf - (num - 1 - i))
counter[i - 1]++;
}
}
return combinations;
}
private static int get_nCr(int n, int r)
{
if(r > n)
{
throw new ArithmeticException("r is greater then n");
}
long numerator = 1;
long denominator = 1;
for (int i = n; i >= r + 1; i--)
{
numerator *= i;
}
for (int i = 2; i <= n - r; i++)
{
denominator *= i;
}
return (int) (numerator / denominator);
}
}

Finding a loop within a Grid (Java)

I am currently working on a problem in which I have a 2D List of Characters with n rows and m columns. Said Characters in the list are either 'N', 'S', 'E', or 'W' representing the 4 coordinates.
For example, a 2D list of 4 rows and 5 columns could be represented as List<List<Character>> grid = :
SESWE
EESNW
NWEEN
EWSEN
In this problem, I also have a starting position within the grid (always somewhere on the edge). For example, in this problem my starting position would be (0,0).
The problem that I am having to solve is that I must following the directions through the grid and identify where a loop occurs, how many instructions come before the loop, and how many instructions the loop has. To follow the directions through the grid, you simply follow whatever coordinate you are at in the grid. For example, (0,0) is S or South, so you go down one element to (1, 0) which is E or East. From there you go east one coordinate to (1,1) which is another E or East. So on and so forth.
For this particular grid, if you follow the coordinates from (0,0), the path through the grid should look like the following:
In this grid, the loop itself has 8 instructions, and there are 3 instructions before the loop.
I am having a hard time coming up with an algorithm that can accomplish this goal. I thought at first that I should first follow the path through the grid and leave a little breadcrumb behind at each element that I have visited so that if I visit it again I know that I am in the loop. So in this case it would look like this after I have visited all of the elements:
. E . . E
. . . . .
N W . . .
E W S E N
I accomplished this with the following:
while (gridCopy.get(curRow).get(curCol) != '.') {
if (gridCopy.get(curRow).get(curCol) != '.') {
if (gridCopy.get(curRow).get(curCol) == 'N') {
gridCopy.get(curRow).set(curCol, '.');
curRow--;
} else if (gridCopy.get(curRow).get(curCol) == 'S') {
gridCopy.get(curRow).set(curCol, '.');
curRow++;
} else if (gridCopy.get(curRow).get(curCol) == 'W') {
gridCopy.get(curRow).set(curCol, '.');
curCol--;
} else if (gridCopy.get(curRow).get(curCol) == 'E') {
gridCopy.get(curRow).set(curCol, '.');
curCol++;
}
}
}
All this does, though, is tell me that I do in fact have a loop in the grid and doesnt tell me how many instructions the loop is and how many instructions are before the loop.
Can anyone help point me in the right direction on this?
Here's one possible implementation. Basically you store the coordinates you've traversed in a list and if the coordinate is already in that list then you've found a loop. I didn't add code to check if the search goes out of bounds so I'm assuming that all the grids are well behaved and that they all have at least one loop. Anyhow below is the code with more explanations as comments:
// Class to store the coordinates
public static class Coordinate {
private int x;
private int y;
public Coordinate(int x, int y) {
this.x = x;
this.y = y;
}
public int getX() {
return x;
}
public int getY() {
return y;
}
#Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
Coordinate that = (Coordinate) o;
if (x != that.x) return false;
return y == that.y;
}
}
Loop finder:
public static void loopFinder(List<List<Character>> grid, int startingX, int startingY) {
// Not checking if one went outside of the grid
// Store the coordinates we've traversed, if we find a duplicate then there's a loop
List<Coordinate> traversedCoordinates = new ArrayList<>();
Coordinate currentCoordinate = new Coordinate(startingX, startingY);
traversedCoordinates.add(currentCoordinate);
while (true) {
char direction = grid.get(currentCoordinate.getY()).get(currentCoordinate.getX());
switch (direction){
case 'N':
currentCoordinate = new Coordinate(currentCoordinate.getX(), currentCoordinate.getY() - 1);
break;
case 'E':
currentCoordinate = new Coordinate(currentCoordinate.getX() + 1, currentCoordinate.getY());
break;
case 'S':
currentCoordinate = new Coordinate(currentCoordinate.getX(), currentCoordinate.getY() + 1);
break;
case 'W':
currentCoordinate = new Coordinate(currentCoordinate.getX() - 1, currentCoordinate.getY());
break;
}
if(traversedCoordinates.contains(currentCoordinate)) {
// found a loop
traversedCoordinates.add(currentCoordinate);
break;
}
traversedCoordinates.add(currentCoordinate);
}
// find index of current coordinate that will give us how many instructions before the loop started
int numOfInstructionsBefore = traversedCoordinates.indexOf(currentCoordinate);
int lengthOfLoop = traversedCoordinates.size() - numOfInstructionsBefore - 1;
// I don't know if you need to include the starting and ending point of the loop
// in that case you might have to offset the two values above.
System.out.println("Number of instruction before the loop: " + numOfInstructionsBefore);
System.out.println("Length of the loop: " + lengthOfLoop);
}
Usage:
public static void main(String[] args) {
List<List<Character>> grid = new ArrayList<>();
grid.add(List.of('S', 'E', 'S', 'W', 'E'));
grid.add(List.of('E', 'E', 'S', 'N', 'W'));
grid.add(List.of('N', 'W', 'E', 'E', 'N'));
grid.add(List.of('E', 'W', 'S', 'E', 'N'));
loopFinder(grid, 0, 0);
}
Output:
Number of instruction before the loop: 3
Length of the loop: 8

How to rearrange elements of array with integer character and symbols?

I have an array in the form of
{1, a, D, 3, h, 2, C, Z, $, o, 5}
the result array should be
{1, 3, 2, 5, a, h, o, D, C, Z, $}
Where rearranged array should have numbers first , then the alphabets with lower case then the alphabets with uppercase and the special characters at last without using an another array.. how to do tat?
Thank u in advance...
private static void arrangeArrayInOrder(List<Character> arr) {
for (int i = 0; i < arr.size(); i++) {
if (arr.get(i) >= '0' && arr.get(i) <= '9') {
arr.add(arr.get(i));
arr.remove(i);
}
}
}
first i tried to move all my integers to my array last and removing it from original position and tried to do the same with remaining conditions.. but stuck here itself couldn't proceed further.
I have made my logic and it works like this:
First calculate how many numbers, small, capitals and special characters are there.
Set the starting index of each type.
Start For-loop and start inserting them at their right place.
Working Code:
public class stackLong
{
static char[] array = {'1', 'a', 'B', '2', 'h', '3', 'C', 'Z', '$', 'o', '5'};
public static void main(String[] args)
{
int number=0,small=0,capital=0,special=0;
//calculates the total number of characters of each type
for(int i =0; i<array.length;i++)
{
if (array[i]>=65 && array[i]<=90) // capital
capital++;
else if (array[i]>=97 && array[i]<=122) //small
small++;
else if (array[i]>=48 && array[i]<=57) // number
number++;
else if ((array[i]>0 && array[i]<=47)||(array[i]>=58 && array[i]<=64)|| (array[i]>=91 && array[i]<=96)||(array[i]>=123 && array[i]<=127))
special++;
}
// sets their starting index
int smallIndex = number;
int capitalIndex = small + smallIndex;
int specialIndex = capitalIndex + capital;
number = 0;
for(int i =0; i<array.length;i++)
{
if (array[i]>=48 && array[i]<=57) // number
{
swap(i,number);
number++;
}
}
for(int i =smallIndex; i<array.length;i++)
{
if (array[i]>=97 && array[i]<=122) //small
{
swap(i,smallIndex);
smallIndex++;
}
}
for(int i =capitalIndex; i<array.length;i++)
{
if (array[i]>=65 && array[i]<=90) // capital
{
swap(i,capitalIndex);
capitalIndex++;
}
}
for(int i =specialIndex; i<array.length;i++) // special
{
if ((array[i]>0 && array[i]<=47)||(array[i]>=58 && array[i]<=64)|| (array[i]>=91 && array[i]<=96)||(array[i]>=123 && array[i]<=127))
{
swap(i,specialIndex);
specialIndex++;
}
}
System.out.printf("\n");
for(int j =0; j<array.length;j++)
{
System.out.printf(array[j] + " ");
}
}
public static void swap(int frst, int scnd)
{
char temp = array[frst];
array[frst] = array[scnd];
array[scnd] = temp;
}
}
NOTE: There are several ways to do this, this may seem a bit naive but during interview they just want to know whether you are on a right track to find the solution of just beating about the bush.

Find all the combination of substrings that add up to the given string

I'm trying to create a data structure that holds all the possible substring combinations that add up to the original string. For example, if the string is "java" the valid results would be "j", "ava", "ja", "v", "a", an invalid result would be "ja", "a" or "a", "jav"
I had it very easy in finding all the possible substrings
String string = "java";
List<String> substrings = new ArrayList<>();
for( int c = 0 ; c < string.length() ; c++ )
{
for( int i = 1 ; i <= string.length() - c ; i++ )
{
String sub = string.substring(c, c+i);
substrings.add(sub);
}
}
System.out.println(substrings);
and now I'm trying to construct a structure that holds only the valid substrings. But its not nearly as easy. I'm in the mist of a very ugly code, fiddling around with the indexes, and no where near of finishing, most likely on a wrong path completely. Any hints?
Here's one approach:
static List<List<String>> substrings(String input) {
// Base case: There's only one way to split up a single character
// string, and that is ["x"] where x is the character.
if (input.length() == 1)
return Collections.singletonList(Collections.singletonList(input));
// To hold the result
List<List<String>> result = new ArrayList<>();
// Recurse (since you tagged the question with recursion ;)
for (List<String> subresult : substrings(input.substring(1))) {
// Case: Don't split
List<String> l2 = new ArrayList<>(subresult);
l2.set(0, input.charAt(0) + l2.get(0));
result.add(l2);
// Case: Split
List<String> l = new ArrayList<>(subresult);
l.add(0, input.substring(0, 1));
result.add(l);
}
return result;
}
Output:
[java]
[j, ava]
[ja, va]
[j, a, va]
[jav, a]
[j, av, a]
[ja, v, a]
[j, a, v, a]
It seems like this is the problem of finding the compositions of the length of the string, and using those compositions to make substrings. So there are 2^n-1 compositions of a number n, which could make it a bit time-consuming for long strings...
Probably somebody would like another solution which is non-recursive and takes no memory to hold a list:
public static List<List<String>> substrings(final String input) {
if(input.isEmpty())
return Collections.emptyList();
final int size = 1 << (input.length()-1);
return new AbstractList<List<String>>() {
#Override
public List<String> get(int index) {
List<String> entry = new ArrayList<>();
int last = 0;
while(true) {
int next = Integer.numberOfTrailingZeros(index >> last)+last+1;
if(next == last+33)
break;
entry.add(input.substring(last, next));
last = next;
}
entry.add(input.substring(last));
return entry;
}
#Override
public int size() {
return size;
}
};
}
public static void main(String[] args) {
System.out.println(substrings("java"));
}
Output:
[[java], [j, ava], [ja, va], [j, a, va], [jav, a], [j, av, a], [ja, v, a], [j, a, v, a]]
It just calculates the next combination based on its index.
Just in case someone will look for the same algorithm in python, here is implementation in Python:
from itertools import combinations
def compositions(s):
n = len(s)
for k in range(n):
for c in combinations(range(1, n), k):
yield tuple(s[i:j] for i, j in zip((0,) + c, c + (n,)))
Example how it works:
>>> for x in compositions('abcd'):
... print(x)
('abcd',)
('a', 'bcd')
('ab', 'cd')
('abc', 'd')
('a', 'b', 'cd')
('a', 'bc', 'd')
('ab', 'c', 'd')
('a', 'b', 'c', 'd')
With a small modification you can generate compositions in different order:
def compositions(s):
n = len(s)
for k in range(n):
for c in itertools.combinations(range(n - 1, 0, -1), k):
yield tuple(s[i:j] for i, j in zip((0,) + c[::-1], c[::-1] + (n,)))
It will give you this:
>>> for x in compositions('abcd'):
... print(x)
('abcd',)
('abc', 'd')
('ab', 'cd')
('a', 'bcd')
('ab', 'c', 'd')
('a', 'bc', 'd')
('a', 'b', 'cd')
('a', 'b', 'c', 'd')
And with another small addition, you can generate only specified number of splits:
def compositions(s, r=None):
n = len(s)
r = range(n) if r is None else [r - 1]
for k in r:
for c in itertools.combinations(range(n - 1, 0, -1), k):
yield tuple(s[i:j] for i, j in zip((0,) + c[::-1], c[::-1] + (n,)))
>>> for x in compositions('abcd', 3):
... print(x)
('ab', 'c', 'd')
('a', 'bc', 'd')
('a', 'b', 'cd')
A different recursive solution that just adds to the list results
static List<List<String>> substrings(String input) {
List<List<String>> result = new ArrayList<>();
if (input.length() == 1) {
result.add(Arrays.asList(new String[]{input}));
}
else {
//iterate j, ja, jav, jav
for (int i = 0; i < input.length()-1; i++ ) {
String root = input.substring(0,i+1);
String leaf = input.substring(i+1);
for( List<String> strings: substrings(leaf) ) {
ArrayList<String> current = new ArrayList<String>();
current.add(root);
current.addAll(strings);
result.add(current);
}
}
//adds the whole string as one of the leaves (ie. java, ava, va, a)
result.add(Arrays.asList(new String[]{input}));
}
return result;
}
This problem can be solve by this code.
public static List<String> subsets(String s) {
if(Objects.isNull(s) || s.length() ==0){
return Collections.emptyList();
}
int length = s.length();
List<String> result = new ArrayList<>();
for (int i = 0; i < length; i++) { // Group loop
String substring = "";
for (int j = 0; j < length; j++) { //
if (i + j > length - 1) {
substring = s.substring(j) + s.substring(0, ((i + j) - length) + 1);
} else {
substring = s.substring(j, j + i + 1);
}
result.add(substring);
}
}
return result;}
OUTPUT
[a, b, c, d, ab, bc, cd, da, abc, bcd, cda, dab, abcd, bcda, cdab, dabc]
You can get the count with the below formula.
print(2**(len("ABCD")-1))
here I am using ABCD as my input string.

How to do a recursive search for a word in the Boggle game board?

Can someone help me with a psuedocode or even the recursive formula that describes the recursive search for a word in the Boggle board so I can get started?
Assuming you have a word list available somewhere, likely stored in a Trie data structure (I've created a working Trie with comments on improving its efficiency here).
Once you have a Trie structure (a prefix tree) which allows you to search for words based on their prefixes, you would want to use a recursive method something like the following psudo-code.
char[][] gameBoard = new char[4][4];
List<String> wordList = new ArrayList<String>();
//fill in the game board with characters
//Start the word search at each letter
for(int x = 0; x < 4; x++){
for(int y = 0; y < 4; y++){
recursiveWordSearch(x, y, "");
}
}
recursiveWordSearch(int x, int y, String word){
//Concatenate gameBoard[x][y] to word.
//Check to see if word is a valid word (check against your word list).
//If word, add to wordList
/*Check word list to see if any words contain current prefix. If not,
then there's no point in continuing further (return). IE if AQZ isn't the
start of any word at all in the list, no reason to keep adding letters, it's
never going to make a word. */
//Otherwise recursively call this method moving left/right/up/down
recursiveWordSearch(x+1, y, word); //move right
recursiveWordSearch(x, y+1, word); //move up
recursiveWordSearch(x-1, y, word); //move left
recursiveWordSearch(x, y-1, word); //move down
/*You'll want to make sure that x-1, x+1, y-1 and y+1 are valid values before
sending them. */
}
To store valid words, data structure with methods that check is given string prefix of some valid word and is given string a valid word is needed, e.g. Trie data structure.
To find all possible valid words, we have to start word for each position, and than recursively visit each not visited neighbour. Here are two methods of python class that implements search of all valid words on given table:
def solve_with( self, ind, inds_passed, word):
word += self.table[ind[0]][ind[1]] # Add next character
if self.trie.is_prefix(word): # Is current string prefix of valid word
if len(word) > 2 and self.trie.is_word(word): # Is current string whole word
self.ret.add(word)
inds_passed.add(ind) # Set this position as visited
for n in self.neigbours(ind): # Pass through all neighbours
if n not in inds_passed: # If not visited already
self.solve_with(n, inds_passed, word) # Recursive call
inds_passed.discard(ind) # Remove position as visited
def solve(self):
self.ret = set() # Set of all word found on table
for x in xrange(0, self.dim): # Start search with each position
for y in xrange(0, self.dim):
self.solve_with( (x,y), set(), '')
return self.ret
Java implementation using DFS approach
import java.util.Arrays;
public class WordBoggle {
static int[] dirx = { -1, 0, 0, 1 };
static int[] diry = { 0, -1, 1, 0 };
public static void main(String[] args) {
char[][] board = { { 'A', 'B', 'C', 'E' }, { 'S', 'F', 'C', 'S' }, { 'A', 'D', 'E', 'E' } };
String word = "ABFSADEESCCEA";
System.out.println(exist(board, word));
}
static boolean exist(char[][] board, String word) {
if (board == null || board.length == 0 || word == null || word.isEmpty())
return false;
boolean[][] visited = new boolean[board.length][board[0].length];
for (int i = 0; i < board.length; i++) {
resetVisited(visited);
for (int j = 0; j < board[0].length; j++) {
if (board[i][j] == word.charAt(i)) {
return DFS(board, word, i, j, 1, visited);
}
}
}
return false;
}
static void resetVisited(boolean[][] visited) {
for (int l = 0; l < visited.length; l++) {
Arrays.fill(visited[l], false);
}
}
static boolean DFS(char[][] board, String word, int i, int j, int k, boolean[][] visited) {
visited[i][j] = true;
if (k >= word.length())
return true;
for (int z = 0; z < 4; z++) {
if (isValid(board, i + dirx[z], j + diry[z], visited)) {
if (word.charAt(k) == board[i + dirx[z]][j + diry[z]]) {
return DFS(board, word, i + dirx[z], j + diry[z], k + 1, visited);
}
}
}
return false;
}

Categories