Finding the number of fails between 3 sets of array - java

This is a simple coding questions that is asking to sum the marks for each students. If the total marks reaches the pass mark then reach to the next student. If they did not reach the pass marks then it will return as failed.
class StudentMarks {
public int getCountFailures() {
int[] student1 = {3, 2, 6, 4, 3, 6, 6, 7, 3, 2};
int[] student2 = {8, 7, 8, 9, 10, 7, 6, 8, 9, 6};
int[] student3 = {2, 5, 3, 1, 4, 3, 3, 2, 5, 6};
int[][] allStudents = {student1, student2, student3};
int numberFails = 0;
int passMark = 50;
// YOUR CODE GOES HERE
return numberFails;
}
}
Test code
int numberFails = marks.getCountFailures();
System.out.println("Number of fails = " + numberFails);
How would I implement a way to sum the marks for each of the students and return the number of fails.
The expected outcome
Number of fails = 2

Seems as a homework question, so this is not a complete answer but would help you come up with one on your own.
// will return the count of the arrays - the sum of the elements
// of which are equal to or cross the threshold.
long count =
Arrays.stream(allStudents)
.peek(a -> System.out.println(Arrays.toString(a)))
.filter(a -> thresholdSum(a) )
.count();
System.out.print(count);
This is the helper method.
public static boolean thresholdSum(int[] a) {
int threshold = 50;
int sum =0;
for (int i : a) {
sum += i;
if (sum >= threshold) {
return true;
}
}
return false;
}

Related

Google Foobar challenge Minion Work Assignment Java test cases not passing

I have tried solving this problem using Java and for some reason only 2 out of 9 test cases pass but locally all my test cases pass. I am 99% positive that there is some issue with Google Foobar Java test cases for this challenge. Did someone encounter this and if yes, what did you do to solve it?
Question was...
Write a function called solution(data, n) that takes in a list of
less than 100 integers and a number n, and returns that same list
but with all of the numbers that occur more than n times removed
entirely.
The returned list should retain the same ordering as the original
list - you don't want to mix up those carefully-planned shift
rotations! For instance, if data was [5, 10, 15, 10, 7] and n was 1,
solution(data, n) would return the list [5, 15, 7] because 10 occurs
twice, and thus was removed from the list entirely.
-- Java cases --
Input:
Solution.solution({1, 2, 3}, 0)
Output:
Input:
Solution.solution({1, 2, 2, 3, 3, 3, 4, 5, 5}, 1)
Output:
1,4
There are 6 more test cases that are hidden.
Below is the solution I created.
public class MinionShift {
public static int[] solution(int[] data, int n) {
if(n<1)
return new int[0];
if(data.length < 1)
return data;
Map<Integer, Integer> map = new HashMap<>();
for(int d: data) {
map.put(d, map.getOrDefault(d, 0) + 1);
}
return Arrays.stream(data).filter(c->map.containsKey(c) && !(map.get(c)>n)).toArray();
}
}
Test cases that I have tried...
[{1, 2, 3}, 0]
[{1, 2, 2, 3, 3, 3, 4, 5, 5}, 1]
[{1, 2, 2, 3, 3, 3, 4, 5, 5}, 10]
[{1, 2, 2, 3, 3, 3, 4, 5, 5}, -1]
[{}, 5]
[{1, 1, 1, 1, 1}, 5]
[{101, 102, 103, 104, 105}, 5]
Edit...
I tried a Java stream based solution as follows but unfortunately the challenge went away as I submitted a Python solution. But I am posting it here anyways.
public class MinionShift {
public static int[] solution(int[] data, int n) {
if(n<1)
return new int[0];
if(data.length < 1)
return data;
return Arrays.stream(data).filter(d->Arrays.stream(data).filter(i->i==d).count()<=n).toArray();
}
}
This is how I got it to work, you have to work backwards with the array. You need to create another array to check for duplicates to remember them.
public static int[] solution(int[] data, int n){
if(n < 1){
return new int[0];
}
if(data.length < 1){
return data;
}
List<Integer> a = Arrays.stream(data).boxed().collect(Collectors.toList());
for(int i = a.size()-1; i > -1; i--){
ArrayList<Integer> t = new ArrayList<>();
for(int j = 0; j < a.size(); j++){
if(a.get(j) == a.get(i)){
t.add(j);
}
}
if(t.size() > n){
for(int j = t.size()-1; j > -1; j--){
a.remove((int) t.get(j));
}
i -= t.size()-1;
}
}
data = new int[a.size()];
int c = 0;
for(int d : a){
data[c] = d;
c++;
}
return data;
}

Find first duplicate element with lowest second occurrence index

I'm trying to solve a problem on CodeFights called firstDuplicate, that states -
Given an array a that contains only numbers in the range from 1 to
a.length, find the first duplicate number for which the second
occurrence has the minimal index. In other words, if there are more
than 1 duplicated numbers, return the number for which the second
occurrence has a smaller index than the second occurrence of the other
number does. If there are no such elements, return -1.
Example
For a = [2, 3, 3, 1, 5, 2], the output should be firstDuplicate(a) =
3.
There are 2 duplicates: numbers 2 and 3. The second occurrence of 3
has a smaller index than than second occurrence of 2 does, so the
answer is 3.
For a = [2, 4, 3, 5, 1], the output should be firstDuplicate(a) = -1.
My solution -
public class FirstDuplicate {
private static HashMap<Integer, Integer> counts = new HashMap<>();
private static void findSecondIndexFrom(int[] num, int n, int i) {
// given an array, a starting index and a number, find second occurrence of that number beginning from next index
for(int x = i; x < num.length; x++) {
if(num[x] == n) {
// second occurrence found - place in map and terminate
counts.put(n, x);
return;
}
}
}
private static int firstDuplicate(int[] a) {
// for each element in loop, if it's not already in hashmap
// find it's second occurrence in array and place number and index in map
for(int i = 0; i < a.length; i++) {
if(!counts.containsKey(a[i])) {
findSecondIndexFrom(a, a[i], i+1);
}
}
System.out.println(counts);
// if map is empty - no duplicate elements, return -1
if(counts.size() == 0) {
return -1;
}
// else - get array of values from map, sort it, find lowest value and return corresponding key
ArrayList<Integer> values = new ArrayList<>(counts.values());
Collections.sort(values);
int lowest = values.get(0);
//System.out.println(lowest);
for(Map.Entry<Integer, Integer> entries: counts.entrySet()) {
if(entries.getValue() == lowest) {
return entries.getKey();
}
}
return -1;
}
public static void main(String[] args) {
// int[] a = new int[]{2, 3, 3, 1, 5, 2};
//int[] a = new int[]{2, 4, 3, 5, 1};
//int[] a = new int[]{8, 4, 6, 2, 6, 4, 7, 9, 5, 8};
//int[] a = new int[]{1, 1, 2, 2, 1};
int[] a = new int[]{10, 6, 8, 4, 9, 1, 7, 2, 5, 3};
System.out.println(firstDuplicate(a));
}
}
This solution passes only for about 4 of the 11 test cases on CodeFights. However, I manually executed each one of the test cases in my IDE, and each one produces the right result.
I can't figure out why this won't work in CodeFights. Does it have something to do with the use of the static HashMap?
Edited: Since adding and checking if element is present in Set can be done in one step, code can be simplified to:
public static int findDuplicateWithLowestIndex(int... a){
Set<Integer> set = new HashSet<>();
for(int num : a){
if(!set.add(num)){
return num;
}
}
return -1;
}
You're completly right Patrick.
Use this solution: here duplicateIndex should be very large number.
package sample;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
public class Duplicate {
public static Integer secondIndex(Integer[] arr) {
List<Integer> arrlist = new ArrayList<>(Arrays.asList(arr));
int duplicateIndex = 999;
int ele = 0;
for (int i = 0; i < arrlist.size(); i++) {
int secondIndex = getSecondIndex(arrlist, arrlist.get(i));
if (secondIndex >= 0 && duplicateIndex > secondIndex) {
duplicateIndex = secondIndex;
ele = arrlist.get(i);
}
}
return duplicateIndex == 999 ? -1 : ele;
}
public static int getSecondIndex(List<Integer> arr, int ele) {
List<Integer> var0 = new ArrayList<>(arr);
var0.set(var0.indexOf(ele), -1);
return var0.indexOf(ele);
}
public static void main(String[] str) {
// Integer[] arr = new Integer[] { 2, 3, 3, 1, 5, 2 };
// Integer[] arr = new Integer[] { 2, 4, 3, 5, 1 };
// Integer[] arr = new Integer[] { 8, 4, 6, 2, 6, 4, 7, 9, 5, 8 };
// Integer[] arr = new Integer[]{1, 1, 2, 2, 1};
Integer[] arr = new Integer[] { 10, 6, 8, 4, 9, 1, 7, 2, 5, 3 };
System.out.println(secondIndex(arr));
}
}
Solution in Javascript
function solution(a) {
const duplicates = [];
for (const i of a) {
if (duplicates.includes(i))
return i;
else
duplicates.push(i);
}
return -1;
}
console.log(solution([2, 1, 3, 5, 3, 2])); // 3
console.log(solution([2, 2])); // 2
console.log(solution([2, 4, 3, 5, 1])); // -1

arraycopy in Binary Search

I need help with my code here please. I wanted it display the arrays every time it is splitted while containing the key value until it arrives with the simplest array with key value in it then it display "Found!". My problem is, it worked for key = 2 only and not others keys. Please help me for that.
package Search;
import java.util.*;
public class BinarySearch{
/**Example is below of what I expected which is a result I obtained from key = 2
[1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15]
[1, 2, 3, 4, 5, 6]
[1, 2]
Found!
**/
public static int binarySearch(int[] list, int key){
int low = 0;
int high = list.length;
while(high >= low){
int mid = (low+high)/2;
int[] temp = new int[high];
System.arraycopy(list, low, temp, 0, high);
System.out.println(Arrays.toString(temp));
int count = 0;
if(key < list[mid]){
high = mid - 1;
if(count<temp.length){
}
}
else if(key == list[mid]){
return mid;
}
else{
low = mid + 1;
}
}
return -1;
}
public static int User(){
Scanner scan = new Scanner(System.in);
System.out.println("Enter key: ");
String input = scan.nextLine();
int user = Integer.parseInt(input);
return user;
}
public static void main(String[] args){
int[] list = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15};
System.out.println("The array: "+Arrays.toString(list));
System.out.println("The key is found at "+BinarySearch.binarySearch(list, BinarySearch.User()));
}
}

Java Algorithm: Segregate Odd Even Numbers (time-space complexity)

I am writing a method that segregates the array of integers so that all the even integers precede all the odd integers in the array. It must take linear time in the size of the array O(n) and operate in place with only a constant amount of extra space.
Input: {2, 4, 7, 6, 1, 3, 5, 4}
Output: 2, 4, 6, 4, 7, 1, 3, 5
Input: {5, 12, 3, 21, 8, 7, 19, 102, 201}
Output: 12, 8, 102, 5, 3, 21, 7, 19, 201
These were my solutions:
private static void segregateArray1(final int[] arr) {
if (arr != null) {
int leftIdx = 0;
int rightIdx = arr.length - 1;
while (leftIdx < rightIdx) {
if (arr[leftIdx] % 2 != 0 && arr[rightIdx] % 2 == 0) {
// swap immediately
int temp = arr[leftIdx];
arr[leftIdx] = arr[rightIdx];
arr[rightIdx] = temp;
leftIdx++;
rightIdx--;
} else {
if (arr[leftIdx] % 2 == 0) {
leftIdx++;
}
if (arr[rightIdx] % 2 == 1) {
rightIdx--;
}
}
}
}
}
Method 1 takes O(n) and does not take up extra space. However, it does not maintain order.
private static int[] segregateArray2(final int[] arr) {
List<Integer> evenArr = new ArrayList<Integer>();
List<Integer> oddArr = new ArrayList<Integer>();
for (int i : arr) {
if (i % 2 == 0) {
evenArr.add(i);
} else {
oddArr.add(i);
}
}
evenArr.addAll(oddArr);
return ArrayUtils.toPrimitive(evenArr.toArray(new Integer[0]));
}
Method 2 creates ArrayList. I am unsure if this is also O(n).
To test:
public static void main(String[] args) {
int[] arr = {2, 4, 7, 6, 1, 3, 5, 4};
segregateArray1(arr);
System.out.println(Arrays.toString(arr));
int[] arr = {2, 4, 7, 6, 1, 3, 5, 4};
// creates another array segragatedArr!
int[] segragatedArr = segregateArray2(arr);
System.out.println(Arrays.toString(segragatedArr));
}
I am not sure if there is a neater solution/simplicity which satisfies time-space complexity (O(n) and space constraint).
The simplest way to do this and keep the same time complexity and also that the size of the output array is the same size as the input array is to do a modulus check on each value and if it is positive that placed to to the front of the array and if negative then to the back. Please keep in mind that you will need two variables to know the next available locations for the positive and negative numbers
ArrayList numberList = new ArrayList<>(Arrays.asList(1,2,3,4,5,6));
numberList.stream().filter(i -> i % 2 == 0).forEach(System.out::println);

How to remove a row from a 2d array?

I have a simple array, sort of like this:
1 2 3 4 5 6 7 8 9
6 2 7 2 9 6 8 10 5
2 6 4 7 8 4 3 2 5
9 8 7 5 9 7 4 1 10
5 3 6 8 2 7 3 7 2
So, let's call this matrix[5][9]. I wish to now remove every row within this matrix that contains a certain value, in this case 10, so I am left with...
1 2 3 4 5 6 7 8 9
2 6 4 7 8 4 3 2 5
5 3 6 8 2 7 3 7 2
Here's a sample class you can run that I believe does what you're looking for. Removing rows from 2D arrays is tricky business because like #KalebBrasee said, you can't really "remove" them, but rather you have to make a whole new 2D array instead. Hope this helps!
import java.util.ArrayList;
import java.util.List;
public class Matrix {
private double[][] data;
public Matrix(double[][] data) {
int r = data.length;
int c = data[0].length;
this.data = new double[r][c];
for (int i = 0; i < r; i++) {
for (int j = 0; j < c; j++) {
this.data[i][j] = data[i][j];
}
}
}
/* convenience method for getting a
string representation of matrix */
public String toString() {
StringBuilder sb = new StringBuilder(1024);
for (double[] row : this.data) {
for (double val : row) {
sb.append(val);
sb.append(" ");
}
sb.append("\n");
}
return (sb.toString());
}
public void removeRowsWithValue(final double value) {
/* Use an array list to track of the rows we're going to want to
keep...arraylist makes it easy to grow dynamically so we don't
need to know up front how many rows we're keeping */
List<double[]> rowsToKeep = new ArrayList<double[]>(this.data.length);
for (double[] row : this.data) {
/* If you download Apache Commons, it has built-in array search
methods so you don't have to write your own */
boolean found = false;
for (double testValue : row) {
/* Using == to compares doubles is generally a bad idea
since they can be represented slightly off their actual
value in memory */
if (Double.compare(value, testValue) == 0) {
found = true;
break;
}
}
/* if we didn't find our value in the current row,
that must mean its a row we keep */
if (!found) {
rowsToKeep.add(row);
}
}
/* now that we know what rows we want to keep, make our
new 2D array with only those rows */
this.data = new double[rowsToKeep.size()][];
for (int i = 0; i < rowsToKeep.size(); i++) {
this.data[i] = rowsToKeep.get(i);
}
}
public static void main(String[] args) {
double[][] test = {
{1, 2, 3, 4, 5, 6, 7, 8, 9},
{6, 2, 7, 2, 9, 6, 8, 10, 5},
{2, 6, 4, 7, 8, 4, 3, 2, 5},
{9, 8, 7, 5, 9, 7, 4, 1, 10},
{5, 3, 6, 8, 2, 7, 3, 7, 2}};
//make the original array and print it out
Matrix m = new Matrix(test);
System.out.println(m);
//remove rows with the value "10" and then reprint the array
m.removeRowsWithValue(10);
System.out.println(m);
}
}
Use System.arraycopy or use java.util.List instead of arrays. ArrayList has fast access to random elements and a slow remove method, it's the opposite with LinkedList. You have to choose for yourself.
At the and you have to recreate the array and discard the old one. Changing the dimension of an existing array is not possible - if want this type of datastructure, then you should build the matrix based on Collections (ArrayList<ArrayList<Double>>), there you can remove a row easily.
Back to arrays - the idea is to collect all rows (double[] arrays) that you want to keep, create a result array with those rows and replace the old one with the new on on Matrix:
public void doSomethingWith(Matrix in) {
List<double[]> survivingRows = new ArrayList<double[]>();
for (double[] row:in.getRows()) {
if (isAGoodOne(row)) {
survivingRows.add(row);
}
}
double[][] result = new double[survivingRows][];
for (int i = 0; i < result.length; i++) {
result[i] = survivingRows.get(i);
}
in.setArray(result);
}
You can't remove elements from the Java built-in array data structure. You'll have to create a new array that has a length one less than the first array, and copy all the arrays into that array EXCEPT the one you want to remove.
My java syntax is a little rusty, but the following, if treated as pseudocode will work
public Matrix removeRows(Matrix input) {
int[][] output = new int[input.numRows][input.numColumns]();
int i = 0;
for (int[] row : input.rows()) { // Matrix.rows() is a method that returns an array of all the rows in the matrix
if (!row.contains(10)) {
output[i] = row;
}
}
return output
My take:
import java.util.Arrays;
public class RemoveArrayRow {
private static <T> T[] concat(T[] a, T[] b) {
final int alen = a.length;
final int blen = b.length;
if (alen == 0) {
return b;
}
if (blen == 0) {
return a;
}
final T[] result = (T[]) java.lang.reflect.Array.newInstance(a.getClass().getComponentType(), alen + blen);
System.arraycopy(a, 0, result, 0, alen);
System.arraycopy(b, 0, result, alen, blen);
return result;
}
public static void main(String[] args) {
double[][] d = { {11, 2, 3, 4, 5, 6, 7, 8, 9, 0},
{12, 2, 3, 4, 5, 6, 7, 8, 9, 1},
{13, 2, 3, 4, 5, 6, 7, 8, 9, 2},
{14, 2, 3, 4, 5, 6, 7, 8, 9, 3},
{15, 2, 3, 4, 5, 6, 7, 8, 9, 4} };
//remove the fourth row:
// (1)
double[][] d1 = concat(Arrays.copyOf(d, 3), Arrays.copyOfRange(d, 4, 5));
// (2)
double[][] d2 = new double[d.length - 1][d[0].length];
System.arraycopy(d, 0, d2, 0, 3);
System.arraycopy(d, 4, d2, 3, 1);
System.out.print(d1.length);
System.out.print(d2.length);
}
}
(1)
If you exclude the concat() function used for concatenating two arrays, it's done in one line:
double[][] d1 = concat(Arrays.copyOf(d, 3), Arrays.copyOfRange(d, 4, 5));
See this question as well. That's where the code for the concat() function comes from.
(2)
This method is faster and only uses already available functions.
Since it cannot avoid creating new 2D array to contain the after-removed data, firstly, create a new 2D int[][] b with same dimension as a[][]. secondly, loop through a[][], assign a to b and move b row up when a contain specific value. and sanity check the last row, which can contain specific data.
public static int[][] remove(int[][] a, int v) {
int r = a.length;
int c = a[0].length;
int[][] b = new int[r][c];
int red = 0;
boolean s = false;
for (int i = 0; i < r; i++) {
for (int j = 0; j < c; j++) {
b[i - red][j] = a[i][j];
if (a[i][j] == v) {
red += 1;
if(i==r-1){
s = true;
}
break;
}
}
}
//check last row
if(s){
for(int i = r-red;i <r-red +1; i++ )
for (int j = 0; j<c; j++){
b[i][j] = 0;
}
}
return b;
}
public static void main(String[] args){
int[][] a = { {1, 2, 3, 4, 5, 6, 7, 8, 1},
{6, 2, 7, 2, 9, 6, 8, 10, 5},
{2, 6, 4, 7, 8, 4, 2, 2, 5},
{9, 8, 7, 5, 9, 7, 4, 1, 1},
{5, 3, 6, 8, 2, 7, 3, 1, 1} };
print(remove(a, 10));
}
public static void print(int[][] a) {
int r = a.length;
int c = a[0].length;
int red = 0;
for (int i = 0; i < r; i++) {
System.out.printf("\nrow %d, \n", i);
for (int j = 0; j < c; j++) {
System.out.printf("%d, ", a[i][j]);
}
}
}
This may not be an exact solution but a concept of how you can achieve it using System.arraycopy.
In the example below, I want to copy all the rows except the first row. In your case, you can skip those rows which contain 10.
String[][] src = getSheetData(service, spreadSheetId, range);
String[][] dest = new String[src.length-1][src[0].length];
for (int i = 1; i < src.length; i++) {
System.arraycopy(src[i], 0, dest[i-1], 0, src[0].length-1);
}
Reference: https://docs.oracle.com/javase/6/docs/api/java/lang/System.html#arraycopy%28java.lang.Object,%20int,%20java.lang.Object,%20int,%20int%29
You can use IntStream.noneMatch method for this purpose:
int[][] arr1 = {
{1, 2, 3, 4, 5, 6, 7, 8, 9},
{6, 2, 7, 2, 9, 6, 8, 10, 5},
{2, 6, 4, 7, 8, 4, 3, 2, 5},
{9, 8, 7, 5, 9, 7, 4, 1, 10},
{5, 3, 6, 8, 2, 7, 3, 7, 2}};
int[][] arr2 = Arrays.stream(arr1)
.filter(row -> Arrays.stream(row).noneMatch(i -> i == 10))
.toArray(int[][]::new);
// output
Arrays.stream(arr2).map(Arrays::toString).forEach(System.out::println);
Output:
[1, 2, 3, 4, 5, 6, 7, 8, 9]
[2, 6, 4, 7, 8, 4, 3, 2, 5]
[5, 3, 6, 8, 2, 7, 3, 7, 2]

Categories