Commit 436c4df6 authored by Dr. Martin Goik's avatar Dr. Martin Goik

Sd1 2019 summer exam + solution

parent b597334b
/.classpath
/.project
/.settings
/.idea
/*.iml
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>de.hdm-stuttgart.mi.sd1</groupId>
<artifactId>sd1_2019summer_exam</artifactId>
<version>0.9</version>
<packaging>jar</packaging>
<name>sd1_2019summer_exam</name>
<url>https://freedocs.mi.hdm-stuttgart.de/sd1_sect_mavenCli.html</url>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>
<repositories>
<repository>
<id>hdm-mi-internal-maven-repo</id>
<url>https://maven.mi.hdm-stuttgart.de/nexus/repository/mi-maven</url>
</repository>
</repositories>
<dependencies>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.12</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j-core</artifactId>
<version>2.12.0</version>
</dependency>
<dependency>
<groupId>de.hdm_stuttgart.mi.exam</groupId>
<artifactId>unitmarking</artifactId>
<version>1.0</version>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.8.1</version>
<configuration>
<source>11</source>
<target>11</target>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-javadoc-plugin</artifactId>
<version>3.1.1</version>
<configuration>
<javaApiLinks>
<property>
<name>api_11</name>
<value>https://klausur.mi.hdm-stuttgart.de/doc/openjdk-11-doc/api/</value>
</property>
</javaApiLinks>
<stylesheetfile>localstyles.css</stylesheetfile>
<additionalJOptions>
<additionalJOption>-html5</additionalJOption>
</additionalJOptions>
<javadocExecutable>${java.home}/bin/javadoc</javadocExecutable>
</configuration>
</plugin>
<plugin>
<artifactId>maven-assembly-plugin</artifactId>
<version>3.1.1</version>
<configuration>
<descriptors>
<descriptor>src/main/assembly/assembly.xml</descriptor>
</descriptors>
</configuration>
<executions>
<execution>
<id>make-assembly</id>
<phase>package</phase>
<goals>
<goal>single</goal>
</goals>
<configuration>
<archive>
<manifest>
<mainClass>de.hdm_stuttgart.mi.sd1.test.ShowReachedPoints</mainClass>
</manifest>
</archive>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
</project>
<assembly
xmlns="http://maven.apache.org/plugins/maven-assembly-plugin/assembly/1.1.3"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/plugins/maven-assembly-plugin/assembly/1.1.3 http://maven.apache.org/xsd/assembly-1.1.3.xsd">
<id>fat-tests</id>
<formats>
<format>jar</format>
</formats>
<includeBaseDirectory>false</includeBaseDirectory>
<dependencySets>
<dependencySet>
<outputDirectory/>
<useProjectArtifact>true</useProjectArtifact>
<unpack>true</unpack>
<scope>test</scope>
</dependencySet>
</dependencySets>
<fileSets>
<fileSet>
<directory>${project.build.directory}/test-classes</directory>
<outputDirectory/>
<includes>
<include>**/*.class</include>
</includes>
<useDefaultExcludes>true</useDefaultExcludes>
</fileSet>
<fileSet>
<directory>${project.build.directory}/classes</directory>
<outputDirectory/>
<includes>
<include>**/*.class</include>
</includes>
<useDefaultExcludes>true</useDefaultExcludes>
</fileSet>
</fileSets>
</assembly>
\ No newline at end of file
package de.hdm_stuttgart.mi.sd1.task1;
/**
* Helper methods.
*/
public class Helper {
/**
* <p>Check whether three integer values are being provided in a strictly ascending order. Examples:</p>
*
* <table class="goikTableDefaults">
*
* <tr>
* <th>Values</th>
* <th>Result</th>
* </tr>
*
* <tr>
* <td>{-1, 3, 7}</td>
* <td>Strictly ascending</td>
* </tr>
*
* <tr>
* <td>{1, 5, 4}</td>
* <td>Not strictly ascending since <code>5 &lt; 4</code> is false.</td>
* </tr>
*
* <tr>
* <td>{1, 2, 2}</td>
* <td>Not strictly ascending since <code>2 &lt; 2</code> is false.</td>
* </tr>
*
* </table>
*
* @param a The first integer value.
* @param b The second integer value.
* @param c The third integer value.
* @return <code>true</code> if all three values are in strictly ascending order, <code>false</code> otherwise.
*/
static public boolean isAscending(final int a, final int b, final int c) {
return true; // TODO:Implement me correctly
}
/**
* <p>A valid title text shall obey the following conditions:</p>
* <ul>
* <li>It must begin with a capital letter.</li>
* <li>It must have a length of at least 20 characters.</li>
* </ul>
*
* <p>Examples:</p>
*
* <table class="goikTableDefaults">
*
* <tr>
* <th>Title</th>
* <th colspan="2">Result</th>
* </tr>
*
* <tr>
* <td><span style="color:red">T</span>his is all quite correct</td>
* <td>Valid</td>
* <td>Length of 25 character and <span style="color:red">'T'</span> being a capital letter</td>
* </tr>
*
* <tr>
* <td><span style="color:red">4</span>all of you: This is bullshit!</td>
* <td>Invalid</td>
* <td><span style="color:red">'4'</span> is not a letter but a digit</td>
* </tr>
*
* <tr>
* <td>Too short!</td>
* <td>Invalid</td>
* <td>20 characters are being required</td>
* </tr>
*
* <tr>
* <td><span style="color:red">l</span>ooks promising but flawed anyway</td>
* <td>Invalid</td>
* <td><span style="color:red">l</span> is small caps rather than a capital letter</td>
* </tr>
*
* </table>
*
* <section class="implementationHints">
*
* <h3>Implementation hints:</h3>
*
* <ul>
* <li>See {@link Character#isUpperCase(char)}.</li>
* <li>See {@link Character#isLetter(char)}.</li>
* </ul>
*
* </section>
*
* @param title The title text to be examined
* @return <code>true</code> if title is non-null and its text meets both conditions,
* <code>false</code> otherwise.
*/
public static boolean checkTitle(final String title) {
return true; // TODO:Implement me correctly
}
/** <p>Tell whether a given character is a vowel or not. The set of vowels is:</p>
*
* <p><code>{a, e, i, o, u}</code> plus the five corresponding uppercase counterparts.</p>
*
* @param candidate The character to be examined.
* @return <code>true</code> if the given character is a vowel, <code>false</code> otherwise.
*/
static public boolean isVowel(final char candidate) {
return true; // TODO:Implement me correctly
}
/**
* <p>Count a string's number of vowels according to {@link #isVowel(char)}. Examples:</p>
*
* <table class="goikTableDefaults">
* <tr>
* <th>String</th>
* <th>Vowel count</th>
* </tr>
*
* <tr>
* <td><code>null</code></td>
* <td>0</td>
* </tr>
*
* <tr>
* <td>Thx</td>
* <td>0</td>
* </tr>
*
* <tr>
* <td><span style="color:red">A</span> T<span style="color:red">e</span>st.</td>
* <td>2</td>
* </tr>
*
* <tr>
* <td>Th<span style="color:red">i</span>s <span style="color:red">i</span>s q<span
* style="color:red">ui</span>t<span style="color:red">e</span> s<span style="color:red">i</span>mpl<span
* style="color:red">e</span>.</td>
* <td>7</td>
* </tr>
* </table>
*
* <section class="implementationHints">
*
* <h3>Implementation hint:</h3>
*
* <p>Use your own {@link #isVowel(char)}} implementation.</p>
*
* </section>
*
* @param s A string possibly containing vowels
* @return The number of vowels being contained within the string in question. Zero in case of a <code>null</code>
* input value.
*/
static public int getNumberOfVowels(final String s) {
return -12345; // TODO:Implement me correctly
}
/**
* <p>Renaming file base names.</p>
*
* <p>File names typically consist of a <span style="color:red">base name</span> separated from an
* <span style="color:green">extension</span> by the first dot <code>'.'</code>
* character i.e. «<code style="color:red">pre70</code><code>.</code><code style="color:green">pdf</code>».</p>
*
* <p>In presence of an extension renaming a file typically refers to
* changing just a file's basename rather than its extension as well:</p>
*
* <table class="goikTableDefaults">
* <tr>
* <th>Renaming <code style="color:red">pre70</code><code>.</code><code style="color:green">pdf</code> to
* <code style="color:red">post70</code><code>.</code><code style="color:green">pdf</code>.</th>
*
* <th>Renaming <code style="color:red">xmlmind</code><code>.</code><code style="color:green">tar.bz2</code> to
* <code style="color:red">other</code><code>.</code><code style="color:green">tar.bz2</code></th>
* </tr>
*
* <tr>
* <td><object data="doc-files/renamePdf.png" type="image/png"></object></td>
*
* <td><object data="doc-files/renameArchive.png" type="image/png"></object></td>
* </tr>
* </table>
*
*
* <section class="implementationHints">
* <p><b>Implementation hints:</b></p>
* <ul>
* <li>See {@link String#indexOf(int)}</li>
* <li>See {@link String#substring(int)}</li>
* </ul>
*
* </section>
*
* @param filename The complete file name possibly including an extension.
* @param newBasename The intended new base name excluding a possible extension.
* @return Replacing the filename up to the <strong>first</strong> occurrence of an extension separation
* <code>'.'</code> character. If no separation character is present, the entire name will be replaced.
*/
public static String renameFileBasename(final String filename, final String newBasename) {
return "Too sad!"; // TODO:Implement me correctly
}
}
\ No newline at end of file
package de.hdm_stuttgart.mi.sd1.task1;
/**
* Array helper methods.
*/
public class HelperArray {
/**
* <p>Filter an array of strings creating a new array containing only non-<code>null</code>values being
* lexicographically larger than a given reference string. The original array will be left untouched.</p>
*
* <p>Examples starting from <code>{"brown", "red", "yellow", "green"}</code>:</p>
*
<table class="goikTableDefaults">
* <tr>
* <th>Reference</th>
* <th colspan="2">Result</th>
* </tr>
*
* <tr>
* <td><code>"magenta"</code></td>
* <td><code>{"red", "yellow"}</code></td>
* <td>Both <code>"brown"</code> and <code>"green"</code> being lexicographically smaller than "magenta"
* get evicted.</td>
* </tr>
*
* <tr>
* <td><code>"red"</code></td>
* <td><code>{"yellow"}</code></td>
* <td>All values except <code>{"yellow"}</code> are lexicographically smaller than <code>"red"</code>.</td>
* </tr>
*
* </table>
*
* <section class="implementationHints">
*
* <h3>Implementation hint:</h3>
*
* <ul>
* <li>See {@link String#compareTo(String)}.</li>
* </ul>
*
* </section>
*
* @param values {@link String} or <code>null</code> values.
* @param reference A reference string defining a filter.
* @return A new array containing all original non-<code>null</code> elements being lexicographically larger than the
* reference string. If either argument is null an empty array will be returned.
*
*/
static public String[] getAlphabeticalFollowers(final String[] values, final String reference) {
return null; // TODO:Implement me correctly
}
/**
* <p>An element <strong>e</strong> of an integer array is called a leader if either of the following two
* statements hold:</p>
*
* <ul>
* <li>
* <p><strong>e</strong> is larger than or equal to all of its right neighbours.</p>
* </li>
* <li>
* <p><strong>e</strong> has got no right neighbours i.e. is itself the last array element.</p>
* <p>Consequence: An array's rightmost element is always a leader.</p>
* </li>
* </ul>
*
* <p>Example: The array <strong>[1, 4, -2, 0, 3]</strong> contains two leaders [4, 3] at array index positions
* 1 and 4 respectively.</p>
*
* @param values A non-empty sequence of values.
* @return An array containing all leader values including possible duplicates preserving their order of appearance
* within the original array.
*/
static public int[] getLeaders(final int[] values) {
return null; // TODO:Implement me correctly
}
}
\ No newline at end of file
package de.hdm_stuttgart.mi.sd1.task2;
import de.hdm_stuttgart.mi.sd1.task2.money.Coin;
/**
*
* <p>Representing money change amounts given in Euro (€) cents by numbers of coins. As an example we
* compose an amount of 924 cents (9€ and 24 cents) starting from numbers of coins:</p>
*
* <object data="doc-files/euros.svg" type="image/svg+xml" width="700" height="400"></object>
*
*<table class="goikTableDefaults">
* <tr>
* <th>Description</th>
* <th>Code</th>
* <th>Result</th>
* </tr>
* <tr>
* <td>
* <ul>
* <li><code style="color:red">4</code> x «two euro» coins ({@link Coin#EURO_2}).</li>
* <li><code style="color:red">1</code> x «one euro» coin ({@link Coin#EURO_1}).</li>
* <li><code style="color:red">1</code> x «twenty cent» coin ({@link Coin#CENT_20}).</li>
* <li><code style="color:red">2</code> x «two cent» coin ({@link Coin#CENT_02}).</li>
* </ul>
* <p>Amount: 924 cents</p>
* </td>
* <td>
* <pre> final ChangeAmount c = new ChangeAmount();
*
* c.{@link #setCoin(Coin, int) setCoin}({@link Coin#EURO_2}, <code style="color:red">4</code>);
* c.{@link #setCoin(Coin, int) setCoin}({@link Coin#EURO_1}, <code style="color:red">1</code>);
* c.{@link #setCoin(Coin, int) setCoin}({@link Coin#CENT_20}, <code style="color:red">1</code>);
* c.{@link #setCoin(Coin, int) setCoin}({@link Coin#CENT_02}, <code style="color:red">2</code>);
*
* System.out.println("Amount: " + c.{@link #getAmount()});</pre>
* </td>
* <td>
* <pre>Amount: 924</pre>
* </td>
* </tr>
* </table>
*
* <p>Conversely a given euro cent amount can be decomposed into a minimal number of coins:</p>
*
*<table class="goikTableDefaults">
* <tr>
* <th>Code</th>
* <th>Result</th>
* </tr>
* <tr>
* <td>
* <pre> final ChangeAmount c = new ChangeAmount();
*
* c.{@link #setAmount(int) setAmount}(924); // 9€ and 24 cent
*
* final int[] coinCounts = c.{@link #getCoins(Coin[]) getCoins}(new Coin[]{
* Coin.EURO_2,
* Coin.EURO_1,
* Coin.CENT_20,
* Coin.CENT_02});
*
* System.out.println({@link java.util.Arrays#toString(int[]) Arrays.toString}(coinCounts));</pre>
* </td>
* <td>
* <pre>[4, 1, 1, 2]</pre>
* </td>
*
* </tr>
* </table>
*
* <p id="minimalNumberOfCoins">Notice that [0, 9, 0, 42] also represents an amount of 942 cents. But the
* number of coins would not be minimal.</p>
*
*
* <section class = "implementationHints">
* <h3>Implementation hints:</h3>
*
* <ol>
* <li>
* <p>All enum {@link Coin} instances are present in the (correctly) ordered array returned
* by {@link Coin#values()}. The {@link Enum#ordinal()} method will return each {@link Coin} instance's
* unique index:</p>
*
* <table class="goikTableDefaults">
* <tr>
* <th>Code</th>
* <th>Result</th>
* </tr>
* <tr>
* <td>
* <pre> for (final Coin c: Coin.values()) {
* System.out.println(<span style="color:red">c</span> + ", index=" + <span
* style="color:DarkOrange">c.ordinal()</span>);}</pre>
* </td>
* <td>
* <pre> <span style="color:red">CENT_01</span>, index=<span style="color:DarkOrange">0</span>
* <span style="color:red">CENT_02</span>, index=<span style="color:DarkOrange">1</span>
* <span style="color:red">CENT_05</span>, index=<span style="color:DarkOrange">2</span>
* <span style="color:red">CENT_10</span>, index=<span style="color:DarkOrange">3</span>
* <span style="color:red">CENT_20</span>, index=<span style="color:DarkOrange">4</span>
* <span style="color:red">CENT_50</span>, index=<span style="color:DarkOrange">5</span>
* <span style="color:red">EURO_1</span>, index=<span style="color:DarkOrange">6</span>
* <span style="color:red">EURO_2</span>, index=<span style="color:DarkOrange">7</span></pre>
* </td>
* </tr>
* </table>
* </li>
*
* <li>
* <p>Use an int[] array of size 8 matching the number of <code>8 == Coin.values().length</code> coins.
* Each position represents the count of the respective coin. Example:</p>
* <table class="goikTableDefaults">
* <tr>
* <th>Code</th>
* <th>Result</th>
* </tr>
* <tr>
* <td>
* <pre> final int[] coinCounts = new int[Coin.values().length];
*
* coinCounts[Coin.CENT_20.ordinal()] = <span style="color:red">2</span>;
* coinCounts[Coin.EURO_2.ordinal()] = <span style="color:DarkOrange">3</span>;
*
* System.out.println(Arrays.toString(coinCounts));</pre>
* </td>
* <td>
* <pre> [0, 0, 0, 0, <span style="color:red">2</span>, 0, 0, <span style="color:DarkOrange">3</span>]</pre>
* </td>
* </tr>
* </table>
*
* <p>The example array containing two «twenty cent» and three «two euro» coins represents
* an overall amount of 640 cents.</p>
* </li>
* </ol>
* </section>
*/
public class ChangeAmount {
/**
* Get current amount.
*
* Example: One «two euro» coin and two «twenty cent» coins amount to 240 cents.
*
* @return The amount of all coins in Euro cent.
*/
public int getAmount() {
return -1234; // TODO:Implement me correctly
}
/**
* Decompose a given Euro cents amount into «optimal» change i.e. requiring a minimal number of coins. See
* <a href="#minimalNumberOfCoins">above remark</a> regarding the word «minimal».
*
* Example: 544 cent will be represented by:
* <ul>
* <li>2 x «two euro» / {@link Coin#EURO_2} coin.</li>
* <li>1 x «one euro» / {@link Coin#EURO_1} coin.</li>
* <li>2 x «twenty cent» / {@link Coin#CENT_20} coin.</li>
* <li>2 x «two cent» / {@link Coin#CENT_02} coin.</li>
* <li>The remaining four coin types not being required will be absent.</li>
* </ul>
*
* @param amount An amount provided as Euro-cent.
*/
public void setAmount(int amount) {
// TODO:Implement me correctly
}
/**
* Set a certain type of coins to a given number.
*
* Example: After calling <code>setCoin(Coin.CENT_20, 3)</code> the change will contain three
* «twenty cent» coins. Example:
*
* <pre>{@code
* final ChangeAmount c = new ChangeAmount();
*
* c.setCoin(Coin.CENT_02, 2); // Adding 2 x «two cent» = 4 cent
* c.setCoin(Coin.CENT_20, 2); // Adding 2 x «twenty cent» = 40 cent.
* c.setCoin(Coin.CENT_50, 1); // Adding 1 x «fifty cent».
*
* System.out.println(c); // 94 cent}</pre>
*
* @param coin The coin, e.g. «fifty cent» to be set: Either of {@link Coin#values()}
* @param num The desired number of coins.
*/
public void setCoin(final Coin coin, final int num) {
// TODO:Implement me correctly
}
/**
* Get number of selected coins within change. Example:
*
* <pre>{@code
* final ChangeAmount c = new ChangeAmount();
*
* c.setAmount(241); // 241 Cent consisting of:
* // 2 x «two Euro»
* // 2 x «twenty cent»
* // 1 x «one cent»
*
* // Query instance for counts of dedicated coins
* final Coin[] coins = {Coin.EURO_2, Coin.CENT_50, Coin.CENT_20};
* final int[] numbers = c.getCoins(coins);// Expecting {1, 0, 2}
* }</pre>
*
* <code>numbers</code> will contain <code>{1, 0, 2}</code> representing one «two euro», zero «euro» and
* two «twenty cent» coins.
*
* @param coins A list of coin values.
* @return The individual number of coins for each desired position.
*/
public int[] getCoins(final Coin[] coins) {
return null; // TODO:Implement me correctly
}
}
\ No newline at end of file
package de.hdm_stuttgart.mi.sd1.task2;
import de.hdm_stuttgart.mi.sd1.task2.money.Coin;
public class CoinDemo {
public static void main(String[] args) {
final ChangeAmount c = new ChangeAmount();
c.setCoin(Coin.EURO_2, 4);
c.setCoin(Coin.EURO_1, 1);
c.setCoin(Coin.CENT_20, 1);
c.setCoin(Coin.CENT_02, 2);
System.out.println("Amount: " + c.getAmount());
}
}
\ No newline at end of file