Lychrel Number Program Error - java

I am trying to make the lychrel number program. but i cannot make it. Criteria is that, list the Lychrel Number which is below in 10000,Lychrel number checking iteration in limited. I have been set it as 30.But i didnt got the solution yet.
number should be listed if the checking completed upto 30 iteration. i didnt get the solutions.help me.
public class LychrelNumber {
static final int MAX_NUMBER = 10000;
static final int MAX_ITERATION = 30;
int iterationCount = 0;
void listTheLychrelNymber() throws Exception {
long i = 0;
long temp;
for (int j = 0; j < MAX_NUMBER; j++) {
iterationCount = 0;
temp = j;
for (i = 0; i < MAX_ITERATION; i++) {
long first = temp;
long second = reverseTheNumber(temp);
long third = first + second;
long fourth = reverseTheNumber(third);
if (third == fourth) {
break;
} else {
temp = third;
if (i == MAX_ITERATION) {
System.out.println("Lychrel Numbers are :" + j);
}
}
}
}
}
long reverseTheNumber(long n) {
long reverse = 0;
while (n != 0) {
reverse = reverse * 10;
reverse = reverse + n % 10;
n = n / 10;
}
return reverse;
}
public static void main(String[] args) {
try {
LychrelNumber lychrelNumber = new LychrelNumber();
lychrelNumber.listTheLychrelNymber();
} catch (Exception e) {
}
}
}
it is build successfull. but i didnt get the output.

Look at your loop of i (I shortened the code a bit)
for (i = 0; i < MAX_ITERATION; i++) {
if (i == MAX_ITERATION) {
System.out.println("Lychrel Numbers are :" + j);
}
}
As you see, you stop looping when i reaches MAX_ITERATION but only print the Lychrel number in the loop if i == MAX_ITERATION (which will of course never happen).

I got the solution.
if (i == (MAX_ITERATION-1)) {
System.out.println("Lychrel Numbers are:" + j);
}
here i made the mistake in Condition Checking..

Related

Finding the smallest integer that appears at least k times

You are given an array A of integers and an integer k. Implement an algorithm that determines, in linear time, the smallest integer that appears at least k times in A.
I have been struggling with this problem for awhile, coding in Java, I need to use a HashTable to find the smallest integer that appears at least k times, it also must be in linear time.
This is what I attempted but it does not pass any of the tests
private static int problem1(int[] arr, int k)
{
// Implement me!
HashMap<Integer, Integer> table = new HashMap<Integer, Integer>();
int ans = Integer.MAX_VALUE;
for (int i=0; i < arr.length; i++) {
if(table.containsKey(arr[i])) {
table.put(arr[i], table.get(arr[i]) + 1);
if (k <= table.get(arr[i])) {
ans = Math.min(ans, arr[i]);
}
}else{
table.put(arr[i], 1);
}
}
return ans;
}
Here is the empty code with all of the test cases:
import java.io.*;
import java.util.*;
public class Lab5
{
/**
* Problem 1: Find the smallest integer that appears at least k times.
*/
private static int problem1(int[] arr, int k)
{
// Implement me!
return 0;
}
/**
* Problem 2: Find two distinct indices i and j such that A[i] = A[j] and |i - j| <= k.
*/
private static int[] problem2(int[] arr, int k)
{
// Implement me!
int i = -1;
int j = -1;
return new int[] { i, j };
}
// ---------------------------------------------------------------------
// Do not change any of the code below!
private static final int LabNo = 5;
private static final String quarter = "Fall 2020";
private static final Random rng = new Random(123456);
private static boolean testProblem1(int[][] testCase)
{
int[] arr = testCase[0];
int k = testCase[1][0];
int answer = problem1(arr.clone(), k);
Arrays.sort(arr);
for (int i = 0, j = 0; i < arr.length; i = j)
{
for (; j < arr.length && arr[i] == arr[j]; j++) { }
if (j - i >= k)
{
return answer == arr[i];
}
}
return false; // Will never happen.
}
private static boolean testProblem2(int[][] testCase)
{
int[] arr = testCase[0];
int k = testCase[1][0];
int[] answer = problem2(arr.clone(), k);
if (answer == null || answer.length != 2)
{
return false;
}
Arrays.sort(answer);
// Check answer
int i = answer[0];
int j = answer[1];
return i != j
&& j - i <= k
&& i >= 0
&& j < arr.length
&& arr[i] == arr[j];
}
public static void main(String args[])
{
System.out.println("CS 302 -- " + quarter + " -- Lab " + LabNo);
testProblems(1);
testProblems(2);
}
private static void testProblems(int prob)
{
int noOfLines = prob == 1 ? 100000 : 500000;
System.out.println("-- -- -- -- --");
System.out.println(noOfLines + " test cases for problem " + prob + ".");
boolean passedAll = true;
for (int i = 1; i <= noOfLines; i++)
{
int[][] testCase = null;
boolean passed = false;
boolean exce = false;
try
{
switch (prob)
{
case 1:
testCase = createProblem1(i);
passed = testProblem1(testCase);
break;
case 2:
testCase = createProblem2(i);
passed = testProblem2(testCase);
break;
}
}
catch (Exception ex)
{
passed = false;
exce = true;
}
if (!passed)
{
System.out.println("Test " + i + " failed!" + (exce ? " (Exception)" : ""));
passedAll = false;
break;
}
}
if (passedAll)
{
System.out.println("All test passed.");
}
}
private static int[][] createProblem1(int testNo)
{
int size = rng.nextInt(Math.min(1000, testNo)) + 5;
int[] numbers = getRandomNumbers(size, size);
Arrays.sort(numbers);
int maxK = 0;
for (int i = 0, j = 0; i < size; i = j)
{
for (; j < size && numbers[i] == numbers[j]; j++) { }
maxK = Math.max(maxK, j - i);
}
int k = rng.nextInt(maxK) + 1;
shuffle(numbers);
return new int[][] { numbers, new int[] { k } };
}
private static int[][] createProblem2(int testNo)
{
int size = rng.nextInt(Math.min(1000, testNo)) + 5;
int[] numbers = getRandomNumbers(size, size);
int i = rng.nextInt(size);
int j = rng.nextInt(size - 1);
if (i <= j) j++;
numbers[i] = numbers[j];
return new int[][] { numbers, new int[] { Math.abs(i - j) } };
}
private static void shuffle(int[] arr)
{
for (int i = 0; i < arr.length - 1; i++)
{
int rndInd = rng.nextInt(arr.length - i) + i;
int tmp = arr[i];
arr[i] = arr[rndInd];
arr[rndInd] = tmp;
}
}
private static int[] getRandomNumbers(int range, int size)
{
int numbers[] = new int[size];
for (int i = 0; i < size; i++)
{
numbers[i] = rng.nextInt(2 * range) - range;
}
return numbers;
}
}
private static int problem1(int[] arr, int k) {
// Implement me!
Map<Integer, Integer> table = new TreeMap<Integer, Integer>();
for (int i = 0; i < arr.length; i++) {
if (table.containsKey(arr[i])) {
table.put(arr[i], table.get(arr[i]) + 1);
} else {
table.put(arr[i], 1);
}
}
for (Map.Entry<Integer,Integer> entry : table.entrySet()) {
//As treemap is sorted, we return the first key with value >=k.
if(entry.getValue()>=k)
return entry.getKey();
}
//Not found
return -1;
}
As others have pointed out, there are a few mistakes. First, the line where you initialize ans,
int ans = 0;
You should initialize ans to Integer.MAX_VALUE so that when you find an integer that appears at least k times for the first time that ans gets set to that integer appropriately. Second, in your for loop, there's no reason to skip the first element while iterating the array so i should be initialized to 0 instead of 1. Also, in that same line, you want to iterate through the entire array, and in your loop's condition right now you have i < k when k is not the length of the array. The length of the array is denoted by arr.length so the condition should instead be i < arr.length. Third, in this line,
if (k < table.get(arr[i])){
where you are trying to check if an integer has occurred at least k times in the array so far while iterating through the array, the < operator should be changed to <= since the keyword here is at least k times, not "more than k times". Fourth, k should never change so you can get rid of this line of code,
k = table.get(arr[i]);
After applying all of those changes, your function should look like this:
private static int problem1(int[] arr, int k)
{
// Implement me!
HashMap<Integer, Integer> table = new HashMap<Integer, Integer>();
int ans = Integer.MAX_VALUE;
for (int i=0; i < arr.length; i++) {
if(table.containsKey(arr[i])) {
table.put(arr[i], table.get(arr[i]) + 1);
if (k <= table.get(arr[i])) {
ans = Math.min(ans, arr[i]);
}
}else{
table.put(arr[i], 1);
}
}
return ans;
}
Pseudo code:
collect frequencies of each number in a Map<Integer, Integer> (number and its count)
set least to a large value
iterate over entries
ignore entry if its value is less than k
if entry key is less than current least, store it as least
return least
One line implementation:
private static int problem1(int[] arr, int k) {
return Arrays.stream(arr).boxed()
.collect(groupingBy(identity(), counting()))
.entrySet().stream()
.filter(entry -> entry.getValue() >= k)
.map(Map.Entry::getKey)
.reduce(MAX_VALUE, Math::min);
}
This was able to pass all the cases! Thank you to everyone who helped!!
private static int problem1(int[] arr, int k)
{
// Implement me!
HashMap<Integer, Integer> table = new HashMap<Integer, Integer>();
int ans = Integer.MAX_VALUE;
for (int i=0; i < arr.length; i++) {
if(table.containsKey(arr[i])) {
table.put(arr[i], table.get(arr[i]) + 1);
}else{
table.put(arr[i], 1);
}
}
Set<Integer> keys = table.keySet();
for(int i : keys){
if(table.get(i) >= k){
ans = Math.min(ans,i);
}
}
if(ans != Integer.MAX_VALUE){
return ans;
}else{
return 0;
}
}

How could I improve the speed/performance for this problem, Java

I saw this challenge on https://www.topcoder.com/ for Beginners. And I really wanted to complete it. I've got so close after so many failures. But I got stuck and don't know what to do no more. Here is what I mean
Question:
Read the input one line at a time and output the current line if and only if you have already read at least 1000 lines greater than the current line and at least 1000 lines less than the current line. (Again, greater than and less than are with respect to the ordering defined by String.compareTo().)
Link to the Challenge
My Solution:
public static void doIt(BufferedReader r, PrintWriter w) throws IOException {
SortedSet<String> linesThatHaveBeenRead = new TreeSet<>();
int lessThan =0;
int greaterThan =0;
Iterator<String> itr;
for (String currentLine = r.readLine(); currentLine != null; currentLine = r.readLine()){
itr = linesThatHaveBeenRead.iterator();
while(itr.hasNext()){
String theCurrentLineInTheSet = itr.next();
if(theCurrentLineInTheSet.compareTo(currentLine) == -1)++lessThan;
else if(theCurrentLineInTheSet.compareTo(currentLine) == 1)++greaterThan;
}
if(lessThan >= 1000 && greaterThan >= 1000){
w.println(currentLine);
lessThan = 0;
greaterThan =0;
}
linesThatHaveBeenRead.add(currentLine);
}
}
PROBLEM
I think the problem with my solution, is because I'm using nested loops which is making it a lot slower, but I've tried other ways and none worked. At this point I'm stuck. The whole point of this challenge is to make use of the most correct data-structure for this problem.
GOAL:
The goal is to use the most efficient data-structure for this problem.
Let me try to present just an accessible refinement of what to do.
public static void
doIt(java.io.BufferedReader r, java.io.PrintWriter w)
throws java.io.IOException {
feedNonExtremes(r, (line) -> { w.println(line);}, 1000, 1000);
}
/** Read <code>r</code> one line at a time and
* output the current line if and only there already were<br/>
* at least <code>nHigh</code> lines greater than the current line <br/>
* and at least <code>nLow</code> lines less than the current line.<br/>
* #param r to read lines from
* #param sink to feed lines to
* #param nLow number of lines comparing too small to process
* #param nHigh number of lines comparing too great to process
*/
static void feedNonExtremes(java.io.BufferedReader r,
Consumer<String> sink, int nLow, int nHigh) {
// collect nLow+nHigh lines into firstLowHigh; instantiate
// - a PriorityQueue(firstLowHigh) highest
// - a PriorityQueue(nLow, (a, b) -> String.compareTo(b, a)) lowest
// remove() nLow elements from highest and insert each into lowest
// for each remaining line
// if greater than the head of highest
// add to highest and remove head
// else if smaller than the head of lowest
// add to lowest and remove head
// else feed to sink
}
Made you a little example with Binary search, now in Java code. It will only use Binary search when newLine is within limits of the sorting.
public static void main(String[] args) {
// Create random lines
ArrayList<String> lines = new ArrayList<String>();
Random rn = new Random();
for (int i = 0; i < 50000; i++) {
int lenght = rn.nextInt(100);
char[] newString = new char[lenght];
for (int j = 0; j < lenght; j++) {
newString[j] = (char) rn.nextInt(255);
}
lines.add(new String(newString));
}
// Here starts logic
ArrayList<String> lowerCompared = new ArrayList<String>();
ArrayList<String> higherCompared = new ArrayList<String>();
int lowBoundry = 1000, highBoundry = 1000;
int k = 0;
int firstLimit = Math.min(lowBoundry, highBoundry);
// first x lines sorter equal
for (; k < firstLimit; k++) {
int index = Collections.binarySearch(lowerCompared, lines.get(k));
if (index < 0)
index = ~index;
lowerCompared.add(index, lines.get(k));
higherCompared.add(index, lines.get(k));
}
for (; k < lines.size(); k++) {
String newLine = lines.get(k);
boolean lowBS = newLine.compareTo(lowerCompared.get(lowBoundry - 1)) < 0;
boolean highBS = newLine.compareTo(higherCompared.get(0)) > 0;
if (lowerCompared.size() == lowBoundry && higherCompared.size() == highBoundry && !lowBS && !highBS) {
System.out.println("Time to print: " + newLine);
continue;
}
if (lowBS) {
int lowerIndex = Collections.binarySearch(lowerCompared, newLine);
if (lowerIndex < 0)
lowerIndex = ~lowerIndex;
lowerCompared.add(lowerIndex, newLine);
if (lowerCompared.size() > lowBoundry)
lowerCompared.remove(lowBoundry);
}
if (highBS) {
int higherIndex = Collections.binarySearch(higherCompared, newLine);
if (higherIndex < 0)
higherIndex = ~higherIndex;
higherCompared.add(higherIndex, newLine);
if (higherCompared.size() > highBoundry)
higherCompared.remove(0);
}
}
}
You need to implement binary search and also need to handle duplicates.
I've done some code sample here which does what you want ( may contains bugs).
public class CheckRead1000 {
public static void main(String[] args) {
// generate strings in revert order to get the worse case
List<String> aaa = new ArrayList<String>();
for (int i = 50000; i > 0; i--) {
aaa.add("some string 123456789" + i);
}
// fast solution
ArrayList<String> sortedLines = new ArrayList<>();
long st1 = System.currentTimeMillis();
for (String a : aaa) {
checkIfRead1000MoreAndLess(sortedLines, a);
}
System.out.println(System.currentTimeMillis() - st1);
// doIt solution
TreeSet<String> linesThatHaveBeenRead = new TreeSet<>();
long st2 = System.currentTimeMillis();
for (String a : aaa) {
doIt(linesThatHaveBeenRead, a);
}
System.out.println(System.currentTimeMillis() - st2);
}
// solution doIt
public static void doIt(SortedSet<String> linesThatHaveBeenRead, String currentLine) {
int lessThan = 0;
int greaterThan = 0;
Iterator<String> itr = linesThatHaveBeenRead.iterator();
while (itr.hasNext()) {
String theCurrentLineInTheSet = itr.next();
if (theCurrentLineInTheSet.compareTo(currentLine) == -1) ++lessThan;
else if (theCurrentLineInTheSet.compareTo(currentLine) == 1) ++greaterThan;
}
if (lessThan >= 1000 && greaterThan >= 1000) {
// System.out.println(currentLine);
lessThan = 0;
greaterThan = 0;
}
linesThatHaveBeenRead.add(currentLine);
}
// will return if we have read more at least 1000 string more and less then our string
private static boolean checkIfRead1000MoreAndLess(List<String> sortedLines, String newLine) {
//adding string to list and calculating its index and the last search range
int indexes[] = addNewString(sortedLines, newLine);
int index = indexes[0]; // index of element
int low = indexes[1];
int high = indexes[2];
//we need to check if this string already was in list for instance
// 1,2,3,4,5,5,5,5,5,6,7 for 5 we need to count 'less' as 4 and 'more' is 2
int highIndex = index;
for (int i = highIndex + 1; i < high; i++) {
if (sortedLines.get(i).equals(newLine)) {
highIndex++;
} else {
//no more duplicates
break;
}
}
int lowIndex = index;
for (int i = lowIndex - 1; i > low; i--) {
if (sortedLines.get(i).equals(newLine)) {
lowIndex--;
} else {
//no more duplicates
break;
}
}
// just calculating how many we did read more and less
if (sortedLines.size() - highIndex - 1 > 1000 && lowIndex > 1000) {
return true;
}
return false;
}
// simple binary search will insert string and return its index and ranges in sorted list
// first int is index,
// second int is start of range - will be used to find duplicates,
// third int is end of range - will be used to find duplicates,
private static int[] addNewString(List<String> sortedLines, String newLine) {
if (sortedLines.isEmpty()) {
sortedLines.add(newLine);
return new int[]{0, 0, 0};
}
// int index = Integer.MAX_VALUE;
int low = 0;
int high = sortedLines.size() - 1;
int mid = 0;
while (low <= high) {
mid = (low + high) / 2;
if (sortedLines.get(mid).compareTo(newLine) < 0) {
low = mid + 1;
} else if (sortedLines.get(mid).compareTo(newLine) > 0) {
high = mid - 1;
} else if (sortedLines.get(mid).compareTo(newLine) == 0) {
// index = mid;
break;
}
if (low > high) {
mid = low;
}
}
if (mid == sortedLines.size()) {
sortedLines.add(newLine);
} else {
sortedLines.add(mid, newLine);
}
return new int[]{mid, low, high};
}
}

Use Recursion to print an array from [0,0,0,0] to [9,9,9,9]I

I just want to print an array from [0,0,0,0] to [9,9,9,9] using recursion.
Firstly , I wrote the code as follows:
public class PrintNumber {
public static void main(String[] args) {
int N = 4;
int[] number = new int[N];
PrintNumber printNumber = new PrintNumber();
printNumber.printNum(number,0);
}
public void printNum(int[] number, int bit) {
if (bit == number.length ) {
System.out.println(Arrays.toString(number));
return;
}
for (int i = 0; i < 10; i++) {
number[bit] = i;
/******** something goes wrong here ********/
printNum(number, ++bit);
/******** something goes wrong here ********/
}
}
}
as you can see , there not too much code , but it didn't work.
So I debugged my code and I found out ++bit (the last line of the code) should be written as bit+1. Then , it works well.
But I am really confused , why is that? ++bit and bit+1 are both to increase the bit by 1 , why it doesn't work for ++bit and it works for bit+1 ?
Thanks a lot .
There is a difference between ++bit and bit + 1. The expression ++bit desugars into what is essentially bit = bit + 1*. So your line becomes.
printNum(number, bit = bit + 1);
So the actual value of the variable bit is changing, and since you call this in a loop, the value is going to keep increasing, which is not desired. Eventually, you get an ArrayIndexOutOfBoundsException when bit becomes too big for the array.
* It actually probably desugars into a more efficient JVM instruction, but semantically, it should be equivalent.
This is a workable solution.
import java.util.Arrays;
public class TestTest {
private static int N = 4;
private static int MAX = 10;
public static void main(String[] args) {
int[] number = new int[N];
TestTest printNumber = new TestTest();
printNumber.printNum(number,0);
}
public void printNum(int[] number, int bit) {
System.out.println(Arrays.toString(number));
if (bit == MAX ) {
return;
}
for (int i = 0; i < N; i++) {
number[i] = bit;
}
printNum(number, ++bit);
}
}
There was several problems:
You mixed loop and recurection.
Wrong array sizes
Wrong array values
Wrong print if-case
Wrong function exit.
This code yeilds stackoverflow exception. but it works for N = 3:
public class TestTest {
private static int N = 3;
private static int MAX = 10;
public static void main(String[] args) {
int[] number = new int[N];
TestTest printNumber = new TestTest();
printNumber.printNum(number);
}
public void printNum(int[] number) {
System.out.println(Arrays.toString(number));
// if (bit == MAX) {
// return;
// }
boolean exit = true;
for (int i = 0; i < N; i++) {
if (number[i] != MAX - 1) {
exit = false;
}
}
if (exit) {
return;
}
number[N - 1]++;
for (int i = N - 1; i >= 0; i--) {
if (number[i] == MAX) {
if (i > 0) {
number[i - 1]++;
number[i] = 0;
}
}
}
printNum(number);
}
}
Loop solution:
public class TestTest {
private static int N = 4;
private static int MAX = 10;
public static void main(String[] args) {
int[] number = new int[N];
TestTest printNumber = new TestTest();
// printNumber.printNum(number);
printNumber.printNumLoop(number);
}
private void printNumLoop(int[] number) {
while(true) {
System.out.println(Arrays.toString(number));
number[N - 1]++;
for (int i = N - 1; i >= 0; i--) {
if (number[i] == MAX) {
if (i > 0) {
number[i - 1]++;
number[i] = 0;
}
}
}
boolean exit = true;
for (int i = 0; i < N; i++) {
if (number[i] != MAX - 1) {
exit = false;
}
}
if (exit) {
System.out.println(Arrays.toString(number));
break;
}
}
}
public void printNum(int[] number) {
// if (bit == MAX) {
// return;
// }
boolean exit = true;
for (int i = 0; i < N; i++) {
if (number[i] != MAX - 1) {
exit = false;
}
}
if (exit) {
return;
}
number[N - 1]++;
for (int i = N - 1; i >= 0; i--) {
if (number[i] == MAX) {
if (i > 0) {
number[i - 1]++;
number[i] = 0;
}
}
}
printNum(number);
}
}

Algorithm: List all prime number using Sieve of Eratosthenes

I have implemented Sieve of Eratosthenes for finding the list of prime number from 1 to n. My code is working fine for inputs from 1 to 10,000 but I am getting following for values >100,000:
Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException: -2146737495
at SieveOfEratosthenes.main(SieveOfEratosthenes.java:53)
I am able to find the issue, which is in the for loop when I am doing i * i as it is going out of Integer range (Integer.MAX_VALUE), but I could not find the solution. Can someone suggest me what changes can be done also I appreciate if someone suggest me any improvement for efficiency in this implementation?
public class SieveOfEratosthenes {
public static void main(String[] args) {
Integer num = Integer.parseInt(args[0]);
Node[] nodes = new Node[num + 1];
for(int i = 1; i < nodes.length; i++) {
Node n = new Node();
n.setValue(i);
n.setMarker(true);
nodes[i] = n;
}
for(int i = 1; i < nodes.length; i++) {
if(nodes[i].getMarker() && nodes[i].getValue() > 1) {
System.out.println("Prime " + nodes[i].getValue());
} else {
continue;
}
for(int j = i * i; j < nodes.length
&& nodes[i].getMarker(); j = j + i) {
nodes[j].setMarker(false);
}
}
System.out.println(l.size());
}
}
class Node {
private int value;
private boolean marker;
public void setValue(int value) {
this.value = value;
}
public int getValue() {
return this.value;
}
public void setMarker(boolean marker) {
this.marker = marker;
}
public boolean getMarker() {
return this.marker;
}
public String toString() {
return ("Value : " + marker + " value " + value);
}
}
Essentially, the for(int j = i * i;... loop is to cross out all multiples of i.
It makes sense only to cross out starting from i * i, since all lesser multiples are already crossed out by their lesser divisors.
There are at least two ways to go from here.
First, you can start crossing out from i * 2 instead of i * i.
This will get rid of the overflow.
On the bad side, the complexity of the sieve would grow from O(n log log n) to O(n log n) then.
Second, you can check whether i * i is already too much, and if it is, skip the loop completely.
Recall that it is essentially skipped anyway for i greater than the square root of nodes.length if no overflow occurs.
For example, just add an if (i * 1L * i < nodes.length) before the loop.
for(int i = 1; i < nodes.length; i++) {
if(nodes[i].getMarker() && nodes[i].getValue() > 1) {
System.out.println("Prime " + nodes[i].getValue());
} else {
continue;
}
TO
int limit = 2 << 14;
for(int i = 1; i < nodes.length; i++) {
if(nodes[i].getMarker() && nodes[i].getValue() > 1 && i <= 2 << 15) {
System.out.println("Prime " + nodes[i].getValue());
if (i > limit) {
continue;
}
} else {
continue;
}

Find smallest number K , if exists, such that product of its digits is N. Eg:when N = 6, smallest number is k=16(1*6=6) and not k=23(2*3=6)

I have made this program using array concept in java. I am getting Exception as ArrayIndexOutOfBound while trying to generate product.
I made the function generateFNos(int max) to generate factors of the given number. For example a number 6 will have factors 1,2,3,6. Now,i tried to combine the first and the last digit so that the product becomes equal to 6.
I have not used the logic of finding the smallest number in that array right now. I will do it later.
Question is Why i am getting Exception as ArrayIndexOutOfBound? [i couldn't figure out]
Below is my code
public class SmallestNoProduct {
public static void generateFNos(int max) {
int ar[] = new int[max];
int k = 0;
for (int i = 1; i <= max; i++) {
if (max % i == 0) {
ar[k] = i;
k++;
}
}
smallestNoProduct(ar);
}
public static void smallestNoProduct(int x[]) {
int j[] = new int[x.length];
int p = x.length;
for (int d = 0; d < p / 2;) {
String t = x[d++] + "" + x[p--];
int i = Integer.parseInt(t);
j[d] = i;
}
for (int u = 0; u < j.length; u++) {
System.out.println(j[u]);
}
}
public static void main(String s[]) {
generateFNos(6);
}
}
****OutputShown****
Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException: 6
at SmallestNoProduct.smallestNoProduct(SmallestNoProduct.java:36)
at SmallestNoProduct.generateFNos(SmallestNoProduct.java:27)
at SmallestNoProduct.main(SmallestNoProduct.java:52)
#Edit
The improved Code using array only.
public class SmallestNoProduct {
public static void generateFNos(int max) {
int s = 0;
int ar[] = new int[max];
int k = 0;
for (int i = 1; i <= max; i++) {
if (max % i == 0) {
ar[k] = i;
k++;
s++;
}
}
for (int g = 0; g < s; g++) {
System.out.println(ar[g]);
}
smallestNoProduct(ar, s);
}
public static void smallestNoProduct(int x[], int s) {
int j[] = new int[x.length];
int p = s - 1;
for (int d = 0; d < p;) {
String t = x[d++] + "" + x[p--];
System.out.println(t);
int i = Integer.parseInt(t);
j[d] = i;
}
/*for (int u = 0; u < j.length; u++) {
System.out.println(j[u]);
}*/
}
public static void main(String s[]) {
generateFNos(6);
}
}
Maybe it better:
public class SmallestNoProduct {
public static int smallest(int n) {
int small = n*n;
for(int i = 1; i < Math.sqrt(n); i++) {
if(n%i == 0) {
int temp = Integer.parseInt(""+i+""+n/i);
int temp2 = Integer.parseInt(""+n/i+""+i);
temp = temp2 < temp? temp2: temp;
if(temp < small) {
small = temp;
}
}
}
return small;
}
public static void main(String[] args) {
System.out.println(smallest(6)); //6
System.out.println(smallest(10)); //25
System.out.println(smallest(100)); //205
}
}
Problem lies in this line
String t=x[d++]+""+x[p--];
x[p--] will try to fetch 7th position value, as p is length of array x i.e. 6 which results in ArrayIndexOutOfBound exception. Array index starts from 0, so max position is 5 and not 6.
You can refer this question regarding postfix expression.
Note: I haven't checked your logic, this answer is only to point out the cause of exception.
We are unnecessarily using array here...
below method should work....
public int getSmallerMultiplier(int n)
{
if(n >0 && n <10) // if n is 6
return (1*10+n); // it will be always (1*10+6) - we cannot find smallest number than this
else
{
int number =10;
while(true)
{
//loop throuogh the digits of n and check for their multiplication
number++;
}
}
}
int num = n;
for(i=9;i>1;i--)
{
while(n%d==0)
{
n=n/d;
arr[i++] = d;
}
}
if(num<=9)
arr[i++] = 1;
//printing array in reverse order;
for(j=i-1;j>=0;j--)
system.out.println(arr[j]);

Categories

Resources