diff --git a/Doc/Sd1/Ref/Screen/lotto-spiel77.jpg b/Doc/Sd1/Ref/Screen/lotto-spiel77.jpg new file mode 100644 index 0000000000000000000000000000000000000000..14a5ee848905e243d2511cf82c2bcac98ae5d29f Binary files /dev/null and b/Doc/Sd1/Ref/Screen/lotto-spiel77.jpg differ diff --git a/Doc/Sd1/Ref/Screen/superenalotto.gif b/Doc/Sd1/Ref/Screen/superenalotto.gif new file mode 100644 index 0000000000000000000000000000000000000000..c572e9427bd724280677282d95f13162d86ce3d4 Binary files /dev/null and b/Doc/Sd1/Ref/Screen/superenalotto.gif differ diff --git a/Doc/Sd1/objectsClasses.xml b/Doc/Sd1/objectsClasses.xml index bfba5544eb442ce33289e77947d38e69eebccef2..6130ddfa28d4951205af9ae9b959c693952e2fd3 100644 --- a/Doc/Sd1/objectsClasses.xml +++ b/Doc/Sd1/objectsClasses.xml @@ -2126,6 +2126,482 @@ long sum = (long)a + b;</programlisting> </section> </section> + <section xml:id="sd1SectLotteryRevisited"> + <title>Lotteries revisited</title> + + <qandaset defaultlabel="qanda" xml:id="sd1QandaLotteryRevisited"> + <qandadiv> + <qandaentry> + <question> + <para>Wrap your implementation from <xref + linkend="sd1SectPlayingLottery"/> into a single method + <methodname>binomial(int n, int k)</methodname>. Then manually + calculate smaller values such as <inlineequation> + <m:math display="inline"> + <m:mrow> + <m:mrow> + <m:mo>(</m:mo> + + <m:mrow> + <m:mtable> + <m:mtr> + <m:mtd> + <m:mi>4</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:math> + </inlineequation> beforehand to define corresponding unit + tests. Do not forget: <inlineequation> + <m:math display="inline"> + <m:mrow> + <m:mrow> + <m:mo>(</m:mo> + + <m:mrow> + <m:mtable> + <m:mtr> + <m:mtd> + <m:mi>1</m:mi> + </m:mtd> + </m:mtr> + + <m:mtr> + <m:mtd> + <m:mi>0</m:mi> + </m:mtd> + </m:mtr> + </m:mtable> + </m:mrow> + + <m:mo>)</m:mo> + </m:mrow> + </m:mrow> + </m:math> + </inlineequation> and <inlineequation> + <m:math display="inline"> + <m:mrow> + <m:mrow> + <m:mo>(</m:mo> + + <m:mrow> + <m:mtable> + <m:mtr> + <m:mtd> + <m:mi>0</m:mi> + </m:mtd> + </m:mtr> + + <m:mtr> + <m:mtd> + <m:mi>0</m:mi> + </m:mtd> + </m:mtr> + </m:mtable> + </m:mrow> + + <m:mo>)</m:mo> + </m:mrow> + </m:mrow> + </m:math> + </inlineequation> are valid expressions as well.</para> + + <para>Manually calculate <inlineequation> + <m:math display="inline"> + <m:mrow> + <m:mrow> + <m:mo>(</m:mo> + + <m:mrow> + <m:mtable> + <m:mtr> + <m:mtd> + <m:mi>22</m:mi> + </m:mtd> + </m:mtr> + + <m:mtr> + <m:mtd> + <m:mi>2</m:mi> + </m:mtd> + </m:mtr> + </m:mtable> + </m:mrow> + + <m:mo>)</m:mo> + </m:mrow> + </m:mrow> + </m:math> + </inlineequation> and <inlineequation> + <m:math display="inline"> + <m:mrow> + <m:mrow> + <m:mo>(</m:mo> + + <m:mrow> + <m:mtable> + <m:mtr> + <m:mtd> + <m:mi>22</m:mi> + </m:mtd> + </m:mtr> + + <m:mtr> + <m:mtd> + <m:mi>20</m:mi> + </m:mtd> + </m:mtr> + </m:mtable> + </m:mrow> + + <m:mo>)</m:mo> + </m:mrow> + </m:mrow> + </m:math> + </inlineequation> beforehand to add more unit tests. Your + implementation is likely to fail for (at least) one of these. + Why does this happen? May you propose a solution? Keep in mind + the idea to deal with <quote>6 out of 90</quote> lottery + situations.</para> + + <tip> + <para>Be careful about possible arithmetic overflows.</para> + </tip> + </question> + + <answer> + <para>A complete implementation among with some unit tests is + available at:</para> + + <annotation role="make"> + <para role="eclipse">Sd1/Binomial/V1</para> + </annotation> + + <para>This actually wraps <xref + linkend="sd1EqnBinomialCalculate"/> into a method + <methodname>public static long binomial(int n, int + k)</methodname>. </para> + + <para>What happens when calculating <inlineequation> + <m:math display="inline"> + <m:mrow> + <m:mrow> + <m:mo>(</m:mo> + + <m:mrow> + <m:mtable> + <m:mtr> + <m:mtd> + <m:mi>22</m:mi> + </m:mtd> + </m:mtr> + + <m:mtr> + <m:mtd> + <m:mi>21</m:mi> + </m:mtd> + </m:mtr> + </m:mtable> + </m:mrow> + + <m:mo>)</m:mo> + </m:mrow> + </m:mrow> + </m:math> + </inlineequation> ?</para> + + <programlisting language="java"> // Numerator product n (n - 1) ... (n - k + 1) + long numerator = 1; + for (int i = n - k + 1; i <= n; i++) { + numerator *= i; + }</programlisting> + + <para>In this case our numerator variable of type + <code>long</code> will be set to a value 22! (factorial). + Consider a simple demo code snippet among with its + result:</para> + + <informaltable border="1"> + <colgroup width="10%"/> + + <colgroup width="90%"/> + + <tr> + <th>Code</th> + + <td valign="top"><programlisting language="java"> public static void main(String[] args) { + long factorial = 1; + + for (int i = 2; i < 22; i++) { + factorial *= i; + System.out.println(factorial); + } + }</programlisting></td> + </tr> + + <tr> + <th>Result</th> + + <td valign="top"><programlisting language="none">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 + +Largest long value:9223372036854775807</programlisting></td> + </tr> + </informaltable> + + <para>So 21! already yields a negative value. Actually + <inlineequation> + <m:math display="inline"> + <m:mrow> + <m:mrow> + <m:mi>20</m:mi> + + <m:mo>!</m:mo> + </m:mrow> + + <m:mo>=</m:mo> + + <m:mi>2432902008176640000</m:mi> + + <m:mo><</m:mo> + + <m:mi>9223372036854775807</m:mi> + </m:mrow> + </m:math> + </inlineequation> still holds. The subsequent multiplication + by 21 however results in an arithmetic overflow.</para> + + <para>This does not show up as an error since exactly the same + (mis)calculation happens for the denominator. Thus their + quotient by coincidence returns a correct value of 1. This + however is no longer true when examining <inlineequation> + <m:math display="inline"> + <m:mrow> + <m:mrow> + <m:mo>(</m:mo> + + <m:mrow> + <m:mtable> + <m:mtr> + <m:mtd> + <m:mi>22</m:mi> + </m:mtd> + </m:mtr> + + <m:mtr> + <m:mtd> + <m:mi>20</m:mi> + </m:mtd> + </m:mtr> + </m:mtable> + </m:mrow> + + <m:mo>)</m:mo> + </m:mrow> + </m:mrow> + </m:math> + </inlineequation>.</para> + + <para>We may still get correct results in many situations + including the given example. If k gets too large we may use: + </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: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:mrow> + <m:mi>n</m:mi> + + <m:mo>-</m:mo> + + <m:mi>k</m:mi> + </m:mrow> + </m:mtd> + </m:mtr> + </m:mtable> + </m:mrow> + + <m:mo>)</m:mo> + </m:mrow> + </m:mrow> + </m:mrow> + </m:math> + </informalequation> + + <para>So instead of calculating <inlineequation> + <m:math display="inline"> + <m:mrow> + <m:mrow> + <m:mo>(</m:mo> + + <m:mrow> + <m:mtable> + <m:mtr> + <m:mtd> + <m:mi>22</m:mi> + </m:mtd> + </m:mtr> + + <m:mtr> + <m:mtd> + <m:mi>20</m:mi> + </m:mtd> + </m:mtr> + </m:mtable> + </m:mrow> + + <m:mo>)</m:mo> + </m:mrow> + </m:mrow> + </m:math> + </inlineequation> we take its sibling <inlineequation> + <m:math display="inline"> + <m:mrow> + <m:mrow> + <m:mo>(</m:mo> + + <m:mrow> + <m:mtable> + <m:mtr> + <m:mtd> + <m:mi>22</m:mi> + </m:mtd> + </m:mtr> + + <m:mtr> + <m:mtd> + <m:mi>2</m:mi> + </m:mtd> + </m:mtr> + </m:mtable> + </m:mrow> + + <m:mo>)</m:mo> + </m:mrow> + </m:mrow> + </m:math> + </inlineequation> having identical value by adding a simple + <code>if</code> statement:</para> + + <programlisting language="java"> public static long binomial(int n, int k) { + + // Trying to avoid arithmetic overflow by making use of: + // n n + // ( ) = ( ) + // k n-k + // + if (n / 2 < k) { + k = n - k; + } + + // Numerator product n (n - 1) ... (n - k + 1) + long numerator = 1; + ...</programlisting> + + <para>Finally our lottery code from <xref + linkend="sd1SectPlayingLottery"/> gets a little bit + simplified:</para> + + <informaltable border="1"> + <colgroup width="10%"/> + + <colgroup width="90%"/> + + <tr> + <th>Code</th> + + <td valign="top"><programlisting language="java"> final int + totalNumberCount = 49, + drawnNumberCount = 6; + + System.out.println( + "Your chance to win when drawing " + drawnNumberCount + + " out of " + totalNumberCount + + " is 1 : " + <emphasis role="bold">Binomial.binomial(totalNumberCount, drawnNumberCount))</emphasis>; + }</programlisting></td> + </tr> + + <tr> + <th>Result</th> + + <td valign="top"><programlisting language="none">Your chance to win when drawing 6 out of 49 is 1 : 13983816</programlisting></td> + </tr> + </informaltable> + </answer> + </qandaentry> + </qandadiv> + </qandaset> + </section> + <section xml:id="sd1Gcd"> <title>The greatest common divisor and the common multiple</title> diff --git a/Doc/Sd1/statements.xml b/Doc/Sd1/statements.xml index 8bdddebbab3469342ec802d8c96fae0c6ee9b17c..390b8b4ef5708095ddc630827e06565c26e4b627 100644 --- a/Doc/Sd1/statements.xml +++ b/Doc/Sd1/statements.xml @@ -347,9 +347,10 @@ Decimal value 14 not yet implemented</programlisting> <qandaentry> <question> <para>Write an application to print an ASCII art Xmas tree. - Provide a configurable parameter which allows for controlling - the tree's size. The following example shows a tree spanning 6 - rows excluding top (X) and bottom (###):</para> + Provide a configurable parameter <code>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> <programlisting language="none"> X * @@ -400,7 +401,7 @@ Decimal value 14 not yet implemented</programlisting> </question> <answer> - <programlisting language="none"> public static void main(String[] args) { + <programlisting language="java"> public static void main(String[] args) { // Example: 6 rows, tree's body loop index ranging from 0 to 5 // @@ -488,8 +489,8 @@ Decimal value 14 not yet implemented</programlisting> </question> <answer> - <para>We start by a version being fully covered by our knowledge - gained so far:</para> + <para>We start from a version being fully covered by our current + knowledge:</para> <programlisting language="java"> public static void main(String[] args) { @@ -1209,6 +1210,598 @@ Decimal value 14 not yet implemented</programlisting> </section> </section> + <section xml:id="sd1SectPlayingLottery"> + <title>Playing lottery</title> + + <qandaset defaultlabel="qanda" xml:id="sd1QandaPlayingLottery"> + <qandadiv> + <qandaentry> + <question> + <para>Many lotteries randomly dram numbers from a given set + like:</para> + + <glosslist> + <glossentry> + <glossterm>Germany / <quote + xml:lang="de">Glücksspirale</quote></glossterm> + + <glossdef> + <informaltable border="1"> + <colgroup width="14%"/> + + <colgroup width="86%"/> + + <tr> + <td valign="top">6 out of 49</td> + + <td><mediaobject> + <imageobject> + <imagedata fileref="Ref/Screen/lotto-spiel77.jpg"/> + </imageobject> + </mediaobject></td> + </tr> + </informaltable> + </glossdef> + </glossentry> + + <glossentry> + <glossterm>Italy / <quote>SuperEnalotto</quote></glossterm> + + <glossdef> + <informaltable border="1"> + <colgroup width="14%"/> + + <colgroup width="86%"/> + + <tr> + <td valign="top">6 out of 90</td> + + <td><mediaobject> + <imageobject> + <imagedata fileref="Ref/Screen/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 drawing n out of m numbers ignoring their order is + being given by the <link + xlink:href="https://en.wikipedia.org/wiki/Binomial_coefficient">binomial + coefficient <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></link>:</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 calculation of + probabilistic success rates. For the German <quote + xml:lang="de">Glücksspirale</quote> a possible output + reads:</para> + + <programlisting language="none">Your chance to win when drawing 6 out of 49 is 1 : 13983816</programlisting> + + <tip> + <orderedlist> + <listitem> + <para>Store parameters like 6 or 49 in variable to keep + your software flexible.</para> + </listitem> + + <listitem> + <para>Use <code>long</code> variables when appropriate to + avoid overflow errors.</para> + </listitem> + + <listitem> + <para>Even if using variables of type <code>long</code> + you will not be able to represent e.g. <quote>90!</quote> + due to an arithmetic overflow. This problem 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.</para> + </listitem> + + <listitem> + <para>The following loop allows for computing a given + number's factorial:</para> + + <programlisting language="java">long factorial = 1; +for (int i = 2; i <= number; i++) { + factorial *= i; +}</programlisting> + + <para>Use similar loops to solve the problem.</para> + </listitem> + </orderedlist> + </tip> + </question> + + <answer> + <para>By simple fraction cancellation we get:</para> + + <equation xml:id="sd1EqnBinomialCalculate"> + <title>Calculating binomials in a slightly more efficient + manner rather than just computing three factorials.</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>As an example we have:</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: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: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:mfrac> + </m:mrow> + </m:math> + </informalequation> + + <para>Calculating numerator and denominator in two separate + loops a possible implementation reads:</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> @@ -2058,17 +2651,17 @@ Congratulations! you won!</programlisting> <title>Pythagorean triples</title> <qandaset defaultlabel="qanda" xml:id="sw1QandaPythagoreanTriples"> - <title>Finding pythagorean triples</title> + <title>Finding Pythagorean triples</title> <qandadiv> <qandaentry> <question> <para>Read the <link xlink:href="http://en.wikipedia.org/wiki/Pythagorean_triple">definition - of pythagorean triples</link>.</para> + of Pythagorean triples</link>.</para> <para>Find all <link - xlink:href="http://en.wikipedia.org/wiki/Pythagorean_triple">pythagorean + xlink:href="http://en.wikipedia.org/wiki/Pythagorean_triple">Pythagorean triples</link> (a,b,c) for which which in addition to their definition the restriction <inlineequation> <m:math display="inline"> diff --git a/P/Sd1/Binomial/V1/.gitignore b/P/Sd1/Binomial/V1/.gitignore new file mode 100644 index 0000000000000000000000000000000000000000..cf5fd6bb26d6450c8c63fb34295192784943cf5e --- /dev/null +++ b/P/Sd1/Binomial/V1/.gitignore @@ -0,0 +1,5 @@ +/.settings +/target +/.classpath +/.project +/A1.log diff --git a/P/Sd1/Binomial/V1/pom.xml b/P/Sd1/Binomial/V1/pom.xml new file mode 100644 index 0000000000000000000000000000000000000000..ecd1d0edda2f356ff34e9d8442f150cd56766e6a --- /dev/null +++ b/P/Sd1/Binomial/V1/pom.xml @@ -0,0 +1,20 @@ +<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> + + <parent> + <groupId>de.hdm-stuttgart.mi</groupId> + <artifactId>lecturenotes-pom</artifactId> + <version>1.0</version> + <relativePath>../../../pom.xml</relativePath> + </parent> + + <groupId>de.hdm-stuttgart.de.sd1</groupId> + <artifactId>binomial</artifactId> + <version>1.1</version> + <packaging>jar</packaging> + + <name>Binomial</name> + <url>http://www.mi.hdm-stuttgart.de/freedocs</url> + +</project> diff --git a/P/Sd1/Binomial/V1/src/main/java/de/hdm_stuttgart/mi/sd1/binomial/Binomial.java b/P/Sd1/Binomial/V1/src/main/java/de/hdm_stuttgart/mi/sd1/binomial/Binomial.java new file mode 100644 index 0000000000000000000000000000000000000000..e91f421480fb750738a1879f7bdc8317afd3dc46 --- /dev/null +++ b/P/Sd1/Binomial/V1/src/main/java/de/hdm_stuttgart/mi/sd1/binomial/Binomial.java @@ -0,0 +1,32 @@ +package de.hdm_stuttgart.mi.sd1.binomial; + +public class Binomial { + + public static long binomial(int n, int k) { + + // Trying to avoid arithmetic overflow by making use of: + // n n + // ( ) = ( ) + // k n-k + // + if (n / 2 < k) { + k = n - k; + } + + // Numerator product n (n - 1) ... (n - k + 1) + long numerator = 1; + for (int i = n - k + 1; i <= n; i++) { + numerator *= i; + } + return numerator / factorial(k); + } + + public static long factorial(int n) { + long ret = 1; + + for (int i = 2; i <= n; i++) { + ret *= i; + } + return ret; + } +} diff --git a/P/Sd1/Binomial/V1/src/main/java/de/hdm_stuttgart/mi/sd1/binomial/FactorialLongLimitTest.java b/P/Sd1/Binomial/V1/src/main/java/de/hdm_stuttgart/mi/sd1/binomial/FactorialLongLimitTest.java new file mode 100644 index 0000000000000000000000000000000000000000..c74094e6ffe97d38cc75a654bf60aca8ed0d3b4d --- /dev/null +++ b/P/Sd1/Binomial/V1/src/main/java/de/hdm_stuttgart/mi/sd1/binomial/FactorialLongLimitTest.java @@ -0,0 +1,15 @@ +package de.hdm_stuttgart.mi.sd1.binomial; + +public class FactorialLongLimitTest { + + public static void main(String[] args) { + long factorial = 1; + + for (int i = 2; i < 22; i++) { + factorial *= i; + System.out.println( i + ": " + factorial); + } + + System.out.println("\nLargest long value:" + Long.MAX_VALUE); + } +} diff --git a/P/Sd1/Binomial/V1/src/main/java/de/hdm_stuttgart/mi/sd1/binomial/Lottery.java b/P/Sd1/Binomial/V1/src/main/java/de/hdm_stuttgart/mi/sd1/binomial/Lottery.java new file mode 100644 index 0000000000000000000000000000000000000000..7a4dd57f1507edb578c05f27695d9f27156e08ae --- /dev/null +++ b/P/Sd1/Binomial/V1/src/main/java/de/hdm_stuttgart/mi/sd1/binomial/Lottery.java @@ -0,0 +1,18 @@ +package de.hdm_stuttgart.mi.sd1.binomial; + +public class Lottery { + + public static void main(String[] args) { + + // Input values: + final int + totalNumberCount = 49, + drawnNumberCount = 6; + + System.out.println( + "Your chance to win when drawing " + drawnNumberCount + + " out of " + totalNumberCount + + " is 1 : " + Binomial.binomial(totalNumberCount, drawnNumberCount)); + } + +} diff --git a/P/Sd1/Binomial/V1/src/test/java/de/hdm_stuttgart/mi/sd1/binomial/test/BinomTest.java b/P/Sd1/Binomial/V1/src/test/java/de/hdm_stuttgart/mi/sd1/binomial/test/BinomTest.java new file mode 100644 index 0000000000000000000000000000000000000000..fa8c806ab2785038fe47a14e8688b31453dd6778 --- /dev/null +++ b/P/Sd1/Binomial/V1/src/test/java/de/hdm_stuttgart/mi/sd1/binomial/test/BinomTest.java @@ -0,0 +1,60 @@ +package de.hdm_stuttgart.mi.sd1.binomial.test; + +import org.junit.Assert; +import org.junit.Test; + +import de.hdm_stuttgart.mi.sd1.binomial.Binomial; + +public class BinomTest { + + @Test + public void test_0_0() { + Assert.assertEquals(1, Binomial.binomial(0, 0)); + } + + @Test + public void test_1_0() { + Assert.assertEquals(1, Binomial.binomial(1, 0)); + } + + @Test + public void test_1_1() { + Assert.assertEquals(1, Binomial.binomial(1, 1)); + } + + @Test + public void test_4_3() { + Assert.assertEquals(4, Binomial.binomial(4, 3)); + } + + @Test + public void test_5_3() { + Assert.assertEquals(10, Binomial.binomial(5, 3)); + } + + @Test + public void test_20_20() { + Assert.assertEquals(1, Binomial.binomial(20, 20)); + } + + // Possible arithmetic overflow situations. + @Test + public void test_22_1() { + Assert.assertEquals(22, Binomial.binomial(22, 1)); + } + + @Test + public void test_22_21() { + Assert.assertEquals(22, Binomial.binomial(22, 21)); + } + + @Test + public void test_22_2() { + Assert.assertEquals(231, Binomial.binomial(22, 2)); + } + + @Test + public void test_22_20() { + Assert.assertEquals(231, Binomial.binomial(22, 20)); + } +}