Java charAt() String index out of range: 5 - java

I am trying to figure out "what 5-digit number when multiplied by 4 gives you its reverse?" using this code but I get error: Exception in thread "main" java.lang.StringIndexOutOfBoundsException: String index out of range: 5
at java.lang.String.charAt(String.java:658)
at Digits.main(Digits.java:12)
public class Digits{
public static void main(String[] args) {
int n = 0;
int b = 0;
String number = Integer.toString(n);
String backwards = Integer.toString(b);
for (int x = 9999; x < 100000 ; x++ ) {
n = x;
b = x *4;
if (number.charAt(0) == backwards.charAt(5 )&& number.charAt(1) == backwards.charAt(4)
&& number.charAt(2) == backwards.charAt(3) && number.charAt(3) == backwards.charAt(2)
&& number.charAt(4) == backwards.charAt(1) && number.charAt(5) == backwards.charAt(0)) {
System.out.println(n);
break;
}
}
Any help would be grealy appreciated

Correct. Because the first five characters are at indices 0, 1, 2, 3 and 4. I would use a StringBuilder (because of StringBuilder.reverse()). And, I would suggest you restrict variable visibility. Then remember to modify number and backwards when you change n and/or b. Something like
for (int x = 9999; x < 100000; x++) {
int n = x;
int b = x * 4;
String number = Integer.toString(n);
String backwards = Integer.toString(b);
StringBuilder sb = new StringBuilder(number);
sb.reverse();
if (sb.toString().equals(backwards)) {
System.out.printf("%s * 4 = %s", number, backwards);
}
}
And I get
21978 * 4 = 87912

backwards and number are String, which internally uses an array. And an array are indexed from 0 to size-1 . Hence such statements will throw ArrayIndexOutOfBoundsException:
backwards.charAt(5 )
number.charAt(5)

At the time you create your strings, both of your ints are 0, so both of your strings are "0" for the duration of your program. What you really want is the strings to change every time your number changes. So your code should look more like this:
public class Digits{
public static void main(String[] args) {
int n = 0;
int b = 0;
String number;
String backwards;
for (int x = 10000; x < 100000 ; x++ ) {
n = x;
b = x *4;
number = Integer.toString(n);
backwards = Integer.toString(b)
. . .
}
In addition, arrays in Java are zero-indexed, so for instance for the string "10000", your program will throw the index out of bounds exception on backwards.charAt(5) because the string is indexed from character 0 to character 4.

Related

Google Foobar level 2 [duplicate]

Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 2 years ago.
Improve this question
I need help with solving the second level of Google's Foobar challenge.
Commander Lambda uses an automated algorithm to assign minions randomly to tasks, in order to keep her minions on their toes. But you've noticed a flaw in the algorithm - it eventually loops back on itself, so that instead of assigning new minions as it iterates, it gets stuck in a cycle of values so that the same minions end up doing the same tasks over and over again. You think proving this to Commander Lambda will help you make a case for your next promotion.
You have worked out that the algorithm has the following process:
1) Start with a random minion ID n, which is a nonnegative integer of length k in base b
2) Define x and y as integers of length k. x has the digits of n in descending order, and y has the digits of n in ascending order
3) Define z = x - y. Add leading zeros to z to maintain length k if necessary
4) Assign n = z to get the next minion ID, and go back to step 2
For example, given minion ID n = 1211, k = 4, b = 10, then x = 2111, y = 1112 and z = 2111 - 1112 = 0999. Then the next minion ID will be n = 0999 and the algorithm iterates again: x = 9990, y = 0999 and z = 9990 - 0999 = 8991, and so on.
Depending on the values of n, k (derived from n), and b, at some point the algorithm reaches a cycle, such as by reaching a constant value. For example, starting with n = 210022, k = 6, b = 3, the algorithm will reach the cycle of values [210111, 122221, 102212] and it will stay in this cycle no matter how many times it continues iterating. Starting with n = 1211, the routine will reach the integer 6174, and since 7641 - 1467 is 6174, it will stay as that value no matter how many times it iterates.
Given a minion ID as a string n representing a nonnegative integer of length k in base b, where 2 <= k <= 9 and 2 <= b <= 10, write a function solution(n, b) which returns the length of the ending cycle of the algorithm above starting with n. For instance, in the example above, solution(210022, 3) would return 3, since iterating on 102212 would return to 210111 when done in base 3. If the algorithm reaches a constant, such as 0, then the length is 1.
Test Cases: Solution.solution("1211", 10) returns 1
Solution.solution("210022", 3) returns 3
Here is my code:
import java.util.ArrayList;
import java.util.Arrays;
public class Solution {
public static int solution(String n, int b) {
int k = n.length();
String m = n;
ArrayList<String> minionID = new ArrayList<>();
while (!minionID.contains(m)) {
minionID.add(m);
char[] s = m.toCharArray();
Arrays.sort(s);
int y = Integer.parseInt(toString(s));
int x = Integer.parseInt(reverseString(s));
if (b == 10) {
int intM = x - y;
m = Integer.toString(intM);
} else {
int intM10 = ((int) Integer.parseInt(toBase10(x,b))) - ((int) Integer.parseInt(toBase10(y, b)));
m = toBaseN(intM10, b);
}
m = addLeadingZeros(k, m);
}
System.out.println(minionID);
return minionID.size() - minionID.indexOf(m);
}
private static String toBaseN (int intBase10, int b) {
int residual = intBase10;
ArrayList<String> digitsBaseN = new ArrayList<>();
while (residual >= b) {
int r = residual % b;
digitsBaseN.add(Integer.toString(residual));
residual = (residual - r) / b;
}
digitsBaseN.add(Integer.toString(residual));
StringBuilder reverseDigits = new StringBuilder();
for (int i = digitsBaseN.size() -1; i >= 0; i--) {
reverseDigits.append(digitsBaseN.get(i));
}
return reverseDigits.toString();
}
private static String toBase10 (int intBaseN, int b) {
int[] xArr = new int[Integer.toString(intBaseN).length()];
int count = 0;
for (int i = xArr.length - 1; i >= 0; i--) {
xArr[count] = Integer.toString(intBaseN).charAt(i) - '0';
count++;
}
int yBase10 = 0;
for(int i = 0; i < xArr.length; i++) {
yBase10 += xArr[i] * (Math.pow(b, i));
}
return Integer.toString(yBase10);
}
public static String toString(char[] arr) {
StringBuilder newString = new StringBuilder();
for (char c : arr) {
newString.append(c);
}
if (newString.toString().contains("-")) {
newString.deleteCharAt(0);
}
return newString.toString();
}
public static String reverseString(char[] arr) {
StringBuilder newString = new StringBuilder();
for (int i = arr.length - 1; i >= 0; i--) {
newString.append(arr[i]);
}
if (newString.toString().contains("-")) {
newString.deleteCharAt(newString.length()-1);
}
return newString.toString();
}
public static String addLeadingZeros(int k, String z) {
if (k > z.length()) {
String zeros = "";
for (int i = 0; i < (k - z.length()); i++) {
zeros += "0";
}
zeros += z;
return zeros;
}
return z;
}
It only works for three out of the ten test cases
def answer(n, b):
k = len(n)
m = n
mini_id = []
while m not in mini_id:
mini_id.append(m)
s = sorted(m)
x_descend = ''.join(s[::-1])
y_ascend = ''.join(s)
if b == 10:
int_m = int(x_descend) - int(y_ascend)
m = str(int_m)
else:
int_m_10 = int(to_base_10(x_descend, b)) - int(to_base_10(y_ascend, b))
m = to_base_n(str(int_m_10), b)
m = (k - len(m)) * '0' + m
return len(mini_id) - mini_id.index(m)

Algorithm to create all permutations and lengths

I am looking to create an algorithm preferably in Java. I would like to go through following char array and create every possible permutations and lengths out of it.
For example, loop and print the following:
a
aa
aaaa
aaaaa
.... keep going ....
aaaaaaaaaaaaaaaaa ....
ab
aba
abaa .............
Till I hit all possible lengths and permutations from my array.
private void method(){
char[] data = "abcdefghiABCDEFGHI0123456789".toCharArray();
// loop and print each time
}
I think it would be silly to come up with 10s of for loops for this. I am guessing some form of recursion would help here but can't get my head around to even start with. Could I get some help with this please? Even if pointing me to a start or a blog or something. Been Googling and looking around and many permutations examples exists but keeps to fixed max length. None seems to have examples on multiple length + permutations. Please advice. Thanks.
Another way to do it is this:
public class HelloWorld{
public static String[] method(char[] arr, int length) {
if(length == arr.length - 1) {
String[] strArr = new String[arr.length];
for(int i = 0; i < arr.length; i ++) {
strArr[i] = String.valueOf(arr[i]);
}
return strArr;
}
String[] before = method(arr, length + 1);
String[] newArr = new String[arr.length * before.length];
for(int i = 0; i < arr.length; i ++) {
for(int j = 0; j < before.length; j ++) {
if(i == 0)
System.out.println(before[j]);
newArr[i * before.length + j] = (arr[i] + before[j]);
}
}
return newArr;
}
public static void main(String []args){
String[] all = method("abcde".toCharArray(), 0);
for(int i = 0; i < all.length; i ++) {
System.out.println(all[i]);
}
}
}
However be careful you'll probably run out of memory or the program will take a looooong time to compile/run if it does at all. You are trying to print 3.437313508041091e+40 strings, that's 3 followed by 40 zeroes.
Here's the solution also in javascript because it starts running but it needs 4 seconds to get to 4 character permutations, for it to reach 5 character permutations it will need about 28 times that time, for 6 characters it's 4 * 28 * 28 and so on.
const method = (arr, length) => {
if(length === arr.length - 1)
return arr;
const hm = [];
const before = method(arr, length + 1);
for(let i = 0; i < arr.length; i ++) {
for(let j = 0; j < before.length; j ++) {
if(i === 0)
console.log(before[j]);
hm.push(arr[i] + before[j]);
}
}
return hm;
};
method('abcdefghiABCDEFGHI0123456789'.split(''), 0).forEach(a => console.log(a));
private void method(){
char[] data = "abcdefghiABCDEFGHI0123456789".toCharArray();
// loop and print each time
}
With your given input there are 3.43731350804×10E40 combinations. (Spelled result in words is eighteen quadrillion fourteen trillion three hundred ninety-eight billion five hundred nine million four hundred eighty-one thousand nine hundred eighty-four. ) If I remember it correctly the maths is some how
1 + x + x^2 + x^3 + x^4 + ... + x^n = (1 - x^n+1) / (1 - x)
in your case
28 + 28^2 + 28^3 + .... 28^28
cause you will have
28 combinations for strings with length one
28*28 combinations for strings with length two
28*28*28 combinations for strings with length three
...
28^28 combinations for strings with length 28
It will take a while to print them all.
One way I can think of is to use the Generex library, a Java library for generating String that match a given regular expression.
Generex github. Look at their page for more info.
Generex maven repo. Download the jar or add dependency.
Using generex is straight forward if you are somehow familiar with regex.
Example using only the first 5 chars which will have 3905 possible combinations
public static void main(String[] args) {
Generex generex = new Generex("[a-e]{1,5}");
System.out.println(generex.getAllMatchedStrings().size());
Iterator iterator = generex.iterator();
while (iterator.hasNext()) {
System.out.println(iterator.next());
}
}
Meaning of [a-e]{1,5} any combination of the chars a,b,c,d,e wit a min length of 1 and max length of 5
output
a
aa
aaa
aaaa
aaaaa
aaaab
aaaac
aaaad
aaaae
aaab
aaaba
aaabb
aaabc
aaabd
aaabe
aaac
....
eeee
eeeea
eeeeb
eeeec
eeeed
eeeee
You can have a for loop that starts from 1 and ends at array.length and in each iteration call a function that prints all the permutations for that length.
public void printPermutations(char[] array, int length) {
/*
* Create all permutations with length = length and print them
*/
}
public void method() {
char data = "abcdefghiABCDEFGHI0123456789".toCharArray();
for(int i = 1; i <= data.length; i ++) {
printPermutations(data, i);
}
}
I think the following recursion could solve your problem:
public static void main(String[] args) {
final String[] data = {"a", "b", "c"};
sampleWithReplacement(data, "", 1, 5);
}
private static void sampleWithReplacement(
final String[] letters,
final String prefix,
final int currentLength,
final int maxLength
) {
if (currentLength <= maxLength) {
for (String letter : letters) {
final String newPrefix = prefix + letter;
System.out.println(newPrefix);
sampleWithReplacement(letters, newPrefix, currentLength + 1, maxLength);
}
}
}
where data specifies your possible characters to sample from.
Is this what you're talking about?
public class PrintPermutations
{
public static String stream = "";
public static void printPermutations (char[] set, int count, int length)
{
if (count < length)
for (int i = 0; i < set.length; ++i)
{
stream += set[i];
System.out.println (stream);
printPermutations (set, count + 1, length);
stream = stream.substring (0, stream.length() - 1);
}
}
public static void main (String[] args)
{
char[] set = "abcdefghiABCDEFGHI0123456789".toCharArray();
printPermutations (set, 0, set.length);
}
}
Test it using a smaller string first.
On an input string 28 characters long this method is never going to end, but for smaller inputs it will generate all permutations up to length n, where n is the number of characters. It first prints all permutations of length 1, then all of length 2 etc, which is different from your example, but hopefully order doesn't matter.
static void permutations(char[] arr)
{
int[] idx = new int[arr.length];
char[] perm = new char[arr.length];
Arrays.fill(perm, arr[0]);
for (int i = 1; i < arr.length; i++)
{
while (true)
{
System.out.println(new String(perm, 0, i));
int k = i - 1;
for (; k >= 0; k--)
{
idx[k] += 1;
if (idx[k] < arr.length)
{
perm[k] = arr[idx[k]];
break;
}
idx[k] = 0;
perm[k] = arr[idx[k]];
}
if (k < 0)
break;
}
}
}
Test:
permutations("abc".toCharArray());
Output:
a
b
c
aa
ab
ac
ba
bb
bc
ca
cb
cc

Adding Numbers and printing the sum vertically using arrays

I have to create a program which adds two integers and prints the sum vertically.
For example, I have.
a=323, b=322.
The output should be:
6
4
5
I've created the code for when the integers are up to two digits, but I want it to work for at least three digits.
Below is the best I could think of.
It may be completely wrong, but the only problem I'm facing is the declaration of array.
It says that the array might not be initialized.
If I set it to null then also it won't assign values to it later.
I know maybe I'm making a big mistake here, but I'll really appreciate if anyone could help me out.
Please keep in mind that I must not use any other functions for this code.
Hope I'm clear.
public class Vert
{
public static void main(String args[])
{
int n,i=0,j,a=323,b=322;
int s[];
n=a+b;
while(n>9)
{
s[i]=n%10;
i++;
s[i]=n/10;
if(s[i]>9)
{
n=s[i];
}
}
j=i;
for(j=i;j>=0;j--)
{
System.out.println(+s[j]);
}
}
}
String conversion seems like cheating, so here's a Stack.
int a = 323, b = 322;
java.util.Stack<Integer> stack = new java.util.Stack<>();
int n = a + b;
while (n > 0) {
stack.push(n % 10);
n = n / 10;
}
while (!stack.isEmpty())
System.out.println(stack.pop());
If an array is required, you need two passes over the sum
int a = 323, b = 322;
// Get the size of the array
int n = a + b;
int size = 0;
while (n > 0) {
size++;
n = n / 10;
}
// Build the output
int s[] = new int[size];
n = a + b;
for (int i = size - 1; n > 0; i--) {
s[i] = n % 10;
n = n / 10;
}
// Print
for (int x : s) {
System.out.println(x);
}
To initialize an array, you need to specify the size of your array as next:
int s[] = new int[mySize];
If you don't know the size of your array, you should consider using a List of Integer instead as next:
List<Integer> s = new ArrayList<Integer>();
Here is how it could be done:
// Convert the sum into a String
String result = String.valueOf(a + b);
for (int i=0; i <result.length();i++) {
// Print one character corresponding to a digit here per line
System.out.println(result.charAt(i));
}
I'd do it like this:
int a = 322;
int b = 322;
int sum = a + b;
String s = Integer.toString(sum);
for(int i = 0; i < s.length(); i++) {
System.out.println(s.charAt(i));
}
But your problem looks like an array is required.
The steps are same as in my solution:
Use int values
Sum the int values (operation)
Convert the int value in an array/string
Output the array/string

Getting a list of binary numbers composing a number

In Java, having a number like 0b1010, I would like to get a list of numbers "composing" this one: 0b1000 and 0b0010 in this example: one number for each bit set.
I'm not sure about the best solution to get it. Do you have any clue ?
Use a BitSet!
long x = 0b101011;
BitSet bs = BitSet.valueOf(new long[]{x});
for (int i = bs.nextSetBit(0); i >=0 ; i = bs.nextSetBit(i+1)) {
System.out.println(1 << i);
}
Output:
1
2
8
32
If you really want them printed out as binary strings, here's a little hack on the above method:
long x = 0b101011;
char[] cs = new char[bs.length()];
Arrays.fill(cs, '0');
BitSet bs = BitSet.valueOf(new long[]{x});
for (int i = bs.nextSetBit(0); i >=0 ; i = bs.nextSetBit(i+1)) {
cs[bs.length()-i-1] = '1';
System.out.println(new String(cs)); // or whatever you want to do with this String
cs[bs.length()-i-1] = '0';
}
Output:
000001
000010
001000
100000
Scan through the bits one by one using an AND operation. This will tell you if a bit at one position is set or not. (https://en.wikipedia.org/wiki/Bitwise_operation#AND). Once you have determined that some ith-Bit is set, make up a string and print it. PSEUDOCODE:
public static void PrintAllSubbitstrings(int number)
{
for(int i=0; i < 32; i++) //32 bits maximum for an int
{
if( number & (1 << i) != 0) //the i'th bit is set.
{
//Make up a bitstring with (i-1) zeroes to the right, then one 1 on the left
String bitString = "1";
for(int j=0; j < (i-1); j++) bitString += "0";
System.out.println(bitString);
}
}
}
Here is a little test that works for me
public static void main(String[] args) {
int num = 0b1010;
int testNum = 0b1;
while(testNum < num) {
if((testNum & num) >0) {
System.out.println(testNum + " Passes");
}
testNum *= 2;
}
}

This program keeps on giving me an error: Exception in thread "main" java.lang.StringIndexOutOfBoundsException: String index out of range: 4

When I write a code like this one, I always get this error. It is definitely building the file but is not it just gives me exemption. I am a beginner. Can you guys please help me out and really point out the mistake that I am making.
public static int binToDec(int i)
{
int[] numbers;//initialize variable
int f = 4;
String iString = "" + i;
int result = 0;
int length = iString.length();
numbers = new int[length];
int power;
for(power = iString.length(); power>=0;power--)
{
while(f == length && f >= 0)
{
numbers[power] = iString.charAt(power)^power;
}
length--;
f--;
}
for(int g = 0; g <= numbers.length; g++)//double check constraints
{
result = numbers[g] = numbers[power];
}
return result;
}
The error it is giving me is:
Exception in thread "main" java.lang.StringIndexOutOfBoundsException: String index out of range: 4
at java.lang.String.charAt(String.java:686)
at BaseConvertor.binToDec(BaseConvertor.java:34)
at BaseConvertorTester.main(BaseConvertorTester.java:10)
I also have a tester file. Here it is:
public class BaseConvertorTester
{
public static void main(String args[])
{
BaseConvertor.binToDec(1010);
}
}
If a String has length X, it means that it has X characters which are indexed starting from 0. So the last character will be at index X-1, not X.
In your for loop you have:
for (power = iString.length(); power >= 0; power--)
but this implies that, if iString has length 4, it will try to access the character at index 4, which would be the fifth (non existing in the string, indeed out of range). Try with
for (power = iString.length() - 1; power >= 0; power--)
Change
for(power = iString.length(); power >= 0; power--)
to
for(power = iString.length(); power > 0; power--)
Your loop is starting at 4 then going to 3 then 2 then 1 then 0 which is a total of 5 times when iString.length() is only 4. Changing the >= to > will exclude 0 running it only 4 times.
I'd also change this
String iString = "" + i;
to
String iString = Integer.toString(i);
better programming.

Categories