From 5056f162e30f49aa2b0a906d4ecb72772129fe9b Mon Sep 17 00:00:00 2001 From: "Dr. Martin Goik" <goik@hdm-stuttgart.de> Date: Thu, 21 May 2020 13:43:47 +0200 Subject: [PATCH] Enhanced X-Mas tree solution --- .../Ref/Statements/MoreFunXmasTree/pom.xml | 76 +++ .../java/de/hdm_stuttgart/mi/sd1/Dummy.java | 25 + .../java/de/hdm_stuttgart/mi/sd1/Xmas.java | 90 +++ .../hdm_stuttgart/mi/sd1/XmasUsingFormat.java | 53 ++ Doc/Sd1/statements.xml | 515 ++++++++++++------ 5 files changed, 595 insertions(+), 164 deletions(-) create mode 100644 Doc/Sd1/Ref/Statements/MoreFunXmasTree/pom.xml create mode 100644 Doc/Sd1/Ref/Statements/MoreFunXmasTree/src/main/java/de/hdm_stuttgart/mi/sd1/Dummy.java create mode 100644 Doc/Sd1/Ref/Statements/MoreFunXmasTree/src/main/java/de/hdm_stuttgart/mi/sd1/Xmas.java create mode 100644 Doc/Sd1/Ref/Statements/MoreFunXmasTree/src/main/java/de/hdm_stuttgart/mi/sd1/XmasUsingFormat.java diff --git a/Doc/Sd1/Ref/Statements/MoreFunXmasTree/pom.xml b/Doc/Sd1/Ref/Statements/MoreFunXmasTree/pom.xml new file mode 100644 index 000000000..af1a514e8 --- /dev/null +++ b/Doc/Sd1/Ref/Statements/MoreFunXmasTree/pom.xml @@ -0,0 +1,76 @@ +<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> + <modelVersion>4.0.0</modelVersion> + + <groupId>de.hdm_stuttgart.mi.sd1</groupId> + <artifactId>morefunxmastree</artifactId> + <version>0.9</version> + <packaging>jar</packaging> + + <name>morefunxmastree</name> + + <url>https://freedocs.mi.hdm-stuttgart.de/sd1_sect_mavenCli.html</url> + + <description>Exercise »More fun with Xmas trees«.</description> + + <properties> + <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> + </properties> + + <build> + <plugins> + + <plugin> + <groupId>org.apache.maven.plugins</groupId> + <artifactId>maven-compiler-plugin</artifactId> + <version>3.8.1</version> + <configuration> + <source>11</source> + <target>11</target> + </configuration> + </plugin> + + <plugin> + <groupId>org.apache.maven.plugins</groupId> + <artifactId>maven-javadoc-plugin</artifactId> + <version>3.1.1</version> + <configuration> + <linksource>true</linksource> + <additionalOptions> + <additionalOption>-html5</additionalOption> + </additionalOptions> + <javadocExecutable>${java.home}/bin/javadoc</javadocExecutable> + </configuration> + </plugin> + + <plugin> + <groupId>org.apache.maven.plugins</groupId> + <artifactId>maven-shade-plugin</artifactId> + <version>3.2.1</version> + <configuration> + <transformers> + <transformer + implementation="org.apache.maven.plugins.shade.resource.ManifestResourceTransformer"> + <manifestEntries> + <Main-Class>de.hdm_stuttgart.mi.sd1.App</Main-Class> + </manifestEntries> + </transformer> + </transformers> + </configuration> + <executions> + <execution> + <phase>package</phase> + <goals> + <goal>shade</goal> + </goals> + </execution> + </executions> + </plugin> + <plugin> + <groupId>org.apache.maven.plugins</groupId> + <artifactId>maven-site-plugin</artifactId> + <version>3.7.1</version> + </plugin> + </plugins> + </build> +</project> diff --git a/Doc/Sd1/Ref/Statements/MoreFunXmasTree/src/main/java/de/hdm_stuttgart/mi/sd1/Dummy.java b/Doc/Sd1/Ref/Statements/MoreFunXmasTree/src/main/java/de/hdm_stuttgart/mi/sd1/Dummy.java new file mode 100644 index 000000000..164929c3f --- /dev/null +++ b/Doc/Sd1/Ref/Statements/MoreFunXmasTree/src/main/java/de/hdm_stuttgart/mi/sd1/Dummy.java @@ -0,0 +1,25 @@ +package de.hdm_stuttgart.mi.sd1; + +public class Dummy { + public static void main(String[] args) { + System.out.print("\""); // Print a double quote " + System.out.print("Hello\n"); // Print 'Hello' followed by a new line. + System.out.print("\t Hello â£"); // Print an indented 'Hello' string. + System.out.println("\u2B95"); // Print a unicode right arrow ⮕ + + + + final int numberOfRowGroups = 5; + System.out.format("%"+ numberOfRowGroups + "s ", "\\ /"); + + System.out.println(); + final int repetitions = 3; + System.out.println("/_".repeat(repetitions)); + + System.out.println(); + final int numberOfSpaces = 6; + System.out.format("%"+ numberOfSpaces + "s ", ""); + System.out.print(":"); + } + +} diff --git a/Doc/Sd1/Ref/Statements/MoreFunXmasTree/src/main/java/de/hdm_stuttgart/mi/sd1/Xmas.java b/Doc/Sd1/Ref/Statements/MoreFunXmasTree/src/main/java/de/hdm_stuttgart/mi/sd1/Xmas.java new file mode 100644 index 000000000..b8da23880 --- /dev/null +++ b/Doc/Sd1/Ref/Statements/MoreFunXmasTree/src/main/java/de/hdm_stuttgart/mi/sd1/Xmas.java @@ -0,0 +1,90 @@ +package de.hdm_stuttgart.mi.sd1; + +/** + * Beginner's way of implementing the »More fun with X-mas trees« exercise. + */ +public class Xmas { + + public static void main(String[] args) { + + // Example: 5 row groups, tree body's loop index ranging from 0 to 4 + + // \ / Part 1: Printing tree's top. + // -->*<-- + // /_\ + // Row group index 0 /_\_\ Part 2: 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 + // /_/_/_/_/_/_/_\ + // [___] Part 3: Bottom trunk line. + + final int numberOfRowGroups = 5; // You may easily change this + // parameter. + // Printing tree's top + // + + // Tree's top first line + for (int x = 0; x < numberOfRowGroups + 1; x++) { // Printing the tree's "\ /" + // top. We need numberOfRows+1 + System.out.print(' '); // preceding spaces before + } // eventually printing the + System.out.println("\\ /"); // "\ /" String. + + // Tree's top second line + for (int x = 0; x < numberOfRowGroups - 1; x++) { // Printing the tree's top '-->*<--' + // We need numberOfRows-1 + System.out.print(' '); // preceding spaces + } // before printing the + System.out.println("-->*<--"); // "-->*<--" string. + + // Tree's top third line + for (int x = 0; x < numberOfRowGroups + 1; x++) { // The tree's lower top "/ \" line. + System.out.print(' '); // Again we need numberOfRowGroups+1 + } // preceding spaces. + System.out.println("/_\\"); + + // Part two: The tree's body + // + 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("/"); // Start of current row group's + for (int x = 0; x < rowGroup + 2;x++) { // first line tree body content + System.out.print("_\\"); // 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("/_"); + } + System.out.println("\\"); // finishing. + } + + // Part three: The tree's bottom trunk + // + for (int x = 0; x < numberOfRowGroups; x++) { // Indenting the bottom trunk ... + System.out.print(' '); + } + System.out.println("[___]"); // printing the trunk. + } + +} diff --git a/Doc/Sd1/Ref/Statements/MoreFunXmasTree/src/main/java/de/hdm_stuttgart/mi/sd1/XmasUsingFormat.java b/Doc/Sd1/Ref/Statements/MoreFunXmasTree/src/main/java/de/hdm_stuttgart/mi/sd1/XmasUsingFormat.java new file mode 100644 index 000000000..8722cd82f --- /dev/null +++ b/Doc/Sd1/Ref/Statements/MoreFunXmasTree/src/main/java/de/hdm_stuttgart/mi/sd1/XmasUsingFormat.java @@ -0,0 +1,53 @@ +package de.hdm_stuttgart.mi.sd1; + + +/** + * Simplified implementation replacing loops by {@link java.io.PrintStream#format(String, Object...)} and + * {@link String#repeat(int)}. + */ +public class XmasUsingFormat { + + public static void main(String[] args) { + + // Example: 5 row groups, tree body's loop index ranging from 0 to 4 + + // \ / Part 1: Printing tree's top. + // -->*<-- + // /_\ + // Row group index 0 /_\_\ Part 2: 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 + // /_/_/_/_/_/_/_\ + // [___] Part 3: Bottom trunk line. + + final int numberOfRowGroups = 5; // You may easily change this parameter. + + // Printing the tree's top + System.out.format("%"+ (numberOfRowGroups + 5) + "s\n", "\\ /"); + System.out.format("%"+ (numberOfRowGroups + 7) + "s\n", "-->*<--"); + System.out.format("%"+ (numberOfRowGroups + 5) + "s\n", "/_\\"); + + // Printing the tree's body + + // Loop printing the tree's body row group wise. + for (int rowGroup = 0; rowGroup < numberOfRowGroups; rowGroup++) { + + // First body line of current group + System.out.format("%"+ (numberOfRowGroups + rowGroup + 6) + "s\n", "/" + "_\\".repeat(rowGroup + 2)); + + // Second body line of current group + System.out.format + ("%"+ (numberOfRowGroups + rowGroup + 6) + "s\\\n", + "/_".repeat(rowGroup + 3)); + } + // Printing the tree's trunk + System.out.format("%"+ (numberOfRowGroups + 6) + "s\n", "[___]"); + } + +} diff --git a/Doc/Sd1/statements.xml b/Doc/Sd1/statements.xml index 6cd304c3f..a7cdefbf6 100644 --- a/Doc/Sd1/statements.xml +++ b/Doc/Sd1/statements.xml @@ -2802,185 +2802,372 @@ for (int row = 0; row < numberOfRows; row++) { </question> <answer> - <para>We start from a version being fully covered by our current - knowledge:</para> + <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/MoreFunXmasTree/src/main/java/de/hdm_stuttgart/mi/sd1/Xmas.java">MI + Gitlab</link> repository. We start from a version being fully + covered by our current knowledge by dissecting the problem. Our + aim is to print the following lines:</para> + + <programlisting language="none"> <emphasis + role="red">\ /</emphasis> <emphasis role="red">Part 1: Printing tree's top.</emphasis> + <emphasis role="red">-->*<--</emphasis> + <emphasis role="red">/_\</emphasis> +Row group index 0 /_\_\ Part 2: 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 showing invisible spaces by <quote>â£</quote>. + 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 obviously 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 <code>"\/"</code>. + Printing <emphasis role="red"><code>\</code></emphasis> in <xref + linkend="glo_Java"/> is surprisingly difficult since the + backslash character is being used to escape double quotes, + newline, tab, <productname>Unicode</productname> and other + characters within strings:</para> + + <programlisting language="none">System.out.print("<emphasis + role="red">\"</emphasis>"); // Print a double quote <emphasis + role="red">"</emphasis> +System.out.print("Hello<emphasis role="red">\n</emphasis>"); // Print 'Hello' followed by a <emphasis + role="red">new line</emphasis>. +System.out.print("<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.print("<emphasis role="red">\\</emphasis>"); // Print a single backslash <emphasis + role="red">\</emphasis> character</programlisting> + + <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 (â£) being represented by the space <code>' + '</code> character.</para> + + <para>Printing our tree's very top thus requires:</para> - <programlisting language="java">public static void main(String[] args) { + <informaltable border="0"> + <col width="80%"/> - // Example: 5 row groups, tree's body loop index ranging from 0 to 4 - - // \ / The tree's top. - // -->*<-- - // /_\ - // 0 /_\_\ Start of tree's body - // /_/_/_\ - // 1 /_\_\_\ - // /_/_/_/_\ - // 2 /_\_\_\_\ - // /_/_/_/_/_\ - // 3 /_\_\_\_\_\ - // /_/_/_/_/_/_\ - // 4 /_\_\_\_\_\_\ - // /_/_/_/_/_/_/_\ End of tree's body - // [___] Bottom trunk line. - - - final int numberOfRowGroups = 5; // You may easily change this - // value. - // Part one: The tree's top - // - for (int x = 0; x < numberOfRowGroups + 1; x++) { // Printing the tree's very - // top. We need numberOfRows+1 - System.out.print(' '); // preceding spaces - } // before printing the - System.out.println("\\ /"); // "\ /" String. - - for (int x = 0; x < numberOfRowGroups - 1; x++) { // Printing the tree's top '*' - // We need numberOfRows-1 - System.out.print(' '); // preceding spaces - } // before printing the - System.out.println("-->*<--"); // "-->*<--" string. - - for (int x = 0; x < numberOfRowGroups + 1; x++) { // The tree's lower top "/ \". - System.out.print(' '); // We need again numberOfRows+1 - } // preceding spaces. - System.out.println("/_\\"); + <col width="20%"/> - // Part two: The tree's body - // - for (int rowGroup = 0; // Outer loop printing the - rowGroup < numberOfRowGroups; rowGroup++) { // tree's body. + <tr> + <th>Code</th> - // First body line of current group - // - for (int x = 0; // Starting first line - x < numberOfRowGroups - rowGroup;x++) { // of row group with + <th>Result</th> + </tr> + + <tr> + <td valign="top"><programlisting language="none">for (int x = 0; x < numberOfRowGroups + 1; x++) { // Printing the tree's "\ /" 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>As you'll probably realize the expression + <code>numberOfRowGroups + 1</code> equals 6 in case of 5 row + groups like in the illustration given before. Printing our + tree's top next two of lines is straightforward:</para> + + <informaltable border="0"> + <col width="80%"/> + + <col width="20%"/> + + <tr> + <th>Code</th> + + <th>Result</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> + + <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> + + <para>We now show the loop's gory details:</para> + + <informaltable border="0"> + <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("/"); // Start of current row group's - for (int x = 0; x < rowGroup + 2;x++) { // first line tree body content - System.out.print("_\\"); // 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("/_"); - } - System.out.println("\\"); // finishing. + 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(); - // Part three: The tree's bottom trunk + // Second body line of current group // - for (int x = 0; x < numberOfRowGroups; x++) { // Indenting the bottom trunk ... - System.out.print(' '); + for (int x = 0; // Starting second line of row + x < numberOfRowGroups - rowGroup - 1; x++) { // group with (numberOfRows - + System.out.print(' '); // row - 1) space (â£) characters } - System.out.println("[___]"); // printing the trunk. -}</programlisting> + 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> - <para>This solution is a bit cumbersome: It involves a repeating - task namely indenting lines by a given amount of spaces.</para> - - <para>So far we have not yet introduced methods. In anticipation - of <link linkend="sd1SectClassMembers">class methods</link> we - provide an alternate solution introducing a method - <methodname>printIndented(...)</methodname> printing a given - string a configurable number of times being indented by a given - number of whitespace characters. This method uses <package - xlink:href="https://docs.oracle.com/javase/10/docs/api/java/lang/System.html">System</package>.<parameter - xlink:href="https://docs.oracle.com/javase/10/docs/api/java/lang/System.html#out">out</parameter>.<methodname - xlink:href="https://docs.oracle.com/javase/10/docs/api/java/io/PrintStream.html#format(java.lang.String,java.lang.Object...)">format(...)</methodname> - as in <xref - linkend="sd1QandaSquareNumberTableFormatted"/>.</para> - - <para>Using <methodname>printIndented(...)</methodname> - considerable enhances our code's readability. We do no longer - need the <quote>inner</quote> loops. On the downside fiddling - with values describing indentations and repetitions is still - being required:</para> - - <programlisting language="java">public class XmasTree { - - // Helper method. - // - // Print string s a number of times defined by the repeat value being preceded by a number - // of whitespace characters ' ' given by the indentation value. - // Thus printIndent(5, "axb", 2) will generate "_____axbaxb" with "_" denoting white space. - // - private static void printIndent(final int indentation, final String s, final int repeat) { - if (0 < indentation) { - final String format = "%" + indentation + "s"; - System.out.format(format, ""); - } - for (int i = 0; i < repeat; i++) { - System.out.print(s); - } - } + <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> - public static void main(String[] args) { + <para>Finally printing the tree's trunk:</para> - // Example: 5 row groups of two lines each, tree's body loop index ranging from 0 to 4 - // - // Each groups consists of two lines having identical structure among all groups: - // Group n: /_\_\ ... _\ «/» followed by repeating «_\» n+2 times - // /_/_ ... /_\ Repeating «/_» n+3 times ending with «\» - - // \ / The tree's top. - // -->*<-- - // /_\ - // 0 /_\_\ Start of tree's body - // /_/_/_\ - // 1 /_\_\_\ - // /_/_/_/_\ - // 2 /_\_\_\_\ - // /_/_/_/_/_\ - // 3 /_\_\_\_\_\ - // /_/_/_/_/_/_\ - // 4 /_\_\_\_\_\_\ - // /_/_/_/_/_/_/_\ End of tree's body - // [___] Bottom trunk line. - - - final int numberOfRowGroups = 5; // You may easily change this value. - - // Part one: The tree's top - // - printIndent(numberOfRowGroups + 1, "\\ /\n" ,1); - printIndent(numberOfRowGroups - 1, "-->*<--\n",1); - printIndent(numberOfRowGroups + 1, "/_\\\n" ,1); - - // Part two: The tree's body - // - for (int rowGroup = 0; // Outer loop printing the - rowGroup < numberOfRowGroups; rowGroup++) { // tree's body group by group. - - printIndent(numberOfRowGroups - rowGroup,"/", 1);// Starting first line of group - printIndent(0,"_\\", rowGroup + 2); // print leaves - System.out.println(); // Finishing first line of group. - - // Second body line of current group - // - printIndent(numberOfRowGroups - rowGroup - 1, "", 1); // Starting second line - printIndent(0, "/_", rowGroup + 3); // of row group - - System.out.println("\\"); // Finish second line of group. - } + <informaltable border="0"> + <col width="80%"/> - // Part three: The tree's bottom trunk - // - printIndent (numberOfRowGroups, "[___]", 1); // Indenting the bottom trunk ... - } -}</programlisting> + <col width="20%"/> + + <tr> + <th>Code</th> + + <th>Result</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>So far quite an amount of energy has been invested into + printing fixed numbers of space characters using loop + statements. The + <classname>System</classname><code>.</code><property>out</property><code>.</code><methodname + xlink:href="https://docs.oracle.com/en/java/javase/14/docs/api/java.base/java/io/PrintStream.html#format(java.lang.String,java.lang.Object...)">format()</methodname> + method as in <xref + linkend="sd1QandaSquareNumberTableFormatted"/> allows for + getting rid of these loops completely. As an example printing + the tree's top simplifies to:</para> + + <informaltable border="0"> + <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 < numberOfRowGroups + 1; x++) { + System.out.print(' '); +} +System.out.println("\\ /"); </programlisting></td> + + <td rowspan="3" valign="top"><screen>â£â£â£â£â£â£\ /</screen></td> + </tr> + + <tr> + <th>Indenting using format()</th> + </tr> + + <tr> + <td valign="top"><programlisting>System.out.format("%"+ numberOfRowGroups + "s ", "\\ /");</programlisting></td> + </tr> + </informaltable> + + <para>Moreover starting with <xref linkend="glo_Java"/> 11 the + <classname + xlink:href="https://docs.oracle.com/en/java/javase/14/docs/api/java.base/java/lang/String.html">String</classname> + class features a <methodname + xlink:href="https://docs.oracle.com/en/java/javase/14/docs/api/java.base/java/lang/String.html#repeat(int)">repeat()</methodname> + method:</para> + + <informaltable border="0"> + <col width="70%"/> + + <col width="30%"/> + + <tr> + <th>String repetitions using loops</th> + + <th>Common result</th> + </tr> + + <tr> + <td valign="top"><programlisting language="none">final int repetitions = 3; +for (int i = 0; i < repetitions; i++) { + System.out.print("/_"); +}</programlisting></td> + + <td rowspan="3" valign="top"><screen>/_/_/_</screen></td> + </tr> + + <tr> + <th>Using <methodname + xlink:href="https://docs.oracle.com/en/java/javase/14/docs/api/java.base/java/lang/String.html#repeat(int)">repeat()</methodname> + instead</th> + </tr> + + <tr> + <td valign="top"><programlisting>final int repetitions = 3; +System.out.println("/_".repeat(repetitions));</programlisting></td> + </tr> + </informaltable> + + <para>Combining both methods completely obsoletes all + <quote>inner</quote> loops thereby considerably enhancing our + code's readability as being shown in the <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</link> + implementation.</para> + + <programlisting language="java">final int numberOfRowGroups = 5; // You may easily change this parameter. + +// Printing the tree's top +System.out.format("%"+ (numberOfRowGroups + 5) + "s\n", "\\ /"); +System.out.format("%"+ (numberOfRowGroups + 7) + "s\n", "-->*<--"); +System.out.format("%"+ (numberOfRowGroups + 5) + "s\n", "/_\\"); + +// Printing the tree's body + +// Loop printing the tree's body row group wise. +for (int rowGroup = 0; rowGroup < numberOfRowGroups; rowGroup++) { + + // First body line of current group + System.out.format("%"+ (numberOfRowGroups + rowGroup + 6) + "s\n", "/" + "_\\".repeat(rowGroup + 2)); + + // Second body line of current group + System.out.format + ("%"+ (numberOfRowGroups + rowGroup + 6) + "s\\\n", + "/_".repeat(rowGroup + 3)); + } +// Printing the tree's trunk +System.out.format("%"+ (numberOfRowGroups + 6) + "s\n", "[___]"); +</programlisting> - <para>Both variants allow for setting e.g. <code + <para>Both implementation variants allow for setting e.g. <code language="java">final int numberOfRowGroups = 8</code> creating - a larger tree (albeit having the same trunk size):</para> + trees of different sizes albeit sharing the same trunk + size:</para> <screen> \ / -->*<-- -- GitLab