Say I have this integer in java, 987654321. I want to be able to remove, say the third and fourth digits, so I can get 9876521 in java.
I know I can do this by converting to a string, then taking a substring, but is there a way to do this without converting to a string?
% and / are your friends here! Using modulus and division we can get pieces of the number that we want.
We use modulus to eliminate the most significant digits, and division to eliminate the least significant digits. We can use division because the remainder gets truncated.
Then we put the two pieces we got from these two operations together. However, we need to shift the digits we got from the division to have room for the least significant digits.
Take 987654321 / 10000, this will give you 98765 (let's call this x)
Take 987654321 % 100, this will give you 21 (let's call this y)
x * 100 + y = 9876521.
More generally, if you want to remove a to bth digits from the number n (where a < b),
n % 10^(a-1) + ((n / 10^(b)) * 10^(a-1))
This will remove only one digit:
public static int RemoveNthPosition(int input, int position) {
int leftDivider = (int) Math.pow(10.0, position);
int rightDivider = (int) Math.pow(10.0, position - 1);
int leftSide = input / leftDivider;
int rightSide = input % rightDivider;
return leftSide * rightDivider + rightSide;
}
To remove multiple at the same time:
public static int RemoveMultiplePositions(int input, int[] positions) {
Arrays.sort(positions);
int result = input;
for (int count = 0; count < positions.length; count++) {
result = RemoveNthPosition(result, positions[count] - count);
}
return result;
}
In your case, it would be:
System.out.println(RemoveMultiplePositions(987654321, new int[] { 3, 4 }));
Related
How would you add digits to the beginning of a number (left hand side) without using a string?
I know that if you try this:
(Some psuedo code)
Let's say I try to make number 534
int current = 5;
int num = 0;
num = (num*10) +current;
then
int current = 3;
int num = 5
num = (num*10) + current;
would make: 53
then
int current = 4;
int num = 53;
num = (num*10) + current;
would make 534
It would keep adding numbers to the right hand side of the number.
However, I am a bit confused on how you would do the opposite. How would you add numbers on the left, so instead of 534 it makes 435?
int num = 123;
int digits = 456;
int powerOfTen = (int) Math.pow(10, (int) (Math.log10(digits) + 1));
int finalNum = digits * powerOfTen + num;
System.out.println(finalNum); // Output: 456123
The number of digits in digits is calculated using Math.log10 and Math.pow, and then used to determine the appropriate power of 10 to multiply digits by. The result is then added to num to obtain the final number with the added digits.
Multiply the digit to add by increasing powers of 10 before summing with the current number.
int num = 0, pow = 1;
num += 5 * pow;
pow *= 10;
num += 3 * pow;
pow *= 10;
num += 4 * pow; // num = 435 at this point
pow *= 10;
// ...
An example without the use of libraries could be this:
First, get the number of digits. Then calculate the number you have to add to your initial number. The sum of these two numbers is the result you're after.
private int addNumberInFrontOf(int initialNumber, int initialNumberToAdd){
int numberOfDigits = getDigits(initialNumber);
int getActualNumberToAdd = getNumberToAdd(initialNumberToAdd, numberOfDigits);
return initialNumber + getActualNumberToAdd;
}
To calculate the number of digits, you can count the number of times you can divide the initial number by 10. Notice you need to use a do-while loop because otherwise the loop wouldn't be triggered if your initial number was 0.
private int getDigits(int number) {
int count = 0;
do {
number = number / 10;
count += 1;
} while (number != 0);
return count;
}
Calculate the number you need to add to your initial number by multiplying the initial number to add with the magnitude. The magnitude simply is 1 multiplied with 10 for every digit in the initial number.
private int getNumberToAdd(int number, int numberOfDigits) {
int magnitude = 1;
for (int i = 0; i < numberOfDigits; i++) {
magnitude *= 10;
}
return number * magnitude;
}
For example, addNumberInFrontOf(456, 123) would result in 123456. Of course, this method won't work when you use positive and negative numbers combined.
You can use String for example.
public static int addLeft(int cur, int num) {
return num == 0 ? cur : Integer.parseInt(cur + String.valueOf(num));
}
In case you want to avoid working with String, you can use recursion instead.
public static int addLeft(int cur, int num) {
return num == 0 ? cur : addLeft(cur, num / 10) * 10 + num % 10;
}
You can use some math, in python
import math
def addLeft(digit, num):
return digit * 10 ** int(math.log10(num) + 1) + num
Note that this might fail for very large numbers on account of precision issues
>>> addLeft(2, 100)
2100
>>> addLeft(3, 99)
399
>>> addLeft(6, 99999999999999)
699999999999999
>>> addLeft(5, 999999999999999)
50999999999999999 (oops)
Can somebody help me with this problem?
Statement: - What is the maximum possible n digit number starting from 0 we can make in K steps
using only 2 operations:-
multiplying by 3 or incrementing by 2.
EXAMPLE :
N =2 K = 5;
-> (0->2->6->8->24->72) 72 IS THE ANSWER
N = 2 , K = 51 -> (0->2->6->8->10->30->32->96->98). 98 is the maximum we can get so need to check for rest of the moves.
My 2 state-recursive solution:-
public static void largestNDigitNumber(long[] highest, long maxValue, long k, long currentValue) {
if (highest[0] == (maxValue - 2)) return; //no need to do anything as we get 98 as highest.
if (k < 0) return; //checking for steps
if (highest[0] < currentValue && currentValue <= (maxValue - 2)) {
highest[0] = currentValue;
}
largestNDigitNumber(highest, maxValue, (k - 1), (currentValue * 3));
largestNDigitNumber(highest, maxValue, (k - 1), (currentValue + 2));
}
public static void main(String[] args) {
int n = 2;
long k = 51;
long maxValue = (long) Math.pow(10, n);
long[] highest = new long[1];
largestNDigitNumber(highest, maxValue, (k - 1), 2);
if (highest[0] < (long) Math.pow(10, (n - 1))) {
System.out.println("-1"); // if it is not possible to make n digit in given steps
} else System.out.println(highest[0]);
}
when "k" is small it is giving the correct answer but for bigger values of "k", it does not show any input. for n=2 and k = 51, it does not show anything.
please help me to improve this code
The question is equivalent to asking what is the largest base 3 number that is less than 10^n/2, and has digit sum plus length less than or equal to k+1. (The answer is then double the base 3 number).
For example, N=2 K=5. What's the largest base 3 number that's less than 50, with length plus digit sum less than or equal to 6. Answer: 1100 (36 decimal), so the answer to the original question is 36*2=72.
For N=2, K=51, the largest base-3 number that's less than 50 is 2001 (49 decimal) and has length sum plus digit sum = 7, which is way less than K+1.
Given this representation, it's easy to solve the problem in O(n) time (in fact, you can solve it using pencil and paper). The length d of the base-3 number is as large as possible such that 3^d < 10^n/2 and d<=K. Then fill in the digits of the number greedily from the most-significant first until you have digit sum K+1-d (or you run out of digits).
Equivalence
First note that without loss of generality you can assume you never have three +2 operations in a row, since that can be done more efficiently by inserting a single +2 operation to before the most recent *3 (or simply replacing it by +2 * 3 if there's no *3 operation). Suppose you have represented the current number as a doubled base-3 number. A +2 operation corresponds to adding 1 to the bottom digit (this never overflows into the next column thanks to the observation above). A *3 operation moves all the digits up one column, introducing a 0 as the bottom digit. Note that because the number is doubled, the +2 operation adds just 1 to the base-3 number!
From this, you can see that you can count the number of operations from observation of the doubled base-3 number. Because *3 introduces a new digit, and +2 increases the digit sum by 1, so the number of operations is equal to the number of digits plus 1, plus the digit sum.
As an example. Suppose you have the doubled base-3 number 2 * 2101, then this is equivalent to 2 * (1+3*3*(1+3*(1+1)))) = (2 + 3*3*(2+3*(2+2))).
I tried something like this. it seems to work fine.
getMaxNumber(2, 5) ==> 72
getMaxNumber(2, 51) ==> 98
private int getMaxNumber(int n, int k){
int N = 0;
for (int i = 0; i < n; i++) {
N = N * 10 + 9;
}
int[] result = new int[1];
helper(N, k, 0, 0, result);
return result[0];
}
private void helper(int N, int K, int n, int k, int[] result){
if(n > N) return;
if(k <= K){
result[0] = Math.max(result[0], n);
}
if(n > 0)
helper(N, K, n * 3, k + 1, result);
helper(N, K, n + 2, k + 1, result);
}
Keeping with the style of your original recursive method. I modified it a bit to produce a working solution:
public static long largestNDigitNumber(int n, long currentK, long maxK, long currentValue) {
if (currentK > maxK || n < 1 || maxK < 1) return 0;
if (currentValue >= Math.pow(10, n))
return 0;
long c1 = largestNDigitNumber(n, currentK + 1, maxK, currentValue * 3);
long c2 = largestNDigitNumber(n, currentK + 1, maxK, currentValue + 2);
if (c1 == 0 && c2 == 0)
return currentValue;
return c1 > c2 ? c1 : c2;
}
public static void main(String[] args) {
int n = 2;
long k = 51;
long largest = largestNDigitNumber(n, 0, k, 0);
System.out.println(largest); //98
}
This recursive method returns values here instead of using an array. Hence the check if one returned value is bigger than the other or they are both 0 before returning.
Both the +2 and *3 operations preserve odd/even parity, so starting from 0 we can only reach even numbers. We could start our search at the highest even number: 8, 98, 998, 9998 etc. and see what the shortest distance to 0 is.
If we are looking for the shortest distance, then there are less choices to make. If the current number is a multiple of 3 then there are two choices, either we divide by 3 or subtract 2. Otherwise the only choice is to subtract 2. I suspect that in the majority of cases, dividing by 3 is the better option, so that might be the first to try to keep the tree smaller.
If the minimum number of steps is less than K then as many divide by 3 operations as needed can be used to make the correct K
If the minimum number of steps is equal to K then the problem is solved.
If the minimum number of steps is more than K then you need to pick a lower starting number. Some even numbers will already have been covered as part of the initial calculation. You get those 'for free', provide you include a small amount of record keeping. You only need to examine large even numbers that were missed earlier due to a 'divide by 3' step.
My problem is as follows; for number N, I need to find out what is the largest value I can count to, when each digit can be used N times.
For example if N = 5, the largest value is 12, since at that point the digit 1 has been used 5 times.
My original approach was to simply iterate through all numbers and keep a tally of how many times each digit has been used so far. This is obviously very inefficient when N is large, so am looking for advice on what would be a smarter (and more efficient) way to achieve this.
public class Counter {
private static Hashtable<Integer, Integer> numbers;
public static void main(String[] args){
Counter c = new Counter();
c.run(9);
}
public Counter() {
numbers = new Hashtable<Integer, Integer>();
numbers.put(0, 0);
numbers.put(1, 0);
numbers.put(2, 0);
numbers.put(3, 0);
numbers.put(4, 0);
numbers.put(5, 0);
numbers.put(6, 0);
numbers.put(7, 0);
numbers.put(8, 0);
numbers.put(9, 0);
}
public static void run(int maxRepeat) {
int keeper = 0;
for(int maxFound = 0; maxFound <= maxRepeat; maxFound++) {
keeper++;
for (int i = 0; i < Integer.toString(keeper).length(); i++) {
int a = Integer.toString(keeper).charAt(i);
//here update the tally for appropriate digit and check if max repeats is reached
}
}
System.out.println(keeper);
}
}
For starters, rather than backing your Counter with a Hashtable, use an int[] instead. When you know exactly how many elements your map has to have, and especially when the keys are numbers, an array is perfect.
That being said, I think the most effective speedup is likely to come from better math, not better algorithms. With some experimentation (or it may be obvious), you'll notice that 1 is always the first digit to be used a given number of times. So given N, if you can find which number is the first to use the digit 1 N+1 times, you know your answer is the number right before that. This would let you solve the problem without actually having to count that high.
Now, let's look at how many 1's are used counting up to various numbers. Throughout this post I will use n to designate a number when we are trying to figure out how many 1's are used to count up to a number, whereas capital N designates how many 1's are used to count up to something.
One digit numbers
Starting with the single-digit numbers:
1: 1
2: 1
...
9: 1
Clearly the number of 1's required to count up to a one-digit number is... 1. Well, actually we forgot one:
0: 0
That will be important later. So we should say this: the number of 1's required to count up to a one-digit number X is X > 0 ? 1 : 0. Let's define a mathematical function f(n) that will represent "number of 1's required to count up to n". Then
f(X) = X > 0 ? 1 : 0
Two-digit numbers
For two-digit numbers, there are two types. For numbers of the form 1X,
10: 2
11: 4
12: 5
...
19: 12
You can think of it like this: counting up to 1X requires a number of 1's equal to
f(9) (from counting up to 9) plus
1 (from 10) plus
X (from the first digits of 11-1X inclusive, if X > 0) plus
however many 1's were required to count up to X
Or mathematically,
f(1X) = f(9) + 1 + X + f(X)
Then there are the two-digit numbers higher than 19:
21: 13
31: 14
...
91: 20
The number of 1's required to count to a two-digit number YX with Y > 1 is
f(19) (from counting up to 19) plus
f(9) * (Y - 2) (from the 1's in numbers 20 through (Y-1)9 inclusive - like if Y = 5, I mean the 1's in 20-49, which come from 21, 31, 41) plus
however many 1's were required to count up to X
Or mathematically, for Y > 1,
f(YX) = f(19) + f(9) * (Y - 2) + f(X)
= f(9) + 1 + 9 + f(9) + f(9) * (Y - 2) + f(X)
= 10 + f(9) * Y + f(X)
Three-digit numbers
Once you get into three-digit numbers, you can kind of extend the pattern. For any three-digit number of the form 1YX (and now Y can be anything), the total count of 1's from counting up to that number will be
f(99) (from counting up to 99) plus
1 (from 100) plus
10 * Y + X (from the first digits of 101-1YX inclusive) plus
however many 1's were required to count up to YX in two-digit numbers
so
f(1YX) = f(99) + 1 + YX + f(YX)
Note the parallel to f(1X). Continuing the logic to more digits, the pattern, for numbers which start with 1, is
f(1[m-digits]) = f(10^m - 1) + 1 + [m-digits] + f([m-digits])
with [m-digits] representing a sequence of digits of length m.
Now, for three-digit numbers ZYX that don't start with 1, i.e. Z > 1, the number of 1's required to count up to them is
f(199) (from counting up to 199) plus
f(99) * (Z - 2) (from the 1's in 200-(Z-1)99 inclusive) plus
however many 1's were required to count up to YX
so
f(ZYX) = f(199) + f(99) * (Z - 2) + f(YX)
= f(99) + 1 + 99 + f(99) + f(99) * (Z - 2) + f(YX)
= 100 + f(99) * Z + f(YX)
And the pattern for numbers that don't start with 1 now seems to be clear:
f(Z[m-digits]) = 10^m + f(10^m - 1) * Z + f([m-digits])
General case
We can combine the last result with the formula for numbers that do start with 1. You should be able to verify that the following formula is equivalent to the appropriate case given above for all digits Z 1-9, and that it does the right thing when Z == 0:
f(Z[m-digits]) = f(10^m - 1) * Z + f([m-digits])
+ (Z > 1) ? 10^m : Z * ([m-digits] + 1)
And for numbers of the form 10^m - 1, like 99, 999, etc. you can directly evaluate the function:
f(10^m - 1) = m * 10^(m-1)
because the digit 1 is going to be used 10^(m-1) times in each of the m digits - for example, when counting up to 999, there will be 100 1's used in the hundreds' place, 100 1's used in the tens' place, and 100 1's used in the ones' place. So this becomes
f(Z[m-digits]) = Z * m * 10^(m-1) + f([m-digits])
+ (Z > 1) ? 10^m : Z * ([m-digits] + 1)
You can tinker with the exact expression, but I think this is pretty close to as good as it gets, for this particular approach anyway. What you have here is a recursion relation that allows you to evaluate f(n), the number of 1's required to count up to n, by stripping off a leading digit at each step. Its time complexity is logarithmic in n.
Implementation
Implementing this function is straightforward given the last formula above. You can technically get away with one base case in the recursion: the empty string, i.e. define f("") to be 0. But it will save you a few calls to also handle single digits as well as numbers of the form 10^m - 1. Here's how I'd do it, omitting a bit of argument validation:
private static Pattern nines = Pattern.compile("9+");
/** Return 10^m for m=0,1,...,18 */
private long pow10(int m) {
// implement with either pow(10, m) or a switch statement
}
public long f(String n) {
int Z = Integer.parseInt(n.substring(0, 1));
int nlen = n.length();
if (nlen == 1) {
return Z > 0 ? 1 : 0;
}
if (nines.matcher(n).matches()) {
return nlen * pow10(nlen - 1);
}
String m_digits = n.substring(1);
int m = nlen - 1;
return Z * m * pow10(m - 1) + f_impl(m_digits)
+ (Z > 1 ? pow10(m) : Z * (Long.parseLong(m_digits) + 1));
}
Inverting
This algorithm solves the inverse of the the question you're asking: that is, it figures out how many times a digit is used counting up to n, whereas you want to know which n you can reach with a given number N of digits (i.e. 1's). So, as I mentioned back in the beginning, you're looking for the first n for which f(n+1) > N.
The most straightforward way to do this is to just start counting up from n = 0 and see when you exceed N.
public long howHigh(long N) {
long n = 0;
while (f(n+1) <= N) { n++; }
return n;
}
But of course that's no better (actually probably worse) than accumulating counts in an array. The whole point of having f is that you don't have to test every number; you can jump up by large intervals until you find an n such that f(n+1) > N, and then narrow down your search using the jumps. A reasonably simple method I'd recommend is exponential search to put an upper bound on the result, followed by a binary search to narrow it down:
public long howHigh(long N) {
long upper = 1;
while (f(upper + 1) <= N) {
upper *= 2;
}
long lower = upper / 2, mid = -1;
while (lower < upper) {
mid = (lower + upper) / 2;
if (f(mid + 1) > N) {
upper = mid;
}
else {
lower = mid + 1;
}
}
return lower;
}
Since the implementation of f from above is O(log(n)) and exponential+binary search is also O(log(n)), the final algorithm should be something like O(log^2(n)), and I think the relation between N and n is linear enough that you could consider it O(log^2(N)) too. If you search in log space and judiciously cache computed values of the function, it might be possible to bring it down to roughly O(log(N)). A variant that might provide a significant speedup is sticking in a round of interpolation search after determining the upper bound, but that's tricky to code properly. Fully optimizing the search algorithm is probably a matter for another question though.
This should be more efficient. Use integer array of size 10 to keep the count of digits.
public static int getMaxNumber(int N) {
int[] counts = new int[10];
int number = 0;
boolean limitReached = false;
while (!limitReached) {
number++;
char[] digits = Integer.toString(number).toCharArray();
for (char digit : digits) {
int count = counts[digit - '0'];
count++;
counts[digit - '0'] = count;
if (count >= N) {
limitReached = true;
}
}
}
return number;
}
UPDATE 1: As #Modus Tollens mentioned initial code has a bug. When N = 3 it returns 11, but there are four 1s between 1 and 11. The fix is to check if limit is breached count[i] > N on given number, previous number should be return. But if for some i count[i] == N for other j count[j] <= N, the actual number should be returned.
Please see corresponding code below:
public static int getMaxNumber(int N) {
int[] counts = new int[10];
int number = 0;
while (true) {
number++;
char[] digits = Integer.toString(number).toCharArray();
boolean limitReached = false;
for (char digit : digits) {
int count = counts[digit - '0'];
count++;
counts[digit - '0'] = count;
if (count == N) {
//we should break loop if some count[i] equals to N
limitReached = true;
} else if (count > N) {
//previous number should be returned immediately
//, if current number gives more unique digits than N
return number - 1;
}
}
if (limitReached) {
return number;
}
}
}
UPDATE 2: As #David Z and #Modus Tollens mentioned, in case if N=13, 30 should be returned, ie, algo stops when N is breached but not reached. If this is initial requirement, the code will be even simpler:
public static int getMaxNumber(int N) {
int[] counts = new int[10];
int number = 0;
while (true) {
number++;
char[] digits = Integer.toString(number).toCharArray();
for (char digit : digits) {
int count = counts[digit - '0'];
count++;
counts[digit - '0'] = count;
if (count > N) {
return number - 1;
}
}
}
}
I am trying to solve a puzzle in Java for my own edification. I am told there is a solution by the guy who designed the puzzle, but I'm not able to find it myself.
Here's the puzzle:
Implement the following method in Java
/**
* Divides a natural number by two.
*
* #param n
* The number to be divided
* #updates n
* #ensures n = floor(n/2)
*/
private static void split(NaturalNumber n) {...}
The NaturalNumber class is simply a class that stores a natural number
using a string. ( That is, it can store numbers much larger than
Integer.MAX_VALUE. )
The class provides these instance methods and inherited
methods, as well as the NaturalNumber.isZero() method, which
returns true if the instance's internal string value is "0", false
otherwise.
It's worth noting that the NaturalNumber.divideBy10() method
essentially pops the rightmost digit off the number, returns it as an
int and updates the instance's internal value.
Do not use static properties on the main class to store values.
Similarly, do not write static helper methods.
Do not convert n to some other data type and operate on that. Do not use external libraries.
Furthermore, split() must be implemented using recursion.
I have the following near solution worked out:
private static void split(NaturalNumber n) {
// Initialize local variables.
String stringBuffer = "";
int numerator = 0;
int quotient = 0;
int remainder = 0;
int thisDigit = n.divideBy10();
if (n.isZero()) {
quotient = thisDigit / 2;
remainder = thisDigit % 2;
n.transferFrom(new NaturalNumber2(quotient * 10 + remainder));
} else {
split(n);
numerator = n.divideBy10() * 10 + thisDigit;
quotient = numerator / 2;
remainder = numerator % 2;
if (!n.isZero()) {
stringBuffer += n.toString();
}
stringBuffer += Integer.toString(quotient * 10 + remainder);
n.transferFrom(new NaturalNumber2(stringBuffer));
}
}
The above simply performs long division. But the last frame in the call stack needlessly appends the remainder of its operation onto the end of the solution.
I have seen solutions to similar problems that recursively subtract two from n, counting how many times two must be subtracted for n to become zero. But those solutions rely on the method having a return value; this puzzle requires there be no return value.
I can also see how to solve the puzzle using one function call to split() and internal loops. But I am told the solution must not rely on loops to operate on n.
Does anyone out there have any insight into a solution?
Suppose the digits of n are a...yz. If y is even, then the digits of n / 2 are the concatenation of a...y / 2 and z / 2. If y is odd, let Y = y - 1. Then the digits of n / 2 are the concatenation of a...Y / 2 and 1z / 2.
We can implement this as follows:
private static void split(NaturalNumber n) {
int z = n.divideBy10();
int y = n.divideBy10();
if (n.isZero()) {
// Base case.
int result = (y * 10 + z) / 2;
n.multiplyBy10(result / 10);
n.multiplyBy10(result % 10);
} else if (y % 2 == 0) {
n.multiplyBy10(y);
split(n);
n.multiplyBy10(z / 2);
} else {
n.multiplyBy10(y - 1);
split(n);
n.multiplyBy10((10 + z) / 2);
}
}
Incidentally, these method names are awful, and making NaturalNumbers mutable is a weird design choice.
I am having my final exam tomorrow so i am practicing some questions.But i am stuck at this question.
Write a method named getNthDigit that returns the n-th digit of an integer.It should work for negative numbers as well.
Eg.
CALL VALUE RETURNED
getNthDigit(123,1) 3
getNthDigit(123,2) 2
getNthDigit(123,3) 1
getNthDigit(-123,1) 3
My code:
public static void getNthDigit(int x,int y){
x=Math.abs(x);
x%10;
}
My thought process is everytime i modulo it by 10,it gives me the last digit.But it is still wrong.Like if i call for getNthDigit(123,2) ,i no longer need the last digit value.
Instead of strings, you could do:
(Math.abs(x) / Math.pow(10, y - 1)) % 10
abs(n) takes care of the negative case.
n / 10^(y - 1) truncates n to the first (counting from the left) y digits.
% 10 gets the last digit of that resulting number.
Modular arithmetic can be used to accomplish what you want. For example, if you divide 123 by 10, and take the remainder, you'd get the first digit 3. If you do integer division of 123 by 100 and then divide the result by 10, you'd get the second digit 2. More generally, the n-th digit of a number can be obtained by the formula (number / base^(n-1)) % base:
public int getNthDigit(int number, int base, int n) {
return (int) ((number / Math.pow(base, n - 1)) % base);
}
System.out.println(getNthDigit(123, 10, 1)); // 3
System.out.println(getNthDigit(123, 10, 2)); // 2
System.out.println(getNthDigit(123, 10, 3)); // 1
Hope it helps.
Why not simply convert the number to string and then get the character at the required position ?
public static void getNthDigit(int x,int y){
String str = String.valueOf(x);
if(str.charAt(0) == '-')
y++;
System.out.println(str.charAt(y-1));
}
I'd write it into a string, strip off any leading -ve and then just index into the string (handling the fact you want 1 based indexes where Java uses 0 based).
Try this:
String s = String.valueOf(x);
int index = s.length()- y;
char result = s.charAt(index);