Lah numbers

Lah numbers, sometimes referred to as ''Stirling numbers of the third kind'', are coefficients of polynomial expansions expressing rising factorials in terms of falling factorials.

Unsigned Lah numbers count the number of ways a set of '''n''' elements can be partitioned into '''k''' non-empty linearly ordered subsets.

Lah numbers are closely related to Stirling numbers of the first & second kinds, and may be derived from them.

Lah numbers obey the identities and relations:
   L(n, 0), L(0, k) = 0   # for n, k > 0
   L(n, n) = 1
   L(n, 1) = n!
   L(n, k) =           ( n! * (n - 1)! ) / ( k! * (k - 1)! ) / (n - k)!      # For unsigned Lah numbers
      ''or''
   L(n, k) = (-1)**n * ( n! * (n - 1)! ) / ( k! * (k - 1)! ) / (n - k)!      # For   signed Lah numbers

;Task:
:* Write a routine (function, procedure, whatever) to find '''unsigned Lah numbers'''. There are several methods to generate unsigned Lah numbers. You are free to choose the most appropriate for your language. If your language has a built-in, or easily, publicly available library implementation, it is acceptable to use that.

:* Using the routine, generate and show here, on this page, a table (or triangle) showing the unsigned Lah numbers, '''L(n, k)''', up to '''L(12, 12)'''. it is optional to show the row / column for n == 0 and k == 0. It is optional to show places where L(n, k) == 0 (when k > n).

:* If your language supports large integers, find and show here, on this page, the maximum value of '''L(n, k)''' where '''n == 100'''.

;See also:

:* '''Wikipedia - Lah number'''
:* '''OEIS:A105278 - Unsigned Lah numbers'''
:* '''OEIS:A008297 - Signed Lah numbers'''

;Related Tasks:

:* '''Stirling numbers of the first kind'''
:* '''Stirling numbers of the second kind'''
:* '''Bell numbers'''

Solution:
import java.math.BigInteger;
import java.util.HashMap;
import java.util.Map;

public class LahNumbers {

    public static void main(String[] args) {
        System.out.println("Show the unsigned Lah numbers up to n = 12:");
        for ( int n = 0 ; n <= 12 ; n++ ) {
            System.out.printf("%5s", n);
            for ( int k = 0 ; k <= n ; k++ ) {
                System.out.printf("%12s", lahNumber(n, k));
            }
            System.out.printf("%n");
        }

        System.out.println("Show the maximum value of L(100, k):");
        int n = 100;
        BigInteger max = BigInteger.ZERO;
        for ( int k = 0 ; k <= n ; k++ ) {
            max = max.max(lahNumber(n, k));
        }
        System.out.printf("%s", max);
    }

    private static Map<String,BigInteger> CACHE = new HashMap<>();

    private static BigInteger lahNumber(int n, int k) {
        String key = n + "," + k;
        if ( CACHE.containsKey(key) ) {
            return CACHE.get(key);
        }

        //  L(n,0) = 0;
        BigInteger result;
        if ( n == 0 && k == 0 ) {
            result = BigInteger.ONE;
        }
        else if ( k == 0 ) {
            result = BigInteger.ZERO;
        }
        else if ( k > n ) {
            result = BigInteger.ZERO;
        }
        else if ( n == 1 && k == 1 ) {
            result = BigInteger.ONE;
        }
        else {
            result = BigInteger.valueOf(n-1+k).multiply(lahNumber(n-1,k)).add(lahNumber(n-1,k-1));
        }

        CACHE.put(key, result);

        return result;
    }

}


Largest int from concatenated ints

Given a set of positive integers, write a function to order the integers in such a way that the concatenation of the numbers forms the largest possible integer and return this integer.

Use the following two sets of integers as tests   and   show your program output here.

:::::*   {1, 34, 3, 98, 9, 76, 45, 4}
:::::*   {54, 546, 548, 60}

;Possible algorithms:
# A solution could be found by trying all combinations and return the best.
# Another way to solve this is to note that in the best arrangement, for any two adjacent original integers '''X''' and '''Y''', the concatenation '''X''' followed by '''Y''' will be numerically greater than or equal to the concatenation '''Y''' followed by '''X.
# Yet another way to solve this is to pad the integers to the same size by repeating the digits then sort using these repeated integers as a sort key.

;See also:
*   Algorithms: What is the most efficient way to arrange the given numbers to form the biggest number?
*   Constructing the largest number possible by rearranging a list

Solution:
import java.util.*;

public class IntConcat {

    private static Comparator<Integer> sorter = new Comparator<Integer>(){
        @Override
        public int compare(Integer o1, Integer o2){
            String o1s = o1.toString();
            String o2s = o2.toString();

            if(o1s.length() == o2s.length()){
                return o2s.compareTo(o1s);
            }

            int mlen = Math.max(o1s.length(), o2s.length());
            while(o1s.length() < mlen * 2) o1s += o1s;
            while(o2s.length() < mlen * 2) o2s += o2s;

            return o2s.compareTo(o1s);
        }
    };

    public static String join(List<?> things){
        String output = "";
        for(Object obj:things){
            output += obj;
        }
        return output;
    }

    public static void main(String[] args){
        List<Integer> ints1 = new ArrayList<Integer>(Arrays.asList(1, 34, 3, 98, 9, 76, 45, 4));

        Collections.sort(ints1, sorter);
        System.out.println(join(ints1));

        List<Integer> ints2 = new ArrayList<Integer>(Arrays.asList(54, 546, 548, 60));

        Collections.sort(ints2, sorter);
        System.out.println(join(ints2));
    }
}


Largest int from concatenated ints

Solution:
import java.util.Comparator;
import java.util.stream.Collectors;
import java.util.stream.Stream;

public interface IntConcat {
  public static Comparator<Integer> SORTER = (o1, o2) -> {
    String o1s = o1.toString();
    String o2s = o2.toString();

    if (o1s.length() == o2s.length()) {
      return o2s.compareTo(o1s);
    }

    int mlen = Math.max(o1s.length(), o2s.length());
    while (o1s.length() < mlen * 2) {
      o1s += o1s;
    }
    while (o2s.length() < mlen * 2) {
      o2s += o2s;
    }

    return o2s.compareTo(o1s);
  };

  public static void main(String[] args) {
    Stream<Integer> ints1 = Stream.of(
      1, 34, 3, 98, 9, 76, 45, 4
    );

    System.out.println(ints1
      .parallel()
      .sorted(SORTER)
      .map(String::valueOf)
      .collect(Collectors.joining())
    );

    Stream<Integer> ints2 = Stream.of(
      54, 546, 548, 60
    );

    System.out.println(ints2
      .parallel()
      .sorted(SORTER)
      .map(String::valueOf)
      .collect(Collectors.joining())
    );
  }
}


Last Friday of each month

Write a program or a script that returns the date of the last Fridays of each month of a given year.

The year may be given through any simple input method in your language (command line, std in, etc).

Example of an expected output:
./last_fridays 2012
2012-01-27
2012-02-24
2012-03-30
2012-04-27
2012-05-25
2012-06-29
2012-07-27
2012-08-31
2012-09-28
2012-10-26
2012-11-30
2012-12-28

;Related tasks
* [[Five weekends]]
* [[Day of the week]]
* [[Find the last Sunday of each month]]

Solution:
import java.text.*;
import java.util.*;

public class LastFridays {

    public static void main(String[] args) throws Exception {
        int year = Integer.parseInt(args[0]);
        GregorianCalendar c = new GregorianCalendar(year, 0, 1);

        for (String mon : new DateFormatSymbols(Locale.US).getShortMonths()) {
            if (!mon.isEmpty()) {
                int totalDaysOfMonth = c.getActualMaximum(Calendar.DAY_OF_MONTH);
                c.set(Calendar.DAY_OF_MONTH, totalDaysOfMonth);

                int daysToRollBack = (c.get(Calendar.DAY_OF_WEEK) + 1) % 7;

                int day = totalDaysOfMonth - daysToRollBack;
                c.set(Calendar.DAY_OF_MONTH, day);

                System.out.printf("%d %s %d\n", year, mon, day);

                c.set(year, c.get(Calendar.MONTH) + 1, 1);
            }
        }
    }
}


Last letter-first letter

A certain children's game involves starting with a word in a particular category.   Each participant in turn says a word, but that word must begin with the final letter of the previous word.   Once a word has been given, it cannot be repeated.   If an opponent cannot give a word in the category, they fall out of the game.

For example, with   "animals"   as the category,

Child 1: dog
Child 2: goldfish
Child 1: hippopotamus
Child 2: snake
...

;Task:
Take the following selection of 70 English Pokemon names   (extracted from   Wikipedia's list of Pokemon)   and generate the/a sequence with the highest possible number of Pokemon names where the subsequent name starts with the final letter of the preceding name.

No Pokemon name is to be repeated.

audino bagon baltoy banette bidoof braviary bronzor carracosta charmeleon
cresselia croagunk darmanitan deino emboar emolga exeggcute gabite
girafarig gulpin haxorus heatmor heatran ivysaur jellicent jumpluff kangaskhan
kricketune landorus ledyba loudred lumineon lunatone machamp magnezone mamoswine
nosepass petilil pidgeotto pikachu pinsir poliwrath poochyena porygon2
porygonz registeel relicanth remoraid rufflet sableye scolipede scrafty seaking
sealeo silcoon simisear snivy snorlax spoink starly tirtouga trapinch treecko
tyrogue vigoroth vulpix wailord wartortle whismur wingull yamask

Extra brownie points for dealing with the full list of   646   names.

Solution:
// derived from C
final class LastLetterFirstLetter {
    static int maxPathLength = 0;
    static int maxPathLengthCount = 0;
    static final StringBuffer maxPathExample = new StringBuffer(500);

    static final String[] names = {"audino", "bagon", "baltoy", "banette",
        "bidoof", "braviary", "bronzor", "carracosta", "charmeleon",
        "cresselia", "croagunk", "darmanitan", "deino", "emboar",
        "emolga", "exeggcute", "gabite", "girafarig", "gulpin",
        "haxorus", "heatmor", "heatran", "ivysaur", "jellicent",
        "jumpluff", "kangaskhan", "kricketune", "landorus", "ledyba",
        "loudred", "lumineon", "lunatone", "machamp", "magnezone",
        "mamoswine", "nosepass", "petilil", "pidgeotto", "pikachu",
        "pinsir", "poliwrath", "poochyena", "porygon2", "porygonz",
        "registeel", "relicanth", "remoraid", "rufflet", "sableye",
        "scolipede", "scrafty", "seaking", "sealeo", "silcoon",
        "simisear", "snivy", "snorlax", "spoink", "starly", "tirtouga",
        "trapinch", "treecko", "tyrogue", "vigoroth", "vulpix",
        "wailord", "wartortle", "whismur", "wingull", "yamask"};

    static void recursive(String[] part, int offset) {
        if (offset > maxPathLength) {
            maxPathLength = offset;
            maxPathLengthCount = 1;
        } else if (offset == maxPathLength) {
            maxPathLengthCount++;
            maxPathExample.setLength(0);
            for (int i = 0; i < offset; i++) {
                maxPathExample.append((i % 5 == 0 ? "\n  " : " "));
                maxPathExample.append(part[i]);
            }
        }
        final char lastChar = part[offset - 1].charAt(part[offset - 1].length()-1);
        for (int i = offset; i < part.length; i++) {
            if (part[i].charAt(0) == lastChar) {
                String tmp = names[offset];
                names[offset] = names[i];
                names[i] = tmp;
                recursive(names, offset+1);
                names[i] = names[offset];
                names[offset] = tmp;
            }
        }
    }

    public static void main(String[] args) {
        for (int i = 0; i < names.length; i++) {
            String tmp = names[0];
            names[0] = names[i];
            names[i] = tmp;
            recursive(names, 1);
            names[i] = names[0];
            names[0] = tmp;
       }
       System.out.println("maximum path length        : " + maxPathLength);
       System.out.println("paths of that length       : " + maxPathLengthCount);
       System.out.println("example path of that length:" + maxPathExample);
    }
}


Latin Squares in reduced form

A Latin Square is in its reduced form if the first row and first column contain items in their natural order. The order n is the number of items. For any given n there is a set of reduced Latin Squares whose size increases rapidly with n. g is a number which identifies a unique element within the set of reduced Latin Squares of order n. The objective of this task is to construct the set of all Latin Squares of a given order and to provide a means which given suitable values for g any element within the set may be obtained.

For a reduced Latin Square the first row is always 1 to n. The second row is all [[Permutations/Derangements]] of 1 to n starting with 2. The third row is all [[Permutations/Derangements]] of 1 to n starting with 3 which do not clash (do not have the same item in any column) with row 2. The fourth row is all [[Permutations/Derangements]] of 1 to n starting with 4 which do not clash with rows 2 or 3. Likewise continuing to the nth row.

Demonstrate by:
* displaying the four reduced Latin Squares of order 4.
* for n = 1 to 6 (or more) produce the set of reduced Latin Squares; produce a table which shows the size of the set of reduced Latin Squares and compares this value times n! times (n-1)! with the values in OEIS A002860.

Solution:
import java.math.BigInteger;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

public class LatinSquaresInReducedForm {

    public static void main(String[] args) {
        System.out.printf("Reduced latin squares of order 4:%n");
        for ( LatinSquare square : getReducedLatinSquares(4) ) {
            System.out.printf("%s%n", square);
        }

        System.out.printf("Compute the number of latin squares from count of reduced latin squares:%n(Reduced Latin Square Count) * n! * (n-1)! = Latin Square Count%n");
        for ( int n = 1 ; n <= 6 ; n++ ) {
            List<LatinSquare> list = getReducedLatinSquares(n);
            System.out.printf("Size = %d, %d * %d * %d = %,d%n", n, list.size(), fact(n), fact(n-1), list.size()*fact(n)*fact(n-1));
        }
    }

    private static long fact(int n) {
        if ( n == 0 ) {
            return 1;
        }
        int prod = 1;
        for ( int i = 1 ; i <= n ; i++ ) {
            prod *= i;
        }
        return prod;
    }

    private static List<LatinSquare> getReducedLatinSquares(int n) {
        List<LatinSquare> squares = new ArrayList<>();

        squares.add(new LatinSquare(n));
        PermutationGenerator permGen = new PermutationGenerator(n);
        for ( int fillRow = 1 ; fillRow < n ; fillRow++ ) {
            List<LatinSquare> squaresNext = new ArrayList<>();
            for ( LatinSquare square : squares ) {
                while ( permGen.hasMore() ) {
                    int[] perm = permGen.getNext();

                    //  If not the correct row - next permutation.
                    if ( (perm[0]+1) != (fillRow+1) ) {
                        continue;
                    }

                    //  Check permutation against current square.
                    boolean permOk = true;
                    done:
                    for ( int row = 0 ; row < fillRow ; row++ ) {
                        for ( int col = 0 ; col < n ; col++ ) {
                            if ( square.get(row, col) == (perm[col]+1) ) {
                                permOk = false;
                                break done;
                            }
                        }
                    }
                    if ( permOk ) {
                        LatinSquare newSquare = new LatinSquare(square);
                        for ( int col = 0 ; col < n ; col++ ) {
                            newSquare.set(fillRow, col, perm[col]+1);
                        }
                        squaresNext.add(newSquare);
                    }
                }
                permGen.reset();
            }
            squares = squaresNext;
        }

        return squares;
    }

    @SuppressWarnings("unused")
    private static int[] display(int[] in) {
        int [] out = new int[in.length];
        for ( int i = 0 ; i < in.length ; i++ ) {
            out[i] = in[i] + 1;
        }
        return out;
    }

    private static class LatinSquare {

        int[][] square;
        int size;

        public LatinSquare(int n) {
            square = new int[n][n];
            size = n;
            for ( int col = 0 ; col < n ; col++ ) {
                set(0, col, col + 1);
            }
        }

        public LatinSquare(LatinSquare ls) {
            int n = ls.size;
            square = new int[n][n];
            size = n;
            for ( int row = 0 ; row < n ; row++ ) {
                for ( int col = 0 ; col < n ; col++ ) {
                    set(row, col, ls.get(row, col));
                }
            }
        }

        public void set(int row, int col, int value) {
            square[row][col] = value;
        }

        public int get(int row, int col) {
            return square[row][col];
        }

        @Override
        public String toString() {
            StringBuilder sb = new StringBuilder();
            for ( int row = 0 ; row < size ; row++ ) {
                sb.append(Arrays.toString(square[row]));
                sb.append("\n");
            }
            return sb.toString();
        }

    }

    private static class PermutationGenerator {

        private int[] a;
        private BigInteger numLeft;
        private BigInteger total;

        public PermutationGenerator (int n) {
            if (n < 1) {
                throw new IllegalArgumentException ("Min 1");
            }
            a = new int[n];
            total = getFactorial(n);
            reset();
        }

        private void reset () {
            for ( int i = 0 ; i < a.length ; i++ ) {
                a[i] = i;
            }
            numLeft = new BigInteger(total.toString());
        }

        public boolean hasMore() {
            return numLeft.compareTo(BigInteger.ZERO) == 1;
        }

        private static BigInteger getFactorial (int n) {
            BigInteger fact = BigInteger.ONE;
            for ( int i = n ; i > 1 ; i-- ) {
                fact = fact.multiply(new BigInteger(Integer.toString(i)));
            }
            return fact;
        }

        /*--------------------------------------------------------
         * Generate next permutation (algorithm from Rosen p. 284)
         *--------------------------------------------------------
         */
        public int[] getNext() {
            if ( numLeft.equals(total) ) {
                numLeft = numLeft.subtract (BigInteger.ONE);
                return a;
            }

            // Find largest index j with a[j] < a[j+1]
            int j = a.length - 2;
            while ( a[j] > a[j+1] ) {
                j--;
            }

            // Find index k such that a[k] is smallest integer greater than a[j] to the right of a[j]
            int k = a.length - 1;
            while ( a[j] > a[k] ) {
                k--;
            }

            // Interchange a[j] and a[k]
            int temp = a[k];
            a[k] = a[j];
            a[j] = temp;

            // Put tail end of permutation after jth position in increasing order
            int r = a.length - 1;
            int s = j + 1;
            while (r > s) {
                int temp2 = a[s];
                a[s] = a[r];
                a[r] = temp2;
                r--;
                s++;
            }

            numLeft = numLeft.subtract(BigInteger.ONE);
            return a;
        }
    }

}


Law of cosines - triples

The Law of cosines states that for an angle g, (gamma) of any triangle, if the sides adjacent to the angle are A and B and the side opposite is C; then the lengths of the sides are related by this formula:
           A2 + B2 - 2ABcos(g) = C2

;Specific angles:
For an angle of of   '''90o'''   this becomes the more familiar "Pythagoras equation":
           A2 + B2  =  C2

For an angle of   '''60o'''   this becomes the less familiar  equation:
           A2 + B2 - AB  =  C2

And finally for an angle of   '''120o'''   this becomes the equation:
           A2 + B2 + AB  =  C2

;Task:
*   Find all integer solutions (in order) to the three specific cases, distinguishing between each angle being considered.
*   Restrain all sides to the integers   '''1..13'''   inclusive.
*   Show how many results there are for each of the three angles mentioned above.
*   Display results on this page.

Note: Triangles with the same length sides but different order are to be treated as the same.

;Optional Extra credit:
* How many 60deg integer triples are there for sides in the range 1..10_000 ''where the sides are not all of the same length''.

;Related Task
* [[Pythagorean triples]]

;See also:
* Visualising Pythagoras: ultimate proofs and crazy contortions Mathlogger Video

Solution:
public class LawOfCosines {

    public static void main(String[] args) {
        generateTriples(13);
        generateTriples60(10000);
    }

    private static void generateTriples(int max) {
        for ( int coeff : new int[] {0, -1, 1} ) {
            int count = 0;
            System.out.printf("Max side length %d, formula:  a*a + b*b %s= c*c%n", max, coeff == 0 ? "" : (coeff<0 ? "-"  : "+") + " a*b ");
            for ( int a = 1 ; a <= max ; a++ ) {
                for ( int b = 1 ; b <= a ; b++ ) {
                    int val = a*a + b*b + coeff*a*b;
                    int c = (int) (Math.sqrt(val) + .5d);
                    if ( c > max ) {
                        break;
                    }
                    if ( c*c == val ) {
                        System.out.printf("  (%d, %d, %d)%n", a, b ,c);
                        count++;
                    }
                }
            }
            System.out.printf("%d triangles%n", count);
        }
    }

    private static void generateTriples60(int max) {
        int count = 0;
        System.out.printf("%nExtra Credit.%nMax side length %d, sides different length, formula:  a*a + b*b - a*b = c*c%n", max);
        for ( int a = 1 ; a <= max ; a++ ) {
            for ( int b = 1 ; b < a ; b++ ) {
                int val = a*a + b*b - a*b;
                int c = (int) (Math.sqrt(val) + .5d);
                if ( c*c == val ) {
                    count++;
                }
            }
        }
        System.out.printf("%d triangles%n", count);
    }

}


Least common multiple

Compute the   least common multiple   (LCM)   of two integers.

Given   ''m''   and   ''n'',   the least common multiple is the smallest positive integer that has both   ''m''   and   ''n''   as factors.

;Example:
The least common multiple of   '''12'''   and   '''18'''   is   '''36''',       because:
:*   '''12'''   is a factor     ('''12''' x '''3''' = '''36'''),     and
:*   '''18'''   is a factor     ('''18''' x '''2''' = '''36'''),     and
:*   there is no positive integer less than   '''36'''   that has both factors.

As a special case,   if either   ''m''   or   ''n''   is zero,   then the least common multiple is zero.

One way to calculate the least common multiple is to iterate all the multiples of   ''m'',   until you find one that is also a multiple of   ''n''.

If you already have   ''gcd''   for [[greatest common divisor]],   then this formula calculates   ''lcm''.

:::: \operatorname{lcm}(m, n) = \frac{|m \times n|}{\operatorname{gcd}(m, n)}

One can also find   ''lcm''   by merging the [[prime decomposition]]s of both   ''m''   and   ''n''.

;Related task
:*   greatest common divisor.

;See also:
*   MathWorld entry:   Least Common Multiple.
*   Wikipedia entry:   Least common multiple.

Solution:
import java.util.Scanner;

public class LCM{
   public static void main(String[] args){
      Scanner aScanner = new Scanner(System.in);

      //prompts user for values to find the LCM for, then saves them to m and n
      System.out.print("Enter the value of m:");
      int m = aScanner.nextInt();
      System.out.print("Enter the value of n:");
      int n = aScanner.nextInt();
      int lcm = (n == m || n == 1) ? m :(m == 1 ? n : 0);
      /* this section increases the value of mm until it is greater
      / than or equal to nn, then does it again when the lesser
      / becomes the greater--if they aren't equal. If either value is 1,
      / no need to calculate*/
      if (lcm == 0) {
         int mm = m, nn = n;
         while (mm != nn) {
             while (mm < nn) { mm += m; }
             while (nn < mm) { nn += n; }
         }
         lcm = mm;
      }
      System.out.println("lcm(" + m + ", " + n + ") = " + lcm);
   }
}


Left factorials

'''Left factorials''',   !n,   may refer to either   ''subfactorials''   or to   ''factorial sums'';
the same notation can be confusingly seen being used for the two different definitions.

Sometimes,   ''subfactorials''   (also known as ''derangements'')   may use any of the notations:
:::::::*     !''n''`
:::::::*     !''n''
:::::::*     ''n''!

(It may not be visually obvious, but the last example uses an upside-down exclamation mark.)

This Rosetta Code task will be using this formula   (''factorial sums'')   for   '''left factorial''':

:::::    !n = \sum_{k=0}^{n-1} k!

:::: where

:::::   !0 = 0

;Task
Display the left factorials for:
*   zero      through        ten     (inclusive)
*   20   through   110          (inclusive)   by tens

Display the length (in decimal digits) of the left factorials for:
*   1,000   through   10,000   (inclusive), by thousands.

;Also see:
*   The OEIS entry: A003422 left factorials
*   The MathWorld entry: left factorial
*   The MathWorld entry: factorial sums
*   The MathWorld entry: subfactorial

;Related task:
*   permutations/derangements (subfactorials)

Solution:
import java.math.BigInteger;

public class LeftFac{
	public static BigInteger factorial(BigInteger n){
		BigInteger ans = BigInteger.ONE;
		for(BigInteger x = BigInteger.ONE; x.compareTo(n) <= 0; x = x.add(BigInteger.ONE)){
			ans = ans.multiply(x);
		}
		return ans;
	}

	public static BigInteger leftFact(BigInteger n){
		BigInteger ans = BigInteger.ZERO;
		for(BigInteger k = BigInteger.ZERO; k.compareTo(n.subtract(BigInteger.ONE)) <= 0; k = k.add(BigInteger.ONE)){
			ans = ans.add(factorial(k));
		}
		return ans;
	}

	public static void main(String[] args){
		for(int i = 0; i <= 10; i++){
			System.out.println("!" + i + " = " + leftFact(BigInteger.valueOf(i)));
		}

		for(int i = 20; i <= 110; i += 10){
			System.out.println("!" + i + " = " + leftFact(BigInteger.valueOf(i)));
		}

		for(int i = 1000; i <= 10000; i += 1000){
			System.out.println("!" + i + " has " + leftFact(BigInteger.valueOf(i)).toString().length() + " digits");
		}
	}
}


Levenshtein distance

{{Wikipedia}}

In information theory and computer science, the '''Levenshtein distance''' is a edit distance). The Levenshtein distance between two strings is defined as the minimum number of edits needed to transform one string into the other, with the allowable edit operations being insertion, deletion, or substitution of a single character.

;Example:
The Levenshtein distance between "'''kitten'''" and "'''sitting'''" is 3, since the following three edits change one into the other, and there isn't a way to do it with fewer than three edits:
::#   '''k'''itten    '''s'''itten       (substitution of 'k' with 's')
::#   sitt'''e'''n    sitt'''i'''n       (substitution of 'e' with 'i')
::#   sittin          sittin'''g'''      (insert 'g' at the end).

''The Levenshtein distance between   "'''rosettacode'''",   "'''raisethysword'''"   is   '''8'''.

''The distance between two strings is same as that when both strings are reversed.''

;Task:
Implements a Levenshtein distance function, or uses a library function, to show the Levenshtein distance between   "kitten"   and   "sitting".

;Related task:
*   [[Longest common subsequence]]

Solution:
public class Levenshtein {

    public static int distance(String a, String b) {
        a = a.toLowerCase();
        b = b.toLowerCase();
        // i == 0
        int [] costs = new int [b.length() + 1];
        for (int j = 0; j < costs.length; j++)
            costs[j] = j;
        for (int i = 1; i <= a.length(); i++) {
            // j == 0; nw = lev(i - 1, j)
            costs[0] = i;
            int nw = i - 1;
            for (int j = 1; j <= b.length(); j++) {
                int cj = Math.min(1 + Math.min(costs[j], costs[j - 1]), a.charAt(i - 1) == b.charAt(j - 1) ? nw : nw + 1);
                nw = costs[j];
                costs[j] = cj;
            }
        }
        return costs[b.length()];
    }

    public static void main(String [] args) {
        String [] data = { "kitten", "sitting", "saturday", "sunday", "rosettacode", "raisethysword" };
        for (int i = 0; i < data.length; i += 2)
            System.out.println("distance(" + data[i] + ", " + data[i+1] + ") = " + distance(data[i], data[i+1]));
    }
}


Levenshtein distance

Solution:
public class Levenshtein{
    public static int levenshtein(String s, String t){
        /* if either string is empty, difference is inserting all chars
         * from the other
         */
        if(s.length() == 0) return t.length();
        if(t.length() == 0) return s.length();

        /* if first letters are the same, the difference is whatever is
         * required to edit the rest of the strings
         */
        if(s.charAt(0) == t.charAt(0))
            return levenshtein(s.substring(1), t.substring(1));

        /* else try:
         *      changing first letter of s to that of t,
         *      remove first letter of s, or
         *      remove first letter of t
         */
        int a = levenshtein(s.substring(1), t.substring(1));
        int b = levenshtein(s, t.substring(1));
        int c = levenshtein(s.substring(1), t);

        if(a > b) a = b;
        if(a > c) a = c;

        //any of which is 1 edit plus editing the rest of the strings
        return a + 1;
    }

    public static void main(String[] args) {
        String s1 = "kitten";
        String s2 = "sitting";
        System.out.println("distance between '" + s1 + "' and '"
                + s2 + "': " + levenshtein(s1, s2));
        s1 = "rosettacode";
        s2 = "raisethysword";
        System.out.println("distance between '" + s1 + "' and '"
                + s2 + "': " + levenshtein(s1, s2));
        StringBuilder sb1 = new StringBuilder(s1);
        StringBuilder sb2 = new StringBuilder(s2);
        System.out.println("distance between '" + sb1.reverse() + "' and '"
                + sb2.reverse() + "': "
                + levenshtein(sb1.reverse().toString(), sb2.reverse().toString()));
    }
}


Levenshtein distance

Solution:
import static java.lang.Math.abs;
import static java.lang.Math.max;

public class Levenshtein {

	public static int ld(String a, String b) {
		return distance(a, b, -1);
	}
	public static boolean ld(String a, String b, int max) {
		return distance(a, b, max) <= max;
	}

	private static int distance(String a, String b, int max) {
		if (a == b) return 0;
		int la = a.length();
		int lb = b.length();
		if (max >= 0 && abs(la - lb) > max) return max+1;
		if (la == 0) return lb;
		if (lb == 0) return la;
		if (la < lb) {
			int tl = la; la = lb; lb = tl;
			String ts = a;  a = b; b = ts;
		}

		int[] cost = new int[lb+1];
		for (int i=0; i<=lb; i+=1) {
			cost[i] = i;
		}

		for (int i=1; i<=la; i+=1) {
			cost[0] = i;
			int prv = i-1;
			int min = prv;
			for (int j=1; j<=lb; j+=1) {
				int act = prv + (a.charAt(i-1) == b.charAt(j-1) ? 0 : 1);
				cost[j] = min(1+(prv=cost[j]), 1+cost[j-1], act);
				if (prv < min) min = prv;
			}
			if (max >= 0 && min > max) return max+1;
		}
		if (max >= 0 && cost[lb] > max) return max+1;
		return cost[lb];
	}

	private static int min(int ... a) {
		int min = Integer.MAX_VALUE;
		for (int i: a) if (i<min) min = i;
		return min;
	}

	public static void main(String[] args) {
		System.out.println(
			ld("kitten","kitten") + " " + // 0
			ld("kitten","sitten") + " " + // 1
			ld("kitten","sittes") + " " + // 2
			ld("kitten","sityteng") + " " + // 3
			ld("kitten","sittYing") + " " + // 4
			ld("rosettacode","raisethysword") + " " + // 8
			ld("kitten","kittenaaaaaaaaaaaaaaaaa") + " " + // 17
			ld("kittenaaaaaaaaaaaaaaaaa","kitten") // 17
		);
		System.out.println(
			ld("kitten","kitten", 3) + " " + // true
			ld("kitten","sitten", 3) + " " + // true
			ld("kitten","sittes", 3) + " " + // true
			ld("kitten","sityteng", 3) + " " + // true
			ld("kitten","sittYing", 3) + " " + // false
			ld("rosettacode","raisethysword", 3) + " " + // false
			ld("kitten","kittenaaaaaaaaaaaaaaaaa", 3) + " " + // false
			ld("kittenaaaaaaaaaaaaaaaaa","kitten", 3) // false
		);
	}
}


Levenshtein distance/Alignment

The [[Levenshtein distance]] algorithm returns the number of atomic operations (insertion, deletion or edition) that must be performed on a string in order to obtain an other one, but it does not say anything about the actual operations used or their order.

An alignment is a notation used to describe the operations used to turn a string into an other.  At some point in the strings, the minus character ('-') is placed in order to signify that a character must be added at this very place.  For instance, an alignment between the words 'place' and 'palace' is:

P-LACE
PALACE

;Task:
Write a function that shows the alignment of two strings for the corresponding levenshtein distance.

As an example, use the words "rosettacode" and "raisethysword".

You can either implement an algorithm, or use a dedicated library (thus showing us how it is named in your language).

Solution:
public class LevenshteinAlignment {

    public static String[] alignment(String a, String b) {
        a = a.toLowerCase();
        b = b.toLowerCase();
        // i == 0
        int[][] costs = new int[a.length()+1][b.length()+1];
        for (int j = 0; j <= b.length(); j++)
            costs[0][j] = j;
        for (int i = 1; i <= a.length(); i++) {
            costs[i][0] = i;
            for (int j = 1; j <= b.length(); j++) {
                costs[i][j] = Math.min(1 + Math.min(costs[i-1][j], costs[i][j-1]), a.charAt(i - 1) == b.charAt(j - 1) ? costs[i-1][j-1] : costs[i-1][j-1] + 1);
            }
        }

	// walk back through matrix to figure out path
	StringBuilder aPathRev = new StringBuilder();
	StringBuilder bPathRev = new StringBuilder();
	for (int i = a.length(), j = b.length(); i != 0 && j != 0; ) {
	    if (costs[i][j] == (a.charAt(i - 1) == b.charAt(j - 1) ? costs[i-1][j-1] : costs[i-1][j-1] + 1)) {
		aPathRev.append(a.charAt(--i));
		bPathRev.append(b.charAt(--j));
	    } else if (costs[i][j] == 1 + costs[i-1][j]) {
		aPathRev.append(a.charAt(--i));
		bPathRev.append('-');
	    } else if (costs[i][j] == 1 + costs[i][j-1]) {
		aPathRev.append('-');
		bPathRev.append(b.charAt(--j));
	    }
	}
        return new String[]{aPathRev.reverse().toString(), bPathRev.reverse().toString()};
    }

    public static void main(String[] args) {
	String[] result = alignment("rosettacode", "raisethysword");
	System.out.println(result[0]);
	System.out.println(result[1]);
    }
}


List rooted trees

You came back from grocery shopping.    After putting away all the goods, you are left with a pile of plastic bags, which you want to save for later use, so you take one bag and stuff all the others into it, and throw it under the sink.   In doing so, you realize that there are various ways of nesting the bags, with all bags viewed as identical.

If we use a matching pair of parentheses to represent a bag, the ways are:

For 1 bag, there's one way:
  ()	<- a bag

for 2 bags, there's one way:
  (())	<- one bag in another

for 3 bags, there are two:
  ((())) <- 3 bags nested Russian doll style
  (()()) <- 2 bags side by side, inside the third

for 4 bags, four:
  (()()())
  ((())())
  ((()()))
  (((())))

Note that because all bags are identical, the two 4-bag strings ((())()) and (()(())) represent the same configuration.

It's easy to see that each configuration for ''n'' bags represents a ''n''-node rooted tree, where a bag is a tree node, and a bag with its content forms a subtree.  The outermost bag is the tree root.  Number of configurations for given ''n'' is given by OEIS A81.

;Task:
Write a program that, when given ''n'', enumerates all ways of nesting ''n'' bags.   You can use the parentheses notation above, or any tree representation that's unambiguous and preferably intuitive.

This task asks for enumeration of trees only; for counting solutions without enumeration, that OEIS page lists various formulas, but that's not encouraged by this task, especially if implementing it would significantly increase code size.

As an example output, run 5 bags.   There should be 9 ways.

Solution:
import java.util.ArrayList;
import java.util.List;

public class ListRootedTrees {
    private static final List<Long> TREE_LIST = new ArrayList<>();

    private static final List<Integer> OFFSET = new ArrayList<>();

    static {
        for (int i = 0; i < 32; i++) {
            if (i == 1) {
                OFFSET.add(1);
            } else {
                OFFSET.add(0);
            }
        }
    }

    private static void append(long t) {
        TREE_LIST.add(1 | (t << 1));
    }

    private static void show(long t, int l) {
        while (l-- > 0) {
            if (t % 2 == 1) {
                System.out.print('(');
            } else {
                System.out.print(')');
            }
            t = t >> 1;
        }
    }

    private static void listTrees(int n) {
        for (int i = OFFSET.get(n); i < OFFSET.get(n + 1); i++) {
            show(TREE_LIST.get(i), n * 2);
            System.out.println();
        }
    }

    private static void assemble(int n, long t, int sl, int pos, int rem) {
        if (rem == 0) {
            append(t);
            return;
        }

        var pp = pos;
        var ss = sl;

        if (sl > rem) {
            ss = rem;
            pp = OFFSET.get(ss);
        } else if (pp >= OFFSET.get(ss + 1)) {
            ss--;
            if (ss == 0) {
                return;
            }
            pp = OFFSET.get(ss);
        }

        assemble(n, t << (2 * ss) | TREE_LIST.get(pp), ss, pp, rem - ss);
        assemble(n, t, ss, pp + 1, rem);
    }

    private static void makeTrees(int n) {
        if (OFFSET.get(n + 1) != 0) {
            return;
        }
        if (n > 0) {
            makeTrees(n - 1);
        }
        assemble(n, 0, n - 1, OFFSET.get(n - 1), n - 1);
        OFFSET.set(n + 1, TREE_LIST.size());
    }

    private static void test(int n) {
        if (n < 1 || n > 12) {
            throw new IllegalArgumentException("Argument must be between 1 and 12");
        }

        append(0);

        makeTrees(n);
        System.out.printf("Number of %d-trees: %d\n", n, OFFSET.get(n + 1) - OFFSET.get(n));
        listTrees(n);
    }

    public static void main(String[] args) {
        test(5);
    }
}


Long year

Most years have 52 weeks, some have 53, according to ISO8601.

;Task:
Write a function which determines if a given year is long (53 weeks) or not, and demonstrate it.

Solution:
import java.time.LocalDate;
import java.time.temporal.WeekFields;

public class LongYear {

    public static void main(String[] args) {
        System.out.printf("Long years this century:%n");
        for (int year = 2000 ; year < 2100 ; year++ ) {
            if ( longYear(year) ) {
                System.out.print(year + "  ");
            }
        }
    }

    private static boolean longYear(int year) {
        return LocalDate.of(year, 12, 28).get(WeekFields.ISO.weekOfYear()) == 53;
    }

}


Longest common subsequence

'''Introduction'''

Define a ''subsequence'' to be any output string obtained by deleting zero or more symbols from an input string.

The '''Longest Common Subsequence''' ('''LCS''') is a subsequence of maximum length common to two or more strings.

Let ''A''  ''A''[0]... ''A''[m - 1] and ''B''  ''B''[0]... ''B''[n - 1], m < n be strings drawn from an alphabet S of size s, containing every distinct symbol in A + B.

An ordered pair (i, j) will be referred to as a match if ''A''[i] = ''B''[j], where 0 <= i < m and 0 <= j < n.

The set of matches '''M''' defines a relation over matches: '''M'''[i, j] = (i, j)  '''M'''.

Define a ''non-strict'' product-order (<=) over ordered pairs, such that (i1, j1) <= (i2, j2) = i1 <= i2 and j1 <= j2.  We define (>=) similarly.

We say ordered pairs p1 and p2 are ''comparable'' if either p1 <= p2 or p1 >= p2 holds.  If i1 < i2 and j2 < j1 (or i2 < i1 and j1 < j2) then neither p1 <= p2 nor p1 >= p2 are possible, and we say p1 and p2 are ''incomparable''.

Define the ''strict'' product-order (<) over ordered pairs, such that (i1, j1) < (i2, j2) = i1 < i2 and j1 < j2.  We define (>) similarly.

A chain '''C''' is a subset of '''M''' consisting of at least one element m; and where either m1 < m2 or m1 > m2 for every pair of distinct elements m1 and m2.  An antichain '''D''' is any subset of '''M''' in which every pair of distinct elements m1 and m2 are incomparable.

A chain can be visualized as a strictly increasing curve that passes through matches (i, j) in the m*n coordinate space of '''M'''[i, j].

Every Common Sequence of length ''q'' corresponds to a chain of cardinality ''q'', over the set of matches '''M'''.  Thus, finding an LCS can be restated as the problem of finding a chain of maximum cardinality ''p''.

According to [Dilworth 1950], this cardinality ''p'' equals the minimum number of disjoint antichains into which '''M''' can be decomposed.  Note that such a decomposition into the minimal number p of disjoint antichains may not be unique.

'''Background'''

Where the number of symbols appearing in matches is small relative to the length of the input strings, reuse of the symbols increases; and the number of matches will tend towards O(''m*n'') quadratic growth.  This occurs, for example, in the Bioinformatics application of nucleotide and protein sequencing.

The divide-and-conquer approach of [Hirschberg 1975] limits the space required to O(''n'').  However, this approach requires O(''m*n'') time even in the best case.

This quadratic time dependency may become prohibitive, given very long input strings.  Thus, heuristics are often favored over optimal Dynamic Programming solutions.

In the application of comparing file revisions, records from the input files form a large symbol space; and the number of symbols approaches the length of the LCS.  In this case the number of matches reduces to linear, O(''n'') growth.

A binary search optimization due to [Hunt and Szymanski 1977] can be applied to the basic Dynamic Programming approach, resulting in an expected performance of O(''n log m'').  Performance can degrade to O(''m*n log m'') time in the worst case, as the number of matches grows to O(''m*n'').

'''Note'''

[Rick 2000] describes a linear-space algorithm with a time bound of O(''n*s + p*min(m, n - p)'').

'''Legend'''

 A, B are input strings of lengths m, n respectively
 p is the length of the LCS
 M is the set of matches (i, j) such that A[i] = B[j]
 r is the magnitude of M
 s is the magnitude of the alphabet S of distinct symbols in A + B

'''References'''

[Dilworth 1950] "A decomposition theorem for partially ordered sets"
by Robert P. Dilworth, published January 1950,
Annals of Mathematics [Volume 51, Number 1, ''pp.'' 161-166]

[Goeman and Clausen 2002] "A New Practical Linear Space Algorithm for the Longest Common
Subsequence Problem" by Heiko Goeman and Michael Clausen,
published 2002, Kybernetika [Volume 38, Issue 1, ''pp.'' 45-66]

[Hirschberg 1975] "A linear space algorithm for computing maximal common subsequences"
by Daniel S. Hirschberg, published June 1975
Communications of the ACM [Volume 18, Number 6, ''pp.'' 341-343]

[Hunt and McIlroy 1976] "An Algorithm for Differential File Comparison"
by James W. Hunt and M. Douglas McIlroy, June 1976
Computing Science Technical Report, Bell Laboratories 41

[Hunt and Szymanski 1977] "A Fast Algorithm for Computing Longest Common Subsequences"
by James W. Hunt and Thomas G. Szymanski, published May 1977
Communications of the ACM [Volume 20, Number 5, ''pp.'' 350-353]

[Rick 2000] "Simple and fast linear space computation of longest common subsequences"
by Claus Rick, received 17 March 2000, Information Processing Letters,
Elsevier Science [Volume 75, ''pp.'' 275-281]

'''Examples'''

The sequences "1234" and "1224533324" have an LCS of "1234":
 '''1234'''
 '''12'''245'''3'''332'''4'''

For a string example, consider the sequences "thisisatest" and "testing123testing". An LCS would be "tsitest":
 '''t'''hi'''si'''sa'''test'''
 '''t'''e'''s'''t'''i'''ng123'''test'''ing

In this puzzle, your code only needs to deal with strings. Write a function which returns an LCS of two strings (case-sensitive). You don't need to show multiple LCS's.

For more information on this problem please see Wikipedia.

Solution:
public static String lcs(String a, String b) {
    int[][] lengths = new int[a.length()+1][b.length()+1];

    // row 0 and column 0 are initialized to 0 already

    for (int i = 0; i < a.length(); i++)
        for (int j = 0; j < b.length(); j++)
            if (a.charAt(i) == b.charAt(j))
                lengths[i+1][j+1] = lengths[i][j] + 1;
            else
                lengths[i+1][j+1] =
                    Math.max(lengths[i+1][j], lengths[i][j+1]);

    // read the substring out from the matrix
    StringBuffer sb = new StringBuffer();
    for (int x = a.length(), y = b.length();
         x != 0 && y != 0; ) {
        if (lengths[x][y] == lengths[x-1][y])
            x--;
        else if (lengths[x][y] == lengths[x][y-1])
            y--;
        else {
            assert a.charAt(x-1) == b.charAt(y-1);
            sb.append(a.charAt(x-1));
            x--;
            y--;
        }
    }

    return sb.reverse().toString();
}


Longest common substring

Write a function that returns the longest common substring of two strings.

Use it within a program that demonstrates sample output from the function, which will consist of the longest common substring between "thisisatest" and "testing123testing".

Note that substrings are consecutive characters within a string.   This distinguishes them from subsequences, which is any sequence of characters within a string, even if there are extraneous characters in between them.

Hence, the [[longest common subsequence]] between "thisisatest" and "testing123testing" is "tsitest", whereas the longest common sub''string'' is just "test".

;References:
*Generalize Suffix Tree
*[[Ukkonen's Suffix Tree Construction]]

Solution:
public class LongestCommonSubstring {

    public static void main(String[] args) {
        System.out.println(lcs("testing123testing", "thisisatest"));
        System.out.println(lcs("test", "thisisatest"));
        System.out.println(lcs("testing", "sting"));
        System.out.println(lcs("testing", "thisisasting"));
    }

    static String lcs(String a, String b) {
        if (a.length() > b.length())
            return lcs(b, a);

        String res = "";
        for (int ai = 0; ai < a.length(); ai++) {
            for (int len = a.length() - ai; len > 0; len--) {

                for (int bi = 0; bi <= b.length() - len; bi++) {

                    if (a.regionMatches(ai, b, bi, len) && len > res.length()) {
                        res = a.substring(ai, ai + len);
                    }
                }
            }
        }
        return res;
    }
}


Longest increasing subsequence

Calculate and show here a longest increasing subsequence of the list:
:\{3, 2, 6, 4, 5, 1\}
And of the list:
:\{0, 8, 4, 12, 2, 10, 6, 14, 1, 9, 5, 13, 3, 11, 7, 15\}

Note that a list may have more than one subsequence that is of the maximum length.

;Ref:
# Dynamic Programming #1: Longest Increasing Subsequence on YouTube
# An efficient solution can be based on Patience sorting.

Solution:
import java.util.*;

public class LIS {
    public static <E extends Comparable<? super E>> List<E> lis(List<E> n) {
        List<Node<E>> pileTops = new ArrayList<Node<E>>();
        // sort into piles
        for (E x : n) {
	    Node<E> node = new Node<E>();
	    node.value = x;
            int i = Collections.binarySearch(pileTops, node);
            if (i < 0) i = ~i;
	    if (i != 0)
		node.pointer = pileTops.get(i-1);
            if (i != pileTops.size())
                pileTops.set(i, node);
            else
                pileTops.add(node);
        }
	// extract LIS from nodes
	List<E> result = new ArrayList<E>();
	for (Node<E> node = pileTops.size() == 0 ? null : pileTops.get(pileTops.size()-1);
                node != null; node = node.pointer)
	    result.add(node.value);
	Collections.reverse(result);
	return result;
    }

    private static class Node<E extends Comparable<? super E>> implements Comparable<Node<E>> {
	public E value;
	public Node<E> pointer;
        public int compareTo(Node<E> y) { return value.compareTo(y.value); }
    }

    public static void main(String[] args) {
	List<Integer> d = Arrays.asList(3,2,6,4,5,1);
	System.out.printf("an L.I.S. of %s is %s\n", d, lis(d));
        d = Arrays.asList(0, 8, 4, 12, 2, 10, 6, 14, 1, 9, 5, 13, 3, 11, 7, 15);
	System.out.printf("an L.I.S. of %s is %s\n", d, lis(d));
    }
}


Lucky and even lucky numbers

Note that in the following explanation list indices are assumed to start at ''one''.

;Definition of lucky numbers
''Lucky numbers'' are positive integers that are formed by:

# Form a list of all the positive odd integers > 01, 3, 5, 7, 9, 11, 13, 15, 17, 19, 21, 23, 25, 27, 29, 31, 33, 35, 37, 39 ...
# Return the first number from the list (which is '''1''').
# (Loop begins here)
#* Note then return the second number from the list (which is '''3''').
#* Discard every third, (as noted), number from the list to form the new list1, 3, 7, 9, 13, 15, 19, 21, 25, 27, 31, 33, 37, 39, 43, 45, 49, 51, 55, 57 ...
# (Expanding the loop a few more times...)
#* Note then return the third number from the list (which is '''7''').
#* Discard every 7th, (as noted), number from the list to form the new list1, 3, 7, 9, 13, 15, 21, 25, 27, 31, 33, 37, 43, 45, 49, 51, 55, 57, 63, 67 ...
#* Note then return the 4th number from the list (which is '''9''').
#* Discard every 9th, (as noted), number from the list to form the new list1, 3, 7, 9, 13, 15, 21, 25, 31, 33, 37, 43, 45, 49, 51, 55, 63, 67, 69, 73 ...
#* Take the 5th, i.e. '''13'''.  Remove every 13th.
#* Take the 6th, i.e. '''15'''.  Remove every 15th.
#* Take the 7th, i.e. '''21'''.  Remove every 21th.
#* Take the 8th, i.e. '''25'''.  Remove every 25th.
# (Rule for the loop)
#* Note the nth, which is m.
#* Remove every mth.
#* Increment n.

;Definition of even lucky numbers
This follows the same rules as the definition of lucky numbers above ''except for the very first step'':
# Form a list of all the positive '''even''' integers > 02, 4, 6, 8, 10, 12, 14, 16, 18, 20, 22, 24, 26, 28, 30, 32, 34, 36, 38, 40 ...
# Return the first number from the list (which is '''2''').
# (Loop begins here)
#* Note then return the second number from the list (which is '''4''').
#* Discard every 4th, (as noted), number from the list to form the new list2, 4, 6, 10, 12, 14, 18, 20, 22, 26, 28, 30, 34, 36, 38, 42, 44, 46, 50, 52 ...
# (Expanding the loop a few more times...)
#* Note then return the third number from the list (which is '''6''').
#* Discard every 6th, (as noted), number from the list to form the new list2, 4, 6, 10, 12, 18, 20, 22, 26, 28, 34, 36, 38, 42, 44, 50, 52, 54, 58, 60 ...
#* Take the 4th, i.e. '''10'''.  Remove every 10th.
#* Take the 5th, i.e. '''12'''.  Remove every 12th.
# (Rule for the loop)
#* Note the nth, which is m.
#* Remove every mth.
#* Increment n.

;Task requirements
* Write one or two subroutines (functions) to generate ''lucky numbers'' and ''even lucky numbers''
* Write a command-line interface to allow selection of which kind of numbers and which number(s). Since input is from the command line, tests should be made for the common errors:
** missing arguments
** too many arguments
** number (or numbers) aren't legal
** misspelled argument ('''lucky''' or '''evenLucky''')
* The command line handling should:
** support mixed case handling of the (non-numeric) arguments
** support printing a particular number
** support printing a range of numbers by their index
** support printing a range of numbers by their values
* The resulting list of numbers should be printed on a single line.

The program should support the arguments:

                             what is displayed  (on a single line)
       argument(s)              (optional verbiage is encouraged)
  +-------------------+----------------------------------------------------+
  |  j                |  Jth       lucky number                            |
  |  j  ,      lucky  |  Jth       lucky number                            |
  |  j  ,  evenLucky  |  Jth  even lucky number                            |
  |                   |                                                    |
  |  j  k             |  Jth  through  Kth (inclusive)       lucky numbers |
  |  j  k      lucky  |  Jth  through  Kth (inclusive)       lucky numbers |
  |  j  k  evenLucky  |  Jth  through  Kth (inclusive)  even lucky numbers |
  |                   |                                                    |
  |  j -k             |  all       lucky numbers in the range  j --> |k|   |
  |  j -k      lucky  |  all       lucky numbers in the range  j --> |k|   |
  |  j -k  evenLucky  |  all  even lucky numbers in the range  j --> |k|   |
  +-------------------+----------------------------------------------------+
                           where    |k|    is the absolute value of   k

Demonstrate the program by:
* showing the first twenty ''lucky'' numbers
* showing the first twenty ''even lucky'' numbers
* showing all ''lucky'' numbers between 6,000 and 6,100 (inclusive)
* showing all ''even lucky'' numbers in the same range as above
* showing the 10,000th ''lucky'' number (extra credit)
* showing the 10,000th ''even lucky'' number (extra credit)

;See also:
* This task is related to the [[Sieve of Eratosthenes]] task.
* OEIS Wiki Lucky numbers.
* Sequence A000959 lucky numbers on The On-Line Encyclopedia of Integer Sequences.
* Sequence A045954 even lucky numbers or ELN on The On-Line Encyclopedia of Integer Sequences.
* Entry lucky numbers on The Eric Weisstein's World of Mathematics.

Solution:
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;

public class LuckyNumbers {

    private static int MAX = 200000;
    private static List<Integer> luckyEven = luckyNumbers(MAX, true);
    private static List<Integer> luckyOdd = luckyNumbers(MAX, false);

    public static void main(String[] args) {
        //  Case 1 and 2
        if ( args.length == 1 || ( args.length == 2 && args[1].compareTo("lucky") == 0 ) ) {
            int n = Integer.parseInt(args[0]);
            System.out.printf("LuckyNumber(%d) = %d%n", n, luckyOdd.get(n-1));
        }
        //  Case 3
        else if ( args.length == 2 && args[1].compareTo("evenLucky") == 0 ) {
            int n = Integer.parseInt(args[0]);
            System.out.printf("EvenLuckyNumber(%d) = %d%n", n, luckyEven.get(n-1));
        }
        //  Case 4 through 9
        else if ( args.length == 2 || args.length == 3 ) {
            int j = Integer.parseInt(args[0]);
            int k = Integer.parseInt(args[1]);
            //  Case 4 and 5
            if ( ( args.length == 2 && k > 0 ) || (args.length == 3 && k > 0 && args[2].compareTo("lucky") == 0 ) ) {
                System.out.printf("LuckyNumber(%d) through LuckyNumber(%d) = %s%n", j, k, luckyOdd.subList(j-1, k));
            }
            //  Case 6
            else if ( args.length == 3 && k > 0 && args[2].compareTo("evenLucky") == 0 ) {
                System.out.printf("EvenLuckyNumber(%d) through EvenLuckyNumber(%d) = %s%n", j, k, luckyEven.subList(j-1, k));
            }
            //  Case 7 and 8
            else if ( ( args.length == 2 && k < 0 ) || (args.length == 3 && k < 0 && args[2].compareTo("lucky") == 0 ) ) {
                int n = Collections.binarySearch(luckyOdd, j);
                int m = Collections.binarySearch(luckyOdd, -k);
                System.out.printf("Lucky Numbers in the range %d to %d inclusive = %s%n", j, -k, luckyOdd.subList(n < 0 ? -n-1 : n, m < 0 ? -m-1 : m+1));
            }
            //  Case 9
            else if ( args.length == 3 && k < 0 && args[2].compareTo("evenLucky") == 0 ) {
                int n = Collections.binarySearch(luckyEven, j);
                int m = Collections.binarySearch(luckyEven, -k);
                System.out.printf("Even Lucky Numbers in the range %d to %d inclusive = %s%n", j, -k, luckyEven.subList(n < 0 ? -n-1 : n, m < 0 ? -m-1 : m+1));
            }
        }
    }

    private static List<Integer> luckyNumbers(int max, boolean even) {
        List<Integer> luckyList = new ArrayList<>();
        for ( int i = even ? 2 : 1 ; i <= max ; i += 2 ) {
            luckyList.add(i);
        }
        int start = 1;
        boolean removed = true;
        while ( removed ) {
            removed = false;
            int increment = luckyList.get(start);
            List<Integer> remove = new ArrayList<>();
            for ( int i = increment-1 ; i < luckyList.size() ; i += increment ) {
                remove.add(0, i);
                removed = true;
            }
            for ( int i : remove ) {
                luckyList.remove(i);
            }
            start++;
        }
        return luckyList;
    }

}


Lychrel numbers

::#   Take an integer n, greater than zero.
::#   Form the next n of its series by reversing the digits of the current n and adding the result to the current n.
::#   Stop when n becomes palindromic - i.e. the digits of n in reverse order == n.

The above recurrence relation when applied to most starting numbers n = 1, 2, ... terminates in a palindrome quite quickly.

;Example:
If n0 = 12 we get

       12
       12 +  21 =  33,   a palindrome!

And if n0 = 55 we get

       55
       55 +  55 = 110
      110 + 011 = 121,   a palindrome!

Notice that the check for a palindrome happens   ''after''   an addition.

Some starting numbers seem to go on forever; the recurrence relation for 196 has been calculated for millions of repetitions forming numbers with millions of digits, without forming a palindrome.

These numbers that do not end in a palindrome are called '''Lychrel numbers'''.

For the purposes of this task a Lychrel number is any starting number that does not form a palindrome within 500 (or more) iterations.

;Seed and related Lychrel numbers:
Any integer produced in the sequence of a Lychrel number is also a Lychrel number.

In general, any sequence from one Lychrel number ''might'' converge to join the sequence from a prior Lychrel number candidate; for example the sequences for the numbers 196 and then 689 begin:

        196
        196 +    691 =   887
        887 +    788 =  1675
       1675 +   5761 =  7436
       7436 +   6347 = 13783
      13783 +  38731 = 52514
      52514 +  41525 = 94039
       ...

        689
        689 +    986 =  1675
       1675 +   5761 =  7436
       ...

So we see that the sequence starting with 689 converges to, and continues with the same numbers as that for 196.

Because of this we can further split the Lychrel numbers into true '''Seed''' Lychrel number candidates, and '''Related''' numbers that produce no palindromes but have integers in their sequence seen as part of the sequence generated from a lower Lychrel number.

;Task:
*   Find the number of seed Lychrel number candidates and related numbers for n in the range 1..10000 inclusive. (With that iteration limit of 500).
*    Print the number of seed Lychrels found; the actual seed Lychrels; and just the ''number'' of relateds found.
*    Print any seed Lychrel or related number that is itself a palindrome.

Show all output here.

;References:
*   What's special about 196? Numberphile video.
*   A023108 Positive integers which apparently never result in a palindrome under repeated applications of the function f(x) = x + (x with digits reversed).
*   Status of the 196 conjecture? Mathoverflow.

Solution: Translation of [[Lychrel_numbers#Python|Python]] via [[Lychrel_numbers#D|D]]


Lychrel numbers

Solution:
import java.math.BigInteger;
import java.util.*;

public class Lychrel {

    static Map<BigInteger, Tuple> cache = new HashMap<>();

    static class Tuple {
        final Boolean flag;
        final BigInteger bi;

        Tuple(boolean f, BigInteger b) {
            flag = f;
            bi = b;
        }
    }

    static BigInteger rev(BigInteger bi) {
        String s = new StringBuilder(bi.toString()).reverse().toString();
        return new BigInteger(s);
    }

    static Tuple lychrel(BigInteger n) {
        Tuple res;
        if ((res = cache.get(n)) != null)
            return res;

        BigInteger r = rev(n);
        res = new Tuple(true, n);
        List<BigInteger> seen = new ArrayList<>();

        for (int i = 0; i < 500; i++) {
            n = n.add(r);
            r = rev(n);

            if (n.equals(r)) {
                res = new Tuple(false, BigInteger.ZERO);
                break;
            }

            if (cache.containsKey(n)) {
                res = cache.get(n);
                break;
            }

            seen.add(n);
        }

        for (BigInteger bi : seen)
            cache.put(bi, res);

        return res;
    }

    public static void main(String[] args) {

        List<BigInteger> seeds = new ArrayList<>();
        List<BigInteger> related = new ArrayList<>();
        List<BigInteger> palin = new ArrayList<>();

        for (int i = 1; i <= 10_000; i++) {
            BigInteger n = BigInteger.valueOf(i);

            Tuple t = lychrel(n);

            if (!t.flag)
                continue;

            if (n.equals(t.bi))
                seeds.add(t.bi);
            else
                related.add(t.bi);

            if (n.equals(t.bi))
                palin.add(t.bi);
        }

        System.out.printf("%d Lychrel seeds: %s%n", seeds.size(), seeds);
        System.out.printf("%d Lychrel related%n", related.size());
        System.out.printf("%d Lychrel palindromes: %s%n", palin.size(), palin);
    }
}


MAC vendor lookup

Every connected device around the world comes with a unique Media Access Control address, or a   MAC address.

A common task a network administrator may come across is being able to identify a network device's manufacturer when given only a MAC address.

;Task:
Interface with one (or numerous) APIs that exist on the internet and retrieve the device manufacturer based on a supplied MAC address.

A MAC address that does not return a valid result should return the String "N/A".   An error related to the network connectivity or the API should return a null result.

Many implementations on this page use http://api.macvendors.com/ which, as of 19th September 2021, is throttling requests. After only 2 calls, the following response is returned for all subsequent requests. If you are planning to use the same provider or going to run the examples on this page, consider building in a delay between two calls.

'''{"errors":{"detail":"Too Many Requests","message":"Please slow down your requests or upgrade your plan at https://macvendors.com"}}'''

Solution:
package com.jamesdonnell.MACVendor;

import java.io.BufferedReader;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.HttpURLConnection;
import java.net.URL;

/** MAC Vendor Lookup class.
 * www.JamesDonnell.com
 * @author James A. Donnell Jr. */
public class Lookup {
	/** Base URL for API. The API from www.macvendors.com was chosen. */
	private static final String baseURL = "http://api.macvendors.com/";

	/** Performs lookup on MAC address(es) supplied in arguments.
	 * @param args MAC address(es) to lookup. */
	public static void main(String[] args) {
		for (String arguments : args)
			System.out.println(arguments + ": " + get(arguments));
	}

	/** Performs lookup on supplied MAC address.
	 * @param macAddress MAC address to lookup.
	 * @return Manufacturer of MAC address. */
	private static String get(String macAddress) {
		try {
			StringBuilder result = new StringBuilder();
			URL url = new URL(baseURL + macAddress);
			HttpURLConnection conn = (HttpURLConnection) url.openConnection();
			conn.setRequestMethod("GET");
			BufferedReader rd = new BufferedReader(new InputStreamReader(conn.getInputStream()));
			String line;
			while ((line = rd.readLine()) != null) {
				result.append(line);
			}
			rd.close();
			return result.toString();
		} catch (FileNotFoundException e) {
			// MAC not found
			return "N/A";
		} catch (IOException e) {
			// Error during lookup, either network or API.
			return null;
		}
	}
}


Mad Libs

{{wikipedia}}

Mad Libs is a phrasal template word game where one player prompts another for a list of words to substitute for blanks in a story, usually with funny results.

;Task;
Write a program to create a Mad Libs like story.

The program should read an arbitrary multiline story from input.

The story will be terminated with a blank line.

Then, find each replacement to be made within the story, ask the user for a word to replace it with, and make all the replacements.

Stop when there are none left and print the final story.

The input should be an arbitrary story in the form:

 went for a walk in the park.
found a .  decided to take it home.

Given this example, it should then ask for a name, a he or she and a noun ( gets replaced both times with the same value).

Solution:
import java.util.*;

public class MadLibs {

    public static void main(String[] args){
        Scanner input = new Scanner(System.in);

        String name, gender, noun;

        System.out.print("Enter a name: ");
        name = input.next();

        System.out.print("He or she: ");
        gender = input.next();

        System.out.print("Enter a noun: ");
        noun = input.next();

        System.out.println("\f" + name + " went for a walk in the park. " + gender + "\nfound a " + noun + ". " + name + " decided to take it home.");

    }
}


Magic 8-ball

Create Magic 8-Ball.

See details at:   Magic 8-Ball.

Solution:
import java.util.Random;
import java.util.Scanner;

public class MagicEightBall {

    public static void main(String[] args) {
        new MagicEightBall().run();
    }

    private static String[] ANSWERS = new String[] {"It is certain.", "It is decidedly so.", "Without a doubt.", "Yes - definitely.",
            "You may rely on it.", "As I see it, yes.", "Most likely.", "Outlook good.", "Yes.", "Signs point to yes.",
            "Reply hazy, try again.", "Ask again later.", "Better not tell you now.", "Cannot predict now.", "Concentrate and ask again.",
            "Don't count on it.", "My reply is no.", "My sources say no.", "Outlook not so good.", "Very doubtful. "};

    public void run() {
        Random random = new Random();
        System.out.printf("Hello.  The Magic 8 Ball knows all.  Type your question.%n%n");
        try ( Scanner in = new Scanner(System.in); ) {
            System.out.printf("?  ");
            while ( (in.nextLine()).length() > 0 ) {
                System.out.printf("8 Ball Response:  %s%n", ANSWERS[random.nextInt(ANSWERS.length)]);
                System.out.printf("?  ");
            }
        }
        System.out.printf("%n8 Ball Done.  Bye.");
    }
}


Magic squares of doubly even order

Solution:
public class MagicSquareDoublyEven {

    public static void main(String[] args) {
        int n = 8;
        for (int[] row : magicSquareDoublyEven(n)) {
            for (int x : row)
                System.out.printf("%2s ", x);
            System.out.println();
        }
        System.out.printf("\nMagic constant: %d ", (n * n + 1) * n / 2);
    }

    static int[][] magicSquareDoublyEven(final int n) {
        if (n < 4 || n % 4 != 0)
            throw new IllegalArgumentException("base must be a positive "
                    + "multiple of 4");

        // pattern of count-up vs count-down zones
        int bits = 0b1001_0110_0110_1001;
        int size = n * n;
        int mult = n / 4;  // how many multiples of 4

        int[][] result = new int[n][n];

        for (int r = 0, i = 0; r < n; r++) {
            for (int c = 0; c < n; c++, i++) {
                int bitPos = c / mult + (r / mult) * 4;
                result[r][c] = (bits & (1 << bitPos)) != 0 ? i + 1 : size - i;
            }
        }
        return result;
    }
}


Magic squares of odd order

A magic square is an   '''NxN'''   square matrix whose numbers (usually integers) consist of consecutive numbers arranged so that the sum of each row and column,   ''and''   both long (main) diagonals are equal to the same sum (which is called the   ''magic number''   or   ''magic constant'').

The numbers are usually (but not always) the first   '''N'''2   positive integers.

A magic square whose rows and columns add up to a magic number but whose main diagonals do not, is known as a ''semimagic square''.

{| class="wikitable" style="float:right;border: 4px solid blue; background:lightgreen; color:black; margin-left:auto;margin-right:auto;text-align:center;width:15em;height:15em;table-layout:fixed;font-size:150%"
|-
| '''8''' || '''1''' || '''6'''
|-
| '''3''' || '''5''' || '''7'''
|-
| '''4''' || '''9''' || '''2'''
|}

;Task
For any odd   '''N''',   generate a magic square with the integers   ''' 1''' --> '''N''',   and show the results here.

Optionally, show the ''magic number''.

You should demonstrate the generator by showing at least a magic square for   '''N''' = '''5'''.

; Related tasks
* [[Magic squares of singly even order]]
* [[Magic squares of doubly even order]]

; See also:
* MathWorld(tm) entry: Magic_square
* Odd Magic Squares (1728.org)

Solution:
public class MagicSquare {

    public static void main(String[] args) {
        int n = 5;
        for (int[] row : magicSquareOdd(n)) {
            for (int x : row)
                System.out.format("%2s ", x);
            System.out.println();
        }
        System.out.printf("\nMagic constant: %d ", (n * n + 1) * n / 2);
    }

    public static int[][] magicSquareOdd(final int base) {
        if (base % 2 == 0 || base < 3)
            throw new IllegalArgumentException("base must be odd and > 2");

        int[][] grid = new int[base][base];
        int r = 0, number = 0;
        int size = base * base;

        int c = base / 2;
        while (number++ < size) {
            grid[r][c] = number;
            if (r == 0) {
                if (c == base - 1) {
                    r++;
                } else {
                    r = base - 1;
                    c++;
                }
            } else {
                if (c == base - 1) {
                    r--;
                    c = 0;
                } else {
                    if (grid[r - 1][c + 1] == 0) {
                        r--;
                        c++;
                    } else {
                        r++;
                    }
                }
            }
        }
        return grid;
    }
}


Magic squares of singly even order

A magic square is an '''NxN''' square matrix whose numbers consist of consecutive numbers arranged so that the sum of each row and column, ''and'' both diagonals are equal to the same sum (which is called the ''magic number'' or ''magic constant'').

A  magic square of singly even order has a size that is a multiple of 4, plus 2 (e.g. 6, 10, 14). This means that the subsquares have an odd size, which plays a role in the construction.

;Task
Create a magic square of 6 x 6.

; Related tasks
* [[Magic squares of odd order]]
* [[Magic squares of doubly even order]]

; See also
* Singly Even Magic Squares (1728.org)

Solution:
public class MagicSquareSinglyEven {

    public static void main(String[] args) {
        int n = 6;
        for (int[] row : magicSquareSinglyEven(n)) {
            for (int x : row)
                System.out.printf("%2s ", x);
            System.out.println();
        }
        System.out.printf("\nMagic constant: %d ", (n * n + 1) * n / 2);
    }

    public static int[][] magicSquareOdd(final int n) {
        if (n < 3 || n % 2 == 0)
            throw new IllegalArgumentException("base must be odd and > 2");

        int value = 0;
        int gridSize = n * n;
        int c = n / 2, r = 0;

        int[][] result = new int[n][n];

        while (++value <= gridSize) {
            result[r][c] = value;
            if (r == 0) {
                if (c == n - 1) {
                    r++;
                } else {
                    r = n - 1;
                    c++;
                }
            } else if (c == n - 1) {
                r--;
                c = 0;
            } else if (result[r - 1][c + 1] == 0) {
                r--;
                c++;
            } else {
                r++;
            }
        }
        return result;
    }

    static int[][] magicSquareSinglyEven(final int n) {
        if (n < 6 || (n - 2) % 4 != 0)
            throw new IllegalArgumentException("base must be a positive "
                    + "multiple of 4 plus 2");

        int size = n * n;
        int halfN = n / 2;
        int subSquareSize = size / 4;

        int[][] subSquare = magicSquareOdd(halfN);
        int[] quadrantFactors = {0, 2, 3, 1};
        int[][] result = new int[n][n];

        for (int r = 0; r < n; r++) {
            for (int c = 0; c < n; c++) {
                int quadrant = (r / halfN) * 2 + (c / halfN);
                result[r][c] = subSquare[r % halfN][c % halfN];
                result[r][c] += quadrantFactors[quadrant] * subSquareSize;
            }
        }

        int nColsLeft = halfN / 2;
        int nColsRight = nColsLeft - 1;

        for (int r = 0; r < halfN; r++)
            for (int c = 0; c < n; c++) {
                if (c < nColsLeft || c >= n - nColsRight
                        || (c == nColsLeft && r == nColsLeft)) {

                    if (c == 0 && r == nColsLeft)
                        continue;

                    int tmp = result[r][c];
                    result[r][c] = result[r + halfN][c];
                    result[r + halfN][c] = tmp;
                }
            }

        return result;
    }
}


Map range

Given two ranges:
:::*   [a_1,a_2]   and
:::*   [b_1,b_2];
:::*   then a value   s   in range   [a_1,a_2]
:::*   is linearly mapped to a value   t   in range   [b_1,b_2]
   where:

:::*   t = b_1 + {(s - a_1)(b_2 - b_1) \over (a_2 - a_1)}

;Task:
Write a function/subroutine/... that takes two ranges and a real number, and returns the mapping of the real number from the first to the second range.

Use this function to map values from the range    [0, 10]    to the range    [-1, 0].

;Extra credit:
Show additional idiomatic ways of performing the mapping, using tools available to the language.

Solution:
public class Range {
	public static void main(String[] args){
		for(float s = 0;s <= 10; s++){
			System.out.println(s + " in [0, 10] maps to "+
					mapRange(0, 10, -1, 0, s)+" in [-1, 0].");
		}
	}

	public static double mapRange(double a1, double a2, double b1, double b2, double s){
		return b1 + ((s - a1)*(b2 - b1))/(a2 - a1);
	}
}


Maximum triangle path sum

Starting from the top of a pyramid of numbers like this, you can walk down going one step on the right or on the left, until you reach the bottom row:

                          55
                        94 48
                       95 30 96
                     77 71 26 67

One of such walks is 55 - 94 - 30 - 26.
You can compute the total of the numbers you have seen in such walk,
in this case it's 205.

Your problem is to find the maximum total among all possible paths from the top to the bottom row of the triangle. In the little example above it's 321.

;Task:
Find the maximum total in the triangle below:

                          55
                        94 48
                       95 30 96
                     77 71 26 67
                    97 13 76 38 45
                  07 36 79 16 37 68
                 48 07 09 18 70 26 06
               18 72 79 46 59 79 29 90
              20 76 87 11 32 07 07 49 18
            27 83 58 35 71 11 25 57 29 85
           14 64 36 96 27 11 58 56 92 18 55
         02 90 03 60 48 49 41 46 33 36 47 23
        92 50 48 02 36 59 42 79 72 20 82 77 42
      56 78 38 80 39 75 02 71 66 66 01 03 55 72
     44 25 67 84 71 67 11 61 40 57 58 89 40 56 36
   85 32 25 85 57 48 84 35 47 62 17 01 01 99 89 52
  06 71 28 75 94 48 37 10 23 51 06 48 53 18 74 98 15
27 02 92 23 08 71 76 84 15 52 92 63 81 10 44 10 69 93

Such numbers can be included in the solution code, or read from a "triangle.txt" file.

This task is derived from the Euler Problem #18.

Solution:
import java.nio.file.*;
import static java.util.Arrays.stream;

public class MaxPathSum {

    public static void main(String[] args) throws Exception {
        int[][] data = Files.lines(Paths.get("triangle.txt"))
                .map(s -> stream(s.trim().split("\\s+"))
                        .mapToInt(Integer::parseInt)
                        .toArray())
                .toArray(int[][]::new);

        for (int r = data.length - 1; r > 0; r--)
            for (int c = 0; c < data[r].length - 1; c++)
                data[r - 1][c] += Math.max(data[r][c], data[r][c + 1]);

        System.out.println(data[0][0]);
    }
}


McNuggets problem

From Wikipedia:
 The McNuggets version of the coin problem was introduced by Henri Picciotto,
 who included it in his algebra textbook co-authored with Anita Wah. Picciotto
 thought of the application in the 1980s while dining with his son at
 McDonald's, working the problem out on a napkin. A McNugget number is
 the total number of McDonald's Chicken McNuggets in any number of boxes.
 In the United Kingdom, the original boxes (prior to the introduction of
 the Happy Meal-sized nugget boxes) were of 6, 9, and 20 nuggets.

;Task:
Calculate (from 0 up to a limit of 100) the largest non-McNuggets
number (a number ''n'' which cannot be expressed with ''6x + 9y + 20z = n''
where ''x'', ''y'' and ''z'' are natural numbers).

Solution:
public class McNuggets {

    public static void main(String... args) {
        int[] SIZES = new int[] { 6, 9, 20 };
        int MAX_TOTAL = 100;
        // Works like Sieve of Eratosthenes
        int numSizes = SIZES.length;
        int[] counts = new int[numSizes];
        int maxFound = MAX_TOTAL + 1;
        boolean[] found = new boolean[maxFound];
        int numFound = 0;
        int total = 0;
        boolean advancedState = false;
        do {
            if (!found[total]) {
                found[total] = true;
                numFound++;
            }

            // Advance state
            advancedState = false;
            for (int i = 0; i < numSizes; i++) {
                int curSize = SIZES[i];
                if ((total + curSize) > MAX_TOTAL) {
                    // Reset to zero and go to the next box size
                    total -= counts[i] * curSize;
                    counts[i] = 0;
                }
                else {
                    // Adding a box of this size still keeps the total at or below the maximum
                    counts[i]++;
                    total += curSize;
                    advancedState = true;
                    break;
                }
            }

        } while ((numFound < maxFound) && advancedState);

        if (numFound < maxFound) {
            // Did not find all counts within the search space
            for (int i = MAX_TOTAL; i >= 0; i--) {
                if (!found[i]) {
                    System.out.println("Largest non-McNugget number in the search space is " + i);
                    break;
                }
            }
        }
        else {
            System.out.println("All numbers in the search space are McNugget numbers");
        }

        return;
    }
}


Meissel–Mertens constant

Calculate Meissel-Mertens constant up to a precision your language can handle.

;Motivation:
Analogous to Euler's constant, which is important in determining the sum of reciprocal natural numbers, Meissel-Mertens' constant is important in calculating the sum of reciprocal primes.

;Example:
We consider the finite sum of reciprocal natural numbers:

''1 + 1/2 + 1/3 + 1/4 + 1/5 ... 1/n''

this sum can be well approximated with:

''log(n) + E''

where ''E'' denotes Euler's constant: 0.57721...

''log(n)'' denotes the natural logarithm of ''n''.

Now consider the finite sum of reciprocal primes:

''1/2 + 1/3 + 1/5 + 1/7 + 1/11 ... 1/p''

this sum can be well approximated with:

''log( log(p) ) + M''

where ''M'' denotes Meissel-Mertens constant: 0.26149...

;See:
:*   Details in the Wikipedia article:  Meissel-Mertens constant

Solution:
import java.util.ArrayList;
import java.util.BitSet;
import java.util.List;

/**
 * Calculates the Meissel-Mertens constant correct to 9 s.f. in approximately 15 seconds.
 */
public final class MeisselMertensConstant {

	public static void main(String[] aArgs) {
		List<Double> primeReciprocals = listPrimeReciprocals(1_000_000_000);
		final double euler = 0.577_215_664_901_532_861;
		double sum = 0.0;
	    for ( double reciprocal : primeReciprocals ) {
	    	sum +=  reciprocal + Math.log(1.0 - reciprocal);
	    }

	    final double constant = euler + sum;
	    System.out.println("The Meissel-Mertens constant = " + constant);
	}

	private static List<Double> listPrimeReciprocals(int aLimit) {
		BitSet sieve = new BitSet(aLimit + 1);
		sieve.set(2, aLimit + 1);

		final int squareRoot = (int) Math.sqrt(aLimit);
		for ( int i = 2; i <= squareRoot; i = sieve.nextSetBit(i + 1) ) {
			for ( int j = i * i; j <= aLimit; j += i ) {
				sieve.clear(j);
			}
		}

		List<Double> result = new ArrayList<Double>(sieve.cardinality());
		for ( int i = 2; i >= 0; i = sieve.nextSetBit(i + 1) ) {
			result.add(1.0 / i);
		}

		return result;
	}

}


Metallic ratios

Many people have heard of the '''Golden ratio''', phi ('''ph'''). Phi is just one of a series
of related ratios that are referred to as the "'''Metallic ratios'''".

The '''Golden ratio''' was discovered and named by ancient civilizations as it was
thought to be the most pure and beautiful (like Gold). The '''Silver ratio''' was was
also known to the early Greeks, though was not named so until later as a nod to
the '''Golden ratio''' to which it is closely related. The series has been extended to
encompass all of the related ratios and was given the general name '''Metallic ratios''' (or ''Metallic means'').
''Somewhat incongruously as the original Golden ratio referred to the adjective "golden" rather than the metal "gold".''

'''Metallic ratios''' are the real roots of the general form equation:

          x2 - bx - 1 = 0

where the integer '''b''' determines which specific one it is.

Using the quadratic equation:

          ( -b +- (b2 - 4ac) ) / 2a = x

Substitute in (from the top equation) '''1''' for '''a''', '''-1''' for '''c''', and recognising that -b is negated we get:

          ( b +- (b2 + 4) ) ) / 2 = x

We only want the real root:

          ( b + (b2 + 4) ) ) / 2 = x

When we set '''b''' to '''1''', we get an irrational number: the '''Golden ratio'''.

          ( 1 + (12 + 4) ) / 2  =  (1 + 5) / 2 = ~1.618033989...

With '''b''' set to '''2''', we get a different irrational number: the '''Silver ratio'''.

          ( 2 + (22 + 4) ) / 2  =  (2 + 8) / 2 = ~2.414213562...

When the ratio '''b''' is '''3''', it is commonly referred to as the '''Bronze''' ratio, '''4''' and '''5'''
are sometimes called the '''Copper''' and '''Nickel''' ratios, though they aren't as
standard. After that there isn't really any attempt at standardized names. They
are given names here on this page, but consider the names fanciful rather than
canonical.

Note that technically, '''b''' can be '''0''' for a "smaller" ratio than the '''Golden ratio'''.
We will refer to it here as the '''Platinum ratio''', though it is kind-of a
degenerate case.

'''Metallic ratios''' where '''b''' > '''0''' are also defined by the irrational continued fractions:

          [b;b,b,b,b,b,b,b,b,b,b,b,b,b,b,b,b...]

So, The first ten '''Metallic ratios''' are:

:::::: {| class="wikitable" style="text-align: center;"
|+ Metallic ratios
!Name!!'''b'''!!Equation!!Value!!Continued fraction!!OEIS link
|-
|Platinum||0||(0 + 4) / 2|| 1||-||-
|-
|Golden||1||(1 + 5) / 2|| 1.618033988749895...||[1;1,1,1,1,1,1,1,1,1,1...]||[[OEIS:A001622]]
|-
|Silver||2||(2 + 8) / 2|| 2.414213562373095...||[2;2,2,2,2,2,2,2,2,2,2...]||[[OEIS:A014176]]
|-
|Bronze||3||(3 + 13) / 2|| 3.302775637731995...||[3;3,3,3,3,3,3,3,3,3,3...]||[[OEIS:A098316]]
|-
|Copper||4||(4 + 20) / 2|| 4.23606797749979...||[4;4,4,4,4,4,4,4,4,4,4...]||[[OEIS:A098317]]
|-
|Nickel||5||(5 + 29) / 2|| 5.192582403567252...||[5;5,5,5,5,5,5,5,5,5,5...]||[[OEIS:A098318]]
|-
|Aluminum||6||(6 + 40) / 2|| 6.16227766016838...||[6;6,6,6,6,6,6,6,6,6,6...]||[[OEIS:A176398]]
|-
|Iron||7||(7 + 53) / 2|| 7.140054944640259...||[7;7,7,7,7,7,7,7,7,7,7...]||[[OEIS:A176439]]
|-
|Tin||8||(8 + 68) / 2|| 8.123105625617661...||[8;8,8,8,8,8,8,8,8,8,8...]||[[OEIS:A176458]]
|-
|Lead||9||(9 + 85) / 2|| 9.109772228646444...||[9;9,9,9,9,9,9,9,9,9,9...]||[[OEIS:A176522]]
|}

There are other ways to find the '''Metallic ratios'''; one, (the focus of this task)
is through '''successive approximations of Lucas sequences'''.

A traditional '''Lucas sequence''' is of the form:

    x''n'' = P * x''n-1'' - Q * x''n-2''

and starts with the first 2 values '''0, 1'''.

For our purposes in this task, to find the metallic ratios we'll use the form:

    x''n'' = b * x''n-1'' + x''n-2''

( '''P''' is set to '''b''' and '''Q''' is set to '''-1'''. ) To avoid "divide by zero" issues we'll start the sequence with the first two terms '''1, 1'''. The initial starting value has very little effect on the final ratio or convergence rate. ''Perhaps it would be more accurate to call it a Lucas-like sequence.''

At any rate, when '''b = 1''' we get:

    x''n'' = x''n-1'' + x''n-2''

    1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89, 144...

more commonly known as the Fibonacci sequence.

When '''b = 2''':

    x''n'' = 2 * x''n-1'' + x''n-2''

    1, 1, 3, 7, 17, 41, 99, 239, 577, 1393...

And so on.

To find the ratio by successive approximations, divide the ('''n+1''')th term by the
'''n'''th. As '''n''' grows larger, the ratio will approach the '''b''' metallic ratio.

For '''b = 1''' (Fibonacci sequence):

    1/1   = 1
    2/1   = 2
    3/2   = 1.5
    5/3   = 1.666667
    8/5   = 1.6
    13/8  = 1.625
    21/13 = 1.615385
    34/21 = 1.619048
    55/34 = 1.617647
    89/55 = 1.618182
    etc.

It converges, but pretty slowly. In fact, the '''Golden ratio''' has the slowest
possible convergence for any irrational number.

;Task

For each of the first '''10 Metallic ratios'''; '''b''' = '''0''' through '''9''':

* Generate the corresponding "Lucas" sequence.
* Show here, on this page, at least the first '''15''' elements of the "Lucas" sequence.
* Using successive approximations, calculate the value of the ratio accurate to '''32''' decimal places.
* Show the '''value''' of the '''approximation''' at the required accuracy.
* Show the '''value''' of '''n''' when the approximation reaches the required accuracy (How many iterations did it take?).

Optional, stretch goal - Show the '''value''' and number of iterations '''n''', to approximate the '''Golden ratio''' to '''256''' decimal places.

You may assume that the approximation has been reached when the next iteration does not cause the value (to the desired places) to change.

;See also
* Wikipedia: Metallic mean
* Wikipedia: Lucas sequence

Solution:
import java.math.BigDecimal;
import java.math.BigInteger;
import java.math.MathContext;
import java.util.ArrayList;
import java.util.List;

public class MetallicRatios {

    private static String[] ratioDescription = new String[] {"Platinum", "Golden", "Silver", "Bronze", "Copper", "Nickel", "Aluminum", "Iron", "Tin", "Lead"};

    public static void main(String[] args) {
        int elements = 15;
        for ( int b = 0 ; b < 10 ; b++ ) {
            System.out.printf("Lucas sequence for %s ratio, where b = %d:%n", ratioDescription[b], b);
            System.out.printf("First %d elements: %s%n", elements, lucasSequence(1, 1, b, elements));
            int decimalPlaces = 32;
            BigDecimal[] ratio = lucasSequenceRatio(1, 1, b, decimalPlaces+1);
            System.out.printf("Value to %d decimal places after %s iterations : %s%n", decimalPlaces, ratio[1], ratio[0]);
            System.out.printf("%n");
        }
        int b = 1;
        int decimalPlaces = 256;
        System.out.printf("%s ratio, where b = %d:%n", ratioDescription[b], b);
        BigDecimal[] ratio = lucasSequenceRatio(1, 1, b, decimalPlaces+1);
        System.out.printf("Value to %d decimal places after %s iterations : %s%n", decimalPlaces, ratio[1], ratio[0]);
    }

    private static BigDecimal[] lucasSequenceRatio(int x0, int x1, int b, int digits) {
        BigDecimal x0Bi = BigDecimal.valueOf(x0);
        BigDecimal x1Bi = BigDecimal.valueOf(x1);
        BigDecimal bBi = BigDecimal.valueOf(b);
        MathContext mc = new MathContext(digits);
        BigDecimal fractionPrior = x1Bi.divide(x0Bi, mc);
        int iterations = 0;
        while ( true ) {
            iterations++;
            BigDecimal x = bBi.multiply(x1Bi).add(x0Bi);
            BigDecimal fractionCurrent = x.divide(x1Bi, mc);
            if ( fractionCurrent.compareTo(fractionPrior) == 0 ) {
                break;
            }
            x0Bi = x1Bi;
            x1Bi = x;
            fractionPrior = fractionCurrent;
        }
        return new BigDecimal[] {fractionPrior, BigDecimal.valueOf(iterations)};
    }

    private static List<BigInteger> lucasSequence(int x0, int x1, int b, int n) {
        List<BigInteger> list = new ArrayList<>();
        BigInteger x0Bi = BigInteger.valueOf(x0);
        BigInteger x1Bi = BigInteger.valueOf(x1);
        BigInteger bBi = BigInteger.valueOf(b);
        if ( n > 0 ) {
            list.add(x0Bi);
        }
        if ( n > 1 ) {
            list.add(x1Bi);
        }
        while ( n > 2 ) {
            BigInteger x = bBi.multiply(x1Bi).add(x0Bi);
            list.add(x);
            n--;
            x0Bi = x1Bi;
            x1Bi = x;
        }
        return list;
    }

}


Metronome

The task is to implement a   metronome.

The metronome should be capable of producing high and low audio beats, accompanied by a visual beat indicator, and the beat pattern and tempo should be configurable.

For the purpose of this task, it is acceptable to play sound files for production of the beat notes, and an external player may be used.

However, the playing of the sounds should not interfere with the timing of the metronome.

The visual indicator can simply be a blinking red or green area of the screen (depending on whether a high or low beat is being produced), and the metronome can be implemented using a terminal display, or optionally, a graphical display, depending on the language capabilities.

If the language has no facility to output sound, then it is permissible for this to implemented using just the visual indicator.

Solution:
class Metronome{
	double bpm;
	int measure, counter;
	public Metronome(double bpm, int measure){
		this.bpm = bpm;
		this.measure = measure;
	}
	public void start(){
		while(true){
			try {
				Thread.sleep((long)(1000*(60.0/bpm)));
			}catch(InterruptedException e) {
				e.printStackTrace();
			}
			counter++;
			if (counter%measure==0){
				 System.out.println("TICK");
			}else{
				 System.out.println("TOCK");
			}
		}
	}
}
public class test {
	public static void main(String[] args) {
		Metronome metronome1 = new Metronome(120,4);
		metronome1.start();
	}
}


Mian-Chowla sequence

The Mian-Chowla sequence is an integer sequence defined recursively.

Mian-Chowla is an infinite instance of a Sidon sequence, and belongs to the class known as B2 sequences.

The sequence starts with:

::a1 = 1

then for n > 1, an is the smallest positive integer such that every pairwise sum

::ai + aj

is distinct, for all i and j less than or equal to n.

;The Task:

:* Find and display, here, on this page the first 30 terms of the Mian-Chowla sequence.
:* Find and display, here, on this page the 91st through 100th terms of the Mian-Chowla sequence.

Demonstrating working through the first few terms longhand:

::a1 = 1

::1 + 1 = 2

Speculatively try a2 = 2

::1 + 1 = 2
::1 + 2 = 3
::2 + 2 = 4

There are no repeated sums so '''2''' is the next number in the sequence.

Speculatively try a3 = 3

::1 + 1 = 2
::1 + 2 = 3
::1 + 3 = 4
::2 + 2 = 4
::2 + 3 = 5
::3 + 3 = 6

Sum of '''4''' is repeated so '''3''' is rejected.

Speculatively try a3 = 4

::1 + 1 = 2
::1 + 2 = 3
::1 + 4 = 5
::2 + 2 = 4
::2 + 4 = 6
::4 + 4 = 8

There are no repeated sums so '''4''' is the next number in the sequence.

And so on...

;See also:

:* OEIS:A005282 Mian-Chowla sequence

Solution:
import java.util.Arrays;

public class MianChowlaSequence {

    public static void main(String[] args) {
        long start = System.currentTimeMillis();
        System.out.println("First 30 terms of the Mian–Chowla sequence.");
        mianChowla(1, 30);
        System.out.println("Terms 91 through 100 of the Mian–Chowla sequence.");
        mianChowla(91, 100);
        long end = System.currentTimeMillis();
        System.out.printf("Elapsed = %d ms%n", (end-start));
    }

    private static void mianChowla(int minIndex, int maxIndex) {
        int [] sums = new int[1];
        int [] chowla = new int[maxIndex+1];
        sums[0] = 2;
        chowla[0] = 0;
        chowla[1] = 1;
        if ( minIndex == 1 ) {
            System.out.printf("%d ", 1);
        }
        int chowlaLength = 1;
        for ( int n = 2 ; n <= maxIndex ; n++ ) {

            //  Sequence is strictly increasing.
            int test = chowla[n - 1];
            //  Bookkeeping.  Generate only new sums.
            int[] sumsNew = Arrays.copyOf(sums, sums.length + n);
            int sumNewLength = sums.length;
            int savedsSumNewLength = sumNewLength;

            //  Generate test candidates for the next value of the sequence.
            boolean found = false;
            while ( ! found ) {
                test++;
                found = true;
                sumNewLength = savedsSumNewLength;
                //  Generate test sums
                for ( int j = 0 ; j <= chowlaLength ; j++ ) {
                    int testSum = (j == 0 ? test : chowla[j]) + test;
                    boolean duplicate = false;

                    //  Check if test Sum in array
                    for ( int k = 0 ; k < sumNewLength ; k++ ) {
                        if ( sumsNew[k] == testSum ) {
                            duplicate = true;
                            break;
                        }
                    }
                    if ( ! duplicate ) {
                        //  Add to array
                        sumsNew[sumNewLength] = testSum;
                        sumNewLength++;
                    }
                    else {
                        //  Duplicate found.  Therefore, test candidate of the next value of the sequence is not OK.
                        found = false;
                        break;
                    }
                }
            }

            //  Bingo!  Now update bookkeeping.
            chowla[n] = test;
            chowlaLength++;
            sums = sumsNew;
            if ( n >= minIndex ) {
                System.out.printf("%d %s", chowla[n], (n==maxIndex ? "\n" : ""));
            }
        }
    }

}


Middle three digits

Write a function/procedure/subroutine that is called with an integer value and returns the middle three digits of the integer if possible or a clear indication of an error if this is not possible.

Note: The order of the middle digits should be preserved.

Your function should be tested with the following values; the first line should return valid answers, those of the second line should return clear indications of an error:

123, 12345, 1234567, 987654321, 10001, -10001, -123, -100, 100, -12345
1, 2, -1, -10, 2002, -2002, 0

Show your output on this page.

Solution:
public class MiddleThreeDigits {

    public static void main(String[] args) {
        final long[] passing = {123, 12345, 1234567, 987654321, 10001, -10001,
            -123, -100, 100, -12345, Long.MIN_VALUE, Long.MAX_VALUE};

        final int[] failing = {1, 2, -1, -10, 2002, -2002, 0, Integer.MIN_VALUE,
            Integer.MAX_VALUE};

        for (long n : passing)
            System.out.printf("middleThreeDigits(%s): %s\n", n, middleThreeDigits(n));

        for (int n : failing)
            System.out.printf("middleThreeDigits(%s): %s\n", n, middleThreeDigits(n));
    }

    public static <T> String middleThreeDigits(T n) {
        String s = String.valueOf(n);
        if (s.charAt(0) == '-')
            s = s.substring(1);
        int len = s.length();
        if (len < 3 || len % 2 == 0)
            return "Need odd and >= 3 digits";
        int mid = len / 2;
        return s.substring(mid - 1, mid + 2);
    }
}