public static int maxIceCream(int[][] costs, int coins) {
Arrays.sort(costs);
boolean found = false;
for (int i = 0; i < costs.length; ++i) {
if (coins != costs[i]) {
coins -= costs[i];
found = true;
break;
} else {
return i;
}
}
return costs.length;
}
compare to integer and integer array
You are getting the error message because "costs" is a 2D matrix and "coins" is an integer.
So, you can't compare an integer(int) to array of integer(int[]).
Try looping two times over the "costs" to compare to all the values
public static int maxIceCream(int[][] costs, int coins) {
Arrays.sort(costs);
boolean found = false;
for (int i = 0; i < costs.length; ++i) {
for (int j = 0; j < costs[i].length; ++j) {
if (coins != costs[i][j]) {
coins -= costs[i][j];
found = true;
break;
} else {
return i;
}
}
}
return costs.length;
}
Related
I would like the code below, to return the value of 'i' if the character is available in the array, if not I would like to return -1. However, Whenever I execute the code it returns -1 for both the conditions. Could you please guide me as to where I'm going wrong?
public class CharacterList {
private char[] charArray;
private int count;
public CharacterList(int arraySize) {
charArray = new char[arraySize];
for (int i = 0; i < charArray.length; i++) {
charArray[i] = ' ';
}
count = 0;
}
public int indexOf(char searchingChar) {
int a = 0;
for (int i = 0; i < charArray.length; i++) {
if (charArray[i] == searchingChar) {
a = i;
} else {
a = -1;
}
}
return a;
}
}
You are resetting a to -1 each time a character is not the char you are searching for. Instead, return the index when you find it and return -1 at the end of the method.
public int indexOf(char searchingChar) {
for (int i = 0; i < charArray.length; i++) {
if (charArray[i] == searchingChar) {
return i;
}
}
return -1;
}
you can initialize a to -1 and break of the char matches
public int indexOf(char searchingChar) {
a = -1;
for (int i = 0; i < charArray.length; i++) {
if (charArray[i] == searchingChar) {
a = i;
break;
}
}
return a;
}
I need to return -1 if one of this two conditions: biggerThanK(array[i], k), or prim(array[i]) return false. I tried to put an else { smallest = -1; } but if I input values that respect both conditions it still displays -1.
import java.util.Scanner;
public class Main {
public static Scanner scanner = new Scanner(System.in);
public static void main(String[] args) {
int smallest = Integer.MAX_VALUE;
int n = scanner.nextInt();
int k = scanner.nextInt();
int[] array = new int[n];
for (int i = 0; i < array.length; i++) {
array[i] = scanner.nextInt();
}
for (int i = 0; i < array.length; i++) {
if (biggerThanK(array[i], k) && prim(array[i])) {
if (array[i] < smallest) {
smallest = array[i];
}
}
}
System.out.println(smallest);
}
public static boolean biggerThanK(int number, int k) {
if (number >= k) {
return true;
} else {
return false;
}
}
public static boolean prim(int number) {
for (int i = 2; i < number; i++) {
if (number % i == 0) {
return false;
}
} return true;
}
}
You should put this in a function.
If only one of the conditions needs to be false, I would use an architecture like this :
if(condition 1)
if(condition 2)
//update smallest
else
return -1
else
return -1
I want to check if the sum of each row in any matrix is equal. How should I rewrite this to avoid NPE?
I can make it work for "normal" matrices like int[][] a = {{1,2,3}, {4,5,6}}, but I want it to work even when testing with null and empty matrices.
public static boolean allRowSumsEqual(int[][] m) {
boolean a = false;
int x = 0;
int total = rowSum(m[0]);
for (int i = 0; i < m.length; i++) {
for (int j = 0; j < m[i].length; j++) {
x += m[i][j];
}
if (x != total) {
a = false;
break;
} else {
x = 0;
a = true;
}
}
return a;
}
public static int rowSum(int[] v) {
int vSum = 0;
for (int i = 0; i < v.length; i++) {
vSum += v[i];
}
return vSum;
}
As you said, this does work for most matrices. There are a few places I might check for null, see modified code below:
public static boolean allRowSumsEqual(int[][] m){
if(m == null) return true;
if(m.length == 0) return true;
boolean a = false;
int x = 0;
int total = rowSum(m[0]);
for (int i = 1; i < m.length; i++){
// You can use your own function instead of the inner for loop
x = rowSum(m[i]);
if (x != total) {
a = false;
break;
} else {
x = 0;
a = true;
}
}
return a;
}
public static int rowSum(int[] v){
int vSum = 0;
// Assume a null row has sum 0
if(v == null) return 0;
for (int i = 0 ; i < v.length ; i++){
vSum += v[i];
}
return vSum;
}
You need to define a result or an exception if you want to check for "null" parameter. You can return true if null is valid or false otherwise.
if(m == null) return true;
Empty or one lined matrices can return true all the time and does not require any calculation:
if(m.length < 2) return true;
The line test is more simple, I think:
// expect a positiv result
boolean result = true;
// calculate first line
int firstLine = rowSum(m[0]);
// loop remaining lines
for (int i = 1 ; i < m.length ; i++){
// compare first line with current line
if (firstLine != rowSum(m[i]))
{
// not equal -> change result
result = false;
// break loop
break;
}
}
return result;
public class Snippet {
public static boolean allRowSumsEqual(int[][] m) {
if (null == m || 0 == m.length)
return true;
boolean a = false;
int x = 0;
int total = 0;
if (null != m[0])
total = rowSum(m[0]);
for (int i = 1; i < m.length; i++) {
if (null != m[i]) {
for (int j = 0; j < m[i].length; j++) {
x += m[i][j];
}
} else
x = 0;
if (x != total) {
a = false;
break;
} else {
x = 0;
a = true;
}
}
return a;
}
public static int rowSum(int[] v) {
int vSum = 0;
for (int i = 0; i < v.length; i++) {
vSum += v[i];
}
return vSum;
}
public static void main(String[] args) {
int[][] a = { { 1, 2, 3 }, { 3, 2, 1 }, null };
System.out.println(allRowSumsEqual(a));
int[][] b = { null, null, null };
System.out.println(allRowSumsEqual(b));
}
}
What do you think of this solution:
public static boolean allRowSumsEqual(int[][] m) {
if(m == null) { return false; }
int sum = 0;
for(int i = 0; i < m.length; i++) {
int temp = 0;
if(m[i] == null) { continue; }
for(int j = 0; j < m[i].length; j++) {
temp += m[i][j];
}
if(i == 0) { //is the first row
sum = temp;
}
else if(sum != temp) {
return false;
}
}
return true;
}
public class Sudoku {
public static void main(String[] args) {
// Row and column Latin but with invalid subsquares
String config1 = "1234567892345678913456789124567891235678912346" + "78912345789123456891234567912345678";
String[][] puzzle1 = makeSudoku(config1);
if (isValidSudoku(puzzle1)) {
System.out.println("This puzzle is valid.");
} else {
System.out.println("This puzzle is invalid.");
}
System.out.println(getPrintableSudoku(puzzle1));
System.out.println("--------------------------------------------------");
// Row Latin but column not Latin and with invalid subsquares
String config2 = "12345678912345678912345678912345678912345678" + "9123456789123456789123456789123456789";
String[][] puzzle2 = makeSudoku(config2);
if (isValidSudoku(puzzle2)) {
System.out.println("This puzzle is valid.");
} else {
System.out.println("This puzzle is invalid.");
}
System.out.println(getPrintableSudoku(puzzle2));
System.out.println("--------------------------------------------------");
// A valid sudoku
String config3 = "25813764914698532779324685147286319558149273663" + "9571482315728964824619573967354218";
String[][] puzzle3 = makeSudoku(config3);
if (isValidSudoku(puzzle3)) {
System.out.println("This puzzle is valid.");
} else {
System.out.println("This puzzle is invalid.");
}
System.out.println(getPrintableSudoku(puzzle3));
System.out.println("--------------------------------------------------");
}
public static String[][] makeSudoku(String s) {
int SIZE = 9;
int k = 0;
String[][] x = new String[SIZE][SIZE];
for (int i = 0; i < SIZE; i++) {
for (int j = 0; j < SIZE; j++) {
x[i][j] = s.substring(k, k + 1);
k++;
}
}
return x;
}
public static String getPrintableSudoku(String[][] x) {
int SIZE = 9;
String temp = "";
for (int i = 0; i < SIZE; i++) {
if ((i == 3) || (i == 6)) {
temp = temp + "=================\n";
}
for (int j = 0; j < SIZE; j++) {
if ((j == 3) || (j == 6)) {
temp = temp + " || ";
}
temp = temp + x[i][j];
}
temp = temp + "\n";
}
return temp;
}
//sudoku validation
public static boolean isValidSudoku(String[][] x) {
return rowsAreLatin(x) && colsAreLatin(x) && goodSubsquares(x);
}
public static boolean rowsAreLatin(String[][] x) {
// fill in your code here
boolean result = true; // Assume rows are latin
for (int i = 0; i < 9; i++) {
result = result && rowIsLatin(x, i); // Make sure each row is latin
}
return result;
}
public static boolean rowIsLatin(String[][] x, int i) {
boolean[] found = new boolean[9];
for (int j = 0; j < 9; j++) {
found[Integer.parseInt(x[i][j])] = true;
}
for (int j = 0; j < 9; j++) {
if (!found[j]) {
return false;
}
}
return true;
}
public static boolean colsAreLatin(String[][] x) {
// fill in your code here
boolean result = true; // Assume cols are latin
for (int j = 0; j < 9; j++) {
result = result && colIsLatin(x, j); // Make sure each row is latin
}
return result;
}
public static boolean colIsLatin(String[][] x, int j) {
// fill in your code here
boolean[] found = new boolean[9];
for (int i = 0; i < 9; i++) {
found[Integer.parseInt(x[i][j])] = true;
}
for (int i = 0; i < 9; i++) {
if (!found[i]) {
return false;
}
}
return true;
}
public static boolean goodSubsquares(String[][] x) {
return true;
}
public static boolean goodSubsquare(String[][] x, int i, int j) {
boolean[] found = new boolean[9];
// We have a 3 x 3 arrangement of subsquares
// Multiplying each subscript by 3 converts to the original array subscripts
for (int p = i * 3, rowEnd = p + 3; p < rowEnd; p++) {
for (int q = j * 3, colEnd = q + 3; q < colEnd; q++) {
found[Integer.parseInt(x[p][q])] = true;
}
}
for (int p = 0; p < 9; p++) {
if (!found[p]) {
return false;
}
}
return true;
}
}
This the error I am getting. Help!
Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException: 9
at Sudoku.rowIsLatin(Sudoku.java:104)
at Sudoku.rowsAreLatin(Sudoku.java:93)
at Sudoku.isValidSudoku(Sudoku.java:85)
at Sudoku.main(Sudoku.java:8)
Java Result: 1
The problem is with the line:
Integer.parseInt(x[i][j])
Sudoku numbers range from [1, 9], but indices for an array (of length 9) range from [0, 8]. So, when the (i, j) element is a 9, the index is 9 and therefore the IndexOutOfBoundsException is being thrown.
You'll have to change it to
found[Integer.parseInt(x[i][j]) - 1] = true;
Note that you also make the same mistake in the column's respective method.
I've spent quite a while working on Problem #23 on Project Euler.
The answer the program below gives me is 4190428, and I can't figure out why.
I think it's probably a one or two character mistake somewhere.
public long problem23() {
ArrayList<Integer> abundantNumbers = new ArrayList<Integer>();
int limit = 28123;
for(int i = 2; i < limit; i++) {
if(isAbundantNum(i)) {
abundantNumbers.add(i);
}
}
boolean [] abundantSum = new boolean [limit+1];
for(int a = 0; a < abundantNumbers.size(); a++) {
for(int b = 1; b < abundantNumbers.size(); b++) {
int temp = abundantNumbers.get(a) + abundantNumbers.get(b);
if(temp <= limit) {
abundantSum[temp] = true;
} else {
break;
}
}
}
long sum = 0;
for(int i = 1; i <= limit; i++) {
if(!abundantSum[i]) {
sum += i;
}
}
return sum;
}
public boolean isAbundantNum(int n) {
int factorSum = 1;
for(int i = 2; i < Math.sqrt(n); i++) {
if(n%i == 0) {
factorSum += i; factorSum += n/i;
}
}
if(factorSum > n) {
System.out.println(n);
return true;
}
return false;
}
Edit: Added isAbundantNum(int n) method.
You have 2 bugs...
for(int b = 1; b < abundantNumbers.size(); b++) {
'b' should start at zero not 1
for(int i = 2; i < Math.sqrt(n); i++) {
if(n%i == 0) {
factorSum += i; factorSum += n/i;
}
}
Factoring like that gives you duplicates (like 2*2 = 4, you're getting both 2s).
Try something like:
for(int i = 2; i < n; i++) {
if(n%i == 0) {
factorSum += i;
}
}
Here is another implementation:
import java.util.ArrayList;
import java.util.List;
public class P23 {
final static int MIN = 12;
final static int MAX = 28123;
static boolean numbers[] = new boolean[MAX+1];
static List<Integer> abundantNumbers = new ArrayList();
public static void main(String args[]) {
generateAbundants(MIN, MAX);
int size = abundantNumbers.size();
for (int i = 0; i < size; i++) {
for (int j = i; j < size; j++) {
int current = abundantNumbers.get(i) + abundantNumbers.get(j);
if (current <= MAX) {
numbers[current] = true;
} else {
break;
}
}
}
long sum = 0;
for (int i = 1 ; i <= MAX ; i++ ) {
if ( numbers[i] == false ) {
sum += i;
}
}
System.out.println(sum);
}
private static int sumOfProperDivisors(int x) {
int sum = 1;
int squareRoot = (int) Math.sqrt(x);
for (int i = 2; i <= squareRoot; i++) {
if (x % i == 0) {
sum += i;
sum += x / i;
}
}
// if x is a perfect square, it's square root was added twice
if (squareRoot * squareRoot == x) {
sum -= squareRoot;
}
return sum;
}
private static boolean isAbundant(int x) {
if (x < sumOfProperDivisors(x)) {
return true;
}
return false;
}
private static void generateAbundants(int min, int max) {
for (int i = min; i < max; i++) {
if (isAbundant(i)) {
abundantNumbers.add(i);
}
}
}
}
Time: 455 ms
Explanation:
The default value for j is i. You can take j = 0 ( as Ted Bigham said -> b in that case ), because it will work, but it will take into consideration every number twice ( 12+20 = 20+12 ). It's more efficient to start from i. Why isn't it good to start from 1? Because you can loose solutions: in my example 24 = 12 + 12.
Regarding the for loop containing the divisors part, you can use the approach containing sqrt because it's more efficient ( O(sqrt(n)) instead of O(n) ), but you have to adjust it. In my example you can see that I have <= squareRoot because if I don't use =, it will skip some values ( E.g.: 6 is divisor for 36, but you don't include it in your solution ). Because I counted 6 twice, I remove one of those roots. Of course that Ted's method is good, but sometimes it's better to have an improved performance, even if the simplicity is affected.