Merge pull request 'Data structures: Medium' from data_structures into master

Reviewed-on: https://hattori.ztsh.eu/stawros/hackerrank/pulls/2
This commit is contained in:
Piotr Dec 2024-03-15 22:45:32 +01:00
commit 8fac37d685
20 changed files with 906 additions and 1 deletions

View file

@ -0,0 +1,26 @@
package eu.ztsh.training.hackerrank.datastructures.array_1d;
import java.util.Arrays;
import java.util.Scanner;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.stream.Stream;
/**
* Custom modern class for 1D Array task.
*/
public class CustomSolution {
public static void main(String[] args) {
var scan = new Scanner(System.in);
int n = scan.nextInt();
// 1. Create an array, a, capable of holding n integers.
int[] a = new int[n];
var index = new AtomicInteger(0);
// 2. Modify the code in the loop so that it saves each sequential value to its corresponding location in the array.
Stream.generate(scan::nextInt)
.limit(n) // takeWhile doesn't fill last element
.forEachOrdered(item -> a[index.getAndIncrement()] = item);
Arrays.stream(a).forEachOrdered(System.out::println);
}
}

View file

@ -0,0 +1,30 @@
package eu.ztsh.training.hackerrank.datastructures.array_1d;
import java.util.Scanner;
/**
* Java 1D Array task.
* Task spec: Java 8 + partially locked editor
* source: https://www.hackerrank.com/challenges/java-1d-array-introduction/problem
*/
public class Solution {
public static void main(String[] args) {
Scanner scan = new Scanner(System.in);
int n = scan.nextInt();
// BEGIN: unlocked editor
int[] a = new int[n];
int index = 0;
while (scan.hasNext()) {
a[index] = scan.nextInt();
index++;
}
// END: unlocked editor
scan.close();
// Prints each sequential element in array a
for (int i = 0; i < a.length; i++) {
System.out.println(a[i]);
}
}
}

View file

@ -0,0 +1,63 @@
package eu.ztsh.training.hackerrank.datastructures.array_1d_pt2;
import java.util.Arrays;
import java.util.Scanner;
public class Solution {
public static boolean canWin(int leap, int[] game) {
return move(0, leap, game, new int[]{});
}
static boolean isWinningMove(int index, int leap, int length) {
return index == length - 1 || index + leap > length - 1;
}
static boolean canMoveForward(int index, int[] game) {
return game[index + 1] == 0; // We don't check last index as it is considered as winning move
}
static boolean canMoveBackward(int index, int[] game) {
return index > 0 && game[index - 1] == 0;
}
static boolean canJump(int index, int leap, int[] game) {
return game[index + leap] == 0; // We don't bother here about index overflow too
}
private static boolean move(int index, int leap, int[] game, int[] history) {
if (Arrays.stream(history).anyMatch(i -> i == index)) {
return false;
}
var newHistory = Arrays.copyOf(history, history.length + 1);
newHistory[newHistory.length - 1] = index;
if (isWinningMove(index, leap, game.length)) {
return true;
}
if (canMoveForward(index, game) && move(index + 1, leap, game, newHistory)) {
return true;
}
if (canJump(index, leap, game) && move(index + leap, leap, game, newHistory)) {
return true;
}
return canMoveBackward(index, game) && move(index - 1, leap, game, newHistory);
}
public static void main(String[] args) {
Scanner scan = new Scanner(System.in);
int q = scan.nextInt();
while (q-- > 0) {
int n = scan.nextInt();
int leap = scan.nextInt();
int[] game = new int[n];
for (int i = 0; i < n; i++) {
game[i] = scan.nextInt();
}
System.out.println((canWin(leap, game)) ? "YES" : "NO");
}
scan.close();
}
}

View file

@ -0,0 +1,55 @@
package eu.ztsh.training.hackerrank.datastructures.array_2d;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.stream.Collectors;
import java.util.stream.IntStream;
import java.util.stream.Stream;
/**
* Java 2D Array task.
* source: https://www.hackerrank.com/challenges/java-2d-array/problem
*/
public class Solution {
public static void main(String[] args) throws IOException {
BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(System.in));
List<List<Integer>> arr = new ArrayList<>();
IntStream.range(0, 6).forEach(i -> {
try {
arr.add(
Stream.of(bufferedReader.readLine().replaceAll("\\s+$", "").split(" "))
.map(Integer::parseInt)
.collect(Collectors.toList())
);
} catch (IOException ex) {
throw new RuntimeException(ex);
}
});
var array = arr.stream().map(l -> l.stream().mapToInt(i -> i).toArray()).toArray(int[][]::new);
var max = new AtomicInteger(Integer.MIN_VALUE);
IntStream.range(1, 5).forEach(row -> IntStream.range(1, 5).forEach(col -> {
var result = countHourglass(array, row, col);
if (result > max.get()) {
max.set(result);
}
}));
System.out.println(max.get());
bufferedReader.close();
}
private static int countHourglass(int[][] array, int row, int col) {
return array[row - 1][col - 1] + array[row - 1][col] + array[row - 1][col + 1] +
array[row][col] +
array[row + 1][col - 1] + array[row + 1][col] + array[row + 1][col + 1];
}
}

View file

@ -0,0 +1,52 @@
package eu.ztsh.training.hackerrank.datastructures.comparator;
import java.util.Arrays;
import java.util.Comparator;
import java.util.Scanner;
/**
* source: <a href="https://www.hackerrank.com/challenges/java-comparator">Java Comparator</a>
*/
class Checker implements Comparator<Player> {
@Override
public int compare(Player o1, Player o2) {
var points = o2.score - o1.score;
return points != 0 ? points : o1.name.compareTo(o2.name);
}
}
// Hackerrank code below (slightly modified)
public class Solution {
public static void main(String[] args) {
Scanner scan = new Scanner(System.in);
int n = scan.nextInt();
Player[] player = new Player[n];
Checker checker = new Checker();
for (int i = 0; i < n; i++) {
player[i] = new Player(scan.next(), scan.nextInt());
}
scan.close();
Arrays.sort(player, checker);
Arrays.stream(player).forEach(value -> System.out.printf("%s %s%s", value.name, value.score, System.lineSeparator()));
}
}
class Player {
String name;
int score;
Player(String name, int score) {
this.name = name;
this.score = score;
}
}

View file

@ -0,0 +1,65 @@
package eu.ztsh.training.hackerrank.datastructures.dequeue;
import java.util.ArrayDeque;
import java.util.Deque;
import java.util.Scanner;
import java.util.SortedMap;
import java.util.TreeMap;
import java.util.TreeSet;
/**
* Java Dequeue task.
* source: https://www.hackerrank.com/challenges/java-dequeue/problem
*/
public class Solution {
public static void main(String[] args) {
var in = new Scanner(System.in);
int n = in.nextInt();
int m = in.nextInt();
final Deque<Integer> deque = new ArrayDeque<>(m);
var counter = new Counter();
for (int i = 0; i < m; i++) {
var content = in.nextInt();
deque.addLast(content);
counter.add(content);
}
int max = counter.size();
for (int i = m; i < n; i++) {
var content = in.nextInt();
counter.pop(deque.removeFirst());
deque.addLast(content);
counter.add(content);
var newMax = counter.size();
if (newMax > max) {
max = newMax;
}
}
System.out.println(max);
}
}
class Counter {
public void add(int input) {
var content = map.getOrDefault(input, 0);
map.put(input, content + 1);
}
public void pop(int input) {
var content = map.get(input);
if (content == 1) {
map.remove(input);
} else {
map.put(input, content - 1);
}
}
public int size() {
return map.size();
}
private final SortedMap<Integer, Integer> map = new TreeMap<>();
}

View file

@ -0,0 +1,85 @@
package eu.ztsh.training.hackerrank.datastructures.priority_queue;
import java.util.ArrayList;
import java.util.Comparator;
import java.util.List;
import java.util.Objects;
import java.util.PriorityQueue;
import java.util.Scanner;
import java.util.stream.Collectors;
import java.util.stream.Stream;
class Priorities {
List<Student> getStudents(List<String> events) {
var queue = new PriorityQueue<>(events.size(),
Comparator.comparingDouble(Student::getCGPA)
.reversed() // CGPA is the only descending here
.thenComparing(Student::getName)
.thenComparing(Student::getID));
events.forEach(event -> {
var line = event.split(" ");
switch (line[0]) {
case "ENTER" ->
queue.add(new Student(Integer.parseInt(line[3]), line[1], Double.parseDouble(line[2])));
case "SERVED" -> queue.poll();
default -> throw new IllegalArgumentException();
}
});
return Stream.generate(queue::poll).takeWhile(Objects::nonNull).collect(Collectors.toList());
}
}
class Student {
Student(int id, String name, double cgpa) {
this.id = id;
this.name = name;
this.cgpa = cgpa;
}
int getID() {
return id;
}
String getName() {
return name;
}
double getCGPA() {
return cgpa;
}
private final int id;
private final String name;
private final double cgpa;
}
// https://www.hackerrank.com/challenges/java-priority-queue/problem
public class Solution {
public static void main(String[] args) {
int totalEvents = Integer.parseInt(scan.nextLine());
List<String> events = new ArrayList<>();
while (totalEvents-- != 0) {
String event = scan.nextLine();
events.add(event);
}
List<Student> students = priorities.getStudents(events);
if (students.isEmpty()) {
System.out.println("EMPTY");
} else {
for (Student st : students) {
System.out.println(st.getName());
}
}
}
private static Scanner scan = new Scanner(System.in);
private final static Priorities priorities = new Priorities();
}

View file

@ -0,0 +1,41 @@
package eu.ztsh.training.hackerrank.datastructures.stack;
import java.util.Map;
import java.util.Scanner;
import java.util.Stack;
/**
* Java Stack task.
* source: https://www.hackerrank.com/challenges/java-stack
*/
public class Solution {
public static void main(String[] args) {
var scanner = new Scanner(System.in);
while (scanner.hasNext()) {
var stack = new Stack<Character>();
var line = scanner.next();
for (char input : line.toCharArray()) {
if (stack.empty()) {
stack.push(input);
continue;
}
char head = stack.peek();
if (closingChars.getOrDefault(input, '0').equals(head)) {
stack.pop();
} else {
stack.push(input);
}
}
System.out.println(stack.empty());
}
}
private static final Map<Character, Character> closingChars = Map.of(
']', '[',
'}', '{',
')', '('
);
}

View file

@ -0,0 +1,30 @@
package eu.ztsh.training.hackerrank.datastructures.subarray;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.Arrays;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.stream.IntStream;
/**
* Java Subarray task.
* source: https://www.hackerrank.com/challenges/java-negative-subarray/problem
*/
public class Solution {
public static void main(String[] args) throws IOException {
var reader = new BufferedReader(new InputStreamReader(System.in));
var n = Integer.parseInt(reader.readLine());
var array = Arrays.stream(reader.readLine().split(" ")).mapToInt(Integer::parseInt).toArray();
var counter = new AtomicInteger(0);
IntStream.range(0, n).forEach(begin -> IntStream.range(begin, n + 1)
.forEach(end -> {
if (Arrays.stream(array, begin, end).sum() < 0) {
counter.incrementAndGet();
}
}));
System.out.println(counter.get());
}
}

View file

@ -1,5 +1,8 @@
package eu.ztsh.training.hackerrank;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.List;
import java.util.Scanner;
@ -87,6 +90,17 @@ public class EnvironmentTest {
}
@Nested
@DisplayName("Test with BufferedReader created in main(String[]) method")
class EnvironmentReaderTest extends HackerRankEnvironmentTest {
@Override
protected SolutionClassDescription getSolutionClassDescription() {
return new SolutionClassDescription(SampleSolutionWithInlineBufferedReader.class);
}
}
}
class SampleSolutionWithPrivateStaticScanner {
@ -124,3 +138,16 @@ class SampleSolutionWithInlineScanner {
}
}
class SampleSolutionWithInlineBufferedReader {
public static void main(String... args) throws IOException {
var bufferedReader = new BufferedReader(new InputStreamReader(System.in));
String line = bufferedReader.readLine();
do {
System.out.println(line);
line = bufferedReader.readLine();
} while (line != null);
}
}

View file

@ -11,6 +11,8 @@ import java.util.List;
import org.junit.jupiter.api.AfterAll;
import org.junit.jupiter.api.BeforeAll;
import static org.assertj.core.api.Assertions.assertThat;
/**
* Common class with all the necessary logic
*/
@ -30,6 +32,11 @@ public abstract class HackerRankTest {
System.setIn(originalIn);
}
protected void simpleAssert(List<String> input, List<String> expected) {
var result = invoke(input);
assertThat(result).containsExactlyElementsOf(expected);
}
protected List<String> invoke(List<String> input) {
try {
// reset our stdout as check is based on it

View file

@ -11,7 +11,7 @@ import java.util.Arrays;
*/
public record SolutionClassDescription(Class<?> targetClass, String fieldName, FieldModifier[] modifiers) {
SolutionClassDescription(Class<?> targetClass) {
public SolutionClassDescription(Class<?> targetClass) {
this(targetClass, null, null);
}

View file

@ -0,0 +1,51 @@
package eu.ztsh.training.hackerrank.datastructures.array_1d;
import java.util.List;
import eu.ztsh.training.hackerrank.HackerRankTest;
import eu.ztsh.training.hackerrank.SolutionClassDescription;
import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Nested;
import org.junit.jupiter.api.Test;
@DisplayName("HackerRank challenges: Java 1D Array")
class SolutionTest {
@Nested
@DisplayName("Original Solution class")
class OriginalSolutionTest extends Array1DTest {
@Override
protected SolutionClassDescription getSolutionClassDescription() {
return new SolutionClassDescription(Solution.class);
}
}
@Nested
@DisplayName("Custom Solution class")
class CustomSolutionTest extends Array1DTest {
@Override
protected SolutionClassDescription getSolutionClassDescription() {
return new SolutionClassDescription(CustomSolution.class);
}
}
abstract static class Array1DTest extends HackerRankTest {
@Test
public void testCase0() {
simpleAssert(
List.of("5", "10", "20", "30", "40", "50"),
List.of("10", "20", "30", "40", "50")
);
}
@Test
public void testCase1() {
simpleAssert(
List.of("3", "100", "200", "100"),
List.of("100", "200", "100")
);
}
}
}

View file

@ -0,0 +1,83 @@
package eu.ztsh.training.hackerrank.datastructures.array_1d_pt2;
import java.util.List;
import eu.ztsh.training.hackerrank.HackerRankTest;
import eu.ztsh.training.hackerrank.SolutionClassDescription;
import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Nested;
import org.junit.jupiter.api.Test;
import static org.assertj.core.api.Assertions.assertThat;
class SolutionTest extends HackerRankTest {
@Override
protected SolutionClassDescription getSolutionClassDescription() {
return new SolutionClassDescription(Solution.class);
}
@Nested
@DisplayName("Provided test cases")
class TestCases {
@Test
public void testCase0() {
simpleAssert(
List.of(
"4",
"5 3",
"0 0 0 0 0",
"6 5",
"0 0 0 1 1 1",
"6 3",
"0 0 1 1 1 0",
"3 1",
"0 1 0"
),
List.of(
"YES",
"YES",
"NO",
"NO"
)
);
}
}
@Nested
@DisplayName("Unit tests")
class UnitTests {
@Test
public void winningMoveTest() {
assertThat(Solution.isWinningMove(0, 1, 2)).isFalse();
assertThat(Solution.isWinningMove(1, 5, 6)).isTrue();
}
@Test
public void moveForwardTest() {
var game = new int[]{0, 0, 1};
assertThat(Solution.canMoveForward(0, game)).isTrue();
assertThat(Solution.canMoveForward(1, game)).isFalse();
}
@Test
public void moveBackwardTest() {
var game = new int[]{0, 1, 0, 0, 1};
assertThat(Solution.canMoveBackward(0, game)).isFalse();
assertThat(Solution.canMoveBackward(3, game)).isTrue();
assertThat(Solution.canMoveBackward(2, game)).isFalse();
}
@Test
public void jumpTest() {
var game = new int[]{0, 0, 1, 1, 1, 0};
assertThat(Solution.canJump(0, 3, game)).isFalse();
assertThat(Solution.canJump(1, 3, game)).isFalse();
assertThat(Solution.canJump(1, 4, game)).isTrue();
}
}
}

View file

@ -0,0 +1,70 @@
package eu.ztsh.training.hackerrank.datastructures.array_2d;
import java.util.List;
import eu.ztsh.training.hackerrank.HackerRankTest;
import eu.ztsh.training.hackerrank.SolutionClassDescription;
import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Test;
import static org.assertj.core.api.Assertions.assertThat;
@DisplayName("HackerRank challenges: Java 2D Array")
class SolutionTest extends HackerRankTest {
@Test
public void dummyInitTest() {
assertThat(true).isTrue();
}
@Test
public void testCase0() {
simpleAssert(
List.of(
"1 1 1 0 0 0",
"0 1 0 0 0 0",
"1 1 1 0 0 0",
"0 0 2 4 4 0",
"0 0 0 2 0 0",
"0 0 1 2 4 0"
),
List.of("19")
);
}
@Test
public void testCase1() {
simpleAssert(
List.of(
"1 1 1 0 0 0",
"0 1 0 0 0 0",
"1 1 1 0 0 0",
"0 9 2 -4 -4 0",
"0 0 0 -2 0 0",
"0 0 -1 -2 -4 0"
),
List.of("13")
);
}
@Test
public void testCase3() {
simpleAssert(
List.of(
"-1 -1 0 -9 -2 -2",
"-2 -1 -6 -8 -2 -5",
"-1 -1 -1 -2 -3 -4",
"-1 -9 -2 -4 -4 -5",
"-7 -3 -3 -2 -9 -9",
"-1 -3 -1 -2 -4 -5"
),
List.of("-6")
);
}
@Override
protected SolutionClassDescription getSolutionClassDescription() {
return new SolutionClassDescription(Solution.class);
}
}

View file

@ -0,0 +1,39 @@
package eu.ztsh.training.hackerrank.datastructures.comparator;
import eu.ztsh.training.hackerrank.HackerRankTest;
import eu.ztsh.training.hackerrank.SolutionClassDescription;
import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Test;
import java.util.List;
@DisplayName("HackerRank challenges: Java Comparator")
class SolutionTest extends HackerRankTest {
@Test
public void testCase0() {
simpleAssert(
List.of(
"5",
"amy 100",
"david 100",
"heraldo 50",
"aakansha 75",
"aleksa 150"
),
List.of(
"aleksa 150",
"amy 100",
"david 100",
"aakansha 75",
"heraldo 50"
)
);
}
@Override
protected SolutionClassDescription getSolutionClassDescription() {
return new SolutionClassDescription(Solution.class);
}
}

View file

@ -0,0 +1,39 @@
package eu.ztsh.training.hackerrank.datastructures.dequeue;
import java.util.List;
import eu.ztsh.training.hackerrank.HackerRankTest;
import eu.ztsh.training.hackerrank.SolutionClassDescription;
import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Test;
@DisplayName("HackerRank challenges: Java Dequeue")
class SolutionTest extends HackerRankTest {
@Test
public void testCase0() {
simpleAssert(
List.of(
"6 3",
"5 3 5 2 3 2"
),
List.of("3")
);
}
@Test
public void testCase7() {
simpleAssert(
List.of(
"10 3",
"1 1 1 1 1 1 1 1 1 1"
),
List.of("1")
);
}
@Override
protected SolutionClassDescription getSolutionClassDescription() {
return new SolutionClassDescription(Solution.class);
}
}

View file

@ -0,0 +1,47 @@
package eu.ztsh.training.hackerrank.datastructures.priority_queue;
import java.util.List;
import eu.ztsh.training.hackerrank.HackerRankTest;
import eu.ztsh.training.hackerrank.SolutionClassDescription;
import eu.ztsh.training.hackerrank.SolutionClassDescription.FieldModifier;
import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Test;
@DisplayName("HackerRank challenges: Java Priority Queue")
class SolutionTest extends HackerRankTest {
@Test
public void testCase0() {
var input = List.of(
"12",
"ENTER John 3.75 50",
"ENTER Mark 3.8 24",
"ENTER Shafaet 3.7 35",
"SERVED",
"SERVED",
"ENTER Samiha 3.85 36",
"SERVED",
"ENTER Ashley 3.9 42",
"ENTER Maria 3.6 46",
"ENTER Anik 3.95 49",
"ENTER Dan 3.95 50",
"SERVED"
);
var expected = List.of(
"Dan",
"Ashley",
"Shafaet",
"Maria"
);
simpleAssert(input, expected);
}
@Override
protected SolutionClassDescription getSolutionClassDescription() {
return new SolutionClassDescription(Solution.class,
"scan",
new FieldModifier[]{FieldModifier.PRIVATE, FieldModifier.STATIC});
}
}

View file

@ -0,0 +1,67 @@
package eu.ztsh.training.hackerrank.datastructures.stack;
import java.util.List;
import eu.ztsh.training.hackerrank.HackerRankTest;
import eu.ztsh.training.hackerrank.SolutionClassDescription;
import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Test;
@DisplayName("HackerRank challenges: Java Stack")
class SolutionTest extends HackerRankTest {
@Test
public void testCase0() {
simpleAssert(
List.of(
"{}()",
"({()})",
"{}(",
"[]"
),
List.of(
"true",
"true",
"false",
"true"
)
);
}
@Test
public void testCase1() {
simpleAssert(
List.of(
"({}[])",
"(({()})))",
"({(){}()})()({(){}()})(){()}",
"{}()))(()()({}}{}",
"}}}}",
"))))",
"{{{",
"(((",
"[]{}(){()}((())){{{}}}{()()}{{}{}}",
"[[]][][]",
"}{"
),
List.of(
"true",
"false",
"true",
"false",
"false",
"false",
"false",
"false",
"true",
"true",
"false"
)
);
}
@Override
protected SolutionClassDescription getSolutionClassDescription() {
return new SolutionClassDescription(Solution.class);
}
}

View file

@ -0,0 +1,28 @@
package eu.ztsh.training.hackerrank.datastructures.subarray;
import java.util.List;
import eu.ztsh.training.hackerrank.HackerRankTest;
import eu.ztsh.training.hackerrank.SolutionClassDescription;
import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Test;
import static org.assertj.core.api.Assertions.assertThat;
@DisplayName("HackerRank challenges: Java Subarray")
class SolutionTest extends HackerRankTest {
@Test
public void testCase0() {
simpleAssert(
List.of("5", "1 -2 4 -5 1"),
List.of("9")
);
}
@Override
protected SolutionClassDescription getSolutionClassDescription() {
return new SolutionClassDescription(Solution.class);
}
}