Counting with Java - java

I have two given Strings: String a = "111" and String b = "132", for these two String I want to achieve this count order:
111
112
121
122
131
132
Other example is if I have two given String like this: String a = "1111" and String b = "1223", I expect this result:
1111
1112
1113
1121
1122
1123
1211
1212
1213
1221
1222
1223
These can be also longer strings like String a = "0100110" and String b = "01101120".
I'm waiting these Strings from user in condition that every character in String a should be lower or equal than the same character position in String b (String a = "11" and String b = "00" <= not allowed)
This is a recursive method till now but it doesn't work very well because it generates number twice or more depending on the input:
public void expand(String l,String h){
for(int i=l.length()-1; i>=0; i--)
{
sb = new StringBuffer(l);
if(charToDigit(l.charAt(i)) < charToDigit(h.charAt(i))) {
sb.replace(i, i+1, inc(sb.charAt(i)));
expand(sb.toString(),h);
System.out.println(sb.toString());
}
}
}

Call the smaller number x and the larger number y. If you calculate y mod 10 (y % 10), you will find the value of the least significant digit, call this n. Similarly, calculate the least significant digit of x, call it m Then, create a temporary variable i which is equal to x initially. Loop until that number is equal to y.
In the body of the loop, first, print i. Then, if the least significant digit of i (again, calculated by i % 10), call it o, is less than n, increment i by one. Otherwise, if o == n, increase i by 10 - n + m. Naturally, if it is ever the case that o > n, something went wrong (i.e. invalid input from the user), since the guarantee was that all digits of x are less than or equal to the corresponding digits in y.
So, in pseudocode:
x = smaller number
y = larger number
n = y % 10
m = x % 10
i = x
while (i <= y):
print i
o = i % 10
if (o < n):
i += 1
else if (o == n):
i += 10 - n + m

Here is my solution
static String l="000";
static String h="232";
static ArrayList<String> combinations = new ArrayList<String>();
static int stringLength= l.length();
for(int i=0; i<rulelength; i++)
{
combinations.add((charToDigit(h.charAt(i)) - charToDigit(l.charAt(i))+1)+"");
}
int number = 1;
for(int i=0; i<combinations.size(); i++)
{
number*=Integer.parseInt(combinations.get(i));
}
int change = Integer.parseInt(combinations.get(combinations.size()-1));
expand(l, h, change, number);
public static void expand(String l, String h, int change, int comb)
{
StringBuffer sb = new StringBuffer(l);
int pos = stringLength-1;
int tmpPos = pos;
for(int i=1; i<=comb; i++)
{
System.out.println(sb.toString());
sb.replace(pos, pos+1, inc(sb.charAt(pos)));
if((i % change)==0) {
for(int j=stringLength-1; j>0; j--)
{
if(charToDigit(sb.charAt(j)) >= (Integer.parseInt(combinations.get(j))-1))
tmpPos = j-1;
else
break;
}
sb.replace(tmpPos, tmpPos+1, inc(sb.charAt(tmpPos)));
for(int j=stringLength-1; j>tmpPos; j--)
{
sb.replace(j, j+1, l.charAt(j)+"");
}
}
}
}

Related

Count the prime groups

Given an input string of digits, split that into groups of prime numbers by maintaining the order given in the input string and each group should hold all the characters of the input string. Find the count of such groups.
Example:
11375
Ans:
3
Explanation:
The 3 combinations are [11,37,5], [11,3,7,5] and [113,7,5]
Code that I tried
public int countPossibilities(String s) {
int n = s.length();
int[] ar = new int[n + 1];
ar[0] = 1;
for (int i = 1; i < n; i++) {
int j = i - 1;
while (j >= 0 && j >= i - 3) {
if (prime(s.substring(j, i)))
ar[i] += ar[j];
j--;
}
}
return ar[n];
}
public boolean prime(String s) {
int n = Integer.parseInt(s);
if (n < 2) return false;
for (int i = 2; i * i <= n; i++)
if (n % i == 0) return false;
return true;
}
This works fine if the input string length is small.
But the length of the input string can be from 1 to 10^5. So my program fails for large strings.
Example:
1350297079989171477791892123929141605573631151125933376097791877830238462471373933362476484818693477173990672289892448124097556197582379957168911392680312103962394732707409889862447273901522659
Expected result is : 4386816
What is the right approach to solve this problem.
Here's working Python code that answers your long example.
Let dp[i] represent the number of valid combinations ending at the ith index of the input. Then for each prime suffix of length x ending at input[i], we add to dp[i] the count of valid combinations ending at dp[i-x], provided there is also a count of valid combinations recorded for dp[i-x].
# https://rosettacode.org/wiki/Sieve_of_Eratosthenes
def primes2(limit):
if limit < 2: return []
if limit < 3: return [2]
lmtbf = (limit - 3) // 2
buf = [True] * (lmtbf + 1)
for i in range((int(limit ** 0.5) - 3) // 2 + 1):
if buf[i]:
p = i + i + 3
s = p * (i + 1) + i
buf[s::p] = [False] * ((lmtbf - s) // p + 1)
return set(["2"] + [str(i + i + 3) for i, v in enumerate(buf) if v])
def f(n):
# The constant, k, limits the number
# of digits in the suffix we're
# checking for primality.
k = 6
primes = primes2(10**k)
dp = [0] * len(n) + [1]
for i in range(len(n)):
suffix = ""
for j in range(min(i + 1, k)):
suffix = n[i-j] + suffix
if suffix in primes and dp[i-j-1] > 0:
dp[i] += dp[i-j-1]
return dp[len(n) - 1]
Output:
n = "1350297079989171477791892123929141605573631151125933376097791877830238462471373933362476484818693477173990672289892448124097556197582379957168911392680312103962394732707409889862447273901522659"
print(f(n)) # 4386816
Proof of concept from my comments, but in C# (I'm an AP Comp Sci teacher that doesn't like to code in Java; go figure!):
Take the length of the input string minus 1 and call this "padLength".
Now raise 2 to the power of padLength to get the total number of
possibilities for string combinations; call this number
"numberOfCombinations". Next, count from 0 to numberOfCombinations and
convert that decimal number to a BINARY number, left padded with
zeroes out to padLength, called "binaryNumber". The binary number
represents whether or not a space should be added in-between the
digits of the original number. For instance, binary "1100" and dec
"11375" would result in "1 1 375" because 1 means put a space
in-between. This process will give you all combinations of the
original string in the different groups. Then you can extract the
numbers from the groups and see if they are primes...
Code:
private async void button1_Click(object sender, EventArgs e)
{
if (textBox1.Text.Trim().Length == 0) { return; }
textBox1.Enabled = false;
button1.Enabled = false;
textBox2.Clear();
String binary;
StringBuilder sb = new StringBuilder();
String input = textBox1.Text.Trim();
char[] digits = input.ToCharArray();
int padLength = input.Length - 1;
long combinations = (long)Math.Pow(2, padLength);
List<String> combos = new List<string>();
await Task.Run(() => {
for (long i = 0; i < combinations; i++)
{
binary = Convert.ToString(i, 2).ToString().PadLeft(padLength, '0');
char[] binaryDigits = binary.ToCharArray();
sb.Clear();
for (int s = 0; s < digits.Length; s++)
{
sb.Append(digits[s]);
if (s < (digits.Length - 1))
{
if (binaryDigits[s] == '1')
{
sb.Append(' ');
}
}
}
combos.Add(sb.ToString());
}
});
textBox2.Lines = combos.ToArray();
textBox1.Enabled = true;
button1.Enabled = true;
}
Output:
For very large inputs, you won't be able to compute the number of combinations using Math.Pow(), or any built-in methods for converting a decimal to a binary number. In those cases, you can "count manually" in binary by using a String directly and following the counting algorithm. You'd build the binary numbers using only String manipulation directly by inspecting each char to see if it is 1 or 0 and acting accordingly. You'll know you're done when you have a string of ones that has a length one less than the length of your input. It will run a lot slower than working with numbers directly.

Having trouble filling an array of binary numbers from an integer

This is the question we were assigned :
Nine coins are placed in a 3x3 matrix with some face up and some face down. You can represent the state of the coins using a 3x3 matrix with values 0 (heads) and 1 (tails). Here are some examples:
0 0 0 1 0 1 1 1 0
0 1 0 0 0 1 1 0 0
0 0 0 1 0 0 0 0 1
Each state can also be represented using a binary number. For example, the preceding matrices correspond to the numbers:
000010000 101001100 110100001
There are a total of 512 possibilities, so you can use decimal numbers 0, 1, 2, 3,...,511 to represent all the states of the matrix.
Write a program that prompts the user to enter a number between 0 and 511 and displays the corresponding matrix with the characters H and T.
I want the method toBinary() to fill the array binaryNumbers. I realized that this does not fill in 0s to the left. I have to think that through but is that the only thing that is the problem?
//https://www.geeksforgeeks.org/java-program-for-decimal-to-binary-conversion/
import java.util.Scanner;
public class HeadsAndTails {
public static void main(String[] args) {
Scanner input = new Scanner(System.in);
int num = input.nextInt();
int[] binaryNumbers = toBinary(num);
for (int i = 0; i < 9; i++) {
printArr(binaryNumbers);
System.out.print(binaryNumbers[1]);
}
}
public static int[] toBinary(int inputtedNumber) {
int[] binaryNum = new int[9];
int i = 0;
while (inputtedNumber > 0) {
binaryNum[i] = inputtedNumber % 2;
inputtedNumber = inputtedNumber/2;
inputtedNumber++;
} return binaryNum;
}
public static void printArr(int[] arr) {
for (int i = 0; i < 9; i++) {
if (arr[i] == 0) {
System.out.print("H ");
} else {
System.out.print("T ");
}
if (arr[i+1] % 3 == 0) {
System.out.println();
} System.out.print(arr[i]);
}
}
}
Looks like you are incrementing the wrong variable in your while loop:
while (inputtedNumber > 0) {
binaryNum[i] = inputtedNumber % 2;
inputtedNumber = inputtedNumber/2;
i++; // NOT inputtedNumber
} return binaryNum;
Also note, a new int[9] is probably already initialized to 0, but if not, you could just loop 9 times, rather than until the inputtedNumber is 0:
for (int i = 0; i < 9; i++) {
binaryNum[i] = inputtedNumber % 2;
inputtedNumber = inputtedNumber/2;
}
return binaryNum;
Finally, I think your array might be backwards when you're done, so you may need to reverse it or output it in reverse order
I realize this is a homework assignment so you should stick with your current approach. However, sometimes it can be fun to see what can be achieved using the built in features of Java.
The Integer class has a method toBinaryString that's a good starting point:
int n = 23;
String s1 = Integer.toBinaryString(n);
System.out.println(s1);
Output: 10111
But as we can see, this omits leading 0s. We can get these back by making sure our number has a significant digit in the 10th place, using a little bit-twiddling:
String s2 = Integer.toBinaryString(1<<9 | n);
System.out.println(s2);
Output: 1000010111
But now we have a leading 1 that we don't want. We'll strip this off using String.substring, and while we're at it we'll use String.replace to replace 0 with H and 1 with T:
String s3 = Integer.toBinaryString(1<<9 | n).substring(1).replace('0','H').replace('1','T');
System.out.println(s3);
Output: HHHHTHTTT
Now we can print this string in matrix form, again using substring to extract each line and replaceAll to insert the desired spaces:
for(int i=0; i<9; i+=3)
System.out.println(s3.substring(i, i+3).replaceAll("", " ").trim());
Output:
H H H
H T H
T T T
If we're up for a bit of regex wizardry (found here and here) we can do even better:
for(String sl : s3.split("(?<=\\G.{3})"))
System.out.println(sl.replaceAll(".(?=.)", "$0 "));
Putting it all together we get:
int n = 23;
String s3 = Integer.toBinaryString(1<<9 | n).substring(1).replace('0','H').replace('1','T');
for(String s : s3.split("(?<=\\G.{3})"))
System.out.println(s.replaceAll(".(?=.)", "$0 "));

Represent an Integer as a sum of Consecutive positive integers

I am writing code for counting the number of ways an integer can be represented as a sum of the consecutive integers. For Example
15=(7+8),(1+2+3+4+5),(4+5+6). So the number of ways equals 3 for 15.
Now the input size can be <=10^12. My program is working fine till 10^7(i think so, but not sure as i didnt check it on any online judge. Feel free to check the code for that)
but as soon as the i give it 10^8 or higher integer as input. it throws many runtime exceptions(it doesnt show what runtime error). Thanks in advance.
import java.io.*;
//sum needs to contain atleast 2 elements
public class IntegerRepresentedAsSumOfConsecutivePositiveIntegers
{
public static long count = 0;
public static void main(String[] args) throws IOException
{
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
long num = Long.parseLong(br.readLine()); //Enter a number( <=10^12)
driver(num);
System.out.println("count = " + count);
}
public static void driver(long num)
{
long limit = num / 2;
for(long i = 1 ; i <= limit ; i++)
{
func(i,num);
}
}
public static void func(long i,long num)
{
if(i < num)
{
func(i + 1,num - i);
}
else if(i > num)
{
return;
}
else
{
count++;
}
}
}
Use some math: if arithmetic progression with difference 1 starts with a0 and contains n items, then its sum is
S = (2 * a0 + (n-1))/2 * n = a0 * n + n * (n-1) / 2
note that the second summand rises as quadratic function. So instead of checking all a0 in range S/2, we can check all n is smaller range
nmax = Ceil((-1 + Sqrt(1 + 8 * S)) / 2)
(I used some higher approximation).
Just test whether next expression gives integer positive result
a0 = (S - n * (n - 1) / 2) / n
Recursive function isn't suitable when you have big input size like your case.
The maximum depth of the java call stack is about 8900 calls and sometimes only after 7700 calls stack overflow occurs so it really depends on your program input size.
Try this algorithm I think it worked for your problem:
it will work fine until 10^9 after that it will take much more time to finish running the program.
long sum = 0;
int count = 0;
long size;
Scanner in = new Scanner(System.in);
System.out.print("Enter a number <=10^12: ");
long n = in.nextLong();
if(n % 2 != 0){
size = n / 2 + 1;
}
else{
size = n / 2;
}
for(int i = 1; i <= size; i++){
for(int j = i; j <= size; j++){
sum = sum + j;
if(sum == n){
sum = 0;
count++;
break;
}
else if(sum > n){
sum = 0;
break;
}
}
}
System.out.println(count);
Output:
Enter a number <=10^12: 15
3
Enter a number <=10^12: 1000000000
9
BUILD SUCCESSFUL (total time: 10 seconds)
There's a really excellent proof that the answer can be determined by solving for the unique odd factors (Reference). Essentially, for every odd factor of a target value, there exists either an odd series of numbers of that factor multiplied by its average to produce the target value, or an odd average equal to that factor that can be multiplied by double an even-sized series to reach the target value.
public static int countUniqueOddFactors(long n) {
if (n==1) return 1;
Map<Long, Integer> countFactors=new HashMap<>();
while ((n&1)==0) n>>>=1; // Eliminate even factors
long divisor=3;
long max=(long) Math.sqrt(n);
while (divisor <= max) {
if (n % divisor==0) {
if (countFactors.containsKey(divisor)) {
countFactors.put(divisor, countFactors.get(divisor)+1);
} else {
countFactors.put(divisor, 1);
}
n /= divisor;
} else {
divisor+=2;
}
}
int factors=1;
for (Integer factorCt : countFactors.values()) {
factors*=(factorCt+1);
}
return factors;
}
As #MBo noted, if a number S can be partitioned into n consecutive parts, then S - T(n) must be divisible by n, where T(n) is the n'th triangular number, and so you can count the number of partitions in O(sqrt(S)) time.
// number of integer partitions into (at least 2) consecutive parts
static int numberOfTrapezoidalPartitions(final long sum) {
assert sum > 0: sum;
int n = 2;
int numberOfPartitions = 0;
long triangularNumber = n * (n + 1) / 2;
while (sum - triangularNumber >= 0) {
long difference = sum - triangularNumber;
if (difference == 0 || difference % n == 0)
numberOfPartitions++;
n++;
triangularNumber += n;
}
return numberOfPartitions;
}
A bit more math yields an even simpler way. Wikipedia says:
The politeness of a positive number is defined as the number of ways it can be expressed as the sum of consecutive integers. For every x, the politeness of x equals the number of odd divisors of x that are greater than one.
Also see: OEIS A069283
So a simple solution with lots of room for optimization is:
// number of odd divisors greater than one
static int politeness(long x) {
assert x > 0: x;
int p = 0;
for (int d = 3; d <= x; d += 2)
if (x % d == 0)
p++;
return p;
}

nth Binary palindrome with efficient time complexity

Given an integer N, i am trying to find the nth binary palindrome.I have written the following code but it is not efficient.is there a more efficient way in terms of time complexity.
I was trying it out as a problem online and i was supposed to output in 1 sec or less but for every input it takes 2 seconds.
public static Boolean Palind(String n){
String reverse = "";
int length = n.length();
for(int i = length - 1; i >=0;i--){
reverse = reverse + n.charAt(i);
}
if(n.equals(reverse)){
return true;
}
else{
return false;
}
}
public static int Magical(int n){
ArrayList<Integer> res = new ArrayList<Integer>();
for(int i = 1; i < Math.pow(2, n);i++){
if(Palind(Integer.toBinaryString(i))){
res.add(i);
}
}
return res.get(n-1);
}
The relevant OEIS entry (A006995) has a lot of nice tips if you read through it. For example, a(2^n-1)=2^(2n-2)-1 lets you skip right to the (2n - 1)th palindrome really quickly.
It also gives several implementations. For example, the Smalltalk implementation works like this (note that the input value, n, starts with 1 for the first palindrome, 0):
public static final int nthBooleanPalindrome(int n) {
if (n == 1) return 0;
if (n == 2) return 1;
int m = 31 - Integer.numberOfLeadingZeros(n);
int c = 1 << (m - 1);
int b;
if (n >= 3*c) {
int a = n - 3*c;
int d = 2*c*c;
b = d + 1;
int k2 = 1;
for (int i = 1; i < m; i++) {
k2 <<= 1;
b += a*k2/c%2*(k2 + d/k2);
}
}
else {
int a = n - 2*c;
int d = c*c;
b = d + 1 + (n%2*c);
int k2 = 1;
for (int i = 1; i < m - 1; i++) {
k2 <<= 1;
b += a*k2/c%2*(k2 + d/k2);
}
}
return b;
}
Try something like this maybe?
public static void main(String[] args) {
for (int i = 1; i < 65535; i++) {
System.out.println(
i + ": " + getBinaryPalindrom(i) + " = " + Integer.toBinaryString(getBinaryPalindrom(i)));
}
}
public static int getBinaryPalindrom(int N) {
if (N < 4) {
switch (N) {
case 1:
return 0;
case 2:
return 1;
case 3:
return 3;
}
throw new IndexOutOfBoundsException("You need to supply N >= 1");
}
// second highest to keep the right length (highest is always 1)
final int bitAfterHighest = (N >>> (Integer.SIZE - Integer.numberOfLeadingZeros(N) - 2)) & 1;
// now remove the second highest bit to get the left half of our palindrom
final int leftHalf = (((N >>> (Integer.SIZE - Integer.numberOfLeadingZeros(N) - 1)) & 1) << (Integer.SIZE -
Integer.numberOfLeadingZeros(N) - 2)) | ((N << (Integer.numberOfLeadingZeros(N) + 2)) >>> (Integer.numberOfLeadingZeros(N) + 2));
// right half is just the left reversed
final int rightHalf = Integer.reverse(leftHalf);
if (Integer.numberOfLeadingZeros(leftHalf) < Integer.SIZE / 2) {
throw new IndexOutOfBoundsException("To big to fit N=" + N + " into an int");
}
if (bitAfterHighest == 0) {
// First uneven-length palindromes
return (leftHalf << (Integer.SIZE - Integer.numberOfLeadingZeros(leftHalf)) - 1) | (rightHalf
>>> Integer.numberOfTrailingZeros(rightHalf));
} else {
// Then even-length palindromes
return (leftHalf << (Integer.SIZE - Integer.numberOfLeadingZeros(leftHalf))) | (rightHalf
>>> Integer.numberOfTrailingZeros(rightHalf));
}
}
The idea is that each number will become a palindrome once it reverse is added. To have the halves correctly aligned the halves just need to be shifted in place.
The problem why this has gotten a bit complex is that all uneven-length palindromes of a given leftHalf length come before all even-length palindromes of a given leftHalf length. Feel free to provide a better solution.
As int has 32 bit in Java there is a limit on N.
int-Version on ideone.com
And a BigInteger-version to support big values. It is not as fast as the int-version as the byte[]-arrays which store the value of the BigInteger create some overhead.
public static void main(String[] args) {
for (BigInteger i = BigInteger.valueOf(12345678); i.compareTo(BigInteger.valueOf(12345778)) < 0; i = i
.add(BigInteger
.ONE)) {
final BigInteger curr = getBinaryPalindrom(i);
System.out.println(i + ": " + curr + " = " + curr.toString(2));
}
}
public static BigInteger getBinaryPalindrom(BigInteger n) {
if (n.compareTo(BigInteger.ZERO) <= 0) {
throw new IndexOutOfBoundsException("You need to supply N >= 1");
} else if (n.equals(BigInteger.valueOf(1))) {
return BigInteger.valueOf(0);
} else if (n.equals(BigInteger.valueOf(2))) {
return BigInteger.valueOf(1);
} else if (n.equals(BigInteger.valueOf(3))) {
return BigInteger.valueOf(3);
}
final int bitLength = n.bitLength() - 1;
// second highest to keep the right length (highest is always 1)
final boolean bitAfterHighest = n.testBit(bitLength - 1);
// now remove the second highest bit to get the left half of our palindrom
final BigInteger leftHalf = n.clearBit(bitLength).setBit(bitLength - 1);
// right half is just the left reversed
final BigInteger rightHalf;
{
byte[] inArray = leftHalf.toByteArray();
byte[] outArray = new byte[inArray.length];
final int shiftOffset = Integer.SIZE - Byte.SIZE;
for (int i = 0; i < inArray.length; i++) {
outArray[inArray.length - 1 - i] = (byte) (Integer.reverse(inArray[i]) >>> shiftOffset);
}
rightHalf = new BigInteger(1, outArray).shiftRight(outArray.length * Byte.SIZE - bitLength);
}
if (!bitAfterHighest) {
// First uneven-length palindromes
return leftHalf.shiftLeft(bitLength - 1).or(rightHalf);
} else {
// Then even-length palindromes
return leftHalf.shiftLeft(bitLength).or(rightHalf);
}
}
I have the same idea with #Kiran Kumar: you should not count number one by one to find if it is a binary palindrome which is too slow, but rather find the internal pattern that number has.
List the number in binary string one by one, you can find the pattern:
0
1
11
101
1001
1111
...
1......1
And the following is some math problem:
We have 2^round_up((L-2)/2) palindrome of number with length L in binary format.
Sum up every shorter length number, we get following len to sum mapping:
for (int i = 1; i < mapping.length; i++) {
mapping[i] = (long) (mapping[i - 1] + Math.pow(2, Math.ceil((i - 1) * 1.0 / 2)));
}
If we find N range in [count(L), count(L+1)), we can concat it with remaining number:
public static long magical(long n) {
if (n == 0 || n == 1) {
return n;
}
long N = n - 2;
return Long.parseLong(concat(N), 2);
}
private static String concat(long N) {
int midLen = Arrays.binarySearch(indexRange, N);
if (midLen < 0) {
midLen = -midLen - 1;
}
long remaining = N - indexRange[midLen];
String mid = mirror(remaining, midLen);
return '1' + mid + '1';
}
private static String mirror(long n, int midLen) {
int halfLen = (int) Math.ceil(midLen * 1.0 / 2);
// produce fixed length binary string
final String half = Long.toBinaryString(n | (1 << halfLen)).substring(1);
if (midLen % 2 == 0) {
return half + new StringBuilder(half).reverse().toString();
} else {
return half + new StringBuilder(half).reverse().toString().substring(1);
}
}
Full code with test for produce large possible long can be found in my git repo.
Idea to optimize,
Let's look at the palindrome sequence 0, 1, 11, 101, 111, 1001 etc...
All numbers must begin and end with 1, So the middle bits only changes and midle substring should be palindrome for full string to become palindrome,
So let's take a 2 digit binary number - one palindrome is possible.
The binary of the decimal 3 is a palindrome. 11
For a 3 digit binary number 2 palindromes are possible, 2*(no of 1 digit palindrome)
The binary of the decimal 5 is a palindrome. 101
The binary of the decimal 7 is a palindrome. 111
For 5 digit binary number 4 palindromes are possible 2*(no of 3 digit palindrome)
10001,10101, 11011, 11111
and so on,
So it will be 2 + 20 + 21 + 22 +...... +2i-N ,
we solve for i and find out the palindrome number.
So by analysing this sequence we get an equation like 2(i/2)+1 -1 = N
where N is the No of palindrome,
and i is the number of bits in the nth palindrome string,
using this we can find the length of the String, from this we can find the string early.
This might be complex, but helps in solving higher values of N quickly....

Algorithm to find all permutations of a given N with condition

I am designing a program to print all permutations of a given N such that the each digit should be greater than the next digit.
For Example
if N=3:
output should be 123,456,789,134,145,178,189 etc...
Initial Design:
Generate all possible permutations
Pass the generated permutation to a digit extraction function which checks for the condition
Print out the result
This is a very naive algorithm. But I do not know the implementation/initial design because of the dynamic size of N.
Since N will always be less than 10, i've used recursion
Call the function as f(3,0,0)
public static void f(int N,int digit,int num)
{
if(N > 0 )
{
for(int d = digit + 1; d < 11 - N; d++) // earlier d < 10, see comments
{
f(N-1,d,num * 10 + d);
}
}else {
System.out.println(num); //add it to a list or whatever
}
}
Output:
123
124
...
678
679
689
789
The most straightforward way to do this is with recursion. Suppose you've generated the first n digits and the last digit generated is i. You have N - n digits left to generate and they must start with i + 1 or higher. Since the last digit can be no more than 9, the next digit can be no more than 10 - (N - n). This gives the basic rule for recursion. Something like this (in Java) should work:
void generate(int N) {
int[] generated = new int[N];
generate(generated, 0);
}
void generate(int[] generated, int nGenerated) {
if (nGenerated == generated.length) {
// print the generated digits
for (int g : generated) {
System.out.print(g);
}
System.out.println();
return;
}
int max = 10 - (generated.length - nGenerated);
int min = nGenerated == 0 ? 1 : (generated[nGenerated - 1] + 1);
for (int i = min; i <= max; ++i) {
generated[nGenerated] = i;
generate(generated, nGenerated + 1);
}
}
Just generate them in lexicographic order:
123
124
125
...
134
135
...
145
...
234
235
...
245
...
345
This assumes you have digits at most 5. For larger bound B, just keep going. Some simple code to do this is:
nextW = w;
for (int i=n-1; i>=0; --i) {
// THE LARGEST THE iTH DIGIT CAN BE IS B-(n-i-1)
// OTHERWISE YOU CANNOT KEEP INCREASING AFTERWARDS
// WITHOUT USING A NUMBER LARGER THAN B
if w[i]<B-(n-i-1) {
// INCREMENT THE RIGHTMOST POSITION YOU CAN
nextW[i] = w[i]+1;
// MAKE THE SEQUENCE FROM THERE INCREASE BY 1
for (int j=i+1; j<N; ++j) {
nextW[j] = w[i]+j-i+1;
}
// VOILA
return nextW;
}
}
return NULL;
Start with w = [1,2,3,...,N]; (easy to make with a for loop), print w, call the function above with w as an input, print that, and continue. With N = 3 and B = 5, the answer will be the above list (without the ... lines).
If there is no bound B, then you're SOL because there are infinitely many.
In general, you are computing the Nth elementary symmetric function e_N.

Categories

Resources