Skip to content

Commit 9aacad4

Browse files
authored
Merge pull request #3 from arcuri82/update-2020-exam
Update 2020 exam
2 parents 7d3cd70 + 490bf36 commit 9aacad4

File tree

18 files changed

+538
-45
lines changed

18 files changed

+538
-45
lines changed

Diff for: .github/workflows/ci.yml

+22
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
name: CI
2+
3+
on: [push]
4+
5+
jobs:
6+
build:
7+
runs-on: ubuntu-latest
8+
9+
steps:
10+
- uses: actions/checkout@v2
11+
- name: Setup JDK 11
12+
uses: actions/setup-java@v1
13+
with:
14+
java-version: 11
15+
- name: Cache Maven packages
16+
uses: actions/cache@v2
17+
with:
18+
path: ~/.m2
19+
key: ${{ runner.os }}-m2-${{ hashFiles('**/pom.xml') }}
20+
restore-keys: ${{ runner.os }}-m2
21+
- name: Build with Maven
22+
run: mvn clean verify -Dhttp.keepAlive=false -Dmaven.wagon.http.pool=false -Dmaven.wagon.httpconnectionManager.ttlSeconds=120

Diff for: .travis.yml

-40
This file was deleted.

Diff for: README.md

+1-2
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,7 @@
11

22
# Algorithms and Data Structures
33

4-
[![Build Status](https://travis-ci.org/arcuri82/algorithms.svg?branch=master)](https://travis-ci.org/arcuri82/pg4200)
5-
4+
![CI](https://github.com/arcuri82/algorithms/workflows/CI/badge.svg)
65

76
Slides, code examples and exercises (with solutions) for the PG4200 course:
87
Algoritmer og datastrukturer (Algorithms and Data Structures).

Diff for: docs/exercises/ex02.md

+19-3
Original file line numberDiff line numberDiff line change
@@ -45,12 +45,28 @@ On the other hand, when `index > size()/2` it would be more efficient to start f
4545

4646
Write a `MyBidirectionalLinkedListTest` that extends `MyListTestTemplate`.
4747
If your implementation is correct, all tests should pass.
48-
Run the tests with code coverage enabled, and verify that all of the instructions in your
49-
code are covered. If not, add new tests to `MyBidirectionalLinkedListTest`.
50-
48+
5149

5250

5351
## Part D
52+
53+
Write a new class `MyMiddleBidirectionalLinkedList` that extends `MyList`, using `MyBidirectionalLinkedList` as starting point.
54+
However, besides having a link to the `head` and the `tail` of the list, you need to have a 3rd link, pointing to the `middle` of the list.
55+
When you need to access an element (e.g., with a get), then you need to minimize the number of nodes to traverse.
56+
For example, assume a list with 100 elements, and you need to delete the element at position 40.
57+
Then, the most efficient way would be to start from the `middle` link, and go backwards following the previous links till position 40.
58+
On the other hand, if accessing at position 20, it would be more efficient to start from head and follow the next links.
59+
In other words, all indices in the range 25%-75% of the size of the list should be accessed starting from the `middle` link.
60+
61+
Pay particular attention at the fact that, at each `delete` and `add` operation, the value of `middle` will likely need to be updated.
62+
Note: in case of list with an even number of elements, the middle could have 2 values, choose the lower.
63+
For example: `length=1` and `length=2` would have middle at position `0`, whereas `length=3` and `length=4` would have it at position `1`, `length=5` at `2`, and so on.
64+
65+
Write a `MyMiddleBidirectionalLinkedListTest` that extends `MyListTestTemplate`.
66+
If your implementation is correct, all tests should pass.
67+
68+
69+
## Part E
5470

5571
Study the source code of `MyLinkedList`, `MyStackLinkedList` and `MyQueueArray`.
5672
Once you think you fully understand them, write their implementation

Diff for: docs/exercises/ex12.md

+19
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
# Exercise 12
22

3+
## Part A
4+
35
Implement a class `HuffmanIso` that extends `Huffman`.
46
In such class, override the methods `writeTrie` and `readTrie`.
57
When writing/reading a char for a given leaf node, use the charset ISO-8859-1 instead
@@ -25,6 +27,23 @@ Write a test class `HuffmanIsoTest` with the following two tests:
2527
Explain why.
2628

2729

30+
## Part B
31+
32+
Consider a string representation for exam grades, in the format of `<id><grade>`, where `id` is a number starting from 0 (can assume __NO MORE__ than 500 students in an exam, and there can be exams with just a couple of students), and grades in the range `A-F`.
33+
A valid string would be for example: `0A1F2F3C12F13B14B27A201B497A`.
34+
You can assume that the ids are sorted, but there can be holes in the sequence (e.g., representing students that did not submit).
35+
36+
Write a class `GradeCompressorImp` that implements the given `GradeCompressor` interface.
37+
38+
You __MUST__ come up with an efficient compression algorithm which is specialized and customized for this problem domain (i.e., do not use either `Huffman` nor `LZW`, but rather use `DnaCompressor` as inspiration).
39+
For example, if there is just 1 student, you should not use more than 2 bytes in total for the compression.
40+
If there are 100 students, should not use more than 150 bytes.
41+
In your implementation, you can rely on and use the classes `BitWriter` and `BitReader`.
42+
43+
Write a test class `GradeCompressorTest` that extends the given `GradeCompressorTestTemplate` test suite.
44+
If your implementation of `GradeCompressorImp` is correct, all tests should pass.
45+
46+
2847
## Solutions
2948

3049
Solutions to this exercise can be found in the `solutions`

Diff for: exercises/src/main/java/org/pg4200/ex07/AnotherStream.java

+10
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
package org.pg4200.ex07;
22

3+
import java.util.Optional;
4+
import java.util.function.BinaryOperator;
35
import java.util.function.Predicate;
46

57
/**
@@ -30,6 +32,14 @@ public interface AnotherStream<T> {
3032
*/
3133
boolean any(Predicate<T> predicate);
3234

35+
/**
36+
* Performs a reduction on the elements of this stream, using an associative accumulation function,
37+
* and returns an Optional describing the reduced value, if any (ie, if the stream as at least one element).
38+
* This is equivalent to take the first element, apply accumulator with second element, get result
39+
* and apply accumulator with 3rd element, then take this result and accumulate with 4th element, and so on.
40+
*/
41+
Optional<T> reduce(BinaryOperator<T> accumulator);
42+
3343
/**
3444
* Filtering operation that only let pass an element
3545
* once. Ie, if an element in the stream is

Diff for: exercises/src/main/java/org/pg4200/ex09/PatternExamples.java

+11
Original file line numberDiff line numberDiff line change
@@ -30,4 +30,15 @@ public interface PatternExamples {
3030
* - a final domain code, which is at least 2 letters (upper or lower case), and no digits
3131
*/
3232
String emailRegex();
33+
34+
/**
35+
* Need match the following sentence:
36+
*
37+
* Is this an out of season april fools joke?
38+
*
39+
* However, the regex should be general enough to also match for further string variants following these properties:
40+
* a) there can be any number of spaces between the words
41+
* b) each letter can be either in lower or upper case
42+
*/
43+
String isItAJoke();
3344
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
package org.pg4200.ex12;
2+
3+
public interface GradeCompressor {
4+
5+
/**
6+
*
7+
* @param idsAndGrades string list in the form id:grade, eg, 0A1F2C
8+
* @return compressed bytes
9+
*/
10+
byte[] compress(String idsAndGrades);
11+
12+
String decompress(byte[] data);
13+
14+
}

Diff for: exercises/src/test/java/org/pg4200/ex09/PatternExamplesTestTemplate.java

+16
Original file line numberDiff line numberDiff line change
@@ -77,4 +77,20 @@ public void testEmail(){
7777
assertTrue("[email protected]".matches(regex));
7878
assertTrue("[email protected]".matches(regex));
7979
}
80+
81+
@Test
82+
public void testIsItAJoke(){
83+
84+
String regex = getNewInstance().isItAJoke();
85+
86+
assertFalse("".matches(regex));
87+
assertFalse("Is this an out of season april fools jok".matches(regex));
88+
assertFalse("Is this an out of season april fools joke".matches(regex));
89+
assertFalse("a b c d e f g h i?".matches(regex));
90+
assertFalse("i S THIS AN oUT of sEason APRIL FOOLs joKe?".matches(regex));
91+
assertFalse("this Is an out of season april fools joke?".matches(regex));
92+
93+
assertTrue("Is this an out of season april fools joke?".matches(regex));
94+
assertTrue("iS THIS AN oUT of sEason APRIL FOOLs joKe?".matches(regex));
95+
}
8096
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
package org.pg4200.ex12;
2+
3+
import org.junit.jupiter.api.Test;
4+
5+
import static org.junit.jupiter.api.Assertions.assertEquals;
6+
import static org.junit.jupiter.api.Assertions.assertTrue;
7+
8+
public abstract class GradeCompressorTestTemplate {
9+
10+
protected abstract GradeCompressor getNewInstance();
11+
12+
@Test
13+
public void testOne(){
14+
15+
GradeCompressor gc = getNewInstance();
16+
17+
String data = "0A";
18+
byte[] compressed = gc.compress(data);
19+
assertTrue(compressed.length <= 2);
20+
21+
String decompressed = gc.decompress(compressed);
22+
assertEquals(data, decompressed);
23+
}
24+
25+
@Test
26+
public void testSeveral(){
27+
28+
GradeCompressor gc = getNewInstance();
29+
30+
String data = "0A1F2F3C12F13B14B27A201B497A";
31+
byte[] compressed = gc.compress(data);
32+
String decompressed = gc.decompress(compressed);
33+
assertEquals(data, decompressed);
34+
}
35+
36+
@Test
37+
public void test100(){
38+
39+
GradeCompressor gc = getNewInstance();
40+
41+
String data = "";
42+
for(int i=0; i<100; i++){
43+
data += (i + "A");
44+
}
45+
46+
byte[] compressed = gc.compress(data);
47+
assertTrue(compressed.length <= 150);
48+
49+
String decompressed = gc.decompress(compressed);
50+
assertEquals(data, decompressed);
51+
}
52+
}

Diff for: lessons/src/test/java/org/pg4200/les02/list/MyListTestTemplate.java

+19
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,8 @@
66
import static org.junit.jupiter.api.Assertions.assertEquals;
77
import static org.junit.jupiter.api.Assertions.assertThrows;
88
import static org.junit.jupiter.api.Assertions.assertTrue;
9+
import static org.junit.jupiter.api.Assumptions.assumeFalse;
10+
import static org.junit.jupiter.api.Assumptions.assumeTrue;
911

1012
/**
1113
* Created by arcuri82 on 15-Aug-17.
@@ -262,4 +264,21 @@ public void testInsertMiddle(){
262264
assertEquals("b", data.get(2));
263265
assertEquals("c", data.get(3));
264266
}
267+
268+
@Test
269+
public void testInsertAndGetMany(){
270+
271+
//skip running this test on that class, due to limited length
272+
assumeFalse(this.getClass().getSimpleName().equals("MyArrayListTest"));
273+
274+
MyList<Integer> data = getNewInstance(Integer.class);
275+
276+
for(int i=0; i<100; i++){
277+
data.add(i*2);
278+
}
279+
280+
for(int i=0; i<100; i++){
281+
assertEquals(i*2, data.get(i));
282+
}
283+
}
265284
}

0 commit comments

Comments
 (0)