Why am i getting nosuchelementexception in my code - java

Why am i getting NoSuchElementException?
import java.util.ArrayList;
import java.util.Collections;
import java.util.Scanner;
class GFG {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
int t = sc.nextInt();
sc.nextLine();
for (int k = 0; k < t; k++) {
int n = sc.nextInt();
int xn = sc.nextInt();
int yn = sc.nextInt();
sc.nextLine();
ArrayList<Integer> l1 = new ArrayList<Integer>(2000);
ArrayList<Integer> l2 = new ArrayList<Integer>(2000);
int a[] = new int[2000];
int b[] = new int[2000];
for (int i = 0; i < n; i++) {
a[i] = sc.nextInt();
l1.add(a[i]);
}
sc.nextLine();
for (int i = 0; i < n; i++) {
b[i] = sc.nextInt();
l2.add(b[i]);
}
int tip = 0;
while ((xn > 0) && (yn > 0)&& (!l2.isEmpty())&& (!l1.isEmpty())) {
int pi = l1.indexOf(Collections.max(l1));
if (l1.get(pi) >= l2.get(pi)) {
tip += l1.get(pi);
xn--;
} else {
tip += l2.get(pi);
yn--;
}
l2.remove(pi);
l1.remove(pi);
}
if (yn > 0) {
while ((yn > 0) && (!l2.isEmpty())) {
tip += Collections.max(l2);
l2.remove(l2.indexOf(Collections.max(l2)));
yn--;
}
} else {
while ((xn > 0) && (!l1.isEmpty())) {
tip += Collections.max(l1);
l1.remove(l1.indexOf(Collections.max(l1)));
xn--;
}
}
System.out.println(tip);
}
}
}
Output:
Runtime Error: Runtime ErrorException in thread "main"
java.util.NoSuchElementException at
java.util.Scanner.throwFor(Scanner.java:862) at
java.util.Scanner.next(Scanner.java:1485) at
java.util.Scanner.nextInt(Scanner.java:2117) at
java.util.Scanner.nextInt(Scanner.java:2076) at
GFG.main(File.java:22)

I added some logs here:
int tip = 0;
while ((xn > 0) && (yn > 0)) {
System.out.println("l1:"+l1);
System.out.println("Collections.max(l1):"+Collections.max(l1));
int pi = l1.indexOf(Collections.max(l1));
Entring 1 15 9 9 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1
I get a different error.
It prints out:
l1:[1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15]
Collections.max(l1):15
l1:[1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14]
Collections.max(l1):14
l1:[1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13]
Collections.max(l1):13
l1:[1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12]
Collections.max(l1):12
l1:[1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11]
Collections.max(l1):11
l1:[1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
Collections.max(l1):10
l1:[1, 2, 3, 4, 5, 6, 7, 8, 9]
Collections.max(l1):9
l1:[1, 2, 3, 4, 5, 6, 7, 8]
Collections.max(l1):8
l1:[1, 2, 3, 4, 5, 6, 7]
Collections.max(l1):7
l1:[1, 2, 3, 4, 5, 6]
Collections.max(l1):6
l1:[1, 2, 3, 4, 5]
Collections.max(l1):5
l1:[1, 2, 3, 4]
Collections.max(l1):4
l1:[1, 2, 3]
Collections.max(l1):3
l1:[1, 2]
Collections.max(l1):2
l1:[1]
Collections.max(l1):1
l1:[]
Exception in thread "main" java.util.NoSuchElementException
at java.util.ArrayList$Itr.next(ArrayList.java:854)
at java.util.Collections.max(Collections.java:669)
at GFG.main(GFG.java:31)
The problem is that you are calling Collections.max on en empty list.

Related

How to do a one to many mapping by using Java lambdas and streams?

I want to split a list of numbers into multiples of 2, 3, 5 and store the result in a Map. Sample output will be like :
2 -> 2, 6, 10, 18 etc.
3 -> 3, 6, 9 etc.
5 -> 5, 10 etc.
I tried different ways of grouping (by using Collectors.groupingBy()) etc. in the collect() below and got compile errors each time. How do I do this ?
public void groupingByDemo() {
//Split a list of numbers into multiples of 2, 3, 5. Store the result in a Map<Integer, Set>.
List<Integer> multipliers = Arrays.asList(2, 3, 5);
List<Integer> nums = Arrays.asList(1, 2, 4, 6, 7, 8, 9, 10, 11, 16, 17, 25, 27);
Map<Integer, Set> multiples = multipliers
.stream().collect(
//What to put here ? or should I use something else instead of collect() ?
);
}
Here is one way to do it.
List<Integer> multipliers = Arrays.asList(2, 3, 5);
List<Integer> nums = Arrays.asList(1, 2, 4, 6, 7, 8, 9, 10, 11, 16, 17, 25, 27);
Map<Integer, Set<Integer>> map = multipliers.stream()
.collect(Collectors.toMap(m -> m,
m-> nums.stream()
.filter(n -> n % m == 0)
.collect(Collectors.toSet())));
map.forEach((m, n)-> System.out.println(m + " -> " + n));
Here is the output.
2 -> [16, 2, 4, 6, 8, 10]
3 -> [6, 9, 27]
5 -> [25, 10]

Java Permutation Assignment

Main class:
import java.util.List;
import java.util.Random;
public class PermutationGenerator{
public static void main(String[] args) {
Random bruh = new Random();
List<Integer> filledArray = nextPermutation.fillArray();
int[] randomArray = new int[10];
for (int i = 0; i < randomArray.length; i++) {
int randomPosition = bruh.nextInt(10 - i) + 1;
randomArray[i] = filledArray.get(randomPosition);
filledArray.remove(randomPosition);
}
System.out.print("List 1: ");
printArray(randomArray);
}
public static void printArray(int[] array) {
for (int i = 0; i < array.length; i++) {
System.out.print(array[i] + " ");
}
System.out.println();
}
}
Runner Class:
`import java.util.ArrayList;
public class nextPermutation {
public static ArrayList<Integer> fillArray() {
ArrayList<Integer> randomArray = new ArrayList<Integer>();
randomArray.add(0);
randomArray.add(1);
randomArray.add(2);
randomArray.add(3);
randomArray.add(4);
randomArray.add(5);
randomArray.add(6);
randomArray.add(7);
randomArray.add(8);
randomArray.add(9);
randomArray.add(10);
return randomArray;
}
}
`
I'm supposed to print out something like this:
List 1: 4 6 8 1 9 7 10 5 3 2
List 2: 6 8 1 7 3 4 9 10 5 2
List 3: 2 4 9 6 8 1 10 5 7 3
List 4: 8 5 4 3 2 9 6 7 1 10
List 5: 10 3 2 6 8 9 5 7 4 1
List 6: 9 10 3 2 1 5 6 8 4 7
List 7: 3 8 5 9 4 2 10 1 6 7
List 8: 3 2 4 5 7 6 9 8 10 1
List 9: 4 1 5 10 8 3 6 2 7 9
List 10: 3 5 2 4 1 7 9 6 8 10
But for me, it only prints out one line.
I think I can use a for loop in order to do this. Alternatively, I could just brute force it but I prefer the former.
What I need help on is where and how I should start the for loop.
Any help would be appreciated.
Simply I defined your part of your code in a method mixArray()
Then I added a for loop that runs 10 times to print 10 lists.
The for loop in printArray does run 10 times but it prints 1 number and a space during
each loop so that's why you were getting just 1 line at the end.
for (int p = 1; p <= 10; p++) {
mixArray();
System.out.print("List "+p+": ");
printArray(randomArray);
System.out.println();
}
public static void mixArray() {
for (int i = 0; i < randomArray.length; i++) {
int randomPosition = bruh.nextInt(10 - i) + 1;
randomArray[i] = filledArray.get(randomPosition);
filledArray.remove(randomPosition);
}
}
Also you might wanna keep in mind that your randomizing the array method might give you back a duplicate array. The chances are very low but it is possible.
a lot cleaner to simply use Collections::shuffle
List<Integer> filledArray = fillArray();
for (int i = 0; i < 10; i++)
{
Collections.shuffle(filledArray);
System.out.println(filledArray);
}
output
[7, 0, 3, 5, 2, 1, 9, 10, 4, 8, 6]
[3, 7, 6, 0, 1, 8, 4, 5, 9, 2, 10]
[3, 7, 2, 4, 9, 10, 0, 8, 5, 1, 6]
[8, 1, 0, 7, 4, 2, 3, 6, 10, 9, 5]
[2, 3, 8, 4, 5, 10, 9, 1, 6, 7, 0]
[10, 2, 0, 1, 5, 8, 7, 6, 9, 3, 4]
[1, 5, 0, 9, 2, 4, 6, 8, 10, 7, 3]
[2, 8, 1, 9, 7, 3, 5, 6, 10, 4, 0]
[9, 1, 2, 4, 6, 8, 0, 3, 10, 5, 7]
[4, 5, 2, 3, 10, 9, 6, 8, 0, 1, 7]

How to save a 2D array into a text file with BufferedWriter?

I'm trying to store a 2D array in a text file with BufferedWriter and I would also like to retrieve a 2D array from a text file and display in its original array format with BufferedReader. I have little experience with both methods.
The desired outcome to be saved in a txt file is:
1 5 7 8 2 3 9 6 4
4 8 3 7 6 9 2 1 5
6 2 9 5 1 4 7 3 8
5 3 1 9 4 2 6 8 7
2 7 4 3 8 6 5 9 1
8 9 6 1 7 5 3 4 2
9 4 8 2 3 7 1 5 6
3 6 2 4 5 1 8 7 9
7 1 5 6 9 8 4 2 3
BufferedWriter:
// Instantiate a Date object
static Date date = new Date();
static int[][] board = {{0, 0, 5, 9, 7, 1, 8, 4, 6},
{0, 7, 1, 2, 8, 6, 9, 3, 5},
{0, 9, 6, 4, 3, 5, 2, 7, 1},
{0, 6, 8, 7, 4, 9, 5, 2, 3},
{0, 4, 9, 5, 2, 3, 1, 6, 8},
{0, 5, 2, 1, 6, 8, 4, 9, 7},
{0, 2, 4, 8, 1, 7, 3, 5, 9},
{0, 1, 3, 6, 5, 2, 7, 8, 4},
{0, 8, 7, 3, 9, 4, 6, 1, 2}};
try {
File file = new File("/c:/sudoku" + date + ".txt");
if (!file.exists()) {
file.createNewFile();
}
FileWriter fw = new FileWriter(file.getAbsoluteFile());
try (BufferedWriter bw = new BufferedWriter(fw)) {
bw.write(board, 0, board.length());
}
System.out.println("Your Game was saved with success !");
} catch (IOException e) {
}
I suggest (as Bob did) to store it in csv format (comma separated values)
Date date = new Date();
int[][] board = {{0, 0, 5, 9, 7, 1, 8, 4, 6},
{0, 7, 1, 2, 8, 6, 9, 3, 5},
{0, 9, 6, 4, 3, 5, 2, 7, 1},
{0, 6, 8, 7, 4, 9, 5, 2, 3},
{0, 4, 9, 5, 2, 3, 1, 6, 8},
{0, 5, 2, 1, 6, 8, 4, 9, 7},
{0, 2, 4, 8, 1, 7, 3, 5, 9},
{0, 1, 3, 6, 5, 2, 7, 8, 4},
{0, 8, 7, 3, 9, 4, 6, 1, 2}};
StringBuilder builder = new StringBuilder();
for(int i = 0; i < board.length; i++)//for each row
{
for(int j = 0; j < board.length; j++)//for each column
{
builder.append(board[i][j]+"");//append to the output string
if(j < board.length - 1)//if this is not the last row element
builder.append(",");//then add comma (if you don't like commas you can use spaces)
}
builder.append("\n");//append new line at the end of the row
}
BufferedWriter writer = new BufferedWriter(new FileWriter("/c:/sudoku" + date + ".txt"));
writer.write(builder.toString());//save the string representation of the board
writer.close();
Hope it's all clear
EDIT:
Here is how to read back your board:
String savedGameFile = /*...*/;
int[][] board = new int[9][9];
BufferedReader reader = new BufferedReader(new FileReader(savedGameFile));
String line = "";
int row = 0;
while((line = reader.readLine()) != null)
{
String[] cols = line.split(","); //note that if you have used space as separator you have to split on " "
int col = 0;
for(String c : cols)
{
board[row][col] = Integer.parseInt(c);
col++;
}
row++;
}
reader.close();

Java Print the first and last integers in the permutations

I am trying to take the first and last number in each array and find the sum of the 2 and print it off in console. Some guidance? Not exactly sure how to do it thanks! This is what I have so far it just prints off the arrays.
public class Permutations {
public static void main(String args[]) {
List<Integer> permutation = Arrays.asList(1, 2, 3, 4, 5, 6, 7, 8, 9, 10);
for (int i = 0; i < 10; i++) {
Collections.shuffle(permutation);
}
System.out.println("List 1 " + permutation);
System.out.println("List 2 " + permutation);
System.out.println("List 3 " + permutation);
System.out.println("List 4 " + permutation);
System.out.println("List 5 " + permutation);
System.out.println("List 6 " + permutation);
System.out.println("List 7 " + permutation);
System.out.println("List 8 " + permutation);
System.out.println("List 9 " + permutation);
System.out.println("List 10 " + permutation);
}
}
//print off
List 1 [2, 3, 6, 10, 1, 4, 7, 9, 8, 5]
List 2 [2, 3, 6, 10, 1, 4, 7, 9, 8, 5]
List 3 [2, 3, 6, 10, 1, 4, 7, 9, 8, 5]
List 4 [2, 3, 6, 10, 1, 4, 7, 9, 8, 5]
List 5 [2, 3, 6, 10, 1, 4, 7, 9, 8, 5]
List 6 [2, 3, 6, 10, 1, 4, 7, 9, 8, 5]
List 7 [2, 3, 6, 10, 1, 4, 7, 9, 8, 5]
List 8 [2, 3, 6, 10, 1, 4, 7, 9, 8, 5]
List 9 [2, 3, 6, 10, 1, 4, 7, 9, 8, 5]
List 10 [2, 3, 6, 10, 1, 4, 7, 9, 8, 5]
Have you considered using List.get
Then you could simply do
for (int i = 0; i < 10; i++) {
Collections.shuffle(permutation);
System.out.println("List " + (i + 1) + " " + permutation.get(0) + " " +
permutation.get(9) + " sum is " + (permutation.get(0) + permutation.get(9)));
}
of course better to use length of Array rather then 9
Here's a different solution for summing certain elements for your interest:
IntStream.of(0, 9).map(permutation::get).sum();
The potential advantage of this is that it's easy to expand the items you want to sum or to filter or map them without changing the structure of the solution.

Strange selection sort behavior

I have tried to attempt implementing my own Selection Sort code. So far, the code sorta works... It just behaves strangely.
class HelloWorld {
public static void main(String[] args) {
long startTime = System.currentTimeMillis();
int a[] = {
3,7,8,4,22,13,9,5,10
};
int max_pos = a.length-1;
int counter = 0;
int min_sort = 0;
int j = -1;
int min_pos = 0;
int i=0;
while (j < max_pos) {
i=j+1;
min_sort = a[i];
// traverse trough unsorted portion
while (i < max_pos) {
i++;
if (min_sort > a[i]) {
min_sort = a[i]; // minimum unsorted
min_pos = i;
}
}
// sorted portion
j++;
a[min_pos] = a[j];
a[j] = min_sort ;
for(int x=0; x < a.length; x++) {
System.out.print(a[x] + ", ");
}
System.out.print("\t\t");
System.out.println("i: " + i + " j: " + j + " min pos: " + min_pos + " min val: "+ min_sort);
}
}
}
I have tried tracing it, and the output goes like this:
3, 7, 8, 4, 22, 13, 9, 5, 10, i: 8 j: 0 min pos: 0 min val: 3
3, 4, 8, 7, 22, 13, 9, 5, 10, i: 8 j: 1 min pos: 3 min val: 4
3, 4, 5, 7, 22, 13, 9, 8, 10, i: 8 j: 2 min pos: 7 min val: 5
3, 4, 5, 7, 22, 13, 9, 7, 10, i: 8 j: 3 min pos: 7 min val: 7
3, 4, 5, 7, 7, 13, 9, 22, 10, i: 8 j: 4 min pos: 7 min val: 7
3, 4, 5, 7, 7, 9, 13, 22, 10, i: 8 j: 5 min pos: 6 min val: 9
3, 4, 5, 7, 7, 9, 10, 22, 13, i: 8 j: 6 min pos: 8 min val: 10
3, 4, 5, 7, 7, 9, 10, 13, 22, i: 8 j: 7 min pos: 8 min val: 13
3, 4, 5, 7, 7, 9, 10, 13, 22, i: 8 j: 8 min pos: 8 min val: 22
Since this is almost certainly an educational process on your part (real code would just call Arrays.sort()), I won't give a direct answer initially.
Instead, you should notice that it's the line where j == 3 which is when the 8 appears to magically transmogrify into a 7.
So you should start to hone your debugging skills. Run the code through a debugger up to the end of the output of the previous line, then single step every single instruction. At some point, you'll see the 7 become an 8 and that's the code you need to focus on.
Once you've done that, you'll hopefully be able to tell what the problem is. However, if you're still stuck (make sure you try first, or you'll never improve), see below.
t---
This is a detailed analysis of your problem. You are storing information about the minimum (both the value min_sort and its position min_pos) each time you find an element that's smaller than the first one you set up in each iteration of the outer loop:
if (min_sort > a[i]) {
min_sort = a[i]; // minimum unsorted
min_pos = i;
}
Now that's a good way to do it, and these two pieces of information are later used in the swapping process(1):
j++;
a[min_pos] = a[j];
a[j] = min_sort;
However, what of the case where you don't find an element smaller than the first one set up, such as the following where when position 3 holds the value 7 and all values beyond that are greater than 7:
3, 4, 5, 7, 22, 13, 9, 8, 10
^
In that case, the body of the if statement will never be run and the initial conditions from the start of the iteration will still apply:
i=j+1;
min_sort = a[i];
Notice anything missing there? Such as, let's see, the position being set to something?
Bingo! If the first element being checked in an iteration is already in its correct position, min_pos will remain set to whatever it was previously and, when you swap, that's not going to be pretty. You can fix that by changing the code immediately inside the outer while loop to be:
i = j + 1;
min_pos = i; // add this line
min_sort = a[i];
and you'll see the greatly improved (i.e., correct) output of:
3, 7, 8, 4, 22, 13, 9, 5, 10, i: 8 j: 0 min pos: 0 min val: 3
3, 4, 8, 7, 22, 13, 9, 5, 10, i: 8 j: 1 min pos: 3 min val: 4
3, 4, 5, 7, 22, 13, 9, 8, 10, i: 8 j: 2 min pos: 7 min val: 5
3, 4, 5, 7, 22, 13, 9, 8, 10, i: 8 j: 3 min pos: 3 min val: 7
3, 4, 5, 7, 8, 13, 9, 22, 10, i: 8 j: 4 min pos: 7 min val: 8
3, 4, 5, 7, 8, 9, 13, 22, 10, i: 8 j: 5 min pos: 6 min val: 9
3, 4, 5, 7, 8, 9, 10, 22, 13, i: 8 j: 6 min pos: 8 min val: 10
3, 4, 5, 7, 8, 9, 10, 13, 22, i: 8 j: 7 min pos: 8 min val: 13
3, 4, 5, 7, 8, 9, 10, 13, 22, i: 8 j: 8 min pos: 8 min val: 22
(1) The swap, by the way, is not necessary when the smallest remaining value is already in the correct position, though it does no harm. If you wanted to avoid the unnecessary swap, you could use:
j++;
if (min_pos != j) {
a[min_pos] = a[j];
a[j] = min_sort ;
}
However, as stated, it's not a problem to do the swap so it's really up to you.

Categories

Resources