I am working with gray code and I got almost everything, but when the code run, like 1-bit or 2-bit it only prints out 0000 rather than 00 01 11 10.
class GrayCode {
static void genGC(int n){
if(n == 0){
System.out.println(n);
}
else{
genGC(n-1);
genGC(n-1);
}
}
public static void main(String[] args) {
int a = 2;
genGC(a);
}
}
Your problem is that the Gray codes of the required bit length arent just the concatenation of the Grey codes of bit length one less. It's more complicated than that.
This seems to work - although there is an unnecessary amount of list copying - I may try to fix that in a later version.
/**
* Prefix every element of the list with the string.
*
* #param list - The list to prefix.
* #param prefix - The string to prefix each element.
* #return - A new prefixed list.
*/
private List<String> prefix(List<String> list, String prefix) {
List<String> prefixed = new ArrayList<>(list.size());
for (String s : list) {
prefixed.add(prefix + s);
}
return prefixed;
}
/**
* Reflect(reverse) a list.
*
* #param list - The list to reverse.
* #return The reversed list.
*/
private List<String> reflected(List<String> list) {
List<String> reflected = new ArrayList<>(list.size());
// use an ArrayList so I can reverse iterate.
for (ListIterator<String> backwards = new ArrayList<>(list).listIterator(list.size()); backwards.hasPrevious();) {
reflected.add(backwards.previous());
}
return reflected;
}
// Grey codes of one-bit numbers is (0,1).
private static final List<String> OneBit = Arrays.asList("0", "1");
public List<String> greyCodes(int bits) {
if (bits <= 1) {
return OneBit;
} else {
List<String> smaller = greyCodes(bits - 1);
// Prefix the current list with "0"
List<String> grey = prefix(smaller, "0");
// and a reflected version of that list with "1"
grey.addAll(prefix(reflected(smaller), "1"));
return grey;
}
}
The actual recursion to generate the kth Gray code having n bits is ('||' means concatenation):
G (n, k) = 1 || G (n - 1, 2n - k - 1) for k ≥ 2n - 1
G (n, k) = 0 || G (n - 1, k) for k n - 1
Using stopping conditions G (1, 0) = 0 and G (1, 1) = 1 and having 0 ≤ k ≤ 2k - 1
Note the subtraction in (2). It corresponds to the fact that the first half of the sequence of the last 4 digits is a mirror image of the second half. This is why Gray codes are sometimes called Reflected Binary Code (RBC).
If Lisp/Scheme/etc. is your thing, you could generate bit arrays with Gray codes using:
(defun gray (n k)
"Returns the kth Gray code of an n-bit sequence. Output is in the form of a bit array."
(assert (< k (expt 2 n)) (n) "k cannot be higher than ~A~%" (1- (expt 2 n)))
(cond
((= n 1)
(if (zerop k) #*0 #*1))
((>= k (expt 2 (1- n)))
(concatenate 'bit-vector #*1 (gray (1- n) (- (expt 2 n) k 1))))
(t
(concatenate 'bit-vector #*0 (gray (1- n) k)))))
NB. cond above works like switch/case in Java. The function above is a straightforward implementation of the recursive formula above.
If Lisp is not your thing and if recursion is not an absolute requirement for your program, you can amend your code by implementing the formula:
gray = num ^ (num >> 1)
Cheers,
Paulo
Here is a fairly simple Java recursive program that takes a positive integer n and produces n-bit Gray codes:
public static String swap(String s, String r, int i)
{
i = i-1;
String t = s.substring(0,i) + r + s.substring(i+1);
return t;
}
swap takes a string and changes its i-1 character with another string that contains only one character.
public static void beckett(int n, String s)
{
if (n == 0) return;
beckett(n-1, s);
System.out.println(swap(s, "1", n)); s = swap(s, "1", n);
beckett(n-1, s);
}
beckett (in reference to one of Beckett's plays named Quad) produces the Gray codes.
public static void grayCodes(int n)
{
String s = "";
for (int i = 0; i < n; i++)
s += "0";
System.out.println(s);
beckett(n, s);
}
grayCodes makes working with beckett easier (merely reduces the number of inputs).
You can test the above methods with:
public static void main(String[] args)
{
int n = Integer.parseInt(args[0]);
grayCodes(n);
}
For the sample input 3 it gives the following output:
000
100
010
110
001
101
011
111
Hope this helps.
Related
This is the question:
You are given Q queries. Each query consists of a single number N . You can perform any of the operations on in each move:
If we take 2 integers a and b where N=a*b (a ,b cannot be equal to 1), then we can change N=max(a,b)
Decrease the value of N by 1 .
Determine the minimum number of moves required to reduce the value of to .
Input Format
The first line contains the integer Q.
The next Q lines each contain an integer,N .
Output Format
Output Q lines. Each line containing the minimum number of moves required > to reduce the value of N to 0.
I have written the following code. This code is giving some wrong answers and also giving time limit exceed error . Can you tell what are the the mistakes present in my code ? where or what I am doing wrong here?
My code:
public static int downToZero(int n) {
// Write your code here
int count1=0;
int prev_i=0;
int prev_j=0;
int next1=0;
int next2=Integer.MAX_VALUE;
if (n==0){
return 0;
}
while(n!=0){
if(n==1){
count1++;
break;
}
next1=n-1;
outerloop:
for (int i=1;i<=n;i++){
for (int j=1;j<=n;j++){
if (i*j==n){
if (prev_i ==j && prev_j==i){
break outerloop;
}
if (i !=j){
prev_i=i;
prev_j=j;
}
int max=Math.max(i,j);
if (max<next2){
next2=max;
}
}
}
}
n=Math.min(next1,next2);
count1++;
}
return count1;
}
This is part is coded for us:
public class Solution {
public static void main(String[] args) throws IOException {
BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(System.in));
BufferedWriter bufferedWriter = new BufferedWriter(new FileWriter(System.getenv("OUTPUT_PATH")));
int q = Integer.parseInt(bufferedReader.readLine().trim());
for (int qItr = 0; qItr < q; qItr++) {
int n = Integer.parseInt(bufferedReader.readLine().trim());
int result = Result.downToZero(n);
bufferedWriter.write(String.valueOf(result));
bufferedWriter.newLine();
}
bufferedReader.close();
bufferedWriter.close();
}
}
Ex: it is not working for number 7176 ....
To explore all solution tree and find globally optimal solution, we must choose the best result both from all possible divisor pairs and from solution(n-1)
My weird translation to Java (ideone) uses bottom-up dynamic programming to make execution faster.
We calculate solutions for values i from 1 to n, they are written into table[i].
At first we set result into 1 + best result for previous value (table[i-1]).
Then we factor N into all pairs of divisors and check whether using already calculated result for larger divisor table[d] gives better result.
Finally we write result into the table.
Note that we can calculate table once and use it for all Q queries.
class Ideone
{
public static int makezeroDP(int n){
int[] table = new int[n+1];
table[1] = 1; table[2] = 2; table[3] = 3;
int res;
for (int i = 4; i <= n; i++) {
res = 1 + table[i-1];
int a = 2;
while (a * a <= i) {
if (i % a == 0)
res = Math.min(res, 1 + table[i / a]);
a += 1;
}
table[i] = res;
}
return table[n];
}
public static void main (String[] args) throws java.lang.Exception
{
int n = 145;//999999;
System.out.println(makezeroDP(n));
}
}
Old part
Simple implementation (sorry, in Python) gives answer 7 for 7176
def makezero(n):
if n <= 3:
return n
result = 1 + makezero(n - 1)
t = 2
while t * t <= n:
if n % t == 0:
result = min(result, 1 + makezero(n // t))
t += 1
return result
In Python it's needed to set recursion limit or change algorithm. Now use memoization, as I wrote in comments).
t = [-i for i in range(1000001)]
def makezeroMemo(n):
if t[n] > 0:
return t[n]
if t[n-1] < 0:
res = 1 + makezeroMemo(n-1)
else:
res = 1 + t[n-1]
a = 2
while a * a <= n:
if n % a == 0:
res = min(res, 1 + makezeroMemo(n // a))
a += 1
t[n] = res
return res
Bottom-up table dynamic programming. No recursion.
def makezeroDP(n):
table = [0,1,2,3] + [0]*(n-3)
for i in range(4, n+1):
res = 1 + table[i-1]
a = 2
while a * a <= i:
if i % a == 0:
res = min(res, 1 + table[i // a])
a += 1
table[i] = res
return table[n]
We can construct the directed acyclic graph quickly with a sieve and
then compute shortest paths. No trial division needed.
Time and space usage is Θ(N log N).
n_max = 1000000
successors = [[n - 1] for n in range(n_max + 1)]
for a in range(2, n_max + 1):
for b in range(a, n_max // a + 1):
successors[a * b].append(b)
table = [0]
for n in range(1, n_max + 1):
table.append(min(table[s] for s in successors[n]) + 1)
print(table[7176])
Results:
7
EDIT:
The algorithm uses Greedy approach and doesn't return optimal results, it just simplifies OP's approach. For 7176 given as example, below algorithm returns 10, I can see a shorter chain of 7176 -> 104 -> 52 -> 13 -> 12 -> 4 -> 2 -> 1 -> 0 with 8 steps, and expected answer is 7.
Let's review your problem in simple terms.
If we take 2 integers a and b where N=a*b (a ,b cannot be equal to 1), then we can change N=max(a,b)
and
Determine the minimum number of moves required to reduce the value of to .
You're looking for 2 factors of N, a and b and, if you want the minimum number of moves, this means that your maximum at each step should be minimum. We know for a fact that this minimum is reached when factors are closest to N. Let me give you an example:
36 = 1 * 36 = 2 * 18 = 3 * 12 = 4 * 9 = 6 * 6
We know that sqrt(36) = 6 and you can see that the minimum of 2 factors you can get at this step is max(6, 6) = 6. Sure, 36 is 6 squared, let me take a number without special properties, 96, with its square root rounded down to nearest integer 9.
96 = 2 * 48 = 3 * 32 = 4 * 24 = 6 * 16 = 8 * 12
You can see that your minimum value for max(a, b) is max(8, 12) = 12, which is, again, attained when factors are closest to square root.
Now let's look at the code:
for (int i=1;i<=n;i++){
for (int j=1;j<=n;j++){
if (i*j==n){
You can do this in one loop, knowing that n / i returns an integer, therefore you need to check if i * (n / i) == n. With the previous observation, we need to start at the square root, and go down, until we get to 1. If we got i and n / i as factors, we know that this pair is also the minimum you can get at this step. If no factors are found and you reach 1, which obviously is a factor of n, you have a prime number and you need to use the second instruction:
Decrease the value of N by 1 .
Note that if you go from sqrt(n) down to 1, looking for factors, if you find one, max(i, n / i) will be n / i.
Additionally, if n = 1, you take 1 step. If n = 2, you take 2 steps (2 -> 1). If n = 3, you take 3 steps (3 -> 2 -> 1). Therefore if n is 1, 2 or 3, you take n steps to go to 0. OK, less talking, more coding:
static int downToZero(int n) {
if (n == 1 || n == 2 || n == 3) return n;
int sqrt = (int) Math.sqrt(n);
for (int i = sqrt; i > 1; i--) {
if (n / i * i == n) {
return 1 + downToZero(n / i);
}
}
return 1 + downToZero(n - 1);
}
Notice that I'm stopping when i equals 2, I know that if I reach 1, it's a prime number and I need to go a step forward and look at n - 1.
However, I have tried to see the steps your algorithm and mine takes, so I've added a print statement each time n changes, and we both have the same succession: 7176, 92, 23, 22, 11, 10, 5, 4, 2, 1, which returns 10. Isn't that correct?
So, I found a solution which is working for all the test cases -
static final int LIMIT = 1_000_000;
static int[] solutions = buildSolutions();
public static int downToZero(int n) {
// Write your code here
return solutions[n];
}
static int[] buildSolutions() {
int[] solutions = new int[LIMIT + 1];
for (int i = 1; i < solutions.length; i++) {
solutions[i] = solutions[i - 1] + 1;
for (int j = 2; j * j <= i; j++) {
if (i % j == 0) {
solutions[i] = Math.min(solutions[i], solutions[i / j] + 1);
}
}
}
return solutions;
}
}
So here is the thing.
I have to write code to show a binary number X's next smallest "code-X number" which is bigger than binary number X.
code-X number is a binary number which have no continuously 1. For example: 1100 is not a code X number because it has 11, and 1001001001 is a code-X number
Here is my code
String a = "11001110101010";
String b = "";
int d = 0;
for(int i = a.length()-1; i>0;i--){
if(a.charAt(i) == '1' && a.charAt(i-1)=='1'){
while(a.charAt(i)=='1'){
b = b + '0';
if(i!=0){i--;}
d++;
}
}
b = b + a.charAt(i);
}
StringBuffer c = new StringBuffer(b);
System.out.println(c.reverse());
I plan on copy the binary string to string b, replace every '1' which next i is '1' into '0' and insert an '1'
like:
1100 ---> 10000
but i have no idea how to do it :)
May you help me some how? Thanks
Try this. This handles arbitrary length bit strings. The algorithm is as follows.
Needed to conditionally modify last two bits to force a change if the number is not a codeEx number. This ensures it will be higher. Thanks to John Mitchell for this observation.
Starting from the left, find the first group of 1's. e.g 0110
If not at the beginning replace it with 100 to get 1000
Otherwise, insert 1 at the beginning.
In all cases, replace everything to the right of the grouping with 0's.
String x = "10000101000000000001000001000000001111000000000000110000000000011011";
System.out.println(x.length());
String result = codeX(x);
System.out.println(x);
System.out.println(result);
public static String codeX(String bitStr) {
StringBuilder sb = new StringBuilder(bitStr);
int i = 0;
int len = sb.length();
// Make adjust to ensure new number is larger than
// original. If the word ends in 00 or 10, then adding one will
// increase the value in all cases. If it ends in 01
// then replacing with 10 will do the same. Once done
// the algorithm takes over to find the next CodeX number.
if (s.equals("01")) {
sb.replace(len - 2, len, "10");
} else {
sb.replace(len- 1, len, "1");
}
while ((i = sb.indexOf("11")) >= 0) {
sb.replace(i, len, "0".repeat(len - i));
if (i != 0) {
sb.replace(i - 1, i + 2, "100");
} else {
sb.insert(i, "1");
}
}
String str = sb.toString();
i = str.indexOf("1");
return i >= 0 ? str.substring(i) : str;
}
Prints
10000101000000000001000001000000001111000000000000110000000000011011
10000101000000000001000001000000010000000000000000000000000000000000
Using raw binary you can use the following.
public static void main(String[] args) {
long l = 0b1000010100000000010000010000000011110000000000110000000000011011L;
System.out.println(
Long.toBinaryString(nextX(l)));
}
public static long nextX(long l) {
long l2 = l >>> 1;
long next = Long.highestOneBit(l & l2);
long cutoff = next << 1;
long mask = ~(cutoff - 1);
return (l & mask) | cutoff;
}
prints
1000010100000000010000010000000010000000000000000000000000000000
EDIT: Based on #WJS correct way to find the smallest value just larger.
This is a slight expansion WJS' 99% correct answer.
There is just one thing missing, the number is not incremented if there are no consecutive 1's in the original X string.
This modification to the main method handles that.
Edit; Added an else {}. Starting from the end of the string, all digits should be inverted until a 0 is found. Then we change it to a 1 and break before passing the resulting string to WJS' codeX function.
(codeX version does not include sb.replace(len-2,len,"11");)
public static void main(String[] args) {
String x = "10100";
StringBuilder sb = new StringBuilder(x);
if (!x.contains("11")) {
for (int i = sb.length()-1; i >= 0; i--) {
if (sb.charAt(i) == '0') {
sb.setCharAt(i, '1');
break;
} else {
sb.setCharAt(i, '0');
}
}
}
String result = codeX(sb.toString());
System.out.println(x);
System.out.println(result);
}
I am trying to add two binary numbers and then get their sum in binary system. I got their sum in decimal and now I am trying to turn it into binary. But there is problem that when I take their sum (in decimal) and divide by 2 and find remainders(in while loop), I need to put remainders into array in order print its reverse. However, there is an error in array part. Do you have any suggestions with my code? Thanks in advance.
Here is my code:
import java.util.Scanner;
public class ex1 {
public static void main(String[] args) {
Scanner scan = new Scanner(System.in);
int n = scan.nextInt();
int m = scan.nextInt();
int k = dec1(n)+dec2(m);
int i=0,c;
int[] arr= {};
while(k>0) {
c = k % 2;
k = k / 2;
arr[i++]=c; //The problem is here. It shows some //error
}
while (i >= 0) {
System.out.print(arr[i--]);
}
}
public static int dec1(int n) {
int a,i=0;
int dec1 = 0;
while(n>0) {
a=n%10;
n=n/10;
dec1= dec1 + (int) (a * Math.pow(2, i));
i++;
}
return dec1;
}
public static int dec2(int m) {
int b,j=0;
int dec2 = 0;
while(m>0) {
b=m%10;
m=m/10;
dec2= dec2 + (int) (b * Math.pow(2, j));
j++;
}
return dec2;
}
}
Here:
int[] arr= {};
creates an empty array. Arrays don't grow dynamically in Java. So any attempt to access any index of arr will result in an ArrayIndexOutOfBounds exception. Because empty arrays have no "index in bounds" at all.
So:
first ask the user for the count of numbers he wants to enter
then go like: int[] arr = new int[targetCountProvidedByUser];
The "more" real answer would be to use List<Integer> numbersFromUsers = new ArrayList<>(); as such Collection classes allow for dynamic adding/removing of elements. But for a Java newbie, you better learn how to deal with arrays first.
Why are you using two different methods to do the same conversion? All you need is one.
You could have done this in the main method.
int k = dec1(n)+dec1(m);
Instead of using Math.pow which returns a double and needs to be cast, another alternative is the following:
int dec = 0;
int mult = 1;
int bin = 10110110; // 128 + 48 + 6 = 182.
while (bin > 0) {
// get the right most bit
int bit = (bin % 10);
// validate
if (bit < 0 || bit > 1) {
throw new IllegalArgumentException("Not a binary number");
}
// Sum up each product, multiplied by a running power of 2.
// this is required since bits are taken from the right.
dec = dec + mult * bit;
bin /= 10;
mult *= 2; // next power of 2
}
System.out.println(dec); // prints 182
An alternative to that is to use a String to represent the binary number and take the bits from the left (high order position).
String bin1 = "10110110";
int dec1 = 0;
// Iterate over the characters, left to right (high to low)
for (char b : bin1.toCharArray()) {
// convert to a integer by subtracting off character '0'.
int bit = b - '0';
// validate
if (bit < 0 || bit > 1) {
throw new IllegalArgumentException("Not a binary number");
}
// going left to right, first multiply by 2 and then add the bit
// Each time thru, the sum will be multiplied by 2 which shifts everything left
// one bit.
dec1 = dec1 * 2 + bit;
}
System.out.println(dec1); // prints 182
One possible way to display the result in binary is to use a StringBuilder and simply insert the converted bits to characters.
public static String toBin(int dec) {
StringBuilder sb = new StringBuilder();
while (dec > 0) {
// by inserting at 0, the bits end up in
// correct order. Adding '0' to the low order
// bit of dec converts to a character.
sb.insert(0, (char) ((dec & 1) + '0'));
// shift right for next bit to convert.
dec >>= 1;
}
return sb.toString();
}
public static int reverse(int n) {
int result = 0;
while (n > 0) {
result = result * 10 + n % 10;
n = n / 10;
}
return result;
}
I'm trying to reverse the digits of integer. Instead of doing the codes like what I have done, is there any other way to do it? Can i reverse it using java stream?
Another way would be
int digits = 12345;
StringBuilder buf = new StringBuilder(String.valueOf(digits));
System.out.println(buf.reverse());
System.out.println(Integer.valueOf(buf.toString()));
OK, here's a fun implementation with IntStream:
public static int reverse (int n) {
return IntStream.iterate (n, i -> i/10) // produces a infinite IntStream of n, n/10,
// n/100, ...
.limit(10) // 10 elements are sufficient, since int has <= 10 digits
.filter (i -> i > 0) // remove any trailing 0 elements
.map(i -> i % 10) // produce an IntStream of the digits in reversed
// order
.reduce (0, (r,i) -> r*10 + i); // reduce the reversed digits back
// to an int
}
For example, for the input 123456789, it will first generate the infinite IntStream:
123456789,12345678,1234567,123456,12345,1234,123,12,1,0,0,...
After limiting to 10 elements and removing the 0s, we are left with:
123456789,12345678,1234567,123456,12345,1234,123,12,1
After mapping each element to its last digit, we get:
9,8,7,6,5,4,3,2,1
Now we just have to reduce the IntStream in a manner similar to what you did in your question - add each element to the intermediate result multiplied by 10:
((((0 * 10 + 9) * 10 + 8) * 10 + 7) * 10 ....) * 10 + 1
Note that if the input number has 10 digits and the last digit > 1, the reversed result will overflow.
It also doesn't support negative input.
One more stream and Math fun implementation.
public static long reverse(int n) {
return Stream.iterate(
Map.entry(0, n % 10),
entry -> Math.pow(10, entry.getKey()) <= n,
entry -> Map.entry(entry.getKey() + 1,
(int) (n % (int) Math.pow(10, entry.getKey() + 2) / Math.pow(10, entry.getKey() + 1))))
.map(Map.Entry::getValue)
.map(Integer::longValue)
.reduce(0L, (r, i) -> r * 10 + i);
}
You should return long in your method, anyway. But StringBuilder is the best here.
A Stream solution which returns for a given number the reversed String:
int n = 10101010;
String reveresed = String.valueOf(n)
.chars()
.mapToObj(Character::getNumericValue)
.reduce("", (l, r) -> r + l, (l, r) -> l + r);
System.out.println(reveresed); // 01010101
If we convert the reversed String to an Integer and print it we will lose the leading zero:
System.out.println(Integer.valueOf(reveresed).toString()); // 1010101
Along with the other answers, you can try this implementation as well.
public class MyStreamReverser {
public static void main(String[] args) {
streamApiReverser(-9008);
// other outputs to test:
// streamApiReverser(20000090);
// streamApiReverser(-04);
// streamApiReverser(39-02);
}
private static void streamApiReverser(int n) {
// produce an array of strings each having one digit
String[] stringArray = String.valueOf(n).split("\\B");
Stream<String> stringStream = Arrays.stream(stringArray);
stringStream.collect(Collectors.toCollection(LinkedList::new))
.descendingIterator()
.forEachRemaining(System.out::println);
}
}
Output:
8
0
0
-9
Note - Does not play well with leading zeros. 09 doesn't work (since those are treated as octals), works with trailing zeros, should be fine with negatives (but further testing needed).
An easy way to reverse an integer is to parse it into a string, reverse it, and parse it back into a integer.
public static int reverse(int num) {
StringBuffer stringBuffer = new StringBuffer(String.valueOf(num););
stringBuffer.reverse();
return Integer.parseInt(stringBuffer.toString());
}
the quickest answer will be :
public int reverse(int x) {
int rev = 0;
while (x != 0) {
int pop = x%10;
x /= 10;
if (rev > Integer.MAX_VALUE/10 || (rev == Integer.MAX_VALUE / 10 && pop > 7)) return 0;
if (rev < Integer.MIN_VALUE/10 || (rev == Integer.MIN_VALUE / 10 && pop < -8)) return 0;
rev = rev*10+pop;
}
return rev;
}
Given a sequence which contains only various amounts of the numbers 1, 2, 3, and 4 (examples: 13244, 4442, etc), I want to count all its permutations such that no two adjacent numbers are the same. I believe it is O(N! * N) and want to know if there is a better one out there. Anyone have any ideas?
class Ideone
{
static int permutationCount++;
public static void main(String[] args) {
String str = "442213";
permutation("", str);
System.out.println(permutationCount);
}
private static void permutation(String prefix, String str) {
int n = str.length();
if (n == 0){
boolean bad = false;
//Check whether there are repeating adjacent characters
for(int i = 0; i < prefix.length()-1; i++){
if(prefix.charAt(i)==prefix.charAt(i+1))
bad = true;
}
if(!bad){
permutationCount++;
}
}
else {
//Recurse through permutations
for (int i = 0; i < n; i++)
permutation(prefix + str.charAt(i), str.substring(0, i) + str.substring(i+1, n));
}
}
}
I understand your question like this: Given a string containing only numbers 1,2,3,4 - how many permutations of these characters exist that when you put them into string again there won't be any same adjecent numbers.
I would suggest this approach:
L - length of your string
n1 - how many times is 1 repeated, n2 - how many times is 2 repeated etc.
P - number of all possible permutations
P = L! / (n1!*n2!*n3!*n4!)
C - number of all solutions fitting your constraint
C = P - start with all permutations
substract all permutations which have 11 in it (just take 11 as one number)
C = C - (L - 1)! / ((n1 - 1)! * n2! * n3! * n4!)
... do the same for 22 ...
add all permutations which have both 11 and 22 in it (because we have substracted them twice, so you need to add them)
C = C + (L - 2)! / ((n1 - 1)! * (n2 - 1)! * n3! * n4!)
... repeat previous steps for 33 and 44 ...
If you just want to calculate how many permutations match your constraint, it is not required to spell each of them out.
If I get your question right, your input string has 4 distinct input characters 1,2,3,4 and you want to know how many permutations of this are possible?
Then you should use some maths, namely n! / (n-r)!, where n is the number of elements to choose from (4 in this case) and r is the number of positions you want to fill (also 4).
Your example would have 4! / (4-4)! = 24 permutations possible:
{1,2,3,4} {1,2,4,3} {1,3,2,4} {1,3,4,2} {1,4,2,3} {1,4,3,2}
{2,1,3,4} {2,1,4,3} {2,3,1,4} {2,3,4,1} {2,4,1,3} {2,4,3,1}
{3,1,2,4} {3,1,4,2} {3,2,1,4} {3,2,4,1} {3,4,1,2} {3,4,2,1}
{4,1,2,3} {4,1,3,2} {4,2,1,3} {4,2,3,1} {4,3,1,2} {4,3,2,1}
In a nutshell, for length n with n distinct values the count of permutations is n!:
1 -> 1
2 -> 2
3 -> 6
4 -> 24
5 -> 120
...
Edit: After your edits and comments it is clear that I misunderstood the question.
If you just want to check to see if there are no matching adjacent numbers, then you can use a simple loop. This will be O(n) complexity.
public static void main(String[] args) {
String str = "442213";
System.out.println(permutation(str));
}
public static int permutation(String str) {
int permutationCount = 0;
if (str.length() > 1) {
for (int i = 0; i < str.length() - 1; i++) {
if (str.charAt(i) != str.charAt(i + 1)) {
permutationCount++;
}
}
}
return permutationCount;
}
If you wanted to stick with recursion, you could do something like this:
public static void main(String[] args) {
String str = "442213";
System.out.println(permutation(str, 0));
}
public static int permutation(String str, int currentIndex) {
int permutationCount = 0;
if (str == null || currentIndex + 1 >= str.length()) {
return permutationCount;
}
if (str.charAt(currentIndex) != str.charAt(currentIndex + 1)) {
permutationCount = 1;
}
return permutationCount + permutation(str, currentIndex + 1);
}