<?xml version="1.0" encoding="UTF-8"?> <chapter annotations="slide" version="5.1" xml:id="sd1_chap_Statements" xmlns="http://docbook.org/ns/docbook" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:xila="http://www.w3.org/2001/XInclude/local-attributes" xmlns:xi="http://www.w3.org/2001/XInclude" xmlns:svg="http://www.w3.org/2000/svg" xmlns:ns="http://docbook.org/ns/transclusion" xmlns:m="http://www.w3.org/1998/Math/MathML" xmlns:html="http://www.w3.org/1999/xhtml" xmlns:db="http://docbook.org/ns/docbook"> <title>Statements</title> <info> <abstract> <para>Purposes of statements:</para> <para>Declaring variables and assigning values.</para> <para>Control <emphasis role="bold">whether</emphasis> code will be executed.</para> <para>Control <emphasis role="bold">how often</emphasis> code will be executed.</para> </abstract> </info> <figure xml:id="sd1_fig_StatementEndSemicolon"> <title>Statements: General syntax</title> <para>Statement's body terminated by <quote>;</quote></para> <programlisting language="none">{statement};</programlisting> </figure> <figure xml:id="sd1_fig_StatementDeclareVariable"> <title>Statement examples: Declaring and assigning variables</title> <glosslist> <glossentry> <glossterm>Variable declaration:</glossterm> <glossdef> <programlisting language="java">int a;</programlisting> </glossdef> </glossentry> <glossentry> <glossterm>Value assignment:</glossterm> <glossdef> <programlisting language="java">a = 33;</programlisting> </glossdef> </glossentry> <glossentry> <glossterm>Combined declaration and assignment:</glossterm> <glossdef> <programlisting language="java">int a = 33;</programlisting> </glossdef> </glossentry> </glosslist> </figure> <figure xml:id="sd1_fig_StatementVsExpression"> <title>Expression <abbrev>vs.</abbrev> statement</title> <glosslist> <glossentry> <glossterm>Expression:</glossterm> <glossdef> <programlisting language="java">a - 4</programlisting> </glossdef> </glossentry> <glossentry> <glossterm>Statement:</glossterm> <glossdef> <programlisting language="java">b = a - 4;</programlisting> <para>Notice the trailing <quote><code>;</code></quote>.</para> </glossdef> </glossentry> </glosslist> </figure> <figure xml:id="sd1_fig_MultiStmtPerLine"> <title>Multiple statements per line</title> <programlisting language="java">a = b + 3; b = a - 4;</programlisting> <para>Discouraged by good coding practices:</para> <itemizedlist> <listitem> <para>Poor readability</para> </listitem> <listitem> <para>Hampers debugging</para> </listitem> </itemizedlist> </figure> <figure xml:id="sd1_fig_DebugMultiStmtPerLine"> <title>Debugging multiple statements per line</title> <mediaobject> <imageobject> <imagedata fileref="Fig/multipleStatementPerLine.svg"/> </imageobject> </mediaobject> </figure> <figure xml:id="sd1_fig_Blocks"> <title>Blocks</title> <programlisting language="java">double initialAmount = 34; { <emphasis role="red">// first block</emphasis> final double interestRate = 1.2; // 1.2% System.out.println("Interest:" + initialAmount * interestRate / 100); } { <emphasis role="red">// second block</emphasis> final double interestRate = 0.8; // 0.8% System.out.println("Interest:" + initialAmount * interestRate / 100); }</programlisting> <informaltable border="1"> <tr> <td><itemizedlist> <listitem> <para>Defining scopes</para> </listitem> <listitem> <para>Unit of work</para> </listitem> </itemizedlist></td> <td><itemizedlist> <listitem> <para><code language="java">if</code>: Conditional block execution.</para> </listitem> <listitem> <para><code language="java">for</code> / <code language="java">while</code>: Repeated block execution.</para> </listitem> </itemizedlist></td> </tr> </informaltable> </figure> <section xml:id="sd1_sect_statements_if"> <title>The if conditional statement</title> <figure xml:id="sd1_fig_if"> <title>Conditional block execution</title> <informaltable border="1"> <tr> <td valign="top"><programlisting language="java">double saving = 320.00; if (1000 <= saving) { // Rich customer, 1,2% interest rate System.out.println( "Interest:" + 1.2 * saving / 100); } System.out.println("Done!");</programlisting></td> <td rowspan="2" valign="top"><mediaobject> <imageobject> <imagedata fileref="Fig/if.svg"/> </imageobject> </mediaobject></td> </tr> <tr> <td><screen>Done!</screen></td> </tr> </informaltable> </figure> <figure xml:id="sd1_fig_ifSyntax"> <title><code language="java">if</code> syntax</title> <programlisting language="java">if (booleanExpression) (block | statement)</programlisting> </figure> <section xml:id="sd1_sect_else"> <title>if-then-<code>else</code></title> <figure xml:id="sd1_fig_ifElse"> <title><code language="java">if</code> ... <code language="java">else</code></title> <informaltable border="1"> <tr> <td valign="top"><programlisting language="java">double saving = 320.00; if (1000 <= saving <co linkends="sd1_fig_ifElse-1" xml:id="sd1_fig_ifElse-1-co"/>) { <co linkends="sd1_fig_ifElse-2" xml:id="sd1_fig_ifElse-2-co"/> // Rich customer, 1,2% interest rate System.out.println( "Interest:" + 1.2 * saving / 100); } <co linkends="sd1_fig_ifElse-3" xml:id="sd1_fig_ifElse-3-co"/> else { <co linkends="sd1_fig_ifElse-4" xml:id="sd1_fig_ifElse-4-co"/> // Joe customer, 0.8% // standard interest rate System.out.println( "Interest:" + 0.8 * saving / 100); } System.out.println("Done!");</programlisting><screen>Interest:2.56 Done!</screen></td> <td valign="top"><mediaobject> <imageobject> <imagedata fileref="Fig/ifElse.svg"/> </imageobject> </mediaobject></td> </tr> </informaltable> <calloutlist role="slideExclude"> <callout arearefs="sd1_fig_ifElse-1-co" xml:id="sd1_fig_ifElse-1"> <para>Decision on boolean expression.</para> </callout> <callout arearefs="sd1_fig_ifElse-2-co" xml:id="sd1_fig_ifElse-2"> <para>Conditional execution of on block or single statement.</para> </callout> <callout arearefs="sd1_fig_ifElse-3-co" xml:id="sd1_fig_ifElse-3"> <para>Required branch being executed in case of boolean expression being true.</para> </callout> <callout arearefs="sd1_fig_ifElse-4-co" xml:id="sd1_fig_ifElse-4"> <para>Optional branch corresponding to boolean expression being false.</para> </callout> </calloutlist> </figure> <figure xml:id="sd1_fig_ifElseSyntax"> <title><code language="java">if ... else</code> syntax</title> <programlisting language="java">if (booleanExpression) (block | statement) [else (block | statement) ] <co linkends="sd1_fig_ifElseSyntax-1" xml:id="sd1_fig_ifElseSyntax-1-co"/></programlisting> <calloutlist role="slideExclude"> <callout arearefs="sd1_fig_ifElseSyntax-1-co" xml:id="sd1_fig_ifElseSyntax-1"> <para>The <quote>[...]</quote> pair of braces denotes an optional clause that may or may not be present.</para> <para>Thus only the first part <quote><code language="java">if (booleanExpression) (block | statement)</code></quote> is mandatory.</para> </callout> </calloutlist> </figure> <figure xml:id="sd1_fig_bestPracticeCompareEquals"> <title>Best practices comparing for equality</title> <para>Use</para> <programlisting language="java">if (4 == variable) ...</programlisting> <para>in favour of:</para> <programlisting language="java">if (variable == 4) ... <co linkends="sd1_fig_bestPracticeCompareEquals-1" xml:id="sd1_fig_bestPracticeCompareEquals-1-co"/></programlisting> <calloutlist role="slideExclude"> <callout arearefs="sd1_fig_bestPracticeCompareEquals-1-co" xml:id="sd1_fig_bestPracticeCompareEquals-1"> <para>Some programming languages allow for interpreting integer values as logical expressions. In »C / C++« for example an <code>int</code> value of zero is equivalent to <code>false</code> and nonzero values evaluate to <code>true</code>. Consider the following snippet:</para> <programlisting language="c">if (variable = 4) {...} /* Just a single "=" rather then "==" */</programlisting> <para>A <xref linkend="glo_Java"/> compiler will flag this as a compile time error. On contrary in »C / C++« this is perfectly correct code: The term <code>variable = 4</code> having a nonzero value of 4 evaluates to <code>true</code> which in real code would most likely be a bug. Subject to choosing compiler warning options the possible damage may be mitigated depending on the observer's degree of pedantry.</para> <para>Changing the order however even in »C / C++« results in a compile time error since we cannot assign a value to a literal:</para> <programlisting language="java">if (4 = variable) {...} // Compile time error, even in C/C++</programlisting> <para>We are thus able to avoid this type of error in the first place.</para> </callout> </calloutlist> </figure> <qandaset defaultlabel="qanda" xml:id="sd1_qanda_betterSimpleMath"> <title>Providing better display</title> <qandadiv> <qandaentry> <question> <para>We reconsider <xref linkend="sd1_qanda_simpleMath"/>:</para> <informaltable border="1"> <tr> <th>Source code</th> <th>Output</th> </tr> <tr> <td valign="top"><programlisting language="java">int a = -4, b = 100; System.out.println(a + "+" + b+ "=" + (a + b));</programlisting></td> <td valign="top"><screen>-4+100=96</screen></td> </tr> </informaltable> <para>Unfortunately a negative value yields:</para> <informaltable border="1"> <tr> <th>Source code</th> <th>Output</th> </tr> <tr> <td valign="top"><programlisting language="java">int a = 100, b = -4; System.out.println(a + "+" + b + "=" + (a + b));</programlisting></td> <td valign="top"><screen>100+-4=96</screen></td> </tr> </informaltable> <para>This result looks awkward. Modify the code to see <code>100-4=96</code> in such cases. You may reconsider the findings from <xref linkend="sd1QandaBracesInPrintln"/>.</para> </question> <answer> <para>The following simple solution does not work:</para> <informaltable border="0"> <tr> <th>Source code</th> <th>Output</th> </tr> <tr> <td valign="top"><programlisting language="java">int a = 100, b = -4; if (b < 0) { System.out.println(a + b + "=" + (a + b)); } else { System.out.println(a + "+" + b + "=" + (a + b)); }</programlisting></td> <td valign="top"><screen>96=96</screen></td> </tr> </informaltable> <para>Since <code language="java">a</code> and <code language="java">b</code> are both variables of type <code language="java">int</code> they get added rather than string style concatenated:</para> <programlisting language="none">System.out.println(a + b + "=" + (a + b)); <emphasis role="red">╲ ╱ ╱ ╲ ╱ 96 ╱ 96 ╲ ╱ ╱ "96=" ╱ ╲ ╱ "96=96"</emphasis></programlisting> <para>Resolving this issue may be effected by adding an empty string <coref linkend="sd1_qanda_betterSimpleMathEmptyString-1-co"/> forcing <xref linkend="glo_Java"/> to use the concatenation <quote>+</quote> operator in favour of the arithmetic one:</para> <programlisting language="none">System.out.println(a + ""<co xml:id="sd1_qanda_betterSimpleMathEmptyString-1-co"/> + b + "=" + (a + b)); <emphasis role="red">╲ ╱ ╱ ╲ ╱ "100" ╱ 96 ╲ ╱ ╱ "100-4" ╱ ╲ ╱ "100-4=96"</emphasis></programlisting> <informaltable border="0"> <tr> <th>Source code</th> <th>Output</th> </tr> <tr> <td valign="top"><programlisting language="java">int a = 100, b = -4; if (b < 0) { System.out.println(a + "" + b + "=" + (a + b)); } else { System.out.println(a + "+" + b + "=" + (a + b)); }</programlisting></td> <td valign="top"><screen>100-4=96</screen></td> </tr> </informaltable> </answer> </qandaentry> </qandadiv> </qandaset> <qandaset defaultlabel="qanda" xml:id="sd1_qanda_booleanEqual"> <title>Comparing for equality</title> <qandadiv> <qandaentry> <question> <para>Copy the following snippet into your <xref linkend="glo_IDE"/>:</para> <programlisting language="java">int count = 1; if (count = 4) { // is count equal to 4? System.out.println("count is o.K."); }</programlisting> <para>The <xref linkend="glo_Java"/> compiler will indicate an error:</para> <screen>Incompatible types. Required: <emphasis role="red">boolean</emphasis> Found: <emphasis role="red">int</emphasis></screen> <para>Explain its cause in detail by examining the <code language="java">count = 4</code> expression.</para> <tip> <para><xref linkend="glo_Java"/> provides two similar looking operators <code language="java">=</code> and <code language="java">==</code> having (totally) different semantics.</para> </tip> </question> <answer> <para>The two operators <code language="java">=</code> and <code language="java">==</code> are <emphasis>completely</emphasis> unrelated:</para> <glosslist> <glossentry> <glossterm><code language="java">=</code></glossterm> <glossdef> <para>This is being called the assignment operator. A typical statement reads <code language="java">a = 34</code> assigning the <code language="java">int</code> value <code language="java">34</code> to a variable <code language="java">a</code>.</para> <para>Note this operator's semantics being completely different from even elementary math syntax. Consider:</para> <informalequation> <m:math display="block"> <m:mrow> <m:mi>x</m:mi> <m:mo>=</m:mo> <m:mi>y</m:mi> </m:mrow> <m:mo>⇒</m:mo> <m:mrow> <m:msup> <m:mi>x</m:mi> <m:mi>2</m:mi> </m:msup> <m:mo>=</m:mo> <m:msup> <m:mi>y</m:mi> <m:mi>2</m:mi> </m:msup> </m:mrow> </m:math> </informalequation> <para>In math <quote>=</quote> denotes the equality of objects <abbrev>e.g.</abbrev> values, sets, functions and so on.</para> </glossdef> </glossentry> <glossentry> <glossterm><code language="java">==</code></glossterm> <glossdef> <para>The comparison operator matching the usual math semantics comparing:</para> <itemizedlist> <listitem> <para><xref linkend="glo_Java"/> primitive types for equality of value.</para> </listitem> <listitem> <para><xref linkend="glo_Java"/> objects for identity.</para> </listitem> </itemizedlist> <para>In particular an expression like <code language="java">count == 4</code> is of type boolean being either <code language="java">true</code> or <code language="java">false</code>.</para> </glossdef> </glossentry> </glosslist> <para>More formally the expression <code language="java">count = 4</code> is of type <code language="java">int</code> evaluating to 4 (surprise!). However an <code language="java">if (...)</code> operates on <code language="java">boolean</code> values only and <code language="java">if (4)</code> thus does not make sense at all. The code in question may therefore be re-written as:</para> <programlisting language="java">int count = 1; int countAssignment = (count = 4); // Assigning expression count = 4 to variable countAssignment. if (countAssignment) { <emphasis role="red">// Error: An int is not a boolean!</emphasis> System.out.println("count is o.K."); }</programlisting> <para>Since the assignment operator is being evaluated from right to left we actually do not need braces:</para> <programlisting language="java">... int countAssignment = count = 4; // Assigning expression count = 4 to variable countAssignment ...</programlisting> <para>This code is equivalent to its counterpart with respect to compilation. The comment <quote>is count equal to 4?</quote> is thus misleading: The intended comparison requires using the <quote>==</quote> operator rather than an assignment operator <quote>=</quote>. Changing it the resulting expression is indeed of type <code language="java">boolean</code>:</para> <programlisting language="java">int count = 4 + 3; final boolean test = (count == 4); // Now using "==" (comparison) in favour of "=" (assignment) System.out.println("test=" + test);</programlisting> <para>Again we may omit braces here due to operator priority rules:</para> <programlisting language="java">... final boolean test = count == 4; // Now using "==" (comparison) in favour of "=" (assignment) ...</programlisting> <para>The <code language="java">boolean</code> variable <code language="java">test</code> will receive a value of <code language="java">false</code> as expected. Thus our initial code just needs a tiny modification replacing the assignment operator «<code language="java">=</code>» by the comparison operator «<code language="java">==</code>»:</para> <programlisting language="java">int count = 1; if (count == 4) { // is count equal to 4? System.out.println("count is o.K."); }</programlisting> <note xml:id="sd1_note_useLiteralEqualsVariable"> <para>In contrast to <xref linkend="glo_Java"/> some programming languages like C and C++ allow for integer values in <code language="java">if (...)</code> conditionals:</para> <programlisting language="c">#include <stdio.h> int main(int argc, char **args) { int a = 3; if (a = 4) { printf("a has got a value of 4\n"); } }</programlisting> <para>The integer expression <code language="java">count = 4</code> has got a value of 4. Integer values inside an <code language="java">if (...)</code> statement will be evaluated as:</para> <glosslist> <glossentry> <glossterm>true</glossterm> <glossdef> <para>if the expression's value differs from zero</para> </glossdef> </glossentry> <glossentry> <glossterm>false</glossterm> <glossdef> <para>if the expression's value equals zero</para> </glossdef> </glossentry> </glosslist> <para>Thus in C and C++ the expression <code language="java">if(count = 4)</code> will always evaluate to <code language="java">true</code> irrespective of the variable <code language="java">count</code>'s initial value. Most important: The C compiler will not issue an error or warning unless non-default, more restrictive compile time warning options are being activated. Consider this widely used «feature» to be dangerous at best.</para> <para>For this reason it is good practice always using <code language="java">if (4 == count)</code> rather than <code language="java">if (count == 4)</code>: Even in C you cannot assign a value to a constant literal. Thus an accidentally mistyped <code language="java">if (4 = count)</code> statement will definitively result in a compile time error most likely saving its author from tedious debugging.</para> </note> </answer> </qandaentry> </qandadiv> </qandaset> <figure xml:id="sd1_fig_IfOmitBlocks"> <title>Single statement branches</title> <para>Branches containing exactly one statement don't require a block definition.</para> <programlisting language="java">double initialAmount = 3200; if (100000 <= initialAmount) System.out.println("Interest:" + 1.2 * initialAmount / 100); else if (1000 <= initialAmount) System.out.println("Interest:" + 0.8 * initialAmount / 100); else System.out.println("Interest:" + 0);</programlisting> </figure> <figure xml:id="sd1_fig_ifElseNested"> <title>Nested <code language="java">if ... else</code></title> <informaltable border="1"> <col width="40%"/> <col width="60%"/> <tr> <td valign="top"><programlisting language="java">if ('A' == grade || 'B' == grade) { result = "Excellent"; } else { if ('C' == grade) { result = "O.k."; } else { if ('D' == grade) { result = "Passed"; } else { result = "Failed"; } } }</programlisting></td> <td valign="top"><mediaobject> <imageobject> <imagedata fileref="Fig/if_elseIf_else.svg"/> </imageobject> </mediaobject></td> </tr> </informaltable> </figure> </section> <section xml:id="sd1_sect_elseif"> <title>Using <code language="java">else if</code></title> <figure xml:id="sd1_fig_ifElse_else"> <title>Enhanced readability: <code language="java">if ... else if ... else</code></title> <informaltable border="1"> <col width="40%"/> <col width="60%"/> <tr> <td valign="top"><programlisting language="java">if ('A' == grade || 'B' == grade) { result = "Excellent"; } else if ('C' == grade) { result = "O.k."; } else if ('D' == grade) { result = "Passed"; } else { result = "Failed"; }</programlisting></td> <td valign="top"><mediaobject> <imageobject> <imagedata fileref="Fig/if_elseIf_else.svg"/> </imageobject> </mediaobject></td> </tr> </informaltable> </figure> <figure xml:id="sd1_fig_ifElse_elseSyntax"> <title><code language="java">if ... else if ... else</code> syntax</title> <programlisting language="java">if (booleanExpression) (block | statement) [else if (booleanExpression) (block | statement) ]* <co linkends="sd1_fig_ifElse_elseSyntax-1" xml:id="sd1_fig_ifElse_elseSyntax-1-co"/> [else (block | statement) ] <co linkends="sd1_fig_ifElse_elseSyntax-2" xml:id="sd1_fig_ifElse_elseSyntax-2-co"/></programlisting> <calloutlist role="slideExclude"> <callout arearefs="sd1_fig_ifElse_elseSyntax-1-co" xml:id="sd1_fig_ifElse_elseSyntax-1"> <para>The pair of braces [...] indicates an optional clause. The asterisk <quote>*</quote> indicates an arbitrary number of repetitions (zero to infinity).</para> </callout> <callout arearefs="sd1_fig_ifElse_elseSyntax-2-co" xml:id="sd1_fig_ifElse_elseSyntax-2"> <para>The second pair of braces [...] again indicates an optional clause.</para> <para>Thus only the <quote><code language="java">if (booleanExpression) (block | statement)</code></quote> clause is mandatory.</para> </callout> </calloutlist> </figure> <qandaset defaultlabel="qanda" xml:id="sd1_qanda_replaceElseIf"> <title>Replacing <code language="java">else if (...){...}</code> by nested <code language="java">if ... else</code> statements</title> <qandadiv> <qandaentry> <question> <para>A computer newbie did not yet read about the <code language="java">else if(...)</code> branch construct but nevertheless tries to implement the following logic:</para> <programlisting language="java">if (a < 7) { System.out.println("o.K."); } else if (5 == b) { System.out.println("Maybe"); } else { System.out.println("Wrong!"); }</programlisting> <para><code language="java">a</code> and <code language="java">b</code> are supposed to be <code language="java">int</code> variables. Please help our newbie using just <code language="java">if(...){...} else {...} </code> avoiding <code language="java"><emphasis role="red">else if</emphasis>(...) {}</code> branch statements!</para> <tip> <para>As the title suggests you may want to nest an <quote>inner</quote> <code language="java">if(...)</code> inside an <quote>outer</quote> one.</para> </tip> </question> <answer> <para>The solution requires replacing the <code language="java">else if(...)</code> branch by a nested <code language="java">if(...){ ...} else {...}</code> statement by moving the final <code language="java">else</code> block into the nested one.</para> <programlisting language="java">if (a < 7) { System.out.println("o.K."); } else { if (5 == b) { System.out.println("Maybe"); } else { System.out.println("Wrong!"); } }</programlisting> </answer> </qandaentry> </qandadiv> </qandaset> <figure xml:id="sd1_fig_useScannerClass"> <title>User input recipe</title> <informaltable border="0"> <col width="64%"/> <col width="36%"/> <tr> <td valign="top"><programlisting language="java">import java.util.Scanner; public class App { public static void main(String[] args){ final Scanner scan = new Scanner(System.in); System.out.print("Enter a value:"); final int value = scan.nextInt(); System.out.println("You entered " + value); } }</programlisting></td> <td valign="top"><screen>Enter a value:123 You entered 123</screen><para>See <methodname xlink:href="javaapi://java.util.Scanner#nextBoolean()">nextBoolean()</methodname>, <methodname><link xlink:href="javaapi://java.util.Scanner#nextByte()">nextByte()</link></methodname> and friends.</para></td> </tr> </informaltable> </figure> <qandaset defaultlabel="qanda" xml:id="sw1QandaPostExamBonuspoints"> <title>Post modifying an exam's marking</title> <qandadiv> <qandaentry> <question> <para>A lecturer marks an exam having a maximum of 12 reachable points:</para> <informaltable border="1" width="25%"> <tr> <th>Name</th> <th>Mark</th> </tr> <tr> <td>Aaron</td> <td>3</td> </tr> <tr> <td>Maureen</td> <td>11</td> </tr> <tr> <td>Sally</td> <td>1</td> </tr> <tr> <td>...</td> <td>...</td> </tr> </informaltable> <para>The lecturer is dissatisfied with the overall result. He wants to add 3 bonus points but still keeping the maximum of 12 points to be reachable:</para> <informaltable border="1" width="25%"> <tr> <th>Name</th> <th>Mark</th> <th>3 bonus points augmented mark</th> </tr> <tr> <td>Aaron</td> <td>3</td> <td>6</td> </tr> <tr> <td>Maureen</td> <td>11</td> <td><emphasis role="red">12</emphasis></td> </tr> <tr> <td>Sally</td> <td>1</td> <td>4</td> </tr> <tr> <td>...</td> <td>...</td> <td>...</td> </tr> </informaltable> <para>Complete the following code by assigning this modified number of points to the variable <code language="java">newResult</code>.</para> <programlisting language="java">public static void main(String[] args) { int pointsReached = 7; // May range from 0 to 12 points final int maximumPoints = 12; final int pointsToAdd = 3; final int augmentedMark; // TODO: Assignment to variable augmentedMark System.out.println("New Result:" + augmentedMark); }</programlisting> </question> <answer> <para>We present three different solutions:</para> <orderedlist> <listitem> <para>The basic task is to add up the values of <code language="java">pointsReached</code> and <code language="java">pointsToAdd</code>. This sum however must not exceed the <code language="java">maximumPoints</code> limit. We use an <code language="java">if</code> statement for constraint safeguarding:</para> <programlisting language="java">public static void main(String[] args) { final int pointsReached = 7; final int maximumPoints = 12; final int pointsToAdd = 3; final int augmentedMark; if (maximumPoints <= pointsReached + pointsToAdd) { augmentedMark = maximumPoints; } else { augmentedMark = pointsReached + pointsToAdd; } System.out.println("New Result:" + augmentedMark); }</programlisting> </listitem> <listitem> <para>Java's <link xlink:href="https://www.baeldung.com/java-ternary-operator">ternary operator</link> <code language="java">? :</code> allows for replacing the <code language="java">if</code> clause:</para> <programlisting language="java">final int pointsReached = 7; final int maximumPoints = 12; final int pointsToAdd = 3; final int augmentedMark = maximumPoints <= pointsReached + pointsToAdd ? maximumPoints : pointsReached + pointsToAdd; System.out.println("New Result:" + augmentedMark);</programlisting> </listitem> <listitem> <para>The augmented points value equals the minimum of <code language="java">pointsReached + pointsToAdd</code> and <code language="java">maximumPoints</code>. In favour of upcoming <link linkend="sd1SectClassMembers">methods</link> we may code as well:</para> <programlisting language="java">public static void main(String[] args) { final int pointsReached = 7; final int maximumPoints = 12; final int pointsToAdd = 3; final int augmentedMark = <link xlink:href="javaapi://Math#min(int,int)">Math.min</link>(maximumPoints, pointsReached + pointsToAdd); System.out.println("New Result:" + augmentedMark); }</programlisting> <para>You will fully understand the above <classname xlink:href="javaapi://Math">Math</classname>.<methodname xlink:href="javaapi://Math#min(int,int)">min(...)</methodname> expression after finishing the <quote>Static Final Variables</quote> section of <xref linkend="bib_Kurniawan"/>.</para> </listitem> </orderedlist> </answer> </qandaentry> </qandadiv> </qandaset> <qandaset defaultlabel="qanda" xml:id="sd1QandaAtTheBar"> <title>At the bar</title> <qandadiv> <qandaentry> <question> <para>This example uses existing program code to be explained later. You'll implement an interactive application which implements a dialogue with a user asking for input to be entered in a terminal like window as being shown in the following video:</para> <figure xml:id="sd1VideoUsingScannerClass"> <title>Using a <classname xlink:href="javaapi://java.util.Scanner">Scanner</classname> class collecting user input.</title> <mediaobject> <videoobject> <videodata fileref="Fig/scannerUsage.webm"/> </videoobject> </mediaobject> </figure> <para>A bar uses a software system for picking up orders. The bar will serve just orange juice and beer. For legal reasons the latter will only be served to persons of at least 16 years of age. We show three possible user dialogues:</para> <orderedlist> <listitem> <screen>On offer: 1=Beer 2=Orange juice Your choice:>1 Tell me your age please:>15 Sorry mate, you are too young</screen> </listitem> <listitem> <screen>On offer: 1=Beer 2=Orange juice Your choice:>2 o.K.</screen> </listitem> <listitem> <screen>On offer: 1=Beer 2=Orange juice Your choice:>4 Sorry, invalid choice value »4«</screen> </listitem> </orderedlist> <para>Since you may not yet know how to enable <xref linkend="glo_Java"/> applications asking for user input simply use the following recipe to get started:</para> <programlisting language="java" xml:id="sd1_listing_scannerBoilerplate">public static void main(String[] args) { final Scanner scan = new Scanner(System.in); // Creating a scanner for reading user input System.out.print("Please enter a value:"); final int userInput = scan.nextInt(); System.out.println("You entered: " + userInput); // TODO: Implement «at the bar» logic }</programlisting> <para>Copy this boilerplate code into your <xref linkend="glo_IDE"/>. The <xref linkend="glo_IDE"/> will assist you adding a required <code language="java">import java.util.Scanner;</code> statement in your code's header section. Execute this code. You should see a dialogue like:</para> <screen>Please enter a value:112 You entered: 112</screen> <para>Then extend the above code implementing the desired behaviour.</para> </question> <answer> <para>Nested <code language="java">if</code> conditional allows for implementing the desired logic:</para> <programlisting language="java">import java.util.Scanner; public class BarOrder { public static void main(String[] args) { final Scanner scan = new Scanner(System.in); System.out.print("Please choose:\n 1=Beer\n 2=Orange juice\n\nYour choice:>" ); final int beverageChoice = scan.nextInt(); // Read user input if (1 == beverageChoice) { System.out.print("Tell me your age please:>"); final int age = scan.nextInt(); if (age < 16) { System.out.println("Sorry mate, you are too young"); } else { System.out.println("o.K."); } } else if (2 == beverageChoice) { System.out.println("o.K."); } else { System.err.println("Sorry, invalid choice value »" + beverageChoice + "«"); } } }</programlisting> <para>With respect to upcoming <code language="java" linkend="sd1_sect_switch">switch</code> statements a different approach reads:</para> <programlisting language="java">... final int beverageChoice = scan.nextInt(); // Read user input switch (beverageChoice) { case 1: System.out.print("Tell me your age please:>"); final int age = scan.nextInt(); if (age < 16) { System.out.println("Sorry, we are not allowed to serve beer to underage customers"); } else { System.out.println("o.K."); } break; case 2: System.out.println("o.K."); break; default: System.err.println("Sorry, invalid choice value »" + beverageChoice + "«"); break; } ...</programlisting> </answer> </qandaentry> </qandadiv> </qandaset> <qandaset defaultlabel="qanda" xml:id="sd1QandaRomanNumeralsIf"> <title>Roman numerals</title> <qandadiv> <qandaentry> <question> <para>Write an application which turns a positive integer values up to and including 10 into <link xlink:href="https://en.wikipedia.org/wiki/Roman_numerals">Roman numeral</link> representation:</para> <screen>Enter a number:>9 IX</screen> <para>Regarding user input you may start from <xref linkend="sd1_listing_scannerBoilerplate"/> again. If the user enters a value smaller than one or greater than ten the following output is to be expected:</para> <screen>Enter a number:>11 Decimal value 11 not yet implemented</screen> <tip> <para>You may use a series of <code language="java">if () {...} else if () {...} ...</code> statements.</para> </tip> </question> <answer> <para><programlisting language="java">final Scanner scan = new Scanner(System.in); System.out.print("Enter a number:>"); final int number = scan.nextInt(); if (1 == number) { System.out.println("I"); } else if (2 == number) { System.out.println("II"); } else if (3 == number) { System.out.println("III"); } else if (4 == number) { System.out.println("IV"); } else if (5 == number) { System.out.println("V"); } else if (6 == number) { System.out.println("VI"); } else if (7 == number) { System.out.println("VII"); } else if (8 == number) { System.out.println("VIII"); } else if (9 == number) { System.out.println("IX"); } else if (10 == number) { System.out.println("X"); } else { System.out.println("Decimal value " + number + " not yet implemented"); }</programlisting></para> </answer> </qandaentry> </qandadiv> </qandaset> <figure xml:id="sd1_fig_problemNumber2Dayname"> <title>Converting numbers to day's names</title> <informaltable border="0"> <col width="28%"/> <col width="72%"/> <tr> <td valign="top"><para>Task: Convert day's numbers to day's names</para></td> <td valign="top"><informaltable border="1"> <tr> <td>1</td> <td>Monday</td> </tr> <tr> <td>2</td> <td>Tuesday</td> </tr> <tr> <td>3</td> <td>Wednesday</td> </tr> <tr> <td>4</td> <td>Thursday</td> </tr> <tr> <td>5</td> <td>Friday</td> </tr> <tr> <td>6</td> <td>Saturday</td> </tr> <tr> <td>7</td> <td>Sunday</td> </tr> </informaltable></td> </tr> </informaltable> </figure> <figure xml:id="sd1_fig_dayNumber2NameByIfElseif"> <title>Numbers to day's names: The hard way</title> <programlisting language="java">final Scanner scan = new Scanner(System.in)); System.out.print("Enter a weekday number (1=Monday, 2=Tuesday,...) : "); final int number = scan.nextInt(); if (1 == number) { System.out.println("Monday"); } else if (2 == number) { System.out.println("Tuesday"); ... } else if (7 == number) { System.out.println("Sunday"); } else { System.out.println("Invalid number " + number); }</programlisting> </figure> <qandaset defaultlabel="qanda" xml:id="sd1QandaLeapYear"> <title>Leap years</title> <qandadiv> <qandaentry> <question> <para>We want to write an application telling whether a given year is a leap year or not. The following dialogue may serve as an example:</para> <screen>Enter a year:>1980 Year 1980 is a leap year</screen> <screen>Enter a year:>1900 Year 1900 is no leap year</screen> <para>You may reuse the user input handling code from the previous examples.</para> <tip> <para>Read about the <link xlink:href="https://en.wikipedia.org/wiki/Leap_year#Algorithm">leap year algorithm</link>.</para> </tip> </question> <answer> <para>A first straightforward rule translation based solution reads:</para> <programlisting language="java">package start; import java.util.Scanner; public class LeapYear { public static void main(String[] args) { final Scanner scan = new Scanner(System.in)); System.out.print("Enter a year:>"); final int year = scan.nextInt(); if (0 == year % 400) { <emphasis role="bold"> // Every 400 years we do have a leap year.</emphasis> System.out.println( "Year " + year + " is a leap year"); } else if (0 == year % 4 && <emphasis role="bold"> // Every 4 years we do have a leap year</emphasis> 0 != year % 100) { <emphasis role="bold"> // unless year is a multiple of 100.</emphasis> System.out.println("Year " + year + " is a leap year"); } else { System.out.println("Year " + year + " is no leap year"); } } }</programlisting> <para>This solution contains two identical <code language="java">println("Year " + year + " is a leap year")</code> statements. Developers don't favour redundancies: Rearranging and combining the first and third <code language="java">if</code> branch into one resolves the issue:</para> <programlisting language="java">public static void main(String[] args) { ... if (0 == year % 400 || <emphasis role="bold">// Every 400 years we do have a leap year.</emphasis> (0 == year % 4 && <emphasis role="bold">// Every 4 years we do have a leap year</emphasis> 0 != year % 100)) { <emphasis role="bold">// unless year is a multiple of 100.</emphasis> System.out.println("Year " + year + " is a leap year"); } else { System.out.println("Year " + year + " is no leap year"); } ...</programlisting> <para>Some enthusiasts prefer compact expressions at the expense of readability (<quote>Geek syndrome</quote>) sometimes referred to as <quote>syntactic sugar</quote>. The following code based on the <code language="java" xlink:href="https://www.geeksforgeeks.org/java-ternary-operator-with-examples">...? ...: ...</code> operator is fully equivalent:</para> <programlisting language="java">... System.out.println("Year " + year + (year % 400 == 0 || year % 4 == 0 && 0 != year % 100 ? " is a leap year" : " is no leap year")); }</programlisting> </answer> </qandaentry> </qandadiv> </qandaset> </section> </section> <section xml:id="sd1_sect_switch"> <title>The <code language="java">switch</code> statement</title> <figure xml:id="sd1_fig_switch"> <title>Better: Using <code language="java">switch</code></title> <programlisting language="java">... switch(number) { case 1: System.out.println("Monday"); break; case 2: System.out.println("Tuesday"); break; case 3: System.out.println("Wednesday"); break; case 4: System.out.println("Thursday"); break; case 5: System.out.println("Friday"); break; case 6: System.out.println("Saturday"); break; case 7: System.out.println("Sunday"); break; default: System.out.println("Invalid number " + number); break; } ...</programlisting> <screen>Enter a weekday number (1=Monday, 2=Tuesday,...) : 6 Saturday</screen> </figure> <figure xml:id="sd1_fig_switchSyntax"> <title><code language="java">switch</code> Syntax</title> <programlisting language="java">switch(expression) { [case value_1 : [statement]* [break;] ] [case value_2 : [statement]* [break;] ] ... [case value_n : [statement]* [break;] ] [default: [statement]* [break;] ] }</programlisting> </figure> <qandaset defaultlabel="qanda" xml:id="sd1_qanda_whyBreak"> <title>Why <quote>break</quote>?</title> <qandadiv> <qandaentry> <question> <para>Do we need <code language="java">break</code> statements in <xref linkend="sd1_fig_switch"/>? Rewrite <xref linkend="sd1_fig_dayNumber2NameByIfElseif"/> replacing all conditions by <code language="java">switch</code> / <code language="java">case</code> statements without using <code language="java">break</code>. What do you observe on execution?</para> </question> <answer> <para><xref linkend="sd1_fig_dayNumber2NameByIfElseif"/> can be rewritten as:</para> <programlisting language="java">final Scanner scan = new Scanner(System.in); System.out.print("Enter a weekday number (1=Monday, 2=Tuesday,...) : "); final int number = scan.nextInt(); switch(number) { case 1: System.out.println("Monday"); case 2: System.out.println("Tuesday"); case 3: System.out.println("Wednesday"); case 4: System.out.println("Thursday"); case 5: System.out.println("Friday"); case 6: System.out.println("Saturday"); case 7: System.out.println("Sunday"); default: System.out.println("Invalid number " + number); }</programlisting> <para>Entering a day's number 5 yields:</para> <screen>Enter a weekday number (1=Monday, 2=Tuesday,...) : 5 Friday Saturday Sunday Invalid number 5</screen> <para>So the <code language="java">break</code> statements effectively prohibit <quote>fall-through</quote> towards subsequent <code language="java">case</code> labels. Moving <quote>7 / Sunday</quote> to the beginning this becomes even clearer:</para> <programlisting language="java">... switch(number) { case 7: System.out.println("Sunday"); // Deliberately moved to the top case 1: System.out.println("Monday"); case 2: System.out.println("Tuesday"); case 3: System.out.println("Wednesday"); case 4: System.out.println("Thursday"); case 5: System.out.println("Friday"); case 6: System.out.println("Saturday"); default: System.out.println("Invalid number " + number); } ...</programlisting> <para>This time entering a value of 5 again we no longer see <code language="java">"Sunday" on output</code>:</para> <screen>Enter a weekday number (1=Monday, 2=Tuesday,...) : 5 Friday Saturday Invalid number 5</screen> <para>Thus fall-through does not depend on numerical <code language="java">case</code> label ordering but solely on their order of appearance within code.</para> </answer> </qandaentry> </qandadiv> </qandaset> <qandaset defaultlabel="qanda" xml:id="sd1_qanda_monthDays2Name"> <title>Extending to month days</title> <qandadiv> <qandaentry> <question> <para>Consider January 2052:</para> <informaltable border="1"> <tr> <th>Monday</th> <th>Tuesday</th> <th>Wednesday</th> <th>Thursday</th> <th>Friday</th> <th>Saturday</th> <th>Sunday</th> </tr> <tr> <td>1</td> <td>2</td> <td>3</td> <td>4</td> <td>5</td> <td>6</td> <td>7</td> </tr> <tr> <td>8</td> <td>9</td> <td>10</td> <td>11</td> <td>12</td> <td>13</td> <td>14</td> </tr> <tr> <td>15</td> <td>16</td> <td>17</td> <td>18</td> <td>19</td> <td>20</td> <td>21</td> </tr> <tr> <td>22</td> <td>23</td> <td>24</td> <td>25</td> <td>26</td> <td>27</td> <td>28</td> </tr> <tr> <td>29</td> <td>30</td> <td>31</td> <td/> <td/> <td/> <td/> </tr> </informaltable> <para>Write an application converting a given day's number within January 2052 (this may be generalized to arbitrary months) to its name e.g.:</para> <screen>Enter a day's number:>23 Tuesday</screen> <tip> <para>The modulo operator <quote>%</quote> is your friend.</para> </tip> </question> <answer> <para>With respect to <xref linkend="sd1_fig_switch"/> two modification are being required:</para> <programlisting language="none">... switch(<emphasis role="red">day % 7</emphasis>) { case 1: System.out.println("Monday"); break; case 2: System.out.println("Tuesday"); break; ... <emphasis role="red">case 0</emphasis>: System.out.println("Sunday"); break; }</programlisting> </answer> </qandaentry> </qandadiv> </qandaset> <figure xml:id="sd1_fig_switchOnString"> <title>Switching on strings</title> <programlisting language="java">String month, season; ... // Since Java 7: <link xlink:href="javaapi://String">String</link> based <code language="java">case</code> labels switch(month) { case "March": case "April": case "May": season = "Spring"; break; case "June": case "July": case "August": season = "Summer"; break; case "September": case "October": case "November": season = "Autumn"; break; case "December": case "January": case "February": season = "Winter"; break; } }</programlisting> </figure> <qandaset defaultlabel="qanda" xml:id="sd1_qanda_dayname2number"> <title>Converting day's names to numbers.</title> <qandadiv> <qandaentry> <question> <para>Consider the reverse problem to <xref linkend="sd1_fig_problemNumber2Dayname"/>: We want to map a given day's name to its number as in the following example:</para> <screen>Enter a weekday (Monday to Sunday): Friday 5</screen> <para>Issue an error message in case an inappropriate text is being entered:</para> <screen>Enter a weekday (Monday to Sunday): July Unknown day name 'July'</screen> <tip> <orderedlist> <listitem> <para>Starting from <xref linkend="glo_Java"/> 7 <classname xlink:href="javaapi://String">String</classname> based <code language="java">switch</code> statements are allowed.</para> </listitem> <listitem> <para>You may read strings into your application using <classname xlink:href="javaapi://java.util.Scanner">Scanner</classname>.<methodname xlink:href="javaapi://java.util.Scanner#next()">next()</methodname>.</para> </listitem> </orderedlist> </tip> </question> <answer> <programlisting language="java">final Scanner scan = new Scanner(System.in)); System.out.print("Enter a weekday (Monday to Sunday):>"); final String day = scan.next(); switch(day) { case "Monday": System.out.println(1); break; case "Tuesday": System.out.println(2); break; case "Wednesday": System.out.println(3); break; case "Thursday": System.out.println(4); break; case "Friday": System.out.println(5); break; case "Saturday": System.out.println(6); break; case "Sunday": System.out.println(7); break; default: System.out.println("Unknown day name '" + day + "'"); break; }</programlisting> </answer> </qandaentry> </qandadiv> </qandaset> <qandaset defaultlabel="qanda" xml:id="sd1_qanda_dayCategories"> <title>Day categories.</title> <qandadiv> <qandaentry> <question> <para>We want to group working days into categories:</para> <informaltable border="1"> <tr> <th>Day</th> <th>Category</th> </tr> <tr> <td>Monday</td> <td>Start of work week</td> </tr> <tr> <td>Tuesday</td> <td rowspan="3">Midweek</td> </tr> <tr> <td>Wednesday</td> </tr> <tr> <td>Thursday</td> </tr> <tr> <td>Friday</td> <td>End of work week</td> </tr> <tr> <td>Saturday</td> <td rowspan="2">Weekend</td> </tr> <tr> <td>Sunday</td> </tr> </informaltable> <para>Example execution:</para> <screen>Enter a weekday (Monday to Sunday):>Wednesday Midweek</screen> <tip> <para>Sometimes omitting <code language="java">break</code> statements allowing for <link xlink:href="https://www.dummies.com/programming/java/how-to-use-fall-through-to-your-advantage-in-java-programming">fall-through</link> is your friend.</para> </tip> </question> <answer> <programlisting language="java">final Scanner scan = new Scanner(System.in)); System.out.print("Enter a weekday (Monday to Sunday):>"); final String day = scan.next(); switch(day) { case "Monday": System.out.println("Start of work week"); break; case "Tuesday": case "Wednesday": case "Thursday": System.out.println("Midweek"); break; case "Friday": System.out.println("End of work week"); break; case "Saturday": case "Sunday": System.out.println("Weekend"); break; default: System.out.println("Unknown day name " + day); break; }</programlisting> </answer> </qandaentry> </qandadiv> </qandaset> <qandaset defaultlabel="qanda" xml:id="sd1QandaRomanNumeralsSwitch"> <title>Roman numerals, using <code language="java">switch</code></title> <qandadiv> <qandaentry> <question> <para>Re-implement <xref linkend="sd1QandaRomanNumeralsIf"/> using a switch statement rather then an <code language="java">if ... else if ... else</code>.</para> </question> <answer> <para><programlisting language="java">final Scanner scan = new Scanner(System.in)); System.out.print("Enter a number:>"); final int number = scan.nextInt(); switch (number) { case 1: System.out.println("I"); break; case 2: System.out.println("II"); break; case 3: System.out.println("III"); break; case 4: System.out.println("IV"); break; case 5: System.out.println("V"); break; case 6: System.out.println("VI"); break; case 7: System.out.println("VII"); break; case 8: System.out.println("VIII"); break; case 9: System.out.println("IX"); break; case 10: System.out.println("X"); break; default:System.out.println("Decimal value " + number + " not yet implemented"); break; }</programlisting></para> </answer> </qandaentry> </qandadiv> </qandaset> <figure xml:id="sd1_statements_switchTypes"> <title>Allowed types for <code language="java">switch</code> statements</title> <itemizedlist> <listitem> <para><emphasis>Integer types:</emphasis></para> <informaltable border="0"> <tr> <td valign="top"><itemizedlist> <listitem> <para>byte and <classname xlink:href="javaapi://Byte">Byte</classname></para> </listitem> <listitem> <para>short and <classname xlink:href="javaapi://Short">Short</classname></para> </listitem> </itemizedlist></td> <td valign="top"><itemizedlist> <listitem> <para>int and <classname xlink:href="javaapi://Integer">Integer</classname></para> </listitem> <listitem> <para>char and <classname xlink:href="javaapi://Character">Character</classname></para> </listitem> </itemizedlist></td> </tr> </informaltable> </listitem> <listitem> <para><classname xlink:href="javaapi://String">String</classname></para> </listitem> <listitem> <para><link linkend="sd1_classes_enum">enum</link> types</para> </listitem> </itemizedlist> </figure> </section> <section xml:id="sd1_sect_loops"> <title>Loops</title> <figure xml:id="sd1_fig_loopWhy"> <title>Why loops?</title> <para><emphasis>Objective</emphasis>: Execute the same statement multiple times.</para> <para><emphasis><quote>Solution</quote></emphasis>: Copy / paste the statement in question:</para> <programlisting language="java">System.out.println("Do not copy!"); System.out.println("Do not copy!"); System.out.println("Do not copy!"); System.out.println("Do not copy!");</programlisting> <para><emphasis>Problem</emphasis>: Only works if number of repetitions is known at compile time.</para> </figure> <figure xml:id="sd1_fig_loopBadParameterization"> <title>Arbitrary number of repetitions</title> <programlisting language="java">System.out.print("Enter desired number of repetitions: "); final int repetitions = scan.nextInt(); switch(repetitions) { case 5: System.out.println("Do not copy!"); case 4: System.out.println("Do not copy!"); case 3: System.out.println("Do not copy!"); case 2: System.out.println("Do not copy!"); case 1: System.out.println("Do not copy!"); }</programlisting> <para>Limited and clumsy workaround.</para> </figure> <section xml:id="sd1_sect_while"> <title><code language="java">while</code></title> <figure xml:id="sd1_fig_loopParamSolution"> <title>A <code language="java">while</code> loop</title> <informaltable border="1"> <col width="50%"/> <col width="50%"/> <tr> <td valign="top"><programlisting language="java">final int repetitions = scan.nextInt(); <co linkends="sd1_callout_whileLoop-1" xml:id="sd1_callout_whileLoop-1-co"/> int loopCount = 0; <co linkends="sd1_callout_whileLoop-2" xml:id="sd1_callout_whileLoop-2-co"/> while (loopCount < repetitions <co linkends="sd1_callout_whileLoop-3" xml:id="sd1_callout_whileLoop-3-co"/>) { System.out.println("Do not copy!"); <co linkends="sd1_callout_whileLoop-4" xml:id="sd1_callout_whileLoop-4-co"/> loopCount++; <co linkends="sd1_callout_whileLoop-5" xml:id="sd1_callout_whileLoop-5-co"/> }</programlisting><screen>Do not copy! Do not copy! Do not copy!</screen></td> <td valign="top"><mediaobject> <imageobject> <imagedata fileref="Fig/while.svg"/> </imageobject> </mediaobject></td> </tr> </informaltable> <calloutlist role="slideExclude"> <callout arearefs="sd1_callout_whileLoop-1-co" xml:id="sd1_callout_whileLoop-1"> <para>The code block will be repeated this number of times.</para> </callout> <callout arearefs="sd1_callout_whileLoop-2-co" xml:id="sd1_callout_whileLoop-2"> <para>Helper variable keeping track of repetitions.</para> </callout> <callout arearefs="sd1_callout_whileLoop-3-co" xml:id="sd1_callout_whileLoop-3"> <para>Condition to be checked prior each execution.</para> </callout> <callout arearefs="sd1_callout_whileLoop-4-co" xml:id="sd1_callout_whileLoop-4"> <para>Code block of statement(s) to be repeated.</para> </callout> <callout arearefs="sd1_callout_whileLoop-5-co" xml:id="sd1_callout_whileLoop-5"> <para>Helper variable being incremented during each iteration.</para> </callout> </calloutlist> </figure> <figure xml:id="sd1_fig_loopParamSolutionSyntaxSugar"> <title>Combining increment and termination condition</title> <informaltable border="1"> <tr> <th>Code</th> <th>Execution</th> </tr> <tr> <td valign="top"><programlisting language="java">System.out.print("Enter repetitions: "); final int repetitions = scan.nextInt(); int loopCounter = 0; while (loopCounter++ < repetitions) { System.out.println("Do not copy!"); }</programlisting></td> <td valign="top"><screen>Enter repetitions: 3 Do not copy! Do not copy! Do not copy!</screen></td> </tr> </informaltable> </figure> <figure xml:id="sd1_fig_whileSyntax"> <title><code language="java">while</code> syntax</title> <programlisting language="java">while (booleanExpression) (block | statement)</programlisting> </figure> <figure xml:id="sd1_fig_whileEmptyStatement"> <title>Empty <code language="java">while</code> body</title> <programlisting language="java">int threeSeries = 1; while ((threeSeries *=3 ) < 100); System.out.println(threeSeries);</programlisting> <para>Exercise: Guess resulting output.</para> </figure> <qandaset defaultlabel="qanda" xml:id="sd1_statements_qanda_loopSquares"> <title>Generating square numbers</title> <qandadiv> <qandaentry> <question> <para>Write an application printing the first ten square numbers. The output should look like:</para> <screen>The square of 1 is 1 The square of 2 is 4 The square of 3 is 9 The square of 4 is 16 The square of 5 is 25 The square of 6 is 36 The square of 7 is 49 The square of 8 is 64 The square of 9 is 81 The square of 10 is 100</screen> </question> <answer> <programlisting language="java">int counter = 0; while (counter++ < 10) { System.out.println("The square of " + counter + " is " + counter * counter); }</programlisting> </answer> </qandaentry> </qandadiv> </qandaset> <qandaset defaultlabel="qanda" xml:id="sd1_statements_qanda_factorial"> <title>Calculating factorial</title> <qandadiv> <qandaentry> <question> <para>The factorial <inlineequation> <m:math display="inline"> <m:mrow> <m:mi>n</m:mi> <m:mo>!</m:mo> </m:mrow> </m:math> </inlineequation> of a given integer n is being defined as the following product:</para> <informalequation> <m:math display="block"> <m:mrow> <m:mrow> <m:mi>n</m:mi> <m:mo>!</m:mo> </m:mrow> <m:mo>=</m:mo> <m:mrow> <m:mi>n</m:mi> <m:mo>×</m:mo> <m:mrow> <m:mo>(</m:mo> <m:mrow> <m:mi>n</m:mi> <m:mo>-</m:mo> <m:mi>1</m:mi> </m:mrow> <m:mo>)</m:mo> </m:mrow> <m:mo>×</m:mo> <m:mo>⋯</m:mo> <m:mo>×</m:mo> <m:mi>2</m:mi> <m:mo>×</m:mo> <m:mi>1</m:mi> </m:mrow> </m:mrow> </m:math> </informalequation> <para>In addition the factorial of zero is being defined as:</para> <informalequation> <m:math display="block"> <m:mrow> <m:mrow> <m:mi>0</m:mi> <m:mo>!</m:mo> </m:mrow> <m:mo>=</m:mo> <m:mn>1</m:mn> </m:mrow> </m:math> </informalequation> <para>Write an application asking a user for an integer value and calculate the corresponding factorial e.g.:</para> <screen>Enter an integer value: 5 5! == 120</screen> </question> <answer> <programlisting language="java">public static void main(String[] args) { final Scanner scan = new Scanner(System.in); System.out.print("Enter an integer value: "); final int value = scan.nextInt(); long factorial = 1; int i = 1; while (i++ < value) { factorial *= i; } System.out.println(value + "! == " + factorial); }</programlisting> </answer> </qandaentry> </qandadiv> </qandaset> </section> <section xml:id="sd1_sect_doWhile"> <title><code language="java">do ... while</code></title> <para><figure xml:id="sd1_fig_doWhile"> <title>A <code language="java">do ... while</code> loop</title> <informaltable border="1"> <col width="50%"/> <col width="50%"/> <tr> <td valign="top"><programlisting language="java">int sum = 0, value; do { System.out.print( "Enter value, 0 to terminate: "); value = scan.nextInt(); sum += value; } while (0 != value); System.out.println("Sum: " + sum);</programlisting><screen>Enter value, 0 to terminate: 3 Enter value, 0 to terminate: 1 Enter value, 0 to terminate: 0 Sum: 4</screen></td> <td valign="top"><mediaobject> <imageobject> <imagedata fileref="Fig/doWhile.svg"/> </imageobject> </mediaobject></td> </tr> </informaltable> </figure><figure xml:id="sd1_fig_doWhileSyntax"> <title><code language="java">do ... while</code> syntax</title> <programlisting language="java">do (block | statement) while (booleanExpression);</programlisting> </figure><qandaset defaultlabel="qanda" xml:id="sd1_qanda_tellEvenOdd"> <title>Even or odd?</title> <qandadiv> <qandaentry> <question> <para>Write an application which asks for integer values telling its user whether a given value is even or odd. Providing the special value 0 shall terminate your application:</para> <screen>Enter an integer (0 to terminate): 77 77 is an odd number Enter an integer (0 to terminate): -3 -3 is an odd number Enter an integer (0 to terminate): 26 26 is an even number Enter an integer (0 to terminate): 0 0 is an even number Goodbye!</screen> <tip> <orderedlist> <listitem> <para>Use the modulo <quote>%</quote> operator.</para> </listitem> <listitem> <para>Choose an appropriate loop type with respect to your application's termination on user input «0».</para> </listitem> </orderedlist> </tip> </question> <answer> <para>We obviously need a loop to ask for further input unless the last entered value was 0. In any case the loop's statement will be executed at least once:<screen>Enter an integer (0 to terminate): 0 0 is an even number Goodbye!</screen>A <code language="java">do ... while(...)</code> rather than a <code language="java">while(...)</code> loop is thus appropriate. It allows for entering the loop's body <emphasis role="bold">before</emphasis> any check is about to happen:<programlisting language="java">final Scanner scanner = new Scanner(System.in)); int userInput; do { System.out.print("Enter an integer (0 to terminate): "); userInput = scanner.nextInt(); if (0 == userInput % 2) { System.out.println(" " + userInput + " is an even number"); } else { System.out.println(" " + userInput + " is an odd number"); } } while (0 != userInput); System.out.println("Goodbye!"); }</programlisting></para> </answer> </qandaentry> </qandadiv> </qandaset><qandaset defaultlabel="qanda" xml:id="sd1_statements_qanda_approxSqrt"> <title>Square root approximation</title> <qandadiv> <qandaentry> <question> <para>Derived from the <link xlink:href="https://en.wikipedia.org/wiki/Newton%27s_method">Newton–Raphson method</link> we can approximate a given value <inlineequation> <m:math display="inline"> <m:mi>a</m:mi> </m:math> </inlineequation>'s square root <inlineequation> <m:math display="inline"> <m:msqrt> <m:mi>a</m:mi> </m:msqrt> </m:math> </inlineequation> by the following recursively defined series:</para> <glosslist> <glossentry> <glossterm>Start:</glossterm> <glossdef> <informalequation> <m:math display="block"> <m:mrow> <m:msub> <m:mi>x</m:mi> <m:mi>0</m:mi> </m:msub> <m:mo>=</m:mo> <m:mfrac> <m:mi>a</m:mi> <m:mi>2</m:mi> </m:mfrac> </m:mrow> </m:math> </informalequation> </glossdef> </glossentry> <glossentry> <glossterm>Recursion step:</glossterm> <glossdef> <informalequation> <m:math display="block"> <m:mrow> <m:msub> <m:mi>x</m:mi> <m:mrow> <m:mi>n</m:mi> <m:mo>+</m:mo> <m:mi>1</m:mi> </m:mrow> </m:msub> <m:mo>=</m:mo> <m:mrow> <m:mfrac> <m:mi>1</m:mi> <m:mi>2</m:mi> </m:mfrac> <m:mo></m:mo> <m:mrow> <m:mo>(</m:mo> <m:mrow> <m:msub> <m:mi>x</m:mi> <m:mi>n</m:mi> </m:msub> <m:mo>+</m:mo> <m:mfrac> <m:mi>a</m:mi> <m:msub> <m:mi>x</m:mi> <m:mi>n</m:mi> </m:msub> </m:mfrac> </m:mrow> <m:mo>)</m:mo> </m:mrow> </m:mrow> </m:mrow> </m:math> </informalequation> </glossdef> </glossentry> </glosslist> <para>Create a program which interactively asks a user for a positive value and calculate it's square root like e.g.:</para> <screen>Enter a non-negative value: 2.0 The square root of 2.0 is close to 1.414213562373095 It's square is 1.9999999999999996</screen> <tip> <para>Due to the limited precision of machine arithmetics you may continue until your approximation value no longer changes.</para> </tip> </question> <answer> <para>We introduce two variables <code language="java">x_current</code> and <code language="java">x_next</code> referring to <inlineequation> <m:math display="inline"> <m:msub> <m:mi>x</m:mi> <m:mi>n</m:mi> </m:msub> </m:math> </inlineequation> and <inlineequation> <m:math display="inline"> <m:msub> <m:mi>x</m:mi> <m:mrow> <m:mi>n</m:mi> <m:mo>+</m:mo> <m:mi>1</m:mi> </m:mrow> </m:msub> </m:math> </inlineequation> respectively:</para> <programlisting language="java">final Scanner scan = new Scanner(System.in)); System.out.print("Enter a non-negative value: "); final double a = scan.nextDouble(); double x_next = a / 2, x_current; do { x_current = x_next; // Save current approximation value x_next = (x_current + a / x_current) / 2; // Calculate next series value } while (x_next != x_current); // Did we get any closer? System.out.println("The square root of " + a + " is close to " + x_next); System.out.println("It's square is " + x_next * x_next);</programlisting> </answer> </qandaentry> </qandadiv> </qandaset></para> </section> <section xml:id="sd1_sect_for"> <title><code language="java">for</code></title> <figure xml:id="sd1_fig_forConsider"> <title>Frequent usage of <code language="java">while</code></title> <informaltable border="0"> <col width="24%"/> <col width="76%"/> <tr> <td valign="top"><programlisting language="java">int i = 0; <co linkends="sd1_callout_whileLoopJustCounting-1" xml:id="sd1_callout_whileLoopJustCounting-1-co"/> while (i < 5 <co linkends="sd1_callout_whileLoopJustCounting-2" xml:id="sd1_callout_whileLoopJustCounting-2-co"/>) { ... i++; <co linkends="sd1_callout_whileLoopJustCounting-3" xml:id="sd1_callout_whileLoopJustCounting-3-co"/> }</programlisting></td> <td valign="top"><calloutlist> <callout arearefs="sd1_callout_whileLoopJustCounting-1-co" xml:id="sd1_callout_whileLoopJustCounting-1"> <para>Declaring and initializing a loop termination variable.</para> </callout> <callout arearefs="sd1_callout_whileLoopJustCounting-2-co" xml:id="sd1_callout_whileLoopJustCounting-2"> <para>Check for loop termination.</para> </callout> <callout arearefs="sd1_callout_whileLoopJustCounting-3-co" xml:id="sd1_callout_whileLoopJustCounting-3"> <para>Loop progression control</para> </callout> </calloutlist></td> </tr> </informaltable> <para>Nice to have: <emphasis role="red">More concise syntax</emphasis></para> </figure> <figure xml:id="sd1_fig_for"> <title>Replacing <code language="java">while</code> by <code language="java">for</code></title> <informaltable border="1"> <tr> <td><programlisting language="java">for (int i = 0 <coref linkend="sd1_callout_whileLoopJustCounting-1-co"/>; i < 5 <coref linkend="sd1_callout_whileLoopJustCounting-2-co"/>; i++ <coref linkend="sd1_callout_whileLoopJustCounting-3-co"/>) { ... }</programlisting></td> <td><programlisting language="java">int i = 0; <coref linkend="sd1_callout_whileLoopJustCounting-1-co"/> while (i < 5 <coref linkend="sd1_callout_whileLoopJustCounting-2-co"/>) { ... i++; <coref linkend="sd1_callout_whileLoopJustCounting-3-co"/> }</programlisting></td> </tr> </informaltable> </figure> <figure xml:id="sd1_fig_forSyntax"> <title><code language="java">for</code> syntax</title> <programlisting language="java">for ( init ; booleanExpression ; update ) (block | statement)</programlisting> </figure> <figure xml:id="sd1_fig_forVariableScope"> <title><code language="java">for</code> variable scope</title> <informaltable border="1"> <tr> <td><programlisting language="java">// i being defined within // loop's scope for (int i = 0 ; i < 3; i++) { System.out.println(i); } <emphasis role="bold">// Error: i undefined outside // loop's body</emphasis> System.out.println(i);</programlisting></td> <td><programlisting language="java">// i being defined in // «current» scope int i; for (i = 0; i < 3; i++) { System.out.println(i); } System.out.println(i); // o.K.</programlisting></td> </tr> </informaltable> </figure> <figure xml:id="sd1_fig_forVariableScopeEquivalence"> <title><code language="java">for</code> variable scope equivalence</title> <informaltable border="1"> <tr> <td><programlisting language="java">for (int i = 0 ; i < 3; i++) { System.out.println(i); } <emphasis role="bold">// i undefined in outer scope</emphasis></programlisting></td> <td><programlisting language="java">{ // Beginning block scope int i = 0; for (; i < 3; i++) { System.out.println(i); } } // Ending block scope <emphasis role="bold">// i undefined in outer scope</emphasis></programlisting></td> </tr> </informaltable> </figure> <figure xml:id="sd1_fig_forWhileRelation"> <title><code language="java">for</code> <abbrev>vs.</abbrev> while relationship</title> <informaltable border="1"> <tr> <td><programlisting language="java">while ( expression ) (block | statement)</programlisting></td> <td><programlisting language="java">for ( ;expression ;) (block | statement)</programlisting></td> </tr> </informaltable> <para>Observation: <code language="java">for (...)</code> is more general than <code language="java">while(...)</code>.</para> </figure> <qandaset defaultlabel="qanda" xml:id="sd1QandaLoopPrintNumbers"> <title>Printing numbers</title> <qandadiv> <qandaentry> <question> <para>Write code for printing the first 10 numbers. The expected output is:</para> <screen>0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10</screen> <para>Keep the value of 10 flexible <abbrev>i.e.</abbrev> easy to change.</para> </question> <answer> <para>A simple approach is:</para> <programlisting language="java">for (int i = 0; i < 10; i++) { System.out.print(i + ", "); } System.out.println(10);</programlisting> <para>This may be enhanced becoming more flexible:</para> <programlisting language="java">final int LIMIT = 12; // Adjust at your discretion for (int i = 0; i < LIMIT; i++) { System.out.print(i + ", "); } System.out.println(LIMIT);</programlisting> </answer> </qandaentry> </qandadiv> </qandaset> <qandaset defaultlabel="qanda" xml:id="sd1QandaOnlyEven"> <title>Printing just even numbers</title> <qandadiv> <qandaentry> <question> <para>Consider:</para> <programlisting language="java">final int LIMIT = 14; int i = 0; while (i < LIMIT) { if (i % 2 == 0) { System.out.println(i); } i++; }</programlisting> <para>This code effectively filters odd numbers and prints only even ones:</para> <screen>0 2 4 6 8 10 12</screen> <para>Modify this code:</para> <orderedlist> <listitem> <para>no <quote>if</quote> statement shall be used.</para> <tip> <para>Rather then filtering unwanted values try to avoid them in the first place by modifying the enclosing loop.</para> </tip> </listitem> <listitem> <para>Use a <code language="java">for</code> loop in favour of <code language="java">while</code>.</para> </listitem> </orderedlist> </question> <answer> <para>Rather than filtering unwanted values we use a <code language="java">for</code> loop having a step width of 2:</para> <programlisting language="java">final int LIMIT = 14; for (int i = 0; i < LIMIT; i += 2) { System.out.println(i); }</programlisting> <para>The original code could have been modified in this fashion as well:</para> <programlisting language="java">final int LIMIT = 14; int i = 0; while (i < LIMIT) { System.out.println(i); i += 2; // Increment by 2 rather than by 1 }</programlisting> </answer> </qandaentry> </qandadiv> </qandaset> <figure xml:id="sd1_fig_nestedLoops_1"> <title>Nested loops 1</title> <informaltable border="0"> <tr> <td><programlisting language="java">for (int i = 1; i <= 2; i++) { for (int j = 1; j <= 3; j++) { System.out.print("(" + i + "|" + j + ") "); } System.out.println(); // newline }</programlisting></td> <td><screen>(1|1) (1|2) (1|3) (2|1) (2|2) (2|3)</screen></td> </tr> </informaltable> </figure> <figure xml:id="sd1_fig_nestedLoops_2"> <title>Nested loops 2</title> <informaltable border="0"> <tr> <td><programlisting language="java">for (int i = 0; i < 6; i++) { for (int j = 0; j < i; j++) { System.out.print(i + j + " "); } System.out.println(); // newline }</programlisting></td> <td><screen>1 2 3 3 4 5 4 5 6 7 5 6 7 8 9</screen></td> </tr> </informaltable> </figure> <figure xml:id="sd1_fig_nestedLoopsVarRowColumn"> <title>Better readability: <code language="java">row</code> and <code>column</code> in favour of <code language="java">i</code> and <code language="java">j</code></title> <informaltable border="0"> <col width="44%"/> <col width="56%"/> <tr> <td valign="top"><programlisting language="none">// What do i and j actually represent? for (int <emphasis role="red">i</emphasis> = 0; <emphasis role="red">i</emphasis> < 6; <emphasis role="red">i</emphasis>++) { for (int <emphasis role="red">j</emphasis> = 0; <emphasis role="red">j</emphasis> < <emphasis role="red">i</emphasis>; <emphasis role="red">j</emphasis>++) { System.out.print(i + <emphasis role="red">j</emphasis> + " "); } System.out.println(); }</programlisting></td> <td valign="top"><programlisting language="none">// Improved code comprehension. for (int <emphasis role="red">row</emphasis> = 0; <emphasis role="red">row</emphasis> < 6; <emphasis role="red">row</emphasis>++) { for (int <emphasis role="red">column</emphasis> = 0; <emphasis role="red">column</emphasis> < <emphasis role="red">row</emphasis>; <emphasis role="red">column</emphasis>++) { System.out.print(<emphasis role="red"> row</emphasis> + <emphasis role="red">column</emphasis> + " "); } System.out.println(); }</programlisting></td> </tr> </informaltable> </figure> <qandaset defaultlabel="qanda" xml:id="sd1QandaXmasTree"> <title>Merry Xmas</title> <qandadiv> <qandaentry> <question> <para>Write an application to print an ASCII art Xmas tree. Provide a configurable parameter <code language="java">numberOfRows</code> which allows for controlling the tree's size. The following example shows a tree spanning 6 rows excluding the top (X) and the two bottom (###) lines:</para> <screen> X * *** ***** ******* ********* *********** ### ###</screen> <tip> <orderedlist> <listitem> <para>Copy and execute the following code snippet printing a triangle for the sake of a starting point:</para> <informaltable border="1"> <col width="47%"/> <col width="5%"/> <col width="48%"/> <tr> <td valign="top"><programlisting language="java">final int numberOfRows = 7; <co linkends="sd1_callout_printTriangle-1" xml:id="sd1_callout_printTriangle-1-co"/> for (int row = 0; row < numberOfRows; row++) { <co linkends="sd1_callout_printTriangle-2" xml:id="sd1_callout_printTriangle-2-co"/> for (int x = 0; x <= row; x++) { <co linkends="sd1_callout_printTriangle-3" xml:id="sd1_callout_printTriangle-3-co"/> System.out.print('*'); <co linkends="sd1_callout_printTriangle-4" xml:id="sd1_callout_printTriangle-4-co"/> } System.out.println(); <co linkends="sd1_callout_printTriangle-5" xml:id="sd1_callout_printTriangle-5-co"/> }</programlisting></td> <td align="center">⟹</td> <td valign="top"><screen>* ** *** **** ***** ****** *******</screen></td> </tr> </informaltable> <calloutlist> <callout arearefs="sd1_callout_printTriangle-1-co" xml:id="sd1_callout_printTriangle-1"> <para>The number of rows to be printed. Adjusting is easy and allows for printing larger or smaller triangles retaining its shape:</para> <informaltable border="1"> <col width="47%"/> <col width="5%"/> <col width="48%"/> <tr> <td valign="top"><programlisting language="java">final int numberOfRows = 3; ...</programlisting></td> <td align="center">⟹</td> <td valign="top"><screen>* ** ***</screen></td> </tr> </informaltable> </callout> <callout arearefs="sd1_callout_printTriangle-2-co" xml:id="sd1_callout_printTriangle-2"> <para>The <quote>outer</quote> loop. Each step will:</para> <orderedlist> <listitem> <para>Print one more line.</para> </listitem> <listitem> <para>Advance the subsequent <quote>inner</quote> loop by one '*'.</para> </listitem> </orderedlist> </callout> <callout arearefs="sd1_callout_printTriangle-3-co" xml:id="sd1_callout_printTriangle-3"> <para>Print a number of '*' characters. The exact number equals the outer loop's <code language="java">row</code> value plus 1. So a value of <code language="java">row == 4</code> will print 4 + 1 '*' characters.</para> </callout> <callout arearefs="sd1_callout_printTriangle-4-co" xml:id="sd1_callout_printTriangle-4"> <para>Print an individual character. Notice the presence of a <methodname xlink:href="javaapi://java.io.PrintStream#print(java.lang.String)">print(....)</methodname> rather than a <methodname xlink:href="javaapi://java.io.PrintStream#println(java.lang.String)">println()</methodname> method call. This way printing continues within a given line rather than breaking to a new one.</para> </callout> <callout arearefs="sd1_callout_printTriangle-5-co" xml:id="sd1_callout_printTriangle-5"> <para>After each line we need a line break <code language="java">'\n'</code> for starting the next one using <methodname xlink:href="javaapi://java.io.PrintStream#println()">println()</methodname>. If you prefer explicit code you may use <package xlink:href="javaapi://System">System</package>.<parameter xlink:href="javaapi://System#out">out</parameter>. <methodname xlink:href="javaapi://java.io.PrintStream#print(char)">print('\n')</methodname> instead.</para> </callout> </calloutlist> </listitem> <listitem> <para>Before coding the actual tree start by modifying the above triangle code to produce:</para> <screen> * ** *** **** ***** ****** *******</screen> <para>Hint: You will need a second loop inside the <quote>outer</quote> loop for creating spaces using the <code language="java">' '</code> character. The number of spaces depends on the line you are printing. In the current example you'll need 6 spaces for the first line, 5 spaces for the second and so on. Thus the inner loop depends on the line number to be printed.</para> </listitem> </orderedlist> </tip> </question> <answer> <para>We start coding the proposed helper exercise. Each line has to be indented using space <code>' '</code> characters being represented by <quote><emphasis role="red">␣</emphasis></quote> in the right diagram:</para> <informaltable border="1"> <col width="47%"/> <col width="5%"/> <col width="48%"/> <tr> <td valign="top"><programlisting language="java">final int numberOfRows = 7; for (int row = 0; row < numberOfRows; row++) { // Start line print preceding white spaces for (int x = 1; x < numberOfRows - row; x++) { System.out.print(' '); } // continue line printing asterisks for (int x = 0; x <= row; x++) { System.out.print('*'); } System.out.println(); }</programlisting></td> <td align="center">⟹</td> <td valign="top"><screen><emphasis role="red">␣␣␣␣␣␣</emphasis>* <emphasis role="red">␣␣␣␣␣</emphasis>** <emphasis role="red">␣␣␣␣</emphasis>*** <emphasis role="red">␣␣␣</emphasis>**** <emphasis role="red">␣␣</emphasis>***** <emphasis role="red">␣</emphasis>****** *******</screen></td> </tr> </informaltable> <para>A complete solution is available at the <link xlink:href="https://gitlab.mi.hdm-stuttgart.de/goik/GoikLectures/tree/master/Doc/Sd1/Ref/Statements/XmasTree/src/main/java/de/hdm_stuttgart/mi/sd1/Xmas.java">MI Gitlab</link> repository. We start dissecting the problem in a version being fully covered by our current knowledge. Our aim is printing:</para> <screen language="none"> <emphasis role="red">X</emphasis> <emphasis role="red">Part 1: Tree's top.</emphasis> Row index 0 * Part 2: Tree's body Row index 1 *** Row index 2 ***** Row index 3 ******* Row index 4 ********* Row index 5 *********** <emphasis role="red">###</emphasis> <emphasis role="red">Part 3: Bottom trunk lines.</emphasis> <emphasis role="red">###</emphasis></screen> <para>We require the precise indentation values when <abbrev>e.g.</abbrev> starting the tree's body. The following sketch shows two trees of different sizes representing invisible spaces by <quote><emphasis role="red">␣</emphasis></quote>. In the »bigger« tree's first line we need <abbrev>e.g.</abbrev> 5 spaces before actually printing the tree's very top <code>'X'</code> character.</para> <screen language="none"> A tree with A tree with 6 body rows 2 row groups <emphasis role="red">␣␣␣␣␣</emphasis>X <emphasis role="red">␣␣␣</emphasis>X <emphasis role="red">␣␣␣␣␣</emphasis>* <emphasis role="red">␣␣␣</emphasis>* <emphasis role="red">␣␣␣␣</emphasis>*** <emphasis role="red">␣␣</emphasis>*** <emphasis role="red">␣␣␣</emphasis>***** <emphasis role="red">␣</emphasis>***** <emphasis role="red">␣␣</emphasis>******* ******* <emphasis role="red">␣</emphasis>********* <emphasis role="red">␣␣</emphasis>### *********** <emphasis role="red">␣␣␣␣</emphasis>### <emphasis role="red">␣␣␣␣</emphasis>###</screen> <para>The precise amounts of these indentations depend on the tree's size. Printing larger trees requires larger indentation values. The tree's size is being controlled by the parameter <parameter>numberOfRows</parameter>:</para> <programlisting language="java">final int numberOfRows = 6;</programlisting> <para>We start printing the tree's top. This requires <code language="java">numberOfRows</code> space characters followed by the top's <code role="red">'X'</code> character:</para> <informaltable border="1"> <col width="80%"/> <col width="20%"/> <tr> <th>Code</th> <th>Result (added <quote>␣</quote>)</th> </tr> <tr> <td valign="top"><programlisting language="none">for (int x = 0; x < numberOfRows - 1; x++) { // Printing the tree's "<emphasis role="red">X</emphasis>" top. We need System.out.print(' '); // numberOfRowGroups preceding spaces (␣) } // before eventually printing the System.out.println('<emphasis role="red">X</emphasis>'); // "<emphasis role="red">X</emphasis>" String followed by a newline (print<emphasis role="red">ln</emphasis>).</programlisting></td> <td valign="top"><screen><emphasis role="red">␣␣␣␣␣</emphasis>X</screen><para>(<quote>␣</quote> denoting space)</para></td> </tr> </informaltable> <para>Next we focus on the tree's body requiring <code language="java">numberOfRows</code> lines. We index these lines by a variable <code language="java">row</code> ranging from 0 to <code language="java">numberOfRows - 1</code>. Each line then requires a by <code language="java">row</code> index decreasing number of indenting spaces followed by an increasing number of asterisks (<emphasis role="red">*</emphasis>):</para> <informaltable border="1"> <col width="80%"/> <col width="20%"/> <tr> <th>Code</th> <th>Result (added <quote>␣</quote>)</th> </tr> <tr> <td valign="top"><programlisting language="none">for (int row = 0; row < numberOfRows ; row++) { // Outer row per line loop for (int x = 0; x < numberOfRows - row - 1; x++) { // Starting each line with System.out.print(' '); // (numberOfRows - row) } // space (␣) characters ... for (int x = 0; x < 2 * row + 1; x ++) { // .. then printing (2 * row + 1) // asterisk('<emphasis role="red">*</emphasis>') characters ... System.out.print('<emphasis role="red">*</emphasis>'); // (May try '<emphasis role="red">▲</emphasis>' instead?) } System.out.print("\n"); // ... and finally terminating the } // current body row.</programlisting></td> <td valign="top"><screen><emphasis role="red">␣␣␣␣␣</emphasis>X <emphasis role="red">␣␣␣␣␣</emphasis>* <emphasis role="red">␣␣␣␣</emphasis>*** <emphasis role="red">␣␣␣</emphasis>***** <emphasis role="red">␣␣</emphasis>******* <emphasis role="red">␣</emphasis>********* ***********</screen></td> </tr> </informaltable> <para>We finally print the tree's two trunk lines both requiring an indent of <code language="java">numberOfRows - 1</code>.</para> <informaltable border="1"> <col width="80%"/> <col width="20%"/> <tr> <th>Code</th> <th>Result (added <quote>␣</quote>)</th> </tr> <tr> <td valign="top"><programlisting language="none">for (int x = 0; x < numberOfRows - 2; x++) { // Indenting the first System.out.print(' '); // bottom trunk line ... } System.out.println("<emphasis role="red">###</emphasis>"); // ... finishing print. for (int x = 0; x < numberOfRows - 2; x++) { // Indenting the second System.out.print(' '); // bottom trunk line } System.out.println("<emphasis role="red">###</emphasis>"); // ... finishing print.</programlisting></td> <td valign="top"><screen>␣␣␣␣␣X ␣␣␣␣␣* ␣␣␣␣*** ␣␣␣***** ␣␣******* ␣********* *********** ␣␣␣␣<emphasis role="red">###</emphasis> ␣␣␣␣<emphasis role="red">###</emphasis></screen></td> </tr> </informaltable> <para>So far quite an amount of energy has been invested into printing fixed numbers of space (<code>''</code>) characters using loop statements. The <classname>System</classname><code>.</code><property>out</property><code>.</code><methodname xlink:href="javaapi://java.io.PrintStream#format(java.lang.String,java.lang.Object...)">format()</methodname> method as in <xref linkend="sd1QandaSquareNumberTableFormatted"/> allows for getting rid of these. As an example printing the tree's top simplifies to:</para> <informaltable border="1"> <col width="70%"/> <col width="30%"/> <tr> <th>Indenting using loops</th> <th>Common result</th> </tr> <tr> <td valign="top"><programlisting language="java">for (int x = 0; x < numberOfRows + 1; x++) { System.out.print(' '); } System.out.println("<emphasis role="red">X</emphasis>"); </programlisting></td> <td rowspan="3" valign="top"><screen>␣␣␣␣␣<emphasis role="red">X</emphasis></screen></td> </tr> <tr> <th>Indenting using format()</th> </tr> <tr> <td valign="top"><programlisting language="java">System.out.format("%"+ numberOfRows + "s ", "<emphasis role="red">X</emphasis>");</programlisting></td> </tr> </informaltable> <para>Moreover starting with <xref linkend="glo_Java"/> 11 the <classname xlink:href="javaapi://String">String</classname> class features a <methodname xlink:href="javaapi://String#repeat(int)">repeat()</methodname> method:</para> <informaltable border="1"> <col width="70%"/> <col width="30%"/> <tr> <th>String repetitions using loops</th> <th>Common result</th> </tr> <tr> <td valign="top"><programlisting language="java">final int repetitions = 5; for (int i = 0; i < repetitions; i++) { System.out.print("<emphasis role="red">*</emphasis>"); }</programlisting></td> <td rowspan="3" valign="top"><screen><emphasis role="red">*****</emphasis></screen></td> </tr> <tr> <th>Using <methodname xlink:href="javaapi://String#repeat(int)">repeat(int)</methodname> instead</th> </tr> <tr> <td valign="top"><programlisting language="java">final int repetitions = 5; System.out.println("<emphasis role="red">*</emphasis>".repeat(repetitions));</programlisting></td> </tr> </informaltable> <para>Combining both methods completely obsoletes all <quote>inner</quote> loops thereby considerably enhancing our code's readability. You'll see a re-implementation in <link xlink:href="https://gitlab.mi.hdm-stuttgart.de/goik/GoikLectures/tree/master/Doc/Sd1/Ref/Statements/XmasTree/src/main/java/de/hdm_stuttgart/mi/sd1/XmasUsingFormat.java">XmasUsingFormat.java</link>:</para> <programlisting language="java">final int numberOfRows = 6; // You may easily change this value. // Part one: The tree's top System.out.format("%"+ numberOfRows + "s\n", "X"); // Printing the tree's top. // Part two: The tree's body for (int row = 0; row < numberOfRows; row++) { // Outer row per line loop System.out.format( "%"+ (numberOfRows + row) + "s \n", // Printing asterisk(s) "*".repeat(2 * row + 1)); } // Part three: The tree's two bottom trunk lines System.out.format("%"+ (numberOfRows + 1) + "s\n", "###"); System.out.format("%"+ (numberOfRows + 1) + "s\n", "###");</programlisting> <para>Both implementation variants allow for setting e.g. <code language="java">final int numberOfRows = 10</code> creating trees of different sizes albeit sharing the same trunk size:</para> <screen> X * *** ***** ******* ********* *********** ************* *************** ***************** ******************* ### ###</screen> </answer> </qandaentry> </qandadiv> </qandaset> <qandaset defaultlabel="qanda" xml:id="sd1QandaXmasMoreFun"> <title>More fun with Xmas trees</title> <qandadiv> <qandaentry> <question> <para>The following ASCII art for configurable Xmas tree sizes is slightly more challenging :</para> <screen> \ / -->*<-- /_\ /_\_\ /_/_/_\ /_\_\_\ /_/_/_/_\ /_\_\_\_\ /_/_/_/_/_\ /_\_\_\_\_\ /_/_/_/_/_/_\ /_\_\_\_\_\_\ /_/_/_/_/_/_/_\ [___]</screen> <tip> <orderedlist> <listitem> <para>Inside a string literal a backslash <quote>\</quote> has to be escaped by using a double backslash <quote>\\</quote>.</para> </listitem> <listitem> <para>Read about using <classname>System</classname><code>.</code><property>out</property><code>.</code><methodname xlink:href="javaapi://java.io.PrintStream#format(java.lang.String,java.lang.Object...)">format()</methodname> and <methodname xlink:href="javaapi://String#repeat(int)">repeat(int)</methodname> in the previous exercises solution.</para> </listitem> <listitem> <para>The <methodname xlink:href="javaapi://String#indent(int)">indent(int)</methodname> method allows for indenting multi line blocks:</para> <informaltable border="1"> <tr> <th>Code</th> <th>Result ('␣' denoting space)</th> </tr> <tr> <td valign="top"><programlisting language="none">final String block = """ <emphasis role="red">A simple block consisting of three lines</emphasis>"""; System.out.println(block); System.out.println( "\n------------------------\n"); System.out.println(block.indent(10));</programlisting></td> <td valign="top"><screen><emphasis role="red">A simple block consisting of three lines</emphasis> ------------------------ ␣␣␣␣␣␣␣␣␣␣<emphasis role="red">A simple block</emphasis> ␣␣␣␣␣␣␣␣␣␣<emphasis role="red">consisting of</emphasis> ␣␣␣␣␣␣␣␣␣␣<emphasis role="red">three lines</emphasis></screen></td> </tr> </informaltable> </listitem> </orderedlist> </tip> </question> <answer> <programlisting language="none">Looping through <emphasis role="red">\ /</emphasis> <emphasis role="red">Part 1: The tree's top.</emphasis> groups of 2 lines <emphasis role="red">-->*<--</emphasis> <emphasis role="red">/_\</emphasis> Row group index 0 /_\_\ Part 2: The tree's body, printing /_/_/_\ two lines per group index Row group index 1 /_\_\_\ loop iteration. /_/_/_/_\ Row group index 2 /_\_\_\_\ /_/_/_/_/_\ Row group index 3 /_\_\_\_\_\ /_/_/_/_/_/_\ Row group index 4 /_\_\_\_\_\_\ End of tree's body /_/_/_/_/_/_/_\ <emphasis role="red">[___]</emphasis> <emphasis role="red">Part 3: Bottom trunk line.</emphasis></programlisting> <para>For each row group (albeit having different length) the two patterns <code>"/_\_ ... \_\"</code> and <code>"/_/ ... /_\"</code> keep repeating. Like in the previous exercises we need the precise indentation values for <abbrev>e.g.</abbrev> starting the tree's body. The following output shows two trees of different sizes representing invisible spaces by <quote>␣</quote> for better readability. In the »bigger« tree's first line we need <abbrev>e.g.</abbrev> 6 spaces before actually printing the tree's very top "<emphasis role="red"><code>\/</code></emphasis>".</para> <programlisting language="none"> A tree with A tree with 5 row groups 2 row groups ␣␣␣␣␣␣<emphasis role="red">\ /</emphasis> ␣␣␣<emphasis role="red">\ /</emphasis> ␣␣␣␣<emphasis role="red">-->*<--</emphasis> ␣<emphasis role="red">-->*<--</emphasis> ␣␣␣␣␣␣<emphasis role="red">/_\</emphasis> ␣␣␣<emphasis role="red">/_\</emphasis> ␣␣␣␣␣/_\_\ ␣␣/_\_\ ␣␣␣␣/_/_/_\ ␣/_/_/_\ ␣␣␣␣/_\_\_\ ␣/_\_\_\ ␣␣␣/_/_/_/_\ /_/_/_/_\ ␣␣␣/_\_\_\_\ ␣␣<emphasis role="red">[___]</emphasis> ␣␣/_/_/_/_/_\ ␣␣/_\_\_\_\_\ ␣/_/_/_/_/_/_\ ␣/_\_\_\_\_\_\ /_/_/_/_/_/_/_\ ␣␣␣␣␣<emphasis role="red">[___]</emphasis></programlisting> <para>The precise amounts of these indentations again depend on the tree's size. Printing larger trees requires larger indentation values. The tree's size is being controlled by the parameter <parameter>numberOfRowGroups</parameter>:</para> <programlisting language="java">final int numberOfRowGroups = 5;</programlisting> <para>Now we start printing the tree's top <emphasis role="red"><code>\/</code></emphasis>. Printing a backslash <emphasis role="red"><code>\</code></emphasis> in <xref linkend="glo_Java"/> is surprisingly difficult: The character is being used to escape double quotes, newline, tab, <productname>Unicode</productname> and other characters within strings:</para> <informaltable border="1"> <col width="80%"/> <col width="20%"/> <tr> <th>Code</th> <th>Result (added <quote>␣</quote>)</th> </tr> <tr> <td valign="top"><programlisting language="none">System.out.println("<emphasis role="red">\"</emphasis>"); // Print a double quote <emphasis role="red">"</emphasis> System.out.println("Hello<emphasis role="red">\n</emphasis>"); // Print 'Hello' followed by an extra <emphasis role="red">new line</emphasis>. System.out.println("<emphasis role="red">\t</emphasis> Hello"); // Print a <emphasis role="red">tab indented</emphasis> 'Hello' string. System.out.println("<emphasis role="red">\u2B95</emphasis>"); // Print a unicode right arrow <emphasis role="red">⮕</emphasis> System.out.println("<emphasis role="red">\\</emphasis>"); // Print a single backslash <emphasis role="red">\</emphasis> character</programlisting></td> <td valign="top"><screen><emphasis role="red">"</emphasis> <emphasis role="red">Hello</emphasis> <emphasis role="red"> </emphasis>Hello <emphasis role="red">⮕</emphasis> <emphasis role="red">\</emphasis></screen></td> </tr> </informaltable> <para>The above snippet shows a solution: Within a given string the backslash character must itself be escaped by a second one to get a single backslash character on output. In addition we need preceding spaces (<code>' '</code>) being represented by <code>␣</code> in the output screen to the right.</para> <para>Printing our tree's very top thus requires:</para> <informaltable border="1"> <col width="80%"/> <col width="20%"/> <tr> <th>Code</th> <th>Result (added <quote>␣</quote>)</th> </tr> <tr> <td valign="top"><programlisting language="none">for (int x = 0; x < numberOfRowGroups + 1; x++) { // Printing the tree's "<emphasis role="red">\ /</emphasis>" top. We need System.out.print(' '); // numberOfRowGroups+1 preceding spaces (␣) } // before eventually printing the System.out.println("<emphasis role="red">\\ /</emphasis>"); // "<emphasis role="red">\ /</emphasis>" String followed by a newline (print<emphasis role="red">ln</emphasis>).</programlisting></td> <td valign="top"><screen>␣␣␣␣␣␣<emphasis role="red">\ /</emphasis> </screen><para>(<quote>␣</quote> denoting space)</para></td> </tr> </informaltable> <para>The expression <code>numberOfRowGroups + 1</code> equals an indent of 6 in case of 5 row groups with respect to the illustration given before. Likewise the top's next two of lines are straightforward:</para> <informaltable border="1"> <col width="80%"/> <col width="20%"/> <tr> <th>Code</th> <th>Result (added <quote>␣</quote>)</th> </tr> <tr> <td valign="top"><programlisting language="none">for (int x = 0; x < numberOfRowGroups - 1; x++) { // Printing the tree's top '-->*<--' we System.out.print(' '); // need numberOfRows-1 preceding spaces (␣) } // before printing the "<emphasis role="red">-->*<--</emphasis>" System.out.println("<emphasis role="red">-->*<--</emphasis>"); // string. for (int x = 0; x < numberOfRowGroups + 1; x++) { // The tree's lower top "<emphasis role="red">/ \</emphasis>": System.out.print(' '); // We need another numberOfRows+1 } // preceding spaces (␣). System.out.println("<emphasis role="red">/_\\</emphasis>");</programlisting></td> <td valign="top"><screen>␣␣␣␣␣␣\ / ␣␣␣␣<emphasis role="red">-->*<--</emphasis> ␣␣␣␣␣␣<emphasis role="red">/ \</emphasis></screen></td> </tr> </informaltable> <para>We now turn to the tree's body. Following the idea of row groups each consisting of two lines we require:</para> <informaltable border="1"> <col width="80%"/> <col width="20%"/> <tr> <th>Code</th> <th>Result</th> </tr> <tr> <td valign="top"><programlisting language="none">for (int rowGroup = 0; rowGroup < numberOfRowGroups; rowGroup++) { // print first row of group e.g. <emphasis role="red">/_\_\</emphasis> // print second row of group <emphasis role="red">/_/_/_\</emphasis> }</programlisting></td> <td valign="top"><screen>␣␣␣␣␣␣\ / ␣␣␣␣-->*<-- ␣␣␣␣␣␣/ \ ␣␣␣␣␣<emphasis role="red">/_\_\</emphasis> ␣␣␣␣<emphasis role="red">/_/_/_\</emphasis> ...</screen></td> </tr> </informaltable> <para>We now show the loop's gory details:</para> <informaltable border="1"> <col width="80%"/> <col width="20%"/> <tr> <th>Code</th> <th>Result</th> </tr> <tr> <td valign="top"><programlisting language="none">for (int rowGroup = 0; // Outer loop printing the rowGroup < numberOfRowGroups; rowGroup++) { // tree's body. // First body line of current group // for (int x = 0; // Starting first line x < numberOfRowGroups - rowGroup;x++) { // of row group with // (numberOfRows - row) System.out.print(' '); // space (␣) characters } System.out.print("<emphasis role="red">/</emphasis>"); // Start of current row group's for (int x = 0; x < rowGroup + 2;x++) { // first line tree body content System.out.print("<emphasis role="red">_\\</emphasis>"); // finishing. } System.out.println(); // Second body line of current group // for (int x = 0; // Starting second line of row x < numberOfRowGroups - rowGroup - 1; x++) { // group with (numberOfRows - System.out.print(' '); // row - 1) space (␣) characters } for (int x = 0; x < rowGroup + 3;x++) { // tree body content System.out.print("<emphasis role="red">/_</emphasis>"); } System.out.println("<emphasis role="red">\\</emphasis>"); // finishing. }</programlisting></td> <td valign="top"><screen>␣␣␣␣␣␣\ / ␣␣␣␣-->*<-- ␣␣␣␣␣␣/ \ ␣␣␣␣␣<emphasis role="red">/_\_\</emphasis> ␣␣␣␣<emphasis role="red">/_/_/_\</emphasis> ␣␣␣␣<emphasis role="red">/_\_\_\</emphasis> ␣␣␣<emphasis role="red">/_/_/_/_\</emphasis> ␣␣␣<emphasis role="red">/_\_\_\_\</emphasis> ␣␣<emphasis role="red">/_/_/_/_/_\</emphasis> ␣␣<emphasis role="red">/_\_\_\_\_\</emphasis> ␣<emphasis role="red">/_/_/_/_/_/_\</emphasis> ␣<emphasis role="red">/_\_\_\_\_\_\</emphasis> <emphasis role="red">/_/_/_/_/_/_/_\</emphasis></screen></td> </tr> </informaltable> <para>Finally printing the tree's trunk:</para> <informaltable border="1"> <col width="80%"/> <col width="20%"/> <tr> <th>Code</th> <th>Result (added <quote>␣</quote>)</th> </tr> <tr> <td valign="top"><programlisting language="none">// Part three: The tree's bottom trunk // for (int x = 0; x < numberOfRowGroups; x++) { // Indenting the bottom trunk ... System.out.print(' '); } System.out.println("<emphasis role="red">[___]</emphasis>"); // printing the trunk.</programlisting></td> <td valign="top"><screen>␣␣␣␣␣␣\ / ␣␣␣␣-->*<-- ␣␣␣␣␣␣/ \ ␣␣␣␣␣/_\_\ ␣␣␣␣/_/_/_\ ␣␣␣␣/_\_\_\ ␣␣␣/_/_/_/_\ ␣␣␣/_\_\_\_\ ␣␣/_/_/_/_/_\ ␣␣/_\_\_\_\_\ ␣/_/_/_/_/_/_\ ␣/_\_\_\_\_\_\ /_/_/_/_/_/_/_\ ␣␣␣␣␣<emphasis role="red">[___]</emphasis></screen></td> </tr> </informaltable> <para>Similar to the previous exercise <xref linkend="sd1QandaXmasTree"/> this time we replace all inner loops by<classname> using </classname><classname xlink:href="javaapi://String">String</classname>.<methodname xlink:href="javaapi://String#indent(int)">indent()</methodname> and <classname xlink:href="javaapi://String">String</classname>.<methodname xlink:href="javaapi://String#repeat(int)">repeat()</methodname>. This variant's full source code is on offer at <link xlink:href="https://gitlab.mi.hdm-stuttgart.de/goik/GoikLectures/tree/master/Doc/Sd1/Ref/Statements/MoreFunXmasTree/src/main/java/de/hdm_stuttgart/mi/sd1/XmasUsingFormat.java">XmasUsingFormat.java</link>.</para> <programlisting language="java">final int numberOfRowGroups = 5; // You may easily change this parameter. // Printing the tree's top. We have to escape the backslash using \\. System.out.print(""" \\ / -->*<-- /_\\""".indent(numberOfRowGroups)); // Printing the tree's body // Loop printing the tree's body row group wise. for (int rowGroup = 0; rowGroup < numberOfRowGroups; rowGroup++) { final int indentation = numberOfRowGroups - rowGroup + 1; // First body line of current group System.out.print(('/' + "_\\".repeat(rowGroup + 2)).indent(indentation)); // Second body line of current group System.out.print(("/_".repeat(rowGroup + 3) + '\\').indent(indentation - 1)); } // Printing the tree's trunk System.out.print("[___]".indent(numberOfRowGroups + 1));</programlisting> <para>Both implementation variants allow for setting e.g. <code language="java">final int numberOfRowGroups = 8</code> creating trees of different sizes albeit sharing the same trunk size:</para> <screen> \ / -->*<-- /_\ /_\_\ /_/_/_\ /_\_\_\ /_/_/_/_\ /_\_\_\_\ /_/_/_/_/_\ /_\_\_\_\_\ /_/_/_/_/_/_\ /_\_\_\_\_\_\ /_/_/_/_/_/_/_\ /_\_\_\_\_\_\_\ /_/_/_/_/_/_/_/_\ /_\_\_\_\_\_\_\_\ /_/_/_/_/_/_/_/_/_\ /_\_\_\_\_\_\_\_\_\ /_/_/_/_/_/_/_/_/_/_\ [___]</screen> </answer> </qandaentry> </qandadiv> </qandaset> <section xml:id="sd1SectSquareNumberTable"> <title>A table of square numbers</title> <qandaset defaultlabel="qanda" xml:id="sd1QandaSquareNumberTable"> <title>A basic square number table</title> <qandadiv> <qandaentry> <question> <para>Write an application for creating the following table of integer square numbers (<inlineequation> <m:math display="inline"> <m:msup> <m:mi>n</m:mi> <m:mn>2</m:mn> </m:msup> </m:math> </inlineequation>):</para> <screen>n | n * n --+------ 0 | 0 1 | 1 2 | 4 3 | 9 4 | 16 5 | 25 6 | 36 7 | 49 8 | 64 9 | 81</screen> <para>Your solution is expected to be flexible: Sometimes a different limit of e.g. 12 rather than 9 in the above example is being desired. This rules an obvious «solution»:</para> <programlisting language="java">public static void main(String[] args) { System.out.println("n | n * n"); System.out.println("--+------"); System.out.println(0 + " | " + 0); System.out.println(1 + " | " + 1); ... System.out.println(9 + " | " + 81); }</programlisting> <tip> <para>Use a loop printing the table's body values.</para> </tip> </question> <answer> <para>The table head my be copied from the code snippet. In addition we require a loop printing the table's body:</para> <programlisting language="java">public static void main(String[] args) { System.out.println("n | n * n"); // Printing the table's head System.out.println("--+------"); for (int i = 0; i <= 9; i++) { // Printing the table's body System.out.println(i + " | " + i * i); } }</programlisting> </answer> </qandaentry> </qandadiv> </qandaset> <qandaset defaultlabel="qanda" xml:id="sd1QandaSquareNumberTableFormatted"> <title>Tidy up the mess!</title> <qandadiv> <qandaentry> <question> <para>Running the previous code for values beyond 9 suffers from ugly formatting:</para> <screen>n | n * n --+------ 0 | 0 1 | 1 ... 8 | 64 9 | 81 10 | 100 11 | 121 12 | 144 ... 19 | 361 20 | 400</screen> <para>Modify your code by:</para> <orderedlist> <listitem> <para>introducing a single integer constant to define the number of values to be printed (i.e. 20 in the above example).</para> </listitem> <listitem> <para>Right indent all integer values being printed reserving fixed widths for printing integer values.</para> </listitem> </orderedlist> <para>Your application's output shall look like:<screen> n | n * n ---+------ 0| 0 1| 1 ... 8| 64 9| 81 10| 100 11| 121 ... 19| 361 20| 400</screen><tip> <para>Read the track <link xlink:href="https://docs.oracle.com/javase/tutorial/java/data/numberformat.html">Formatting Numeric Print Output</link> and learn how to style numeric output: Use <methodname><link xlink:href="javaapi://System#out">System.out</link>.<link xlink:href="javaapi://java.io.PrintStream#format(java.lang.String,java.lang.Object...)">format</link>(...%nd...)</methodname> instead of <methodname><link xlink:href="javaapi://System#out">System.out</link>.<link xlink:href="javaapi://java.io.PrintStream#println()">println</link>(...)</methodname> statements</para> </tip></para> </question> <answer> <para>The $...d format specifier serves two purposes:</para> <orderedlist> <listitem> <para>A fixed length will be used for printing decimal values.</para> </listitem> <listitem> <para>Numbers will be printed right aligned.</para> </listitem> </orderedlist> <para>Example:</para> <informaltable border="1"> <col width="80%"/> <col width="20%"/> <tr> <th>Code</th> <th>Result (added <quote>␣</quote>)</th> </tr> <tr> <td valign="top"><programlisting language="none"> System.out.format("Start:<emphasis role="red">%5d</emphasis>:End", <emphasis role="red">12</emphasis>); // Printing 12 right aligned in a field of 5 characters padded with 3 spaces to the left <emphasis role="red"> ▲ ┃</emphasis> <emphasis role="red">┗━━━━━━━━━┛</emphasis> <emphasis role="red">replace</emphasis> </programlisting></td> <td valign="top"><screen>Start:<emphasis role="red">␣␣␣12</emphasis>:End</screen></td> </tr> </informaltable> <para>The format string <code language="java">"%3d|%6d\n"</code> allows for two decimal output fields of length 3 and 6 respectively. It thus corresponds to the two variables <code language="java">i</code> and <code language="java">i * i</code> being supplied as arguments:</para> <programlisting language="java">public static void main(String[] args) { final int LIMIT = 20; // The number of records to be printed System.out.println(" n | n * n"); // Printing the table's head System.out.println("---+------"); for (int i = 0; i <= LIMIT; i++) { // Printing the table's body System.out.format("%3d|%6d\n", // Format string i , i * i); // Values being inserted in above format } // string. }</programlisting> </answer> </qandaentry> </qandadiv> </qandaset> <qandaset defaultlabel="qanda" xml:id="sw1QandaSquareNumbersHtmlFormatted"> <title>HTML-ify me</title> <qandadiv> <qandaentry> <question> <para>Modify the previous code to generate HTML output instead of pure text and watch the result using a web browser. The expected output reads:</para> <programlisting language="xml"><html xmlns='http://www.w3.org/1999/xhtml'> <head> <title>A square table</title> <!-- CSS based styling --> <style> table, td, th { border: 1px solid black; } table { border-collapse: collapse; } td { text-align: right; } </style> </head> <body> <table> <tr> <th>n</th><th>n * n</th> </tr> <tr> <td><emphasis role="red">0</emphasis></td><td><emphasis role="red">0</emphasis></td> </tr> <tr> <td><emphasis role="red">1</emphasis></td><td><emphasis role="red">1</emphasis></td> </tr> <tr> <td><emphasis role="red">2</emphasis></td><td><emphasis role="red">4</emphasis></td> </tr> ... </table> </body> </html></programlisting> </question> <answer> <para>A complete solution is being provided by <link xlink:href="https://gitlab.mi.hdm-stuttgart.de/goik/GoikLectures/-/blob/master/Doc/Sd1/Ref/Statements/MultSimpleHtmlTable/src/main/java/de/hdm_stuttgart/mi/sd1/App.java">App.java</link>. This solution uses both <xref linkend="glo_Java"/> 15 multi line blocks and the String.<link xlink:href="javaapi://String#indent(int)">indent(..)</link> method.</para> </answer> </qandaentry> </qandadiv> </qandaset> <qandaset defaultlabel="qanda" xml:id="sd1QandaIntermediateMultiplyTable1"> <title>Auxiliary Example, part 1: A multiplication table</title> <qandadiv> <qandaentry> <question> <para>In order to prepare a more sophisticated square number table we supply a slightly different exercise producing a multiplication table:</para> <screen> * | 1 2 3 4 5 6 7 8 9 10 ---+-------------------------------------------------- 1| 1 2 3 4 5 6 7 8 9 10 2| 2 4 6 8 10 12 14 16 18 20 3| 3 6 9 12 15 18 21 24 27 30 4| 4 8 12 16 20 24 28 32 36 40 5| 5 10 15 20 25 30 35 40 45 50 6| 6 12 18 24 30 36 42 48 54 60 7| 7 14 21 28 35 42 49 56 63 70 8| 8 16 24 32 40 48 56 64 72 80 9| 9 18 27 36 45 54 63 72 81 90 10| 10 20 30 40 50 60 70 80 90 100</screen> <para>The number of rows and columns are equal. Provide an appropriate parameter i.e <code language="java">final int SIZE = 12</code> allowing for a configurable number of columns.</para> <tip> <orderedlist> <listitem> <para>You'll need an inner loop nested within an outer one creating rows and columns like:</para> <programlisting language="none">for (int row = 1; ...){ for (int col = 1; ... ) { ... // Using System.out.print(...) rather than ...print<emphasis role="red">ln</emphasis>() avoiding line breaks. } System.out.println(); // Adding a newline after each set of values }</programlisting> </listitem> <listitem> <para>Having integer values of differing lengths you have to consider right justified output. The integer <link xlink:href="javaapi://java.util.Formatter#syntax">format specifier</link> <code>%...d</code> is your friend here. The subsequent example prints four integer values in right justified style within output fields of common length 5 irrespective of differing lengths:</para> <informaltable border="1"> <tr> <th>Code</th> <th>Output</th> </tr> <tr> <td valign="top"><programlisting language="java">System.out.format("|%5d|%5d|%5d|%5d|", 1, 100, 1000, 10000);</programlisting></td> <td valign="top"><screen>| 1| 100| 1000|10000|</screen></td> </tr> </informaltable> <para>The %...s format specifier may be used for strings accordingly.</para> </listitem> </orderedlist> </tip> </question> <answer> <programlisting language="java">// Block 1: Configuration parameter // final int SIZE = 6; // Table size is subject to change. // Block 2: Printing table's head // System.out.print(" * | "); // Printing table head's first line for (int col = 1; col <= SIZE; col++) { // using column values ranging from 1 to SIZE: System.out.format("%3d ", col); // * | 1 2 3 ... } System.out.print("\n---+" + // Printing table head's second line "-----".repeat(SIZE) ); // ---+--------------- ... // Block 3: Printing table's content // organized in rows and columns. // for (int row = 1; row <= SIZE; row++) { // Printing rows. System.out.format("\n%3d| ", row); // Printing new line by \n and beginning of row e.g. " 5|" for (int col = 1; col <= SIZE; col++) { System.out.format("%3d ", row * col); // Printing row times column product values. } }</programlisting> </answer> </qandaentry> </qandadiv> </qandaset> <qandaset defaultlabel="qanda" xml:id="sd1QandaIntermediateMultiplyTable2"> <title>Auxiliary Example, part 2: Avoiding redundant entries</title> <qandadiv> <qandaentry> <question> <para>It does not make sense to supply both results like e.g. 3 * 4 and 4 * 3. Modify your application to generate:</para> <screen> 1| 1 2| 2 4 3| 3 6 9 4| 4 8 12 16 5| 5 10 15 20 25 6| 6 12 18 24 30 36 7| 7 14 21 28 35 42 49 8| 8 16 24 32 40 48 56 64 9| 9 18 27 36 45 54 63 72 81 10| 10 20 30 40 50 60 70 80 90 100 ---+-------------------------------------------------- * | 1 2 3 4 5 6 7 8 9 10</screen> </question> <answer> <para>We need two changes with respect to the <link linkend="sd1QandaIntermediateMultiplyTable1">previous exercise</link>:</para> <orderedlist> <listitem> <para>The number of columns to be printed has to be limited depending on which row we currently print. We thus replace</para> <programlisting language="none">for (int col = 1; col <= <emphasis role="red">SIZE</emphasis>; col++) { // Printing columns.</programlisting> <para>by</para> <programlisting language="none">for (int col = 1; col <= <emphasis role="red">row</emphasis>; col++) { // Printing columns depending on current row value.</programlisting> </listitem> <listitem> <para>Having a table tail now rather than a head we also have to defer our former solution's second block to the end thereby reversing the order of print statements. The following code also includes some minor newline character fiddling:</para> <programlisting language="java">// Block 1: Configuration parameter // final int SIZE = 10; // Table size is subject to change. // Block 2: Printing table's content // organized in rows and columns. // for (int row = 1; row <= SIZE; row++) { // Printing rows. System.out.format("%3d| ", row); // Printing new line by \n and beginning of row e.g. " 5|" for (int col = 1; col <= row; col++) { System.out.format("%3d ", row * col); // Printing row times column product values. } System.out.println(); // New line after printing row. } // Block 3: Printing table's tail. // System.out.print("---+" + // Printing table tail's first line "-----".repeat(SIZE) + // ---+--------------- ... '\n'); // being finished by a newline character. System.out.print(" * | "); // Printing table tail's second line for (int col = 1; col <= SIZE; col++) { // using column values ranging from 1 to SIZE: System.out.format("%3d ", col); // * | 1 2 3 ... }</programlisting> </listitem> </orderedlist> </answer> </qandaentry> </qandadiv> </qandaset> <qandaset defaultlabel="qanda" xml:id="sd1QandaSquareTableBlocks"> <title>Creating a <quote>real</quote> square table</title> <qandadiv> <qandaentry> <question> <para>The last square number table solution is only appropriate for smaller amounts of data. Growing numbers of elements require rearranging values in blocks avoiding waste of space:</para> <screen> n | n² n | n² n | n² n | n² n | n² ----+--------------+--------------+--------------+--------------+---------- 0 | 0 20 | 400 40 | 1600 60 | 3600 80 | 6400 1 | 1 21 | 441 41 | 1681 61 | 3721 81 | 6561 2 | 4 22 | 484 42 | 1764 62 | 3844 82 | 6724 3 | 9 23 | 529 43 | 1849 63 | 3969 83 | 6889 4 | 16 24 | 576 44 | 1936 64 | 4096 84 | 7056 5 | 25 25 | 625 45 | 2025 65 | 4225 85 | 7225 6 | 36 26 | 676 46 | 2116 66 | 4356 86 | 7396 7 | 49 27 | 729 47 | 2209 67 | 4489 87 | 7569 8 | 64 28 | 784 48 | 2304 68 | 4624 88 | 7744 9 | 81 29 | 841 49 | 2401 69 | 4761 89 | 7921 ----+--------------+--------------+--------------+--------------+---------- 10 | 100 30 | 900 50 | 2500 70 | 4900 90 | 8100 11 | 121 31 | 961 51 | 2601 71 | 5041 91 | 8281 12 | 144 32 | 1024 52 | 2704 72 | 5184 92 | 8464 13 | 169 33 | 1089 53 | 2809 73 | 5329 93 | 8649 14 | 196 34 | 1156 54 | 2916 74 | 5476 94 | 8836 15 | 225 35 | 1225 55 | 3025 75 | 5625 95 | 9025 16 | 256 36 | 1296 56 | 3136 76 | 5776 96 | 9216 17 | 289 37 | 1369 57 | 3249 77 | 5929 97 | 9409 18 | 324 38 | 1444 58 | 3364 78 | 6084 98 | 9604 19 | 361 39 | 1521 59 | 3481 79 | 6241 99 | 9801</screen> <para>Building a table this way requires additional parameters:</para> <itemizedlist> <listitem> <para>The number of blocks in x-direction (5 in the above example)</para> </listitem> <listitem> <para>The number of blocks in y-direction (2 in the above example)</para> </listitem> <listitem> <para>The number of entries per block (10 in the above example)</para> </listitem> </itemizedlist> <para>You require three nested loops.</para> </question> <answer> <programlisting language="java">// Table parameter final int numBlocksHorizontal = 5, numBlocksVertical = 2, entriesPerBlock = 10; // Derived parameter final int numRows = numBlocksVertical * entriesPerBlock; System.out.println(" n | n² ".repeat( // Printing the overall numBlocksHorizontal)); // table's head section for (int y = 0; y < numBlocksVertical; y++) { // Looping through vertically stacked blocks. System.out.println( // Supplementary separator line between "----+----------".repeat(numBlocksHorizontal)); // two vertically adjacent blocks for (int row = 0; // Stepping through the given row < entriesPerBlock; row++) { // block's rows ... for (int col = 0; col < numBlocksHorizontal; col++) { // ... columns within each row. final int cellValue = y * entriesPerBlock // The cell's value + col * numRows + row; // to be squared. System.out.format("%3d | %4d ", // Pretty print cell value cellValue, cellValue * cellValue); // and its square. } System.out.println(); } }</programlisting> </answer> </qandaentry> </qandadiv> </qandaset> <qandaset defaultlabel="qanda" xml:id="sd1QandaSquareTableBlocksHtml"> <title>Creating a sophisticated HTML version of your square table</title> <qandadiv> <qandaentry> <question> <para>On top of the previous square number table we may also create a HTML version.Modify your console output from the previous exercise accordingly. The expected outcome looks like:</para> <screenshot> <info> <title>A <xref linkend="glo_HTML"/> square table till 20*20.</title> </info> <mediaobject> <imageobject> <imagedata fileref="Fig/squareTable.png"/> </imageobject> </mediaobject> </screenshot> <tip> <orderedlist> <listitem> <para>You find a suitable HTML code sample to be generated at <link xlink:href="/Sd1/Ref/Src/squareTable.html">squareTable.html</link>.</para> </listitem> <listitem> <para>Depending on your advance in <xref linkend="glo_HTML"/> and <xref linkend="glo_CSS"/> you may want to postpone this exercise until these two have been thoroughly covered in <link xlink:href="https://www.hdm-stuttgart.de/studierende/stundenplan/vorlesungsverzeichnis/vorlesung_detail?vorlid=5213267">related lectures</link>.</para> </listitem> <listitem> <para>You may also create an expected output HTML table manually <abbrev>e.g.</abbrev> in a separate file <filename>squaretable.html</filename> until its browser view satisfies your expectations. Only then do you know which output your <xref linkend="glo_Java"/> application is about to generate.</para> </listitem> </orderedlist> </tip> </question> <answer> <para>The following solution uses <xref linkend="glo_CSS"/> style definitions in the generated HTML's header section being referenced from the document's body.</para> <programlisting language="java">// Block 1: Setting table parameter final int numBlocksHorizontal = 5, numBlocksVertical = 2, entriesPerBlock = 10; final int numRows = numBlocksVertical * entriesPerBlock; // Block 2: Printing table's static head System.out.println(""" <html xmlns='http://www.w3.org/1999/xhtml'> <head> <meta charset="UTF-8"> <title>A square table</title> <style> table, th, td {border: 1px solid black;} table {border-collapse: collapse;} td {text-align: right;} .greyColumn {background-color:LightGray;} </style> </head> <body> <table> <colgroup>"""); // Block 3: Creating »n | n² | n | n² ...« table header for (int x = 0; x < numBlocksHorizontal; x++) { // Creating the overall // table's head section. if (0 == x % 2) { System.out.println(" <col span='2'/>"); } else { System.out.println(" <col span='2' class='greyColumn'/>"); } } System.out.println(" </colgroup>"); System.out.println(" <tr>"); for (int x = 0; x < numBlocksHorizontal; x++) { // n | n² header line System.out.println(" <th>n</th><th>n²</th>"); } System.out.println(" </tr>\n"); // Block 4: The table's »payload«. for (int y = 0; y < numBlocksVertical; y++) { // Blocks stacked below another System.out.println(" <tr><td></td></tr>"); // extra row. for (int yBlock = 0; yBlock < entriesPerBlock; yBlock++) { // Stepping through values vertically ... System.out.println(" <tr>"); for (int x = 0; x < numBlocksHorizontal; x++) { // and horizontally within each line. final int cellValue = 1 + yBlock // The individual value to be squared. + x * numRows + y * entriesPerBlock; System.out.println( // Pretty print output " <td>" + cellValue + "</td><td>" // value and its square. + cellValue * cellValue + "</td>"); } System.out.println(" </tr>"); } } // Block 5: The table's tail System.out.print(""" </table> </body> </html>"""); </programlisting> </answer> </qandaentry> </qandadiv> </qandaset> </section> <section xml:id="sd1SectPlayingLottery"> <title>Loops and calculations</title> <figure xml:id="sd1_fig_loopCalculations"> <title>Calculating values</title> <informaltable border="1"> <tr> <td><programlisting language="java">final int LIMIT = 5; int sum = 0; for (int i = 1; i <= LIMIT; i++) { sum += i; } System.out.println("1 + ... + " + LIMIT + " = " + sum);</programlisting></td> <td><screen>1 + ... + 5 = 15</screen></td> </tr> </informaltable> </figure> <qandaset defaultlabel="qanda" xml:id="sd1_statement_qanda_fullSum"> <title>Display all summands</title> <qandadiv> <qandaentry> <question> <para>In <xref linkend="sd1_fig_loopCalculations"/> for a given value of limit only the first and last summand will show up: We just see <code>1 + ... + 5 = 15</code> rather than <code>1 + 2 + 3 + 4 + 5 = 15</code>.</para> <para>If <code language="java">LIMIT</code> is equal to one the visible result is even worse:</para> <screen>1 + ... + 1 = 1</screen> <para>Modify the code accordingly to print the above <code>1 + 2 + 3 + 4 + 5 = 15</code> output line.</para> <tip> <para>Using <code language="java">System.out.print(...)</code> rather than <code language="java">System.out.println(...)</code> avoids printing a newline and thus allows for continuation within a given line of output.</para> </tip> </question> <answer> <para>A first approach reads:</para> <programlisting language="java">final int LIMIT = 5; for (int i = 1; i <= LIMIT; i++) { System.out.print(i); System.out.print(" + "); sum += i; } System.out.println(" = " + sum);</programlisting> <para>This is close to the intended output. However our sum ends with an excess trailing <quote><emphasis role="red">+</emphasis></quote> symbol:</para> <screen>1 + 2 + 3 + 4 + 5 <emphasis role="red">+</emphasis> = 15</screen> <para>We get rid of it by introducing an <code language="java">if</code> statement:</para> <programlisting language="none">final int LIMIT = 5; for (int i = 1; i <= LIMIT; i++) { System.out.print(i); <emphasis role="red">if (i < LIMIT)</emphasis> { <emphasis role="bold"> // Avoid '<emphasis role="red">+</emphasis>' for the very last value</emphasis> System.out.print(" + "); } sum += i; } System.out.println(" = " + sum);</programlisting> <para>This avoids the trailing <quote>+</quote>:</para> <screen>1 + 2 + 3 + 4 + 5 = 15</screen> <para>Moreover it works for <code language="java">LIMIT = 1</code> as well:</para> <screen>1 = 1</screen> <para>Instead of filtering the very last <quote><code language="java">+</code></quote> operator we may as well terminate our loop one step earlier and move the last operand to the second <code language="java">println(...)</code> statement leaving us with an identical result:</para> <programlisting language="java">final int LIMIT = 5; int sum = 0; for (int i = 1; i < LIMIT; i++) { System.out.print(i + " + "); sum += i; } System.out.println(LIMIT + " = " + (sum + LIMIT));</programlisting> </answer> </qandaentry> </qandadiv> </qandaset> <qandaset defaultlabel="qanda" xml:id="sd1QandaPlayingLottery"> <title>Playing lottery</title> <qandadiv> <qandaentry> <question> <para>Common lotteries randomly draw numbers from a given set like:</para> <glosslist> <glossentry> <glossterm>Germany / <quote xml:lang="de">Glücksspirale</quote></glossterm> <glossdef> <informaltable border="1"> <col width="14%"/> <col width="86%"/> <tr> <td valign="top">6 out of 49</td> <td><mediaobject> <imageobject> <imagedata fileref="Fig/lotto-spiel77.jpg"/> </imageobject> </mediaobject></td> </tr> </informaltable> </glossdef> </glossentry> <glossentry> <glossterm>Italy / <quote>SuperEnalotto</quote></glossterm> <glossdef> <informaltable border="1"> <col width="14%"/> <col width="86%"/> <tr> <td valign="top">6 out of 90</td> <td><mediaobject> <imageobject> <imagedata fileref="Fig/superenalotto.gif"/> </imageobject> </mediaobject></td> </tr> </informaltable> </glossdef> </glossentry> </glosslist> <para>This category of lottery does not care about ordering (apart from so called jolly numbers). The number of possibilities for drawing k out of n numbers ignoring their ordering is being given by the <link xlink:href="https://en.wikipedia.org/wiki/Binomial_coefficient">binomial coefficient</link> <inlineequation> <m:math display="inline"> <m:mrow> <m:mrow> <m:mo>(</m:mo> <m:mrow> <m:mtable> <m:mtr> <m:mtd> <m:mi>n</m:mi> </m:mtd> </m:mtr> <m:mtr> <m:mtd> <m:mi>k</m:mi> </m:mtd> </m:mtr> </m:mtable> </m:mrow> <m:mo>)</m:mo> </m:mrow> </m:mrow> </m:math> </inlineequation>:</para> <informalequation> <m:math display="block"> <m:mrow> <m:mrow> <m:mrow> <m:mo>(</m:mo> <m:mrow> <m:mtable> <m:mtr> <m:mtd> <m:mi>n</m:mi> </m:mtd> </m:mtr> <m:mtr> <m:mtd> <m:mi>k</m:mi> </m:mtd> </m:mtr> </m:mtable> </m:mrow> <m:mo>)</m:mo> </m:mrow> </m:mrow> <m:mo>=</m:mo> <m:mfrac> <m:mrow> <m:mi>n</m:mi> <m:mo>!</m:mo> </m:mrow> <m:mrow> <m:mrow> <m:mi>k</m:mi> <m:mo>!</m:mo> </m:mrow> <m:mo></m:mo> <m:mrow> <m:mrow> <m:mo>(</m:mo> <m:mrow> <m:mi>n</m:mi> <m:mo>-</m:mo> <m:mi>k</m:mi> </m:mrow> <m:mo>)</m:mo> </m:mrow> <m:mo>!</m:mo> </m:mrow> </m:mrow> </m:mfrac> </m:mrow> </m:math> </informalequation> <para>Write an application which allows for determining the probabilistic success rates using this coefficient. For the German <quote xml:lang="de">Glücksspirale</quote> a possible output reads:</para> <screen>Your chance to win when drawing 6 out of 49 is 1 : 13983816</screen> <para>Store parameters like 6 or 49 in variables to keep your software flexible.</para> <tip> <orderedlist> <listitem> <para>Why is it a bad idea to <abbrev>e.g.</abbrev> compute <inlineequation> <m:math display="inline"> <m:mi>49!</m:mi> </m:math> </inlineequation> directly even when using long variables? Remember <xref linkend="sd1_fig_byteOverflow"/>.</para> </listitem> <listitem> <para>Arithmetic overflow problems can be avoided by simplifying <inlineequation> <m:math display="inline"> <m:mfrac> <m:mrow> <m:mi>n</m:mi> <m:mo>!</m:mo> </m:mrow> <m:mrow> <m:mrow> <m:mi>k</m:mi> <m:mo>!</m:mo> </m:mrow> <m:mo></m:mo> <m:mrow> <m:mrow> <m:mo>(</m:mo> <m:mrow> <m:mi>n</m:mi> <m:mo>-</m:mo> <m:mi>k</m:mi> </m:mrow> <m:mo>)</m:mo> </m:mrow> <m:mo>!</m:mo> </m:mrow> </m:mrow> </m:mfrac> </m:math> </inlineequation> beforehand. You may want to write down an explicit example like <inlineequation> <m:math display="inline"> <m:mrow> <m:mrow> <m:mrow> <m:mo>(</m:mo> <m:mrow> <m:mtable> <m:mtr> <m:mtd> <m:mi>8</m:mi> </m:mtd> </m:mtr> <m:mtr> <m:mtd> <m:mi>3</m:mi> </m:mtd> </m:mtr> </m:mtable> </m:mrow> <m:mo>)</m:mo> </m:mrow> </m:mrow> <m:mo>=</m:mo> <m:mfrac> <m:mrow> <m:mi>8</m:mi> <m:mo>!</m:mo> </m:mrow> <m:mrow> <m:mrow> <m:mi>3</m:mi> <m:mo>!</m:mo> </m:mrow> <m:mo></m:mo> <m:mrow> <m:mrow> <m:mo>(</m:mo> <m:mrow> <m:mi>8</m:mi> <m:mo>-</m:mo> <m:mi>3</m:mi> </m:mrow> <m:mo>)</m:mo> </m:mrow> <m:mo>!</m:mo> </m:mrow> </m:mrow> </m:mfrac> </m:mrow> </m:math> </inlineequation> to learn about cancellation of contributing factors.</para> </listitem> </orderedlist> </tip> </question> <answer> <para>Consider the following snippet:</para> <programlisting language="java">int product = 1; for (int i = 1; i < 50; i++) { product *= i; System.out.println(i + "! == " + product); }</programlisting> <para>This results in:</para> <screen>1! == 1 2! == 2 3! == 6 4! == 24 5! == 120 6! == 720 7! == 5040 8! == 40320 9! == 362880 10! == 3628800 11! == 39916800 12! == 479001600 13! == 1932053504 ... 49! == 0</screen> <para>Only results up to <inlineequation> <m:math display="inline"> <m:mi>12!</m:mi> </m:math> </inlineequation> are correct: The next term <inlineequation> <m:math display="inline"> <m:mi>13!</m:mi> </m:math> </inlineequation> equals 6227020800 which is ways beyond <code xlink:href="javaapi://Integer#MAX_VALUE">Integer.MAX_VALUE</code> == 2147483647 giving rise to a (silent) arithmetic overflow. But even declaring our variable <code language="java">product</code> of type <code language="java">long</code> does not help much:</para> <screen>1! == 1 2! == 2 3! == 6 4! == 24 5! == 120 6! == 720 7! == 5040 8! == 40320 9! == 362880 10! == 3628800 11! == 39916800 12! == 479001600 13! == 6227020800 14! == 87178291200 15! == 1307674368000 16! == 20922789888000 17! == 355687428096000 18! == 6402373705728000 19! == 121645100408832000 20! == 2432902008176640000 21! == -4249290049419214848 ... 49! == 8789267254022766592</screen> <para>This time <code>20! == 2432902008176640000</code> is the last correct value being smaller than <code language="java" xlink:href="javaapi://Long#MAX_VALUE">Long.MAX_VALUE</code> == 9223372036854775807.</para> <para>Fortunately we have another option. Consider an example:</para> <informalequation> <m:math display="block"> <m:mrow> <m:mrow> <m:mrow> <m:mo>(</m:mo> <m:mrow> <m:mtable> <m:mtr> <m:mtd> <m:mi>8</m:mi> </m:mtd> </m:mtr> <m:mtr> <m:mtd> <m:mi>3</m:mi> </m:mtd> </m:mtr> </m:mtable> </m:mrow> <m:mo>)</m:mo> </m:mrow> </m:mrow> <m:mo>=</m:mo> <m:mfrac> <m:mrow> <m:mrow> <m:mi>8</m:mi> <m:mo>×</m:mo> <m:mi>7</m:mi> <m:mo>×</m:mo> <m:mi>6</m:mi> <m:mo>×</m:mo> <m:mi>5</m:mi> <m:mo>×</m:mo> <m:mi>4</m:mi> <m:mo>×</m:mo> <m:mi>3</m:mi> <m:mo>×</m:mo> <m:mi>2</m:mi> <m:mo>×</m:mo> <m:mi>1</m:mi> </m:mrow> </m:mrow> <m:mrow> <m:mrow> <m:mo>(</m:mo> <m:mi>3</m:mi> <m:mo>×</m:mo> <m:mi>2</m:mi> <m:mo>×</m:mo> <m:mi>1</m:mi> <m:mo>)</m:mo> </m:mrow> <m:mo>×</m:mo> <m:mrow> <m:mo>(</m:mo> <m:mi>5</m:mi> <m:mo>×</m:mo> <m:mi>4</m:mi> <m:mo>×</m:mo> <m:mi>3</m:mi> <m:mo>×</m:mo> <m:mi>2</m:mi> <m:mo>×</m:mo> <m:mi>1</m:mi> <m:mo>)</m:mo> </m:mrow> </m:mrow> </m:mfrac> <m:mo>=</m:mo> <m:mfrac> <m:mrow> <m:mrow> <m:mi>8</m:mi> <m:mo>×</m:mo> <m:mi>7</m:mi> <m:mo>×</m:mo> <m:mi>6</m:mi> </m:mrow> </m:mrow> <m:mrow> <m:mrow> <m:mi>3</m:mi> <m:mo>×</m:mo> <m:mi>2</m:mi> <m:mo>×</m:mo> <m:mi>1</m:mi> </m:mrow> </m:mrow> </m:mfrac> <m:mo>=</m:mo> <m:mi>56</m:mi> </m:mrow> </m:math> </informalequation> <para>We generalize this fraction cancellation example:</para> <equation xml:id="sd1EqnBinomialCalculate"> <title>Calculating binomials by cancelling common factors.</title> <m:math display="block"> <m:mrow> <m:mfrac> <m:mrow> <m:mi>n</m:mi> <m:mo>!</m:mo> </m:mrow> <m:mrow> <m:mrow> <m:mi>k</m:mi> <m:mo>!</m:mo> </m:mrow> <m:mo></m:mo> <m:mrow> <m:mrow> <m:mo>(</m:mo> <m:mrow> <m:mi>n</m:mi> <m:mo>-</m:mo> <m:mi>k</m:mi> </m:mrow> <m:mo>)</m:mo> </m:mrow> <m:mo>!</m:mo> </m:mrow> </m:mrow> </m:mfrac> <m:mo>=</m:mo> <m:mfrac> <m:mrow> <m:mi>n</m:mi> <m:mo></m:mo> <m:mrow> <m:mo>(</m:mo> <m:mrow> <m:mi>n</m:mi> <m:mo>-</m:mo> <m:mi>1</m:mi> </m:mrow> <m:mo>)</m:mo> </m:mrow> <m:mo></m:mo> <m:mi>...</m:mi> <m:mo></m:mo> <m:mi>1</m:mi> </m:mrow> <m:mrow> <m:mrow> <m:mi>k</m:mi> <m:mo></m:mo> <m:mrow> <m:mo>(</m:mo> <m:mrow> <m:mi>k</m:mi> <m:mo>-</m:mo> <m:mi>1</m:mi> </m:mrow> <m:mo>)</m:mo> </m:mrow> <m:mo></m:mo> <m:mi>...</m:mi> <m:mo></m:mo> <m:mi>1</m:mi> </m:mrow> <m:mo></m:mo> <m:mrow> <m:mrow> <m:mo>(</m:mo> <m:mrow> <m:mi>n</m:mi> <m:mo>-</m:mo> <m:mi>k</m:mi> </m:mrow> <m:mo>)</m:mo> </m:mrow> <m:mo></m:mo> <m:mrow> <m:mo>(</m:mo> <m:mrow> <m:mi>n</m:mi> <m:mo>-</m:mo> <m:mi>k</m:mi> <m:mo>-</m:mo> <m:mi>1</m:mi> </m:mrow> <m:mo>)</m:mo> </m:mrow> <m:mo></m:mo> <m:mi>...</m:mi> <m:mo></m:mo> <m:mi>1</m:mi> </m:mrow> </m:mrow> </m:mfrac> <m:mo>=</m:mo> <m:mfrac> <m:mrow> <m:mi>n</m:mi> <m:mo></m:mo> <m:mrow> <m:mo>(</m:mo> <m:mrow> <m:mi>n</m:mi> <m:mo>-</m:mo> <m:mi>1</m:mi> </m:mrow> <m:mo>)</m:mo> </m:mrow> <m:mo></m:mo> <m:mi>...</m:mi> <m:mo></m:mo> <m:mrow> <m:mo>(</m:mo> <m:mrow> <m:mi>n</m:mi> <m:mo>-</m:mo> <m:mi>k</m:mi> <m:mo>+</m:mo> <m:mi>1</m:mi> </m:mrow> <m:mo>)</m:mo> </m:mrow> </m:mrow> <m:mrow> <m:mrow> <m:mi>k</m:mi> <m:mo></m:mo> <m:mrow> <m:mo>(</m:mo> <m:mrow> <m:mi>k</m:mi> <m:mo>-</m:mo> <m:mi>1</m:mi> </m:mrow> <m:mo>)</m:mo> </m:mrow> <m:mo></m:mo> <m:mi>...</m:mi> <m:mo></m:mo> <m:mi>1</m:mi> </m:mrow> </m:mrow> </m:mfrac> </m:mrow> </m:math> </equation> <para>And thus:</para> <informalequation> <m:math display="block"> <m:mrow> <m:mrow> <m:mrow> <m:mo>(</m:mo> <m:mrow> <m:mtable> <m:mtr> <m:mtd> <m:mi>49</m:mi> </m:mtd> </m:mtr> <m:mtr> <m:mtd> <m:mi>6</m:mi> </m:mtd> </m:mtr> </m:mtable> </m:mrow> <m:mo>)</m:mo> </m:mrow> </m:mrow> <m:mo>=</m:mo> <m:mfrac> <m:mrow> <m:mrow> <m:mi>49</m:mi> <m:mo>×</m:mo> <m:mi>48</m:mi> <m:mo>×</m:mo> <m:mi>47</m:mi> <m:mo>×</m:mo> <m:mi>46</m:mi> <m:mo>×</m:mo> <m:mi>45</m:mi> <m:mo>×</m:mo> <m:mi>44</m:mi> </m:mrow> </m:mrow> <m:mrow> <m:mrow> <m:mi>6</m:mi> <m:mo>×</m:mo> <m:mi>5</m:mi> <m:mo>×</m:mo> <m:mi>4</m:mi> <m:mo>×</m:mo> <m:mi>3</m:mi> <m:mo>×</m:mo> <m:mi>2</m:mi> <m:mo>×</m:mo> <m:mi>1</m:mi> </m:mrow> </m:mrow> </m:mfrac> <m:mo>=</m:mo> <m:mi>13983816</m:mi> </m:mrow> </m:math> </informalequation> <para>We calculate numerator and denominator in two separate loops:</para> <programlisting language="java">public class Lottery { public static void main(String[] args) { // Input values: final int totalNumberCount = 49, drawnNumberCount = 6; // No changes below this line // Numerator loop long numerator = 1; for (int i = totalNumberCount - drawnNumberCount + 1; i <= totalNumberCount; i++) { numerator *= i; } // Denominator loop calculating the "smaller" factorial long factorial = 1; for (int i = 2; i <= drawnNumberCount; i++) { factorial *= i; } System.out.println("Your chance to win when drawing " + drawnNumberCount + " out of " + totalNumberCount + " is 1 : " + (numerator / factorial)); } }</programlisting> </answer> </qandaentry> </qandadiv> </qandaset> </section> <section xml:id="sd1SectNumberguess"> <title>Guessing numbers</title> <qandaset defaultlabel="qanda" xml:id="sd1QandaNumberguess"> <qandadiv> <qandaentry> <question> <para>Write a simple game asking a user to guess a randomly chosen number.</para> <para>Your program will select an integer (pseudo) random number between zero and an exclusive configurable fixed upper limit e.g. 10. The user will have a configurable number of tries to guess the number in question. Each time after entering a number your program will respond with either of the following:</para> <glosslist> <glossentry> <glossterm>Congratulations, you won!</glossterm> <glossdef> <para>You won!</para> </glossdef> </glossentry> <glossentry> <glossterm>You lost!</glossterm> <glossdef> <para>Game over, try another run?</para> </glossdef> </glossentry> <glossentry> <glossterm>Game continues, either of:</glossterm> <glossdef> <itemizedlist> <listitem> <para>Number is too low</para> </listitem> <listitem> <para>Number is too high</para> </listitem> </itemizedlist> </glossdef> </glossentry> </glosslist> <para>The system offers a maximum number of tries e.g. 6. In the following example the system initially selected the secret number 5. A possible dialogue looks like:</para> <screen>Try to guess my secret number between 0 and 10: You have 5 attempts Input your guess:4 Value is too low Input your guess:6 Value is too high Input your guess:5 Congratulations, you won!</screen> <para>Regarding reading user input and creating random numbers please use the following recipe to get started:</para> <programlisting language="java">package ... import java.util.Random; ... public static void main(String[] args) { // Add some parameter here e.g. range of number to be guessed, // and number of tries. final int randomValue = new Random() // Selecting a pseudo random value .<link xlink:href="javaapi://java.util.Random#nextInt(int)">nextInt(11)</link>; // between 0 and 10 (inclusive). // ToDo: complete the implementation }</programlisting> </question> <answer> <programlisting language="java">final int maxValueInclusive = 10, // Guessing a value from 0 to this value (inclusive) numOfUserAttempts = 5, // User will have this number of tries guessing the random value. randomValue = // Create a random value between 0 new Random().nextInt( // and maxValueInclusive. maxValueInclusive + 1); System.out.println("Try to guess my secret number in between 0 and " + maxValueInclusive + ":"); System.out.println("You have " + numOfUserAttempts + " attempts"); final Scanner scan = new Scanner(System.in)); boolean numberWasFound = false; for (int i = 0; i < numOfUserAttempts; i++) { System.out.print("Input your guess:"); final int userGuess = scan.nextInt(); if (userGuess < randomValue) { System.out.println("Number is too low"); } else if (randomValue < userGuess) { System.out.println("Number is too high"); } else { numberWasFound = true; break; } } if (numberWasFound) { System.out.println("Congratulations, you won!"); } else { System.out.println("Game over, try another run?"); }</programlisting> <para>In case you don't like <code>break</code> statements the following variant also solves the problem:</para> <programlisting language="none">... boolean numberWasFound = false; for (int i = 0; <emphasis role="red">!numberWasFound &&</emphasis> i < numOfUserAttempts; i++) { ... } else { numberWasFound = true; <emphasis role="red">// No »break« statement required anymore</emphasis> } } ...</programlisting> </answer> </qandaentry> </qandadiv> </qandaset> </section> <section xml:id="sd1SectionMinimalDivideFirst20"> <title>Smallest multiple</title> <qandaset defaultlabel="qanda" xml:id="sw1QandaFintMinimumDivideFirst20"> <qandadiv> <qandaentry> <question> <para>2520 is the smallest number that can be divided by each of the numbers from 2 to 10 without any remainder.</para> <para>What is the smallest positive number that is evenly divisible by all of the numbers from 1 to 20?</para> <tip> <para>The remainder operator <quote xlink:href="https://docs.oracle.com/javase/specs/jls/se7/html/jls-15.html#jls-15.17.3">%</quote> allows for testing whether a given integer value <code language="java">n</code> can be divided by an another integer value <code language="java">k</code> without remainder.</para> <para>Increment an integer candidate in a loop till the desired condition is being fulfilled.</para> </tip> </question> <answer> <para>We propose the following solution:</para> <programlisting language="java">final int highestDivisor = 20; // May be adjusted to other limits. int candidate = highestDivisor; // start with highest divisor. boolean atLeastOneRemainder; do { candidate++; // next candidate value. atLeastOneRemainder = false; for (int i = highestDivisor; 2 <= i; i--) { // Higher values are more likely having a remainder atLeastOneRemainder = 0 != candidate % i; // Continue outer while, if (atLeastOneRemainder) { // Is there a non-zero remainder? break; // leave current for loop. } } } while (atLeastOneRemainder); // Increase candidate further? System.out.println(candidate); // Print final result </programlisting> <para>The assignment <code language="java">atLeastOneRemainder = 0 != candidate % i</code> deserves an explanation. Additional braces help understanding the expression:</para> <programlisting language="java">atLeastOneRemainder = (0 != (candidate % i)) <emphasis role="red">╲ ╲ ╱</emphasis> <emphasis role="red">╲</emphasis> int <emphasis role="red">╲ ╱</emphasis> boolean</programlisting> <para>This is fully equivalent to the more explicit code:</para> <programlisting language="java">if (0 == (candidate % i)) { atLeastOneRemainder = false; } else { atLeastOneRemainder = true; }</programlisting> <para>Executing this code results in 232792560 for the smallest desired value.</para> </answer> </qandaentry> </qandadiv> </qandaset> <qandaset defaultlabel="qanda" xml:id="sw1QandaFintMinimumDivideFirst20ByHand"> <title>Smallest multiple, purely algebraic solution</title> <qandadiv> <qandaentry> <question> <para>Solving the previous exercise by a program is quite a no-brainer (from an experienced software developer's point of view). Provide a different solution purely based on algebraic considerations. In other words: Solve the exercice using paper and pencil only.</para> <tip> <para>Consider the underlying prime factors of all values from [2, 3, ...20].</para> </tip> </question> <answer> <para>We decompose each value within [2, 3, ...20] into its prime factors:</para> <informaltable border="1"> <tr> <th rowspan="2" valign="top">Value</th> <th colspan="12">Contributing prime factors</th> </tr> <tr> <td colspan="4">2</td> <td colspan="2">3</td> <td>5</td> <td>7</td> <td>11</td> <td>13</td> <td>17</td> <td>19</td> </tr> <tr> <td align="right">2</td> <td>2</td> <td/> <td/> <td/> <td/> <td/> <td/> <td/> <td/> <td/> <td/> <td/> </tr> <tr> <td align="right">3</td> <td/> <td/> <td/> <td/> <td>3</td> <td/> <td/> <td/> <td/> <td/> <td/> <td/> </tr> <tr> <td align="right">4</td> <td>2</td> <td>2</td> <td/> <td/> <td/> <td/> <td/> <td/> <td/> <td/> <td/> <td/> </tr> <tr> <td align="right">5</td> <td/> <td/> <td/> <td/> <td/> <td/> <td>5</td> <td/> <td/> <td/> <td/> <td/> </tr> <tr> <td align="right">6</td> <td>2</td> <td/> <td/> <td/> <td>3</td> <td/> <td/> <td/> <td/> <td/> <td/> <td/> </tr> <tr> <td align="right">7</td> <td/> <td/> <td/> <td/> <td/> <td/> <td/> <td>7</td> <td/> <td/> <td/> <td/> </tr> <tr> <td align="right">8</td> <td>2</td> <td>2</td> <td>2</td> <td/> <td/> <td/> <td/> <td/> <td/> <td/> <td/> <td/> </tr> <tr> <td align="right">9</td> <td/> <td/> <td/> <td/> <td>3</td> <td>3</td> <td/> <td/> <td/> <td/> <td/> <td/> </tr> <tr> <td align="right">10</td> <td>2</td> <td/> <td/> <td/> <td/> <td/> <td>5</td> <td/> <td/> <td/> <td/> <td/> </tr> <tr> <td align="right">11</td> <td/> <td/> <td/> <td/> <td/> <td/> <td/> <td/> <td>11</td> <td/> <td/> <td/> </tr> <tr> <td align="right">12</td> <td>2</td> <td>2</td> <td/> <td/> <td>3</td> <td/> <td/> <td/> <td/> <td/> <td/> <td/> </tr> <tr> <td align="right">13</td> <td/> <td/> <td/> <td/> <td/> <td/> <td/> <td/> <td/> <td>13</td> <td/> <td/> </tr> <tr> <td align="right">14</td> <td>2</td> <td/> <td/> <td/> <td/> <td/> <td/> <td>7</td> <td/> <td/> <td/> <td/> </tr> <tr> <td align="right">15</td> <td/> <td/> <td/> <td/> <td>3</td> <td/> <td>5</td> <td/> <td/> <td/> <td/> <td/> </tr> <tr> <td align="right">16</td> <td>2</td> <td>2</td> <td>2</td> <td>2</td> <td/> <td/> <td/> <td/> <td/> <td/> <td/> <td/> </tr> <tr> <td align="right">17</td> <td/> <td/> <td/> <td/> <td/> <td/> <td/> <td/> <td/> <td/> <td>17</td> <td/> </tr> <tr> <td align="right">18</td> <td>2</td> <td/> <td/> <td/> <td>3</td> <td>3</td> <td/> <td/> <td/> <td/> <td/> <td/> </tr> <tr> <td align="right">19</td> <td/> <td/> <td/> <td/> <td/> <td/> <td/> <td/> <td/> <td/> <td/> <td>19</td> </tr> <tr> <td align="right">20</td> <td>2</td> <td>2</td> <td/> <td/> <td/> <td/> <td>5</td> <td/> <td/> <td/> <td/> <td/> </tr> </informaltable> <para>As expected we find an identical value for the desired smallest integer value of 2*2*2*2*3*3*5*7*11*13*17*19 = 232792560 which is the <link xlink:href="https://en.wikipedia.org/wiki/Least_common_multiple">least common multiple</link> of [2, 3, ...20].</para> </answer> </qandaentry> </qandadiv> </qandaset> </section> <section xml:id="sw1SectionPythagoreanTriples"> <title>Pythagorean triples</title> <qandaset defaultlabel="qanda" xml:id="sw1QandaPythagoreanTriples1"> <qandadiv> <qandaentry> <question> <para><link xlink:href="https://en.wikipedia.org/wiki/Pythagorean_triple">Pythagorean triples</link> are integer combinations of three values being related by the <link xlink:href="https://en.wikipedia.org/wiki/Pythagorean_theorem">Pythagorean theorem</link>:</para> <mediaobject> <imageobject> <imagedata fileref="Fig/phythagorean.svg"/> </imageobject> </mediaobject> <para>Some integer triples do exist e.g.:</para> <itemizedlist> <listitem> <informalequation> <m:math display="block"> <m:mrow> <m:mrow> <m:msup> <m:mi>3</m:mi> <m:mi>2</m:mi> </m:msup> <m:mo>+</m:mo> <m:msup> <m:mi>4</m:mi> <m:mi>2</m:mi> </m:msup> </m:mrow> <m:mo>=</m:mo> <m:msup> <m:mi>5</m:mi> <m:mi>2</m:mi> </m:msup> </m:mrow> </m:math> </informalequation> </listitem> <listitem> <informalequation> <m:math display="block"> <m:mrow> <m:mrow> <m:msup> <m:mi>6</m:mi> <m:mi>2</m:mi> </m:msup> <m:mo>+</m:mo> <m:msup> <m:mi>8</m:mi> <m:mi>2</m:mi> </m:msup> </m:mrow> <m:mo>=</m:mo> <m:msup> <m:mi>10</m:mi> <m:mi>2</m:mi> </m:msup> </m:mrow> </m:math> </informalequation> </listitem> <listitem> <informalequation> <m:math display="block"> <m:mrow> <m:mrow> <m:msup> <m:mi>5</m:mi> <m:mi>2</m:mi> </m:msup> <m:mo>+</m:mo> <m:msup> <m:mi>12</m:mi> <m:mi>2</m:mi> </m:msup> </m:mrow> <m:mo>=</m:mo> <m:msup> <m:mi>13</m:mi> <m:mi>2</m:mi> </m:msup> </m:mrow> </m:math> </informalequation> </listitem> </itemizedlist> <para>For most combinations however at least one value will be of real rather than of integer value e.g.:</para> <itemizedlist> <listitem> <informalequation> <m:math display="block"> <m:mrow> <m:mrow> <m:msup> <m:mi>3</m:mi> <m:mi>2</m:mi> </m:msup> <m:mo>+</m:mo> <m:msup> <m:mi>5</m:mi> <m:mi>2</m:mi> </m:msup> </m:mrow> <m:mo>=</m:mo> <m:msup> <m:mi>5,83095...</m:mi> <m:mi>2</m:mi> </m:msup> </m:mrow> </m:math> </informalequation> </listitem> <listitem> <informalequation> <m:math display="block"> <m:mrow> <m:mrow> <m:msup> <m:mi>5</m:mi> <m:mi>2</m:mi> </m:msup> <m:mo>+</m:mo> <m:msup> <m:mi>4,8989...</m:mi> <m:mi>2</m:mi> </m:msup> </m:mrow> <m:mo>=</m:mo> <m:msup> <m:mi>7</m:mi> <m:mi>2</m:mi> </m:msup> </m:mrow> </m:math> </informalequation> </listitem> </itemizedlist> <para>Find all <link xlink:href="https://en.wikipedia.org/wiki/Pythagorean_triple">Pythagorean triples</link> <inlineequation> <m:math display="inline"> <m:mrow> <m:mo>(</m:mo> <m:mrow> <m:mi>a</m:mi> <m:mo>,</m:mo> <m:mi>b</m:mi> <m:mo>,</m:mo> <m:mi>c</m:mi> </m:mrow> <m:mo>)</m:mo> </m:mrow> </m:math> </inlineequation> of non-zero integer values being smaller than 100 each. Keep the limit of 100 flexible.</para> <tip> <para>Think of creating all possible triples <inlineequation> <m:math display="inline"> <m:mrow> <m:mo>(</m:mo> <m:mrow> <m:mi>a</m:mi> <m:mo>,</m:mo> <m:mi>b</m:mi> <m:mo>,</m:mo> <m:mi>c</m:mi> </m:mrow> <m:mo>)</m:mo> </m:mrow> </m:math> </inlineequation> not yet obeying any restrictions at all:</para> <informaltable border="1"> <tr> <th>a</th> <th>b</th> <th>c</th> </tr> <tr> <td>1</td> <td>1</td> <td>2</td> </tr> <tr> <td>2</td> <td>1</td> <td>2</td> </tr> <tr> <td>...</td> <td>...</td> <td>...</td> </tr> <tr> <td>99</td> <td>99</td> <td>100</td> </tr> </informaltable> <para>Why does an upper value of 99 appears here for a and b? Why do we have a lower bond of 2 for the variable c?</para> </tip> <tip> <para>Consider using three nested loops for creating all possible combinations. Do not yet bother about possible duplicates. Your result output may look like:</para> <screen>Found (4, 3, 5) Found (3, 4, 5) Found (8, 6, 10) Found (6, 8, 10) ...</screen> </tip> </question> <answer> <para>A value of e.g. b == 100 would imply a == 0 contradicting the description. Likewise c == 1 wouls imply either a == 0 or b == 0;</para> <para>We create all possible combinations by using three nested loops and filtering for the desired results:</para> <programlisting language="java">final int LIMIT = 100; for (int c = 1; c <= LIMIT; c++) { for (int b = 1; b < LIMIT; b++) { for (int a = 1; a < LIMIT; a++) { if (a * a + b * b == c * c ) { // Limit output by filtering for pythagorean triples; System.out.println("Found (" + a + ", " + "" + b + ", " + c + ")"); } } } }</programlisting> <para>This results in:</para> <screen>Found (4, 3, 5) Found (3, 4, 5) Found (8, 6, 10) Found (6, 8, 10) Found (12, 5, 13) ... Found (96, 28, 100) Found (80, 60, 100) Found (60, 80, 100) Found (28, 96, 100)</screen> <para>Note duplicates like <code>(4, 3, 5)</code> and <code>(3, 4, 5)</code> being present in the above list</para> </answer> </qandaentry> </qandadiv> </qandaset> <qandaset defaultlabel="qanda" xml:id="sw1QandaPythagoreanTriplesNoDuplicates"> <title>Avoiding duplicates and gaining performance</title> <qandadiv> <qandaentry> <question> <para>There are several issues with the previous solution:</para> <orderedlist> <listitem> <para>It creates a great number of combinations like <inlineequation> <m:math display="inline"> <m:mrow> <m:mo>(</m:mo> <m:mrow> <m:mn>4</m:mn> <m:mo>,</m:mo> <m:mn>4</m:mn> <m:mo>,</m:mo> <m:mn>5</m:mn> </m:mrow> <m:mo>)</m:mo> </m:mrow> </m:math> </inlineequation> which could be easily ruled out beforehand rather then creating and filtering them.</para> <para>The former solution filters <inlineequation> <m:math display="inline"> <m:msup> <m:mi>99</m:mi> <m:mi>3</m:mi> </m:msup> </m:math> </inlineequation>combinations or roughly one million.</para> </listitem> <listitem> <para>Triples having identical values of <code>a</code> and <code>b</code> in different order like <code>(3, 4, 5)</code> and <code>(4, 3, 5)</code> are equivalent. For this reason we look for ordered triples only.</para> </listitem> </orderedlist> <para>The problem can thus be restated to find the set of all triples <inlineequation> <m:math display="inline"> <m:mrow> <m:mo>(</m:mo> <m:mrow> <m:mi>a</m:mi> <m:mo>,</m:mo> <m:mi>b</m:mi> <m:mo>,</m:mo> <m:mi>c</m:mi> </m:mrow> <m:mo>)</m:mo> <m:mo>∈</m:mo> <m:mrow> <m:msup> <m:mrow> <m:mo>[</m:mo> <m:mrow> <m:mn>1</m:mn> <m:mo>,</m:mo> <m:mi>LIMIT</m:mi> </m:mrow> <m:mo>]</m:mo> </m:mrow> <m:mi>3</m:mi> </m:msup> </m:mrow> </m:mrow> </m:math> </inlineequation> simultaneously obeying:</para> <orderedlist> <listitem xml:id="sw1PhytagoreanTripletCondition1"> <para><inlineequation> <m:math display="inline"> <m:mrow> <m:mi>a</m:mi> <m:mo>≤</m:mo> <m:mi>b</m:mi> <m:mo><</m:mo> <m:mi>c</m:mi> </m:mrow> </m:math> </inlineequation></para> </listitem> <listitem> <para><inlineequation> <m:math display="inline"> <m:mrow> <m:mrow> <m:msup> <m:mi>a</m:mi> <m:mn>2</m:mn> </m:msup> <m:mo>+</m:mo> <m:msup> <m:mi>b</m:mi> <m:mn>2</m:mn> </m:msup> </m:mrow> <m:mo>=</m:mo> <m:msup> <m:mi>c</m:mi> <m:mn>2</m:mn> </m:msup> </m:mrow> </m:math> </inlineequation></para> </listitem> </orderedlist> <para>Your solution shall account for both the number of combinations being evaluated and the number of Pythagorean triples being found creating a final line like:</para> <screen>... (60, 63, 87) (60, 80,100) (65, 72, 97) 52 triples found by filtering 33338 combinations</screen> <para>Your solution should find all 52 triples by filtering from at most 33338 combinations. If you do need less combinations in the first place please let me know. I'm more than happy publishing an enhanced solution.</para> </question> <answer> <para>Based on our previous solution we introduce the following changes:</para> <orderedlist> <listitem> <para>We start with the rectangle's smaller leg:</para> <programlisting language="java">... for (int a = 1; a < LIMIT - 1; a++) { ... } ...</programlisting> <note> <itemizedlist> <listitem> <para>Our rectangle's legs <code>a</code> and <code>b</code> must differ. Otherwise <inlineequation> <m:math display="inline"> <m:mrow> <m:mrow> <m:msup> <m:mi>a</m:mi> <m:mi>2</m:mi> </m:msup> <m:mo>+</m:mo> <m:msup> <m:mi>a</m:mi> <m:mi>2</m:mi> </m:msup> </m:mrow> <m:mo>=</m:mo> <m:mrow> <m:mi>2</m:mi> <m:mo></m:mo> <m:msup> <m:mi>a</m:mi> <m:mi>2</m:mi> </m:msup> </m:mrow> <m:mo>=</m:mo> <m:msup> <m:mi>c</m:mi> <m:mi>2</m:mi> </m:msup> </m:mrow> </m:math> </inlineequation> would imply <inlineequation> <m:math display="inline"> <m:mrow> <m:mi>c</m:mi> <m:mo>=</m:mo> <m:mrow> <m:mi>a</m:mi> <m:mo></m:mo> <m:msqrt> <m:mi>2</m:mi> </m:msqrt> </m:mrow> </m:mrow> </m:math> </inlineequation> which cannot be satisfied for natural numbers.</para> </listitem> <listitem> <para>From a rectangular triangle's perspective <code>c</code> must be larger than both legs <code>a</code> and <code>b</code> respectively.</para> </listitem> <listitem> <para>We want our triples to be ordered. Thus <inlineequation> <m:math display="inline"> <m:mrow> <m:mi>0</m:mi> <m:mo><</m:mo> <m:mi>a</m:mi> <m:mo><</m:mo> <m:mi>b</m:mi> <m:mo><</m:mo> <m:mi>c</m:mi> <m:mo>≤</m:mo> <m:mi>LIMIT</m:mi> </m:mrow> </m:math> </inlineequation> must hold and the rectangle's leg <code>a</code> therefore can only exceed a value of <code>LIMIT - 2</code>.</para> </listitem> </itemizedlist> </note> </listitem> <listitem> <para>Since <inlineequation> <m:math display="inline"> <m:mrow> <m:mi>a</m:mi> <m:mo><</m:mo> <m:mi>b</m:mi> </m:mrow> </m:math> </inlineequation> holds the next inner loop is straightforward:</para> <programlisting language="java">... for (int b = a + 1; b < LIMIT; b++) { final int /* useful constants*/ aPlusB = a + b, aSquarePlusBsquare = a * a + b * b; ... } ...</programlisting> <note> <para>The two variables <code>aPlusB</code> and <code>aSquarePlusBsquare</code> will not have to be re-calculated inside the innermost loop yet to be defined.</para> </note> </listitem> <listitem> <para>We are dealing with triangles. c must thus be longer than the triangle's longest leg. The innermost loop will terminate on multiple conditions:</para> <programlisting language="java">... for (int c = b + 1; <emphasis role="red">c <= LIMIT</emphasis> && <emphasis role="red">c < aPlusB</emphasis> && // <emphasis role="red">c * c <= aSquarePlusBsquare</emphasis>; c++) { ...</programlisting> </listitem> <listitem> <para>Finally we re-write our filtering condition:</para> <programlisting language="java">... if (<emphasis role="red">aSquarePlusBsquare == c * c</emphasis>) { // Equivalent to a² + b² == c² System.out.format("(%2d, %2d, %3d)\n", a, b, c); }</programlisting> </listitem> </orderedlist> <para>Piecing together these snippets and adding two variables <code language="java">comparisons</code> and <code language="java">countTriples</code> for accounting yields our final solution:</para> <programlisting language="java">final int LIMIT = 100; int comparisons = 0, countTriples = 0; for (int a = 1; a < LIMIT - 1; a++) { for (int b = a + 1; b < LIMIT; b++) { final int aPlusB = a + b, aSquarePlusBsquare = a * a + b * b; for (int c = b + 1; // c must be longer than the maximum of a and b c <= LIMIT && c < aPlusB && // c must be smaller than the sum of a and b c * c <= aSquarePlusBsquare; // c² must not be larger than a² + b² c++) { if (aSquarePlusBsquare == c * c) { // Equivalent to a² + b² == c² System.out.format("(%2d, %2d, %3d)\n", a, b , c); countTriples++; } comparisons++; } } } System.out.println(countTriples + " triples found by filtering " + comparisons + " combinations"); </programlisting> </answer> </qandaentry> </qandadiv> </qandaset> </section> </section> </section> <section xml:id="sd1SectExternalLogicExercises"> <title>Logic related external exercises</title> <para>Solve:</para> <itemizedlist> <listitem> <para><link xlink:href="http://codingbat.com/java/Warmup-1">Warmup-1</link> excluding <link xlink:href="http://codingbat.com/prob/p191914">Warmup-1 > notString</link>.</para> </listitem> <listitem> <para><link xlink:href="http://codingbat.com/java/Logic-1">Logic-1</link>.</para> </listitem> </itemizedlist> </section> <section xml:id="sd1_statements_sect_usingJunit"> <title>Using automated tests.</title> <figure xml:id="sd1_statements_fig_codingBatTests"> <title>Response to coding errors</title> <mediaobject> <imageobject> <imagedata fileref="Fig/codingbat.svg"/> </imageobject> </mediaobject> </figure> <figure xml:id="sd1_statements_fig_unitTestExplanations"> <title>Unit test concept</title> <itemizedlist> <listitem> <para>Will be <link linkend="sd1_sect_unitTestExample">explained in detail</link>.</para> </listitem> <listitem> <para>Idea: Feed in samples, check results for correctness.</para> </listitem> <listitem> <para>Previous slide: <link xlink:href="https://codingbat.com/prob/p160543">Logic-1 > alarmClock</link></para> </listitem> <listitem> <para>Sample project at <link xlink:href="https://gitlab.mi.hdm-stuttgart.de/goik/GoikLectures/tree/master/Doc/Sd1/Ref/Statements/BasicUnitTest">MI Gitlab</link>.</para> </listitem> </itemizedlist> </figure> <figure xml:id="sd1_statements_fig_alarmWithErrors"> <title>alarmClock(...) with errors</title> <programlisting language="java">public class AlarmClock { /** Given a day of the week encoded as 0=Sun, 1=Mon,... */ static <co linkends="sd1_statements_fig_alarmWithErrors-1" xml:id="sd1_statements_fig_alarmWithErrors-1-co"/> public String alarmClock(int day, boolean vacation) { switch (day) { case 1: ... if (vacation) { return "off"; } else { return "10:00"; ...</programlisting> <calloutlist role="slideExclude"> <callout arearefs="sd1_statements_fig_alarmWithErrors-1-co" xml:id="sd1_statements_fig_alarmWithErrors-1"> <para>The static keyword is required here as being explained in <xref linkend="sd1SectClassMembers"/>.</para> </callout> </calloutlist> </figure> <figure xml:id="sd1_statements_fig_testingAlarm"> <title>Testing alarmClock(...)</title> <programlisting language="none">public class AlarmClockTest { @Test <co linkends="sd1_statements_fig_testingAlarm-1" xml:id="sd1_statements_fig_testingAlarm-1-co"/> public void test_1_false() { Assert.assertEquals( "7:00", AlarmClock.alarmClock(1, false)); } <emphasis role="red">▲</emphasis> <emphasis role="red">▲</emphasis> <emphasis role="red">▲</emphasis> ... <emphasis role="red">┃</emphasis> <emphasis role="red">┃</emphasis> <emphasis role="red">┃</emphasis> <emphasis role="red">Expected result</emphasis> <emphasis role="red">Input parameter</emphasis> @Test <emphasis role="red">┃</emphasis> <emphasis role="red">┃</emphasis> <emphasis role="red">┃</emphasis> public void test_0_false() { <emphasis role="red">▼</emphasis> <emphasis role="red">▼</emphasis> <emphasis role="red">▼</emphasis> Assert.assertEquals("10:00", AlarmClock.alarmClock(0, false)); } ...</programlisting> <calloutlist role="slideExclude"> <callout arearefs="sd1_statements_fig_testingAlarm-1-co" xml:id="sd1_statements_fig_testingAlarm-1"> <para>Explanation in <xref linkend="sd1_sect_unitTestExample"/>.</para> </callout> </calloutlist> </figure> <figure xml:id="Details"> <title>Testing alarmClock(...) details</title> <programlisting language="none">public class AlarmClockTest { <emphasis role="red">Input parameter</emphasis> @Test <emphasis role="red">┃</emphasis> <emphasis role="red">┃</emphasis> public void test_1_false() { <emphasis role="red">▼</emphasis> <emphasis role="red">▼</emphasis> final String <emphasis role="red">result</emphasis> = AlarmClock.alarmClock(1, false); <emphasis role="red">┗━━━━━━━━━━━━━━━┓</emphasis> <emphasis role="red">▼</emphasis> Assert.assertEquals( "7:00", <emphasis role="red">result</emphasis>); } <emphasis role="red">▲</emphasis> ... <emphasis role="red">┃</emphasis> <emphasis role="red">Expected result</emphasis></programlisting> </figure> </section> </chapter>