Validate International Securities Identification Number

An International Securities Identification Number (ISIN) is a unique international identifier for a financial security such as a stock or bond.

;Task:
Write a function or program that takes a string as input, and checks whether it is a valid ISIN.

It is only valid if it has the correct format,   ''and''   the embedded checksum is correct.

Demonstrate that your code passes the test-cases listed below.

;Details:
The format of an ISIN is as follows:

+------------- a 2-character ISO country code (A-Z)
| +----------- a 9-character security code (A-Z, 0-9)
| |        +-- a checksum digit (0-9)
AU0000XVGZA3

For this task, you may assume that any 2-character alphabetic sequence is a valid country code.

The checksum can be validated as follows:
# '''Replace letters with digits''', by converting each character from base 36 to base 10, e.g. AU0000XVGZA3 -1030000033311635103.
# '''Perform the Luhn test on this base-10 number.'''There is a separate task for this test: ''[[Luhn test of credit card numbers]]''.You don't have to replicate the implementation of this test here   ---   you can just call the existing function from that task.   (Add a comment stating if you did this.)

;Test cases:
:::: {| class="wikitable"
! ISIN
! Validity
! Comment
|-
| US0378331005  || valid ||
|-
| US0373831005  || not valid || The transposition typo is caught by the checksum constraint.
|-
| U50378331005  || not valid || The substitution typo is caught by the format constraint.
|-
| US03378331005 || not valid || The duplication typo is caught by the format constraint.
|-
| AU0000XVGZA3  || valid ||
|-
| AU0000VXGZA3  || valid || Unfortunately, not ''all'' transposition typos are caught by the checksum constraint.
|-
| FR0000988040  || valid ||
|}

(The comments are just informational.   Your function should simply return a Boolean result.   See [[#Raku]] for a reference solution.)

Related task:
* [[Luhn test of credit card numbers]]

;Also see:
* Interactive online ISIN validator
* Wikipedia article: International Securities Identification Number

Solution:
public class ISIN {

    public static void main(String[] args) {
        String[] isins = {
            "US0378331005",
            "US0373831005",
            "U50378331005",
            "US03378331005",
            "AU0000XVGZA3",
            "AU0000VXGZA3",
            "FR0000988040"
        };
        for (String isin : isins)
            System.out.printf("%s is %s\n", isin, ISINtest(isin) ? "valid" : "not valid");
    }

    static boolean ISINtest(String isin) {
        isin = isin.trim().toUpperCase();

        if (!isin.matches("^[A-Z]{2}[A-Z0-9]{9}\\d$"))
            return false;

        StringBuilder sb = new StringBuilder();
        for (char c : isin.substring(0, 12).toCharArray())
            sb.append(Character.digit(c, 36));

        return luhnTest(sb.toString());
    }

    static boolean luhnTest(String number) {
        int s1 = 0, s2 = 0;
        String reverse = new StringBuffer(number).reverse().toString();
        for (int i = 0; i < reverse.length(); i++){
            int digit = Character.digit(reverse.charAt(i), 10);
            //This is for odd digits, they are 1-indexed in the algorithm.
            if (i % 2 == 0){
                s1 += digit;
            } else { // Add 2 * digit for 0-4, add 2 * digit - 9 for 5-9.
                s2 += 2 * digit;
                if(digit >= 5){
                    s2 -= 9;
                }
            }
        }
        return (s1 + s2) % 10 == 0;
    }
}


Van Eck sequence

The sequence is generated by following this pseudo-code:

A:  The first term is zero.
    Repeatedly apply:
        If the last term is *new* to the sequence so far then:
B:          The next term is zero.
        Otherwise:
C:          The next term is how far back this last term occured previously.

;Example:
Using A:
:0
Using B:
:0 0
Using C:
:0 0 1
Using B:
:0 0 1 0
Using C:  (zero last occurred two steps back - before the one)
:0 0 1 0 2
Using B:
:0 0 1 0 2 0
Using C:  (two last occurred two steps back - before the zero)
:0 0 1 0 2 0 2 2
Using C:  (two last occurred one step back)
:0 0 1 0 2 0 2 2 1
Using C:  (one last appeared six steps back)
:0 0 1 0 2 0 2 2 1 6
...

;Task:
# Create a function/procedure/method/subroutine/... to generate the Van Eck sequence of numbers.
# Use it to display here, on this page:
:# The first ten terms of the sequence.
:# Terms 991 - to - 1000 of the sequence.

;References:
* Don't Know (the Van Eck Sequence) - Numberphile video.
* Wikipedia Article: Van Eck's Sequence.
*  OEIS sequence: A181391.

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

public class VanEckSequence {

    public static void main(String[] args) {
        System.out.println("First 10 terms of Van Eck's sequence:");
        vanEck(1, 10);
        System.out.println("");
        System.out.println("Terms 991 to 1000 of Van Eck's sequence:");
        vanEck(991, 1000);
    }

    private static void vanEck(int firstIndex, int lastIndex) {
        Map<Integer,Integer> vanEckMap = new HashMap<>();
        int last = 0;
        if ( firstIndex == 1 ) {
            System.out.printf("VanEck[%d] = %d%n", 1, 0);
        }
        for ( int n = 2 ; n <= lastIndex ; n++ ) {
            int vanEck = vanEckMap.containsKey(last) ? n - vanEckMap.get(last) : 0;
            vanEckMap.put(last, n);
            last = vanEck;
            if ( n >= firstIndex ) {
                System.out.printf("VanEck[%d] = %d%n", n, vanEck);
            }
        }

    }

}


Van der Corput sequence

When counting integers in binary, if you put a (binary) point to the right of the count then the column immediately to the left denotes a digit with a multiplier of 2^0; the digit in the next column to the left has a multiplier of 2^1; and so on.

So in the following table:
  0.
  1.
 10.
 11.
 ...
the binary number "10" is 1 \times 2^1 + 0 \times 2^0.

You can also have binary digits to the right of the "point", just as in the decimal number system. In that case, the digit in the place immediately to the right of the point has a weight of 2^{-1}, or 1/2.
The weight for the second column to the right of the point is 2^{-2} or 1/4. And so on.

If you take the integer binary count of the first table, and ''reflect'' the digits about the binary point, you end up with '''the van der Corput sequence of numbers in base 2'''.

  .0
  .1
  .01
  .11
  ...

The third member of the sequence, binary 0.01, is therefore 0 \times 2^{-1} + 1 \times 2^{-2} or 1/4.

 Monte Carlo simulations.
This sequence is also a superset of the numbers representable by the "fraction" field of an old IEEE floating point standard. In that standard, the "fraction" field represented the fractional part of a binary number beginning with "1." e.g. 1.101001101.

'''Hint'''

A ''hint'' at a way to generate members of the sequence is to modify a routine used to change the base of an integer:
>>> def base10change(n, base):
	digits = []
	while n:
		n,remainder = divmod(n, base)
		digits.insert(0, remainder)
	return digits

>>> base10change(11, 2)
[1, 0, 1, 1]
the above showing that 11 in decimal is 1\times 2^3 + 0\times 2^2 + 1\times 2^1 + 1\times 2^0.
Reflected this would become .1101 or 1\times 2^{-1} + 1\times 2^{-2} + 0\times 2^{-3} + 1\times 2^{-4}

;Task description:
* Create a function/method/routine that given ''n'', generates the ''n'''th term of the van der Corput sequence in base 2.
* Use the function to compute ''and display'' the first ten members of the sequence. (The first member of the sequence is for ''n''=0).

* As a stretch goal/extra credit, compute and show members of the sequence for bases other than 2.

;See also:
* The Basic Low Discrepancy Sequences
* [[Non-decimal radices/Convert]]
* Van der Corput sequence

Solution:
public class VanDerCorput{
	public static double vdc(int n){
		double vdc = 0;
		int denom = 1;
		while(n != 0){
			vdc += n % 2.0 / (denom *= 2);
			n /= 2;
		}
		return vdc;
	}

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


Variable declaration reset

A decidely non-challenging task to highlight a potential difference between programming languages.

Using a straightforward longhand loop as in the JavaScript and Phix examples below, show the locations of elements which are identical to the immediately preceding element in {1,2,2,3,4,4,5}. The (non-blank) results may be 2,5 for zero-based or 3,6 if one-based.
The purpose is to determine whether variable declaration (in block scope) resets the contents on every iteration.
There is no particular judgement of right or wrong here, just a plain-speaking statement of subtle differences.
Should your first attempt bomb with "unassigned variable" exceptions, feel free to code it as (say)
  // int prev // crashes with unassigned variable
     int prev = -1 // predictably no output
If your programming language does not support block scope (eg assembly) it should be omitted from this task.

Solution:
public class VariableDeclarationReset {
    public static void main(String[] args) {
        int[] s = {1, 2, 2, 3, 4, 4, 5};

        // There is no output as 'prev' is created anew each time
        // around the loop and set to zero.
        for (int i = 0; i < s.length; ++i) {
            int curr = s[i];
            int prev = 0;
//          int prev; // triggers "error: variable prev might not have been initialized"
            if (i > 0 && curr == prev) System.out.println(i);
            prev = curr;
        }

        int gprev = 0;

        // Now 'gprev' is used and reassigned
        // each time around the loop producing the desired output.
        for (int i = 0; i < s.length; ++i) {
            int curr = s[i];
            if (i > 0 && curr == gprev) System.out.println(i);
            gprev = curr;
        }
    }
}


Vector products

A vector is defined as having three dimensions as being represented by an ordered collection of three numbers:   (X, Y, Z).

If you imagine a graph with the   '''x'''   and   '''y'''   axis being at right angles to each other and having a third,   '''z'''   axis coming out of the page, then a triplet of numbers,   (X, Y, Z)   would represent a point in the region,   and a vector from the origin to the point.

Given the vectors:
         A = (a1,  a2,  a3)
 B = (b1,  b2,  b3)
 C = (c1,  c2,  c3)
then the following common vector products are defined:
* '''The dot product'''       (a scalar quantity)
::::  A * B = a1b1   +   a2b2   +    a3b3
* '''The cross product'''       (a vector quantity)
::::  A x B = (a2b3   -   a3b2,     a3b1   -   a1b3,     a1b2   -   a2b1)
* '''The scalar triple product'''       (a scalar quantity)
::::  A * (B x C)
* '''The vector triple product'''       (a vector quantity)
::::  A x (B x C)

;Task:
Given the three vectors:
         a = ( 3,    4,    5)
         b = ( 4,    3,    5)
         c = (-5,  -12,  -13)
# Create a named function/subroutine/method to compute the dot product of two vectors.
# Create a function to compute the cross product of two vectors.
# Optionally create a function to compute the scalar triple product of three vectors.
# Optionally create a function to compute the vector triple product of three vectors.
# Compute and display: a * b
# Compute and display: a x b
# Compute and display: a * (b x c), the scalar triple product.
# Compute and display: a x (b x c), the vector triple product.

;References:
*   A starting page on Wolfram MathWorld is   {{Wolfram|Vector|Multiplication}}.
*   Wikipedia   dot product.
*   Wikipedia   cross product.
*   Wikipedia   triple product.

;Related tasks:
*   [[Dot product]]
*   [[Quaternion type]]

Solution:
public class VectorProds{
    public static class Vector3D<T extends Number>{
        private T a, b, c;

        public Vector3D(T a, T b, T c){
            this.a = a;
            this.b = b;
            this.c = c;
        }

        public double dot(Vector3D<?> vec){
            return (a.doubleValue() * vec.a.doubleValue() +
                    b.doubleValue() * vec.b.doubleValue() +
                    c.doubleValue() * vec.c.doubleValue());
        }

        public Vector3D<Double> cross(Vector3D<?> vec){
            Double newA = b.doubleValue()*vec.c.doubleValue() - c.doubleValue()*vec.b.doubleValue();
            Double newB = c.doubleValue()*vec.a.doubleValue() - a.doubleValue()*vec.c.doubleValue();
            Double newC = a.doubleValue()*vec.b.doubleValue() - b.doubleValue()*vec.a.doubleValue();
            return new Vector3D<Double>(newA, newB, newC);
        }

        public double scalTrip(Vector3D<?> vecB, Vector3D<?> vecC){
            return this.dot(vecB.cross(vecC));
        }

        public Vector3D<Double> vecTrip(Vector3D<?> vecB, Vector3D<?> vecC){
            return this.cross(vecB.cross(vecC));
        }

        @Override
        public String toString(){
            return "<" + a.toString() + ", " + b.toString() + ", " + c.toString() + ">";
        }
    }

    public static void main(String[] args){
        Vector3D<Integer> a = new Vector3D<Integer>(3, 4, 5);
        Vector3D<Integer> b = new Vector3D<Integer>(4, 3, 5);
        Vector3D<Integer> c = new Vector3D<Integer>(-5, -12, -13);

        System.out.println(a.dot(b));
        System.out.println(a.cross(b));
        System.out.println(a.scalTrip(b, c));
        System.out.println(a.vecTrip(b, c));
    }
}


Vector products

Solution:
import java.util.Arrays;
import java.util.stream.IntStream;

public class VectorsOp {
	// Vector dot product using Java SE 8 stream abilities
	// the method first create an array of size values,
	// and map the product of each vectors components in a new array (method map())
	// and transform the array to a scalr by summing all elements (method reduce)
	// the method parallel  is there for optimization
	private static int dotProduct(int[] v1, int[] v2,int length) {

	int result = IntStream.range(0, length)
	                           .parallel()
	                            .map( id -> v1[id] * v2[id])
	                            .reduce(0, Integer::sum);

	    return result;
	}

	// Vector Cross product using Java SE 8 stream abilities
	// here we map in a new array where each element is equal to the cross product
	// With Stream is is easier to handle N dimensions vectors
	private static int[] crossProduct(int[] v1, int[] v2,int length) {

		int  result[] = new int[length] ;
		//result[0] = v1[1] * v2[2] - v1[2]*v2[1] ;
		//result[1] = v1[2] * v2[0] - v1[0]*v2[2] ;
		// result[2] = v1[0] * v2[1] - v1[1]*v2[0] ;

		result = IntStream.range(0, length)
			.parallel()
	 		.map( i ->   v1[(i+1)%length] * v2[(i+2)%length] -  v1[(i+2)%length]*v2[(i+1)%length])
	 		.toArray();

		 return result;
	}

	public static void main (String[] args)
	{
	   	int[] vect1 = {3, 4, 5};
	   	int[] vect2 = {4, 3, 5};
	    int[] vect3 = {-5, -12, -13};

	    System.out.println("dot product =:" + dotProduct(vect1,vect2,3));

	    int[] prodvect = new int[3];
	    prodvect = crossProduct(vect1,vect2,3);
	    System.out.println("cross product =:[" + prodvect[0] + ","
	    	                                   + prodvect[1] + ","
	    	                                   + prodvect[2] + "]");

	    prodvect = crossProduct(vect2,vect3,3);
	    System.out.println("scalar product =:" + dotProduct(vect1,prodvect,3));

	    prodvect = crossProduct(vect1,prodvect,3);

	    System.out.println("triple product =:[" + prodvect[0] + ","
	    	                                   + prodvect[1] + ","
	    	                                   + prodvect[2] + "]");

	   }
}


Verhoeff algorithm

Description
The Verhoeff algorithm is a checksum formula for error detection developed by the Dutch mathematician Jacobus Verhoeff and first published in 1969. It was the first decimal check digit algorithm which detects all single-digit errors, and all transposition errors involving two adjacent digits, which was at the time thought impossible with such a code.

As the workings of the algorithm are clearly described in the linked Wikipedia article they will not be repeated here.

;Task:
Write routines, methods, procedures etc. in your language to generate a Verhoeff checksum digit for non-negative integers of any length and to validate the result. A combined routine is also acceptable.

The more mathematically minded may prefer to generate the 3 tables required from the description provided rather than to hard-code them.

Write your routines in such a way that they can optionally display digit by digit calculations as in the Wikipedia example.

Use your routines to calculate check digits for the integers: '''236''', '''12345''' and '''123456789012''' and then validate them. Also attempt to validate the same integers if the check digits in all cases were '''9''' rather than what they actually are.

Display digit by digit calculations for the first two integers but not for the third.

;Related task:
*   [[Damm algorithm]]

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

public class VerhoeffAlgorithm {

	public static void main(String[] args) {
		initialise();

		List<List<Object>> tests = List.of(
			List.of( "236", true ), List.of( "12345", true ), List.of( "123456789012", false ) );

		for ( List<Object> test : tests ) {
		    Object object = verhoeffChecksum((String) test.get(0), false, (boolean) test.get(1));
		    System.out.println("The check digit for " + test.get(0) + " is " + object + "\n");

		    for ( String number : List.of( test.get(0) + String.valueOf(object), test.get(0) + "9" ) ) {
		        object = verhoeffChecksum(number, true, (boolean) test.get(1));
		        String result = (boolean) object ? "correct" : "incorrect";
		        System.out.println("The validation for " + number + " is " + result + ".\n");
		    }
		}
	}

	private static Object verhoeffChecksum(String number, boolean doValidation, boolean doDisplay) {
		if ( doDisplay ) {
			String calculationType = doValidation ? "Validation" : "Check digit";
	        System.out.println(calculationType + " calculations for " + number + "\n");
	        System.out.println(" i  ni  p[i, ni]  c");
	        System.out.println("-------------------");
	    }

		if ( ! doValidation ) {
			number += "0";
		}

	    int c = 0;
	    final int le = number.length() - 1;
	    for ( int i = le; i >= 0; i-- ) {
	    	final int ni = number.charAt(i) - '0';
	        final int pi = permutationTable.get((le - i) % 8).get(ni);
	        c = multiplicationTable.get(c).get(pi);

	        if ( doDisplay ) {
	        	System.out.println(String.format("%2d%3d%8d%6d\n", le - i, ni, pi, c));
	        }
	    }

	    if ( doDisplay && ! doValidation ) {
	    	System.out.println("inverse[" + c + "] = " + inverse.get(c) + "\n");
	    }

	    return doValidation ? c == 0 : inverse.get(c);
	}

	private static void initialise() {
		multiplicationTable = List.of(
			List.of( 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 ),
			List.of( 1, 2, 3, 4, 0, 6, 7, 8, 9, 5 ),
			List.of( 2, 3, 4, 0, 1, 7, 8, 9, 5, 6 ),
			List.of( 3, 4, 0, 1, 2, 8, 9, 5, 6, 7 ),
			List.of( 4, 0, 1, 2, 3, 9, 5, 6, 7, 8 ),
			List.of( 5, 9, 8, 7, 6, 0, 4, 3, 2, 1 ),
			List.of( 6, 5, 9, 8, 7, 1, 0, 4, 3, 2 ),
			List.of( 7, 6, 5, 9, 8, 2, 1, 0, 4, 3 ),
			List.of( 8, 7, 6, 5, 9, 3, 2, 1, 0, 4 ),
			List.of( 9, 8, 7, 6, 5, 4, 3, 2, 1, 0 )
		);

		inverse = Arrays.asList( 0, 4, 3, 2, 1, 5, 6, 7, 8, 9 );

		permutationTable = List.of(
				List.of( 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 ),
				List.of( 1, 5, 7, 6, 2, 8, 3, 0, 9, 4 ),
				List.of( 5, 8, 0, 3, 7, 9, 6, 1, 4, 2 ),
				List.of( 8, 9, 1, 6, 0, 4, 3, 5, 2, 7 ),
				List.of( 9, 4, 5, 3, 1, 2, 6, 8, 7, 0 ),
				List.of( 4, 2, 8, 6, 5, 7, 3, 9, 0, 1 ),
				List.of( 2, 7, 9, 3, 8, 0, 6, 4, 1, 5 ),
				List.of( 7, 0, 4, 6, 9, 1, 3, 2, 5, 8 )
		);
	}

	private static List<List<Integer>> multiplicationTable;
	private static List<Integer> inverse;
	private static List<List<Integer>> permutationTable;

}


Video display modes

The task is to demonstrate how to switch video display modes within the language. A brief description of the supported video modes would be useful.

Solution:
import java.awt.Color;
import java.awt.DisplayMode;
import java.awt.GraphicsConfiguration;
import java.awt.GraphicsDevice;
import java.awt.GraphicsEnvironment;
import java.util.concurrent.TimeUnit;

import javax.swing.JFrame;
import javax.swing.JLabel;

public final  class VideoDisplay {

	public static void main(String[] aArgs) throws InterruptedException  {
		GraphicsEnvironment environment = GraphicsEnvironment.getLocalGraphicsEnvironment();
	   	GraphicsDevice[] screens = environment.getScreenDevices();
	   	System.out.println("Number of video screens: " + screens.length + System.lineSeparator());

	   	for ( GraphicsDevice screen : screens ) {
	   		System.out.println("Full screen display is supported: "
	   			+ screen.isFullScreenSupported() + System.lineSeparator());

	   		GraphicsConfiguration[] configurations = screen.getConfigurations();

	   		System.out.println("This screen has number of configurations: " + configurations.length);
	   		for ( GraphicsConfiguration config : configurations ) {
	   			System.out.println("Configuration supports translucency: " + config.isTranslucencyCapable());
	   		}

	   		DisplayMode[] modes = screen.getDisplayModes();
	   		System.out.println(System.lineSeparator() + "This screen has " + modes.length + " modes of operation");

	   		for ( DisplayMode mode : modes ) {
		         System.out.println(mode.getWidth() + " X " + mode.getHeight()
		         	+ " with refresh rate " + mode.getRefreshRate() + " Hz");
		    }
	    }

	   	// Uncomment the line below to see an example of programmatically changing the video display.
	   	// new VideoDisplay();
	}

	private VideoDisplay() throws InterruptedException {
		JFrame.setDefaultLookAndFeelDecorated(true);
    	JFrame frame = new JFrame("Video Display Demonstration");
    	frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    	frame.setBackground(Color.LIGHT_GRAY);
    	frame.add( new JLabel(MESSAGE) );
    	frame.setSize(800, 600);

    	GraphicsDevice screen = GraphicsEnvironment.getLocalGraphicsEnvironment().getDefaultScreenDevice();
    	DisplayMode originalDisplayMode = screen.getDisplayMode();
    	screen.setFullScreenWindow(frame);
    	screen.setDisplayMode( new DisplayMode(800, 600, 32, 60) );
    	frame.setVisible(true);

    	TimeUnit.SECONDS.sleep(3);

    	screen.setDisplayMode(originalDisplayMode);

    	TimeUnit.SECONDS.sleep(3);

    	Runtime.getRuntime().exit(0);
    }

    private static final String MESSAGE = "Please wait for a few seconds."
    	+ " Your video display will then be returned to its original setting.";

}


Visualize a tree

A tree structure   (i.e. a rooted, connected acyclic graph)   is often used in programming.

It's often helpful to visually examine such a structure.

There are many ways to represent trees to a reader, such as:
:::*   indented text   (a la unix  tree  command)
:::*   nested HTML tables
:::*   hierarchical GUI widgets
:::*   2D   or   3D   images
:::*   etc.

;Task:
Write a program to produce a visual representation of some tree.

The content of the tree doesn't matter, nor does the output format, the only requirement being that the output is human friendly.

Make do with the vague term "friendly" the best you can.

Solution:
public class VisualizeTree {
    public static void main(String[] args) {
        BinarySearchTree tree = new BinarySearchTree();

        tree.insert(100);
        for (int i = 0; i < 20; i++)
            tree.insert((int) (Math.random() * 200));
        tree.display();
    }
}

class BinarySearchTree {
    private Node root;

    private class Node {
        private int key;
        private Node left, right;

        Node(int k) {
            key = k;
        }
    }

    public boolean insert(int key) {
        if (root == null)
            root = new Node(key);
        else {
            Node n = root;
            Node parent;
            while (true) {
                if (n.key == key)
                    return false;

                parent = n;

                boolean goLeft = key < n.key;
                n = goLeft ? n.left : n.right;

                if (n == null) {
                    if (goLeft) {
                        parent.left = new Node(key);
                    } else {
                        parent.right = new Node(key);
                    }
                    break;
                }
            }
        }
        return true;
    }

    public void display() {
        final int height = 5, width = 64;

        int len = width * height * 2 + 2;
        StringBuilder sb = new StringBuilder(len);
        for (int i = 1; i <= len; i++)
            sb.append(i < len - 2 && i % width == 0 ? "\n" : ' ');

        displayR(sb, width / 2, 1, width / 4, width, root, " ");
        System.out.println(sb);
    }

    private void displayR(StringBuilder sb, int c, int r, int d, int w, Node n,
            String edge) {
        if (n != null) {
            displayR(sb, c - d, r + 2, d / 2, w, n.left, " /");

            String s = String.valueOf(n.key);
            int idx1 = r * w + c - (s.length() + 1) / 2;
            int idx2 = idx1 + s.length();
            int idx3 = idx1 - w;
            if (idx2 < sb.length())
                sb.replace(idx1, idx2, s).replace(idx3, idx3 + 2, edge);

            displayR(sb, c + d, r + 2, d / 2, w, n.right, "\\ ");
        }
    }
}


Vogel's approximation method

Vogel's Approximation Method (VAM) is a technique for finding a good initial feasible solution to an allocation problem.

The powers that be have identified 5 tasks that need to be solved urgently. Being imaginative chaps, they have called them "A", "B", "C", "D", and "E". They estimate that:
* A will require 30 hours of work,
* B will require 20 hours of work,
* C will require 70 hours of work,
* D will require 30 hours of work, and
* E will require 60 hours of work.

They have identified 4 contractors willing to do the work, called "W", "X", "Y", and "Z".
* W has 50 hours available to commit to working,
* X has 60 hours available,
* Y has 50 hours available, and
* Z has 50 hours available.
The cost per hour for each contractor for each task is summarized by the following table:

   A  B  C  D  E
W 16 16 13 22 17
X 14 14 13 19 15
Y 19 19 20 23 50
Z 50 12 50 15 11

The task is to use VAM to allocate contractors to tasks. It scales to large problems, so ideally keep sorts out of the iterative cycle. It works as follows:

:Step 1: Balance the given transportation problem if either (total supply>total demand) or (total supply
        A       B       C       D       E       W       X       Y       Z
1       2       2       0       4       4       3       1       0       1   E-Z(50)

Determine the largest difference (D or E above). In the case of ties I shall choose the one with the lowest price (in this case E because the lowest price for D is Z=15, whereas for E it is Z=11). For your choice determine the minimum cost (chosen E above so Z=11 is chosen now). Allocate as much as possible from Z to E (50 in this case limited by Z's supply).
Adjust the supply and demand accordingly. If demand or supply becomes 0 for a given task or contractor it plays no further part. In this case Z is out of it. If you choose arbitrarily, and chose D see here for the working.

Repeat until all supply and demand is met:

2       2       2       0       3       2       3       1       0       -   C-W(50)
3       5       5       7       4      35       -       1       0       -   E-X(10)
4       5       5       7       4       -       -       1       0       -   C-X(20)
5       5       5       -       4       -       -       0       0       -   A-X(30)
6       -      19       -      23       -       -       -       4       -   D-Y(30)
        -       -       -       -       -       -       -       -       -   B-Y(20)

Finally calculate the cost of your solution. In the example given it is PS3100:

   A  B  C  D  E
W       50
X 30    20    10
Y    20    30
Z             50

The optimal solution determined by GLPK is PS3100:

   A  B  C  D  E
W       50
X 10 20 20    10
Y 20       30
Z             50

;Cf.
* Transportation problem

Solution:
import java.util.Arrays;
import static java.util.Arrays.stream;
import java.util.concurrent.*;

public class VogelsApproximationMethod {

    final static int[] demand = {30, 20, 70, 30, 60};
    final static int[] supply = {50, 60, 50, 50};
    final static int[][] costs = {{16, 16, 13, 22, 17}, {14, 14, 13, 19, 15},
    {19, 19, 20, 23, 50}, {50, 12, 50, 15, 11}};

    final static int nRows = supply.length;
    final static int nCols = demand.length;

    static boolean[] rowDone = new boolean[nRows];
    static boolean[] colDone = new boolean[nCols];
    static int[][] result = new int[nRows][nCols];

    static ExecutorService es = Executors.newFixedThreadPool(2);

    public static void main(String[] args) throws Exception {
        int supplyLeft = stream(supply).sum();
        int totalCost = 0;

        while (supplyLeft > 0) {
            int[] cell = nextCell();
            int r = cell[0];
            int c = cell[1];

            int quantity = Math.min(demand[c], supply[r]);
            demand[c] -= quantity;
            if (demand[c] == 0)
                colDone[c] = true;

            supply[r] -= quantity;
            if (supply[r] == 0)
                rowDone[r] = true;

            result[r][c] = quantity;
            supplyLeft -= quantity;

            totalCost += quantity * costs[r][c];
        }

        stream(result).forEach(a -> System.out.println(Arrays.toString(a)));
        System.out.println("Total cost: " + totalCost);

        es.shutdown();
    }

    static int[] nextCell() throws Exception {
        Future<int[]> f1 = es.submit(() -> maxPenalty(nRows, nCols, true));
        Future<int[]> f2 = es.submit(() -> maxPenalty(nCols, nRows, false));

        int[] res1 = f1.get();
        int[] res2 = f2.get();

        if (res1[3] == res2[3])
            return res1[2] < res2[2] ? res1 : res2;

        return (res1[3] > res2[3]) ? res2 : res1;
    }

    static int[] diff(int j, int len, boolean isRow) {
        int min1 = Integer.MAX_VALUE, min2 = Integer.MAX_VALUE;
        int minP = -1;
        for (int i = 0; i < len; i++) {
            if (isRow ? colDone[i] : rowDone[i])
                continue;
            int c = isRow ? costs[j][i] : costs[i][j];
            if (c < min1) {
                min2 = min1;
                min1 = c;
                minP = i;
            } else if (c < min2)
                min2 = c;
        }
        return new int[]{min2 - min1, min1, minP};
    }

    static int[] maxPenalty(int len1, int len2, boolean isRow) {
        int md = Integer.MIN_VALUE;
        int pc = -1, pm = -1, mc = -1;
        for (int i = 0; i < len1; i++) {
            if (isRow ? rowDone[i] : colDone[i])
                continue;
            int[] res = diff(i, len2, isRow);
            if (res[0] > md) {
                md = res[0];  // max diff
                pm = i;       // pos of max diff
                mc = res[1];  // min cost
                pc = res[2];  // pos of min cost
            }
        }
        return isRow ? new int[]{pm, pc, mc, md} : new int[]{pc, pm, mc, md};
    }
}


Wagstaff primes

Definition
A ''Wagstaff prime'' is a prime number of the form ''(2^p + 1)/3'' where the exponent ''p'' is an odd prime.

;Example
(2^5 + 1)/3 = 11 is a Wagstaff prime because both 5 and 11 are primes.

;Task
Find and show here the first ''10'' Wagstaff primes and their corresponding exponents ''p''.

;Stretch (requires arbitrary precision integers)
Find and show here the exponents ''p'' corresponding to the next ''14'' Wagstaff primes (not the primes themselves) and any more that you have the patience for.

When testing for primality, you may use a method which determines that a large number is probably prime with reasonable certainty.

;Note
It can be shown (see talk page) that ''(2^p + 1)/3'' is always integral if ''p'' is odd. So there's no need to check for that prior to checking for primality.

;References

* Wikipedia - Wagstaff prime
* OEIS:A000979 - Wagstaff primes

Solution:
import java.math.BigInteger;

public class Main {
  public static void main(String[] args) {
    BigInteger d = new BigInteger("3"), a;
    int lmt = 25, sl, c = 0;
    for (int i = 3; i < 5808; ) {
      a = BigInteger.ONE.shiftLeft(i).add(BigInteger.ONE).divide(d);
      if (a.isProbablePrime(1)) {
        System.out.printf("%2d %4d ", ++c, i);
        String s = a.toString(); sl = s.length();
        if (sl < lmt) System.out.println(a);
        else System.out.println(s.substring(0, 11) + ".." + s.substring(sl - 11, sl) + " " + sl + " digits");
      }
      i = BigInteger.valueOf(i).nextProbablePrime().intValue();
    }
  }
}


War card game

War Card Game

Simulate the card game War.  Use the Bicycle playing card manufacturer's rules. Show a game as played.  User input is optional.

References:

:* Bicycle card company: War game site

:* Wikipedia: War (card game)

Related tasks:
* [[Playing cards]]
* [[Card shuffles]]
* [[Deal cards for FreeCell]]
* [[Poker hand_analyser]]
* [[Go Fish]]

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

public final class WarCardGame {

	public static void main(String[] args) {
		WarGame warGame = new WarGame();

		while ( ! warGame.gameOver() ) {
			warGame.nextTurn();
		}

		warGame.declareWinner();
	}

}

final class WarGame {

	public WarGame() {
		deck = new ArrayList<Card>(52);
        for ( Character suit : SUITS ) {
            for ( Character pip : PIPS ) {
                deck.add( new Card(suit, pip) );
            }
        }
        Collections.shuffle(deck);

        handA = new ArrayList<Card>(deck.subList(0, 26));
        handB = new ArrayList<Card>(deck.subList(26, 52));
        tabledCards = new ArrayList<Card>();
	}

	public void nextTurn() {
		Card cardA = handA.remove(0);
		Card cardB = handB.remove(0);
		tabledCards.add(cardA);
		tabledCards.add(cardB);
		int rankA = PIPS.indexOf(cardA.pip);
		int rankB = PIPS.indexOf(cardB.pip);

		System.out.print(cardA + "  " + cardB);
		if ( rankA > rankB ) {
            System.out.println("  Player A takes the cards");
            Collections.shuffle(tabledCards);
            handA.addAll(tabledCards);
            tabledCards.clear();
		} else if ( rankA < rankB ) {
            System.out.println("  Player B takes the cards");
            Collections.shuffle(tabledCards);
            handB.addAll(tabledCards);
            tabledCards.clear();
		} else {
	        System.out.println("      War!");
            if ( gameOver() ) {
                return;
            }

            Card cardAA = handA.remove(0);
            Card cardBB = handB.remove(0);
            tabledCards.add(cardAA);
    		tabledCards.add(cardBB);
    		System.out.println("?   ?   Cards are face down");
    		if ( gameOver() ) {
                return;
            }

            nextTurn();
		}
	}

	public boolean gameOver() {
		return handA.size() == 0 || handB.size() == 0;
	}

    public void declareWinner() {
        if ( handA.size() == 0 && handB.size() == 0 ) {
        	System.out.println("The game ended in a tie");
        } else if ( handA.size() == 0 ) {
        	System.out.println("Player B has won the game");
        } else {
            System.out.println("Player A has won the game");
        }
    }

    private record Card(Character suit, Character pip) {

    	@Override
    	public String toString() {
    		return "" + pip + suit;
    	}

    }

	private List<Card> deck, handA, handB, tabledCards;

	private static final List<Character> PIPS =
		Arrays.asList( '2', '3', '4', '5', '6', '7', '8', '9', 'T', 'J', 'Q', 'K', 'A' );
	private static final List<Character> SUITS = List.of( 'C', 'D', 'H', 'S' );

}


Water collected between towers

In a two-dimensional world, we begin with any bar-chart (or row of close-packed 'towers', each of unit width), and then it rains,
completely filling all convex enclosures in the chart with water.

9               ##           9               ##
8               ##           8               ##
7     ##        ##           7     ####
6     ##  ##    ##           6     ######
5 ##  ##  ##  ####           5 ##########
4 ##  ##  ########           4 ############
3 ######  ########           3 ##############
2 ################  ##       2 ##################
1 ####################       1 ####################

In the example above, a bar chart representing the values [5, 3, 7, 2, 6, 4, 5, 9, 1, 2] has filled, collecting 14 units of water.

Write a function, in your language, from a given array of heights, to the number of water units that can be held in this way, by a corresponding bar chart.

Calculate the number of water units that could be collected by bar charts representing each of the following seven series:

   [[1, 5, 3, 7, 2],
    [5, 3, 7, 2, 6, 4, 5, 9, 1, 2],
    [2, 6, 3, 5, 2, 8, 1, 4, 2, 2, 5, 3, 5, 7, 4, 1],
    [5, 5, 5, 5],
    [5, 6, 7, 8],
    [8, 7, 7, 6],
    [6, 7, 10, 7, 6]]

See, also:

* Four Solutions to a Trivial Problem - a Google Tech Talk by Guy Steele
* Water collected between towers on Stack Overflow, from which the example above is taken)
* An interesting Haskell solution, using the Tardis monad, by Phil Freeman in a Github gist.

Solution:
public class WaterBetweenTowers {
    public static void main(String[] args) {
        int i = 1;
        int[][] tba = new int[][]{
            new int[]{1, 5, 3, 7, 2},
            new int[]{5, 3, 7, 2, 6, 4, 5, 9, 1, 2},
            new int[]{2, 6, 3, 5, 2, 8, 1, 4, 2, 2, 5, 3, 5, 7, 4, 1},
            new int[]{5, 5, 5, 5},
            new int[]{5, 6, 7, 8},
            new int[]{8, 7, 7, 6},
            new int[]{6, 7, 10, 7, 6}
        };

        for (int[] tea : tba) {
            int rht, wu = 0, bof;
            do {
                for (rht = tea.length - 1; rht >= 0; rht--) {
                    if (tea[rht] > 0) {
                        break;
                    }
                }

                if (rht < 0) {
                    break;
                }

                bof = 0;
                for (int col = 0; col <= rht; col++) {
                    if (tea[col] > 0) {
                        tea[col]--;
                        bof += 1;
                    } else if (bof > 0) {
                        wu++;
                    }
                }
                if (bof < 2) {
                    break;
                }
            } while (true);

            System.out.printf("Block %d", i++);
            if (wu == 0) {
                System.out.print(" does not hold any");
            } else {
                System.out.printf(" holds %d", wu);
            }
            System.out.println(" water units.");
        }
    }
}


Weird numbers

In number theory, a perfect either).

In other words, the sum of the proper divisors of the number (divisors including 1 but not itself) is greater than the number itself (the number is ''abundant''), but no subset of those divisors sums to the number itself (the number is not ''semiperfect'').

For example:

* '''12''' is ''not'' a weird number.
** It is abundant; its proper divisors '''1, 2, 3, 4, 6''' sum to '''16''' (which ''is'' > 12),
** but it ''is'' semiperfect, e.g.:     '''6 + 4 + 2 == 12'''.
* '''70''' ''is'' a weird number.
** It is abundant; its proper divisors '''1, 2, 5, 7, 10, 14, 35''' sum to '''74''' (which ''is'' > 70),
** and there is no subset of proper divisors that sum to '''70'''.

;Task:
Find and display, here on this page, the first '''25''' weird numbers.

;Related tasks:
:* Abundant, deficient and perfect number classifications
:* Proper divisors

;See also:
:* OEIS: A006037 weird numbers
:* Wikipedia: weird number
:* MathWorld: weird number

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

public class WeirdNumbers {

    public static void main(String[] args) {
        int n = 2;
        //  n += 2 : No odd weird numbers < 10^21
        for ( int count = 1 ; count <= 25 ; n += 2 ) {
            if ( isWeird(n) ) {
                System.out.printf("w(%d) = %d%n", count, n);
                count++;
            }
        }
    }

    private static boolean isWeird(int n) {
        List<Integer> properDivisors = getProperDivisors(n);
        return isAbundant(properDivisors, n) && ! isSemiPerfect(properDivisors, n);
    }

    private static boolean isAbundant(List<Integer> divisors, int n) {
        int divisorSum = divisors.stream().mapToInt(i -> i.intValue()).sum();
        return divisorSum > n;
    }

    //  Use Dynamic Programming
    private static boolean isSemiPerfect(List<Integer> divisors, int sum) {
        int size = divisors.size();

        //  The value of subset[i][j] will be true if there is a subset of divisors[0..j-1] with sum equal to i
        boolean subset[][] = new boolean[sum+1][size+1];

        // If sum is 0, then answer is true
        for (int i = 0; i <= size; i++) {
            subset[0][i] = true;
        }

        //  If sum is not 0 and set is empty, then answer is false
        for (int i = 1; i <= sum; i++) {
            subset[i][0] = false;
        }

        // Fill the subset table in bottom up manner
        for ( int i = 1 ; i <= sum ; i++ ) {
            for ( int j = 1 ; j <= size ; j++ ) {
                subset[i][j] = subset[i][j-1];
                int test = divisors.get(j-1);
                if ( i >= test ) {
                    subset[i][j] = subset[i][j] || subset[i - test][j-1];
                }
            }
        }

        return subset[sum][size];
    }

    private static final List<Integer> getProperDivisors(int number) {
        List<Integer> divisors = new ArrayList<Integer>();
        long sqrt = (long) Math.sqrt(number);
        for ( int i = 1 ; i <= sqrt ; i++ ) {
            if ( number % i == 0 ) {
                divisors.add(i);
                int div = number / i;
                if ( div != i && div != number ) {
                    divisors.add(div);
                }
            }
        }
        return divisors;
    }

}


Word frequency

Given a text file and an integer   '''n''',   print/display the   '''n'''   most
common words in the file   (and the number of their occurrences)   in decreasing frequency.

For the purposes of this task:
*   A word is a sequence of one or more contiguous letters.
*   You are free to define what a   ''letter''   is.
*   Underscores, accented letters, apostrophes, hyphens, and other special characters can be handled at your discretion.
*   You may treat a compound word like   '''well-dressed'''   as either one word or two.
*   The word   '''it's'''   could also be one or two words as you see fit.
*   You may also choose not to support non US-ASCII characters.
*   Assume words will not span multiple lines.
*   Don't worry about normalization of word spelling differences.
*   Treat   '''color'''   and   '''colour'''   as two distinct words.
*   Uppercase letters are considered equivalent to their lowercase counterparts.
*   Words of equal frequency can be listed in any order.
*   Feel free to explicitly state the thoughts behind the program decisions.

Show example output using Les Miserables from Project Gutenberg as the text file input and display the top   '''10'''   most used words.

;History:
This task was originally taken from programming pearls from Communications of the ACM June 1986 Volume 29 Number 6
where this problem is solved by Donald Knuth using literate programming and then critiqued by Doug McIlroy,
demonstrating solving the problem in a 6 line Unix shell script (provided as an example below).

;References:
*McIlroy's program

Solution:
void printWordFrequency() throws URISyntaxException, IOException {
    URL url = new URI("https://www.gutenberg.org/files/135/135-0.txt").toURL();
    try (BufferedReader reader = new BufferedReader(new InputStreamReader(url.openStream()))) {
        Pattern pattern = Pattern.compile("(\\w+)");
        Matcher matcher;
        String line;
        String word;
        Map<String, Integer> map = new HashMap<>();
        while ((line = reader.readLine()) != null) {
            matcher = pattern.matcher(line);
            while (matcher.find()) {
                word = matcher.group().toLowerCase();
                if (map.containsKey(word)) {
                    map.put(word, map.get(word) + 1);
                } else {
                    map.put(word, 1);
                }
            }
        }
        /* print out top 10 */
        List<Map.Entry<String, Integer>> list = new ArrayList<>(map.entrySet());
        list.sort(Map.Entry.comparingByValue());
        Collections.reverse(list);
        int count = 1;
        for (Map.Entry<String, Integer> value : list) {
            System.out.printf("%-20s%,7d%n", value.getKey(), value.getValue());
            if (count++ == 10) break;
        }
    }
}


Word frequency

Solution:
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import java.util.stream.Collectors;

public class WordCount {
    public static void main(String[] args) throws IOException {
        Path path = Paths.get("135-0.txt");
        byte[] bytes = Files.readAllBytes(path);
        String text = new String(bytes);
        text = text.toLowerCase();

        Pattern r = Pattern.compile("\\p{javaLowerCase}+");
        Matcher matcher = r.matcher(text);
        Map<String, Integer> freq = new HashMap<>();
        while (matcher.find()) {
            String word = matcher.group();
            Integer current = freq.getOrDefault(word, 0);
            freq.put(word, current + 1);
        }

        List<Map.Entry<String, Integer>> entries = freq.entrySet()
            .stream()
            .sorted((i1, i2) -> Integer.compare(i2.getValue(), i1.getValue()))
            .limit(10)
            .collect(Collectors.toList());

        System.out.println("Rank  Word  Frequency");
        System.out.println("====  ====  =========");
        int rank = 1;
        for (Map.Entry<String, Integer> entry : entries) {
            String word = entry.getKey();
            Integer count = entry.getValue();
            System.out.printf("%2d    %-4s    %5d\n", rank++, word, count);
        }
    }
}


Word ladder

Yet another shortest path problem. Given two words of equal length the task is to transpose the first into the second.

Only one letter may be changed at a time and the change must result in a word in unixdict, the minimum number of intermediate words should be used.

Demonstrate the following:

A boy can be made into a man: boy -> bay -> ban -> man

With a little more difficulty a girl can be made into a lady: girl -> gill -> gall -> gale -> gaze -> laze -> lazy -> lady

A john can be made into a jane: john -> cohn -> conn -> cone -> cane -> jane

A child can not be turned into an adult.

Optional transpositions of your choice.

Solution:
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.PriorityQueue;
import java.util.Set;
import java.util.stream.IntStream;

public class WordLadder {
    private static int distance(String s1, String s2) {
        assert s1.length() == s2.length();
        return (int) IntStream.range(0, s1.length())
            .filter(i -> s1.charAt(i) != s2.charAt(i))
            .count();
    }

    private static void wordLadder(Map<Integer, Set<String>> words, String fw, String tw) {
        wordLadder(words, fw, tw, 8);
    }

    private static void wordLadder(Map<Integer, Set<String>> words, String fw, String tw, int limit) {
        if (fw.length() != tw.length()) {
            throw new IllegalArgumentException("From word and to word must have the same length");
        }

        Set<String> ws = words.get(fw.length());
        if (ws.contains(fw)) {
            List<String> primeList = new ArrayList<>();
            primeList.add(fw);

            PriorityQueue<List<String>> queue = new PriorityQueue<>((chain1, chain2) -> {
                int cmp1 = Integer.compare(chain1.size(), chain2.size());
                if (cmp1 == 0) {
                    String last1 = chain1.get(chain1.size() - 1);
                    int d1 = distance(last1, tw);

                    String last2 = chain2.get(chain2.size() - 1);
                    int d2 = distance(last2, tw);

                    return Integer.compare(d1, d2);
                }
                return cmp1;
            });
            queue.add(primeList);

            while (queue.size() > 0) {
                List<String> curr = queue.remove();
                if (curr.size() > limit) {
                    continue;
                }

                String last = curr.get(curr.size() - 1);
                for (String word : ws) {
                    if (distance(last, word) == 1) {
                        if (word.equals(tw)) {
                            curr.add(word);
                            System.out.println(String.join(" -> ", curr));
                            return;
                        }

                        if (!curr.contains(word)) {
                            List<String> cp = new ArrayList<>(curr);
                            cp.add(word);
                            queue.add(cp);
                        }
                    }
                }
            }
        }

        System.err.printf("Cannot turn `%s` into `%s`%n", fw, tw);
    }

    public static void main(String[] args) throws IOException {
        Map<Integer, Set<String>> words = new HashMap<>();
        for (String line : Files.readAllLines(Path.of("unixdict.txt"))) {
            Set<String> wl = words.computeIfAbsent(line.length(), HashSet::new);
            wl.add(line);
        }

        wordLadder(words, "boy", "man");
        wordLadder(words, "girl", "lady");
        wordLadder(words, "john", "jane");
        wordLadder(words, "child", "adult");
        wordLadder(words, "cat", "dog");
        wordLadder(words, "lead", "gold");
        wordLadder(words, "white", "black");
        wordLadder(words, "bubble", "tickle", 12);
    }
}


Word ladder

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

public class WordLadder {
    public static void main(String[] args) {
        try {
            Map<Integer, List<String>> words = new HashMap<>();
            try (BufferedReader reader = new BufferedReader(new FileReader("unixdict.txt"))) {
                String line;
                while ((line = reader.readLine()) != null)
                    words.computeIfAbsent(line.length(), k -> new ArrayList<String>()).add(line);
            }
            wordLadder(words, "boy", "man");
            wordLadder(words, "girl", "lady");
            wordLadder(words, "john", "jane");
            wordLadder(words, "child", "adult");
            wordLadder(words, "cat", "dog");
            wordLadder(words, "lead", "gold");
            wordLadder(words, "white", "black");
            wordLadder(words, "bubble", "tickle");
        } catch (Exception e)  {
            e.printStackTrace();
        }
    }

    // Returns true if strings s1 and s2 differ by one character.
    private static boolean oneAway(String s1, String s2) {
        if (s1.length() != s2.length())
            return false;
        boolean result = false;
        for (int i = 0, n = s1.length(); i != n; ++i) {
            if (s1.charAt(i) != s2.charAt(i)) {
                if (result)
                    return false;
                result = true;
            }
        }
        return result;
    }

    // If possible, print the shortest chain of single-character modifications that
    // leads from "from" to "to", with each intermediate step being a valid word.
    // This is an application of breadth-first search.
    private static void wordLadder(Map<Integer, List<String>> words, String from, String to) {
        List<String> w = words.get(from.length());
        if (w != null) {
            Deque<String> poss = new ArrayDeque<>(w);
            Deque<String> f = new ArrayDeque<String>();
            f.add(from);
            Deque<Deque<String>> queue = new ArrayDeque<>();
            queue.add(f);
            while (!queue.isEmpty()) {
                Deque<String> curr = queue.poll();
                for (Iterator<String> i = poss.iterator(); i.hasNext(); ) {
                    String str = i.next();
                    if (!oneAway(str, curr.getLast()))
                        continue;
                    if (to.equals(str)) {
                        curr.add(to);
                        System.out.println(String.join(" -> ", curr));
                        return;
                    }
                    Deque<String> temp = new ArrayDeque<>(curr);
                    temp.add(str);
                    queue.add(temp);
                    i.remove();
                }
            }
        }
        System.out.printf("%s into %s cannot be done.\n", from, to);
    }
}


Word search

A word search puzzle typically consists of a grid of letters in which words are hidden.

There are many varieties of word search puzzles. For the task at hand we will use a rectangular grid in which the words may be placed horizontally, vertically, or diagonally. The words may also be spelled backwards.

The words may overlap but are not allowed to zigzag, or wrap around.

;Task
Create a 10 by 10 word search and fill it using words from the unixdict. Use only words that are longer than 2, and contain no non-alphabetic characters.

The cells not used by the hidden words should contain the message: ''Rosetta Code'', read from left to right, top to bottom. These letters should be somewhat evenly distributed over the grid, not clumped together. The message should be in upper case, the hidden words in lower case. All cells should either contain letters from the hidden words or from the message.

Pack a minimum of 25 words into the grid.

Print the resulting grid and the solutions.

;Example

     0  1  2  3  4  5  6  7  8  9

0    n  a  y  r  y  R  e  l  m  f
1    y  O  r  e  t  s  g  n  a  g
2    t  n  e  d  i  S  k  y  h  E
3    n  o  t  n  c  p  c  w  t  T
4    a  l  s  u  u  n  T  m  a  x
5    r  o  k  p  a  r  i  s  h  h
6    a  A  c  f  p  a  e  a  c  C
7    u  b  u  t  t  t  O  l  u  n
8    g  y  h  w  a  D  h  p  m  u
9    m  i  r  p  E  h  o  g  a  n

parish     (3,5)(8,5)   gangster   (9,1)(2,1)
paucity    (4,6)(4,0)   guaranty   (0,8)(0,1)
prim       (3,9)(0,9)   huckster   (2,8)(2,1)
plasm      (7,8)(7,4)   fancy      (3,6)(7,2)
hogan      (5,9)(9,9)   nolo       (1,2)(1,5)
under      (3,4)(3,0)   chatham    (8,6)(8,0)
ate        (4,8)(6,6)   nun        (9,7)(9,9)
butt       (1,7)(4,7)   hawk       (9,5)(6,2)
why        (3,8)(1,8)   ryan       (3,0)(0,0)
fay        (9,0)(7,2)   much       (8,8)(8,5)
tar        (5,7)(5,5)   elm        (6,0)(8,0)
max        (7,4)(9,4)   pup        (5,3)(3,5)
mph        (8,8)(6,8)

Solution:
import java.io.*;
import static java.lang.String.format;
import java.util.*;

public class WordSearch {
    static class Grid {
        int numAttempts;
        char[][] cells = new char[nRows][nCols];
        List<String> solutions = new ArrayList<>();
    }

    final static int[][] dirs = {{1, 0}, {0, 1}, {1, 1}, {1, -1}, {-1, 0},
    {0, -1}, {-1, -1}, {-1, 1}};

    final static int nRows = 10;
    final static int nCols = 10;
    final static int gridSize = nRows * nCols;
    final static int minWords = 25;

    final static Random rand = new Random();

    public static void main(String[] args) {
        printResult(createWordSearch(readWords("unixdict.txt")));
    }

    static List<String> readWords(String filename) {
        int maxLen = Math.max(nRows, nCols);

        List<String> words = new ArrayList<>();
        try (Scanner sc = new Scanner(new FileReader(filename))) {
            while (sc.hasNext()) {
                String s = sc.next().trim().toLowerCase();
                if (s.matches("^[a-z]{3," + maxLen + "}$"))
                    words.add(s);
            }
        } catch (FileNotFoundException e) {
            System.out.println(e);
        }
        return words;
    }

    static Grid createWordSearch(List<String> words) {
        Grid grid = null;
        int numAttempts = 0;

        outer:
        while (++numAttempts < 100) {
            Collections.shuffle(words);

            grid = new Grid();
            int messageLen = placeMessage(grid, "Rosetta Code");
            int target = gridSize - messageLen;

            int cellsFilled = 0;
            for (String word : words) {
                cellsFilled += tryPlaceWord(grid, word);
                if (cellsFilled == target) {
                    if (grid.solutions.size() >= minWords) {
                        grid.numAttempts = numAttempts;
                        break outer;
                    } else break; // grid is full but we didn't pack enough words, start over
                }
            }
        }

        return grid;
    }

    static int placeMessage(Grid grid, String msg) {
        msg = msg.toUpperCase().replaceAll("[^A-Z]", "");

        int messageLen = msg.length();
        if (messageLen > 0 && messageLen < gridSize) {
            int gapSize = gridSize / messageLen;

            for (int i = 0; i < messageLen; i++) {
                int pos = i * gapSize + rand.nextInt(gapSize);
                grid.cells[pos / nCols][pos % nCols] = msg.charAt(i);
            }
            return messageLen;
        }
        return 0;
    }

    static int tryPlaceWord(Grid grid, String word) {
        int randDir = rand.nextInt(dirs.length);
        int randPos = rand.nextInt(gridSize);

        for (int dir = 0; dir < dirs.length; dir++) {
            dir = (dir + randDir) % dirs.length;

            for (int pos = 0; pos < gridSize; pos++) {
                pos = (pos + randPos) % gridSize;

                int lettersPlaced = tryLocation(grid, word, dir, pos);
                if (lettersPlaced > 0)
                    return lettersPlaced;
            }
        }
        return 0;
    }

    static int tryLocation(Grid grid, String word, int dir, int pos) {

        int r = pos / nCols;
        int c = pos % nCols;
        int len = word.length();

        //  check bounds
        if ((dirs[dir][0] == 1 && (len + c) > nCols)
                || (dirs[dir][0] == -1 && (len - 1) > c)
                || (dirs[dir][1] == 1 && (len + r) > nRows)
                || (dirs[dir][1] == -1 && (len - 1) > r))
            return 0;

        int rr, cc, i, overlaps = 0;

        // check cells
        for (i = 0, rr = r, cc = c; i < len; i++) {
            if (grid.cells[rr][cc] != 0 && grid.cells[rr][cc] != word.charAt(i))
                return 0;
            cc += dirs[dir][0];
            rr += dirs[dir][1];
        }

        // place
        for (i = 0, rr = r, cc = c; i < len; i++) {
            if (grid.cells[rr][cc] == word.charAt(i))
                overlaps++;
            else
                grid.cells[rr][cc] = word.charAt(i);

            if (i < len - 1) {
                cc += dirs[dir][0];
                rr += dirs[dir][1];
            }
        }

        int lettersPlaced = len - overlaps;
        if (lettersPlaced > 0) {
            grid.solutions.add(format("%-10s (%d,%d)(%d,%d)", word, c, r, cc, rr));
        }

        return lettersPlaced;
    }

    static void printResult(Grid grid) {
        if (grid == null || grid.numAttempts == 0) {
            System.out.println("No grid to display");
            return;
        }
        int size = grid.solutions.size();

        System.out.println("Attempts: " + grid.numAttempts);
        System.out.println("Number of words: " + size);

        System.out.println("\n     0  1  2  3  4  5  6  7  8  9");
        for (int r = 0; r < nRows; r++) {
            System.out.printf("%n%d   ", r);
            for (int c = 0; c < nCols; c++)
                System.out.printf(" %c ", grid.cells[r][c]);
        }

        System.out.println("\n");

        for (int i = 0; i < size - 1; i += 2) {
            System.out.printf("%s   %s%n", grid.solutions.get(i),
                    grid.solutions.get(i + 1));
        }
        if (size % 2 == 1)
            System.out.println(grid.solutions.get(size - 1));
    }
}


Word wrap

Even today, with proportional fonts and complex layouts, there are still cases where you need to wrap text at a specified column.

;Basic task:
The basic task is to wrap a paragraph of text in a simple way in your language.

If there is a way to do this that is built-in, trivial, or provided in a standard library, show that.  Otherwise implement the minimum length greedy algorithm from Wikipedia.

Show your routine working on a sample of text at two different wrap columns.

;Extra credit:
Wrap text using a more sophisticated algorithm such as the Knuth and Plass TeX algorithm.
If your language provides this, you get easy extra credit,
but you ''must reference documentation'' indicating that the algorithm
is something better than a simple minimum length algorithm.

If you have both basic and extra credit solutions, show an example where
the two algorithms give different results.

Solution:
package rosettacode;

import java.util.StringTokenizer;

public class WordWrap
{
    int defaultLineWidth=80;
    int defaultSpaceWidth=1;
    void minNumLinesWrap(String text)
    {
        minNumLinesWrap(text,defaultLineWidth);
    }
    void minNumLinesWrap(String text,int LineWidth)
    {
        StringTokenizer st=new StringTokenizer(text);
        int SpaceLeft=LineWidth;
        int SpaceWidth=defaultSpaceWidth;
        while(st.hasMoreTokens())
        {
            String word=st.nextToken();
            if((word.length()+SpaceWidth)>SpaceLeft)
            {
                System.out.print("\n"+word+" ");
                SpaceLeft=LineWidth-word.length();
            }
            else
            {
                System.out.print(word+" ");
                SpaceLeft-=(word.length()+SpaceWidth);
            }
        }
    }
    public static void main(String[] args)
    {
        WordWrap now=new WordWrap();
        String wodehouse="Old Mr MacFarland (_said Henry_) started the place fifteen years ago. He was a widower with one son and what you might call half a daughter. That's to say, he had adopted her. Katie was her name, and she was the child of a dead friend of his. The son's name was Andy. A little freckled nipper he was when I first knew him--one of those silent kids that don't say much and have as much obstinacy in them as if they were mules. Many's the time, in them days, I've clumped him on the head and told him to do something; and he didn't run yelling to his pa, same as most kids would have done, but just said nothing and went on not doing whatever it was I had told him to do. That was the sort of disposition Andy had, and it grew on him. Why, when he came back from Oxford College the time the old man sent for him--what I'm going to tell you about soon--he had a jaw on him like the ram of a battleship. Katie was the kid for my money. I liked Katie. We all liked Katie.";
        System.out.println("DEFAULT:");
        now.minNumLinesWrap(wodehouse);
        System.out.println("\n\nLINEWIDTH=120");
        now.minNumLinesWrap(wodehouse,120);
    }

}


World Cup group stage

It's World Cup season (or at least it was when this page was created)!

The World Cup is an international football/soccer tournament that happens every 4 years.   Countries put their international teams together in the years between tournaments and qualify for the tournament based on their performance in other international games.   Once a team has qualified they are put into a group with 3 other teams.

For the first part of the World Cup tournament the teams play in "group stage" games where each of the four teams in a group plays all three other teams once.   The results of these games determine which teams will move on to the "knockout stage" which is a standard single-elimination tournament.   The two teams from each group with the most standings points move on to the knockout stage.

Each game can result in a win for one team and a loss for the other team or it can result in a draw/tie for each team.
:::*   A win is worth three points.
:::*   A draw/tie is worth one point.
:::*   A loss is worth zero points.

;Task:
:*   Generate all possible outcome combinations for the six group stage games.   With three possible outcomes for each game there should be 36 = 729 of them.
:*   Calculate the standings points for each team with each combination of outcomes.
:*   Show a histogram (graphical,   ASCII art, or straight counts--whichever is easiest/most fun) of the standings points for all four teams over all possible outcomes.

Don't worry about tiebreakers as they can get complicated.   We are basically looking to answer the question "if a team gets x standings points, where can they expect to end up in the group standings?".

''Hint: there should be no possible way to end up in second place with less than two points as well as no way to end up in first with less than three.   Oddly enough, there is no way to get 8 points at all.''

Solution:
import java.util.Arrays;

public class GroupStage{
    //team left digit vs team right digit
    static String[] games = {"12", "13", "14", "23", "24", "34"};
    static String results = "000000";//start with left teams all losing

    private static boolean nextResult(){
        if(results.equals("222222")) return false;
        int res = Integer.parseInt(results, 3) + 1;
        results = Integer.toString(res, 3);
        while(results.length() < 6) results = "0" + results;	//left pad with 0s
        return true;
    }

    public static void main(String[] args){
        int[][] points = new int[4][10]; 		//playing 3 games, points range from 0 to 9
        do{
            int[] records = {0,0,0,0};
            for(int i = 0; i < 6; i++){
                switch(results.charAt(i)){
                    case '2': records[games[i].charAt(0) - '1'] += 3; break;    //win for left team
                    case '1':                                                   //draw
                        records[games[i].charAt(0) - '1']++;
                        records[games[i].charAt(1) - '1']++;
                        break;
                    case '0': records[games[i].charAt(1) - '1'] += 3; break;    //win for right team
                }
            }
            Arrays.sort(records);	//sort ascending, first place team on the right
            points[0][records[0]]++;
            points[1][records[1]]++;
            points[2][records[2]]++;
            points[3][records[3]]++;
        }while(nextResult());
        System.out.println("First place: " + Arrays.toString(points[3]));
        System.out.println("Second place: " + Arrays.toString(points[2]));
        System.out.println("Third place: " + Arrays.toString(points[1]));
        System.out.println("Fourth place: " + Arrays.toString(points[0]));
    }
}


Write float arrays to a text file

Write two equal-sized numerical arrays 'x' and 'y' to
a two-column text file named 'filename'.

The first column of the file contains values from an 'x'-array with a
given 'xprecision', the second -- values from 'y'-array with 'yprecision'.

For example, considering:
    x = {1, 2, 3, 1e11};
    y = {1, 1.4142135623730951, 1.7320508075688772, 316227.76601683791};
                                                           /* sqrt(x) */
    xprecision = 3;
    yprecision = 5;

The file should look like:
    1    1
    2    1.4142
    3    1.7321
    1e+011   3.1623e+005

This task is intended as a subtask for [[Measure relative performance of sorting algorithms implementations]].

Solution:
import java.io.*;

public class FloatArray {
    public static void writeDat(String filename, double[] x, double[] y,
                                int xprecision, int yprecision)
        throws IOException {
        assert x.length == y.length;
        PrintWriter out = new PrintWriter(filename);
        for (int i = 0; i < x.length; i++)
            out.printf("%."+xprecision+"g\t%."+yprecision+"g\n", x[i], y[i]);
        out.close();
    }

    public static void main(String[] args) {
        double[] x = {1, 2, 3, 1e11};
        double[] y = new double[x.length];
        for (int i = 0; i < x.length; i++)
            y[i] = Math.sqrt(x[i]);

        try {
            writeDat("sqrt.dat", x, y, 3, 5);
        } catch (IOException e) {
            System.err.println("writeDat: exception: "+e);
        }

        try {
            BufferedReader br = new BufferedReader(new FileReader("sqrt.dat"));
            String line;
            while ((line = br.readLine()) != null)
                System.out.println(line);
        } catch (IOException e) { }
    }
}


Write language name in 3D ASCII

Write/display a language's name in '''3D''' ASCII.

(We can leave the definition of "3D ASCII" fuzzy,
so long as the result is interesting or amusing,
not a cheap hack to satisfy the task.)

;Related tasks:
* draw a sphere
* draw a cuboid
* draw a rotating cube
* draw a Deathstar

Solution:
public class F5{
    char[]z={' ',' ','_','/',};
    long[][]f={
        {87381,87381,87381,87381,87381,87381,87381,},
        {349525,375733,742837,742837,375733,349525,349525,},
        {742741,768853,742837,742837,768853,349525,349525,},
        {349525,375733,742741,742741,375733,349525,349525,},
        {349621,375733,742837,742837,375733,349525,349525,},
        {349525,375637,768949,742741,375733,349525,349525,},
        {351157,374101,768949,374101,374101,349525,349525,},
        {349525,375733,742837,742837,375733,349621,351157,},
        {742741,768853,742837,742837,742837,349525,349525,},
        {181,85,181,181,181,85,85,},
        {1461,1365,1461,1461,1461,1461,2901,},
        {742741,744277,767317,744277,742837,349525,349525,},
        {181,181,181,181,181,85,85,},
        {1431655765,3149249365L,3042661813L,3042661813L,3042661813L,1431655765,1431655765,},
        {349525,768853,742837,742837,742837,349525,349525,},
        {349525,375637,742837,742837,375637,349525,349525,},
        {349525,768853,742837,742837,768853,742741,742741,},
        {349525,375733,742837,742837,375733,349621,349621,},
        {349525,744373,767317,742741,742741,349525,349525,},
        {349525,375733,767317,351157,768853,349525,349525,},
        {374101,768949,374101,374101,351157,349525,349525,},
        {349525,742837,742837,742837,375733,349525,349525,},
        {5592405,11883957,11883957,5987157,5616981,5592405,5592405,},
        {366503875925L,778827027893L,778827027893L,392374737749L,368114513237L,366503875925L,366503875925L,},
        {349525,742837,375637,742837,742837,349525,349525,},
        {349525,742837,742837,742837,375733,349621,375637,},
        {349525,768949,351061,374101,768949,349525,349525,},
        {375637,742837,768949,742837,742837,349525,349525,},
        {768853,742837,768853,742837,768853,349525,349525,},
        {375733,742741,742741,742741,375733,349525,349525,},
        {192213,185709,185709,185709,192213,87381,87381,},
        {1817525,1791317,1817429,1791317,1817525,1398101,1398101,},
        {768949,742741,768853,742741,742741,349525,349525,},
        {375733,742741,744373,742837,375733,349525,349525,},
        {742837,742837,768949,742837,742837,349525,349525,},
        {48053,23381,23381,23381,48053,21845,21845,},
        {349621,349621,349621,742837,375637,349525,349525,},
        {742837,744277,767317,744277,742837,349525,349525,},
        {742741,742741,742741,742741,768949,349525,349525,},
        {11883957,12278709,11908533,11883957,11883957,5592405,5592405,},
        {11883957,12277173,11908533,11885493,11883957,5592405,5592405,},
        {375637,742837,742837,742837,375637,349525,349525,},
        {768853,742837,768853,742741,742741,349525,349525,},
        {6010197,11885397,11909973,11885397,6010293,5592405,5592405,},
        {768853,742837,768853,742837,742837,349525,349525,},
        {375733,742741,375637,349621,768853,349525,349525,},
        {12303285,5616981,5616981,5616981,5616981,5592405,5592405,},
        {742837,742837,742837,742837,375637,349525,349525,},
        {11883957,11883957,11883957,5987157,5616981,5592405,5592405,},
        {3042268597L,3042268597L,3042661813L,1532713813,1437971797,1431655765,1431655765,},
        {11883957,5987157,5616981,5987157,11883957,5592405,5592405,},
        {11883957,5987157,5616981,5616981,5616981,5592405,5592405,},
        {12303285,5593941,5616981,5985621,12303285,5592405,5592405,},};
    public static void main(String[]a){
        new F5(a.length>0?a[0]:"Java");}
    private F5(String s){
        StringBuilder[]o=new StringBuilder[7];
        for(int i=0;i<7;i++)o[i]=new StringBuilder();
        for(int i=0,l=s.length();i<l;i++){
            int c=s.charAt(i);
            if(65<=c&&c<=90)c-=39;
            else if(97<=c&&c<=122)c-=97;
            else c=-1;
            long[]d=f[++c];
            for(int j=0;j<7;j++){
                StringBuilder b=new StringBuilder();
                long v=d[j];
                while(v>0){
                    b.append(z[(int)(v&3)]);
                    v>>=2;}
                o[j].append(b.reverse().toString());}}
        for(int i=0;i<7;i++){
            for(int j=0;j<7-i;j++)
                System.out.print(' ');
            System.out.println(o[i]);}}}


Write to Windows event log

Write script status to the Windows Event Log

Solution:
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.util.Locale;
import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;

public class WriteToWindowsEventLog {
    public static void main(String[] args) throws IOException, InterruptedException {
        String osName = System.getProperty("os.name").toUpperCase(Locale.ENGLISH);
        if (!osName.startsWith("WINDOWS")) {
            System.err.println("Not windows");
            return;
        }

        Process process = Runtime.getRuntime().exec("EventCreate /t INFORMATION /id 123 /l APPLICATION /so Java /d \"Rosetta Code Example\"");
        process.waitFor(10, TimeUnit.SECONDS);
        int exitValue = process.exitValue();
        System.out.printf("Process exited with value %d\n", exitValue);
        if (exitValue != 0) {
            InputStream errorStream = process.getErrorStream();
            String result = new BufferedReader(new InputStreamReader(errorStream))
                .lines()
                .collect(Collectors.joining("\n"));
            System.err.println(result);
        }
    }
}


Yellowstone sequence

The '''Yellowstone sequence''', also called the '''Yellowstone permutation''', is defined as:

For n <= 3,

    a(n) = n

For n >= 4,

    a(n) = the smallest number not already in sequence such that a(n) is relatively prime to a(n-1) and
           is not relatively prime to a(n-2).

The sequence is a permutation of the natural numbers, and gets its name from what its authors felt was a spiking, geyser like appearance of a plot of the sequence.

;Example:
a(4) is 4 because 4 is the smallest number following 1, 2, 3 in the sequence that is relatively prime to the entry before it (3), and is not relatively prime to the number two entries before it (2).

;Task
: Find and show as output the first  '''30'''  Yellowstone numbers.

;Extra
:  Demonstrate how to plot, with x = n and y coordinate a(n), the first 100 Yellowstone numbers.

;Related tasks:
:*   Greatest common divisor.
:*   Plot coordinate pairs.

;See also:
:*   The OEIS entry:   A098550 The Yellowstone permutation.
:*   Applegate et al, 2015: The Yellowstone Permutation [https://arxiv.org/abs/1501.01669].

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

public class YellowstoneSequence {

    public static void main(String[] args) {
         System.out.printf("First 30 values in the yellowstone sequence:%n%s%n", yellowstoneSequence(30));
    }

    private static List<Integer> yellowstoneSequence(int sequenceCount) {
        List<Integer> yellowstoneList = new ArrayList<Integer>();
        yellowstoneList.add(1);
        yellowstoneList.add(2);
        yellowstoneList.add(3);
        int num = 4;
        List<Integer> notYellowstoneList = new ArrayList<Integer>();
        int yellowSize = 3;
        while ( yellowSize < sequenceCount ) {
            int found = -1;
            for ( int index = 0 ; index < notYellowstoneList.size() ; index++ ) {
                int test = notYellowstoneList.get(index);
                if ( gcd(yellowstoneList.get(yellowSize-2), test) > 1 && gcd(yellowstoneList.get(yellowSize-1), test) == 1 ) {
                    found = index;
                    break;
                }
            }
            if ( found >= 0 ) {
                yellowstoneList.add(notYellowstoneList.remove(found));
                yellowSize++;
            }
            else {
                while ( true ) {
                    if ( gcd(yellowstoneList.get(yellowSize-2), num) > 1 && gcd(yellowstoneList.get(yellowSize-1), num) == 1 ) {
                        yellowstoneList.add(num);
                        yellowSize++;
                        num++;
                        break;
                    }
                    notYellowstoneList.add(num);
                    num++;
                }
            }
        }
        return yellowstoneList;
    }

    private static final int gcd(int a, int b) {
        if ( b == 0 ) {
            return a;
        }
        return gcd(b, a%b);
    }

}


Zeckendorf number representation

Just as numbers can be represented in a positional notation as sums of multiples of the powers of ten (decimal) or two (binary); all the positive integers can be represented as the sum of one or zero times the distinct members of the Fibonacci series.

Recall that the first six distinct Fibonacci numbers are:  1, 2, 3, 5, 8, 13.

The decimal number eleven can be written as 0*13 + 1*8 + 0*5 + 1*3 + 0*2 + 0*1 or 010100 in positional notation where the columns represent multiplication by a particular member of the sequence. Leading zeroes are dropped so that 11 decimal becomes 10100.

10100 is not the only way to make 11 from the Fibonacci numbers however;  0*13 + 1*8 + 0*5 + 0*3 + 1*2 + 1*1 or 010011 would also represent decimal 11. For a true Zeckendorf number there is the added restriction that ''no two consecutive Fibonacci numbers can be used'' which leads to the former unique solution.

;Task:
Generate and show here a table of the Zeckendorf number representations of the decimal numbers zero to twenty, in order.

The intention in this task to find the Zeckendorf form of an arbitrary integer.  The Zeckendorf form can be iterated by some bit twiddling rather than calculating each value separately but leave that to another separate task.

;Also see:
*   OEIS A014417   for the the sequence of required results.
*   Brown's Criterion - Numberphile

;Related task:
*   [[Fibonacci sequence]]

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

public class Zeckendorf {

    private List<Integer> getFibList(final int maxNum, final int n1, final int n2, final List<Integer> fibs){
        if(n2 > maxNum) return fibs;

        fibs.add(n2);

        return getFibList(maxNum, n2, n1 + n2, fibs);
    }

    public String getZeckendorf(final int num) {
        if (num <= 0) return "0";

        final List<Integer> fibs = getFibList(num, 1, 2, new ArrayList<Integer>(){{ add(1); }});

        return getZeckString("", num, fibs.size() - 1, fibs);
    }

    private String getZeckString(final String zeck, final int num, final int index, final List<Integer> fibs){
        final int curFib = fibs.get(index);
        final boolean placeZeck = num >= curFib;

        final String outString = placeZeck ? zeck + "1" : zeck + "0";
        final int outNum = placeZeck ? num - curFib : num;

        if(index == 0) return outString;

        return  getZeckString(outString, outNum, index - 1, fibs);
    }

    public static void main(final String[] args) {
        final Zeckendorf zeckendorf = new Zeckendorf();

        for(int i =0; i <= 20; i++){
            System.out.println("Z("+ i +"):\t" + zeckendorf.getZeckendorf(i));
        }
    }
}


Zhang-Suen thinning algorithm

Solution:
import java.awt.Point;
import java.util.*;

public class ZhangSuen {

    final static String[] image = {
        "                                                          ",
        " #################                   #############        ",
        " ##################               ################        ",
        " ###################            ##################        ",
        " ########     #######          ###################        ",
        "   ######     #######         #######       ######        ",
        "   ######     #######        #######                      ",
        "   #################         #######                      ",
        "   ################          #######                      ",
        "   #################         #######                      ",
        "   ######     #######        #######                      ",
        "   ######     #######        #######                      ",
        "   ######     #######         #######       ######        ",
        " ########     #######          ###################        ",
        " ########     ####### ######    ################## ###### ",
        " ########     ####### ######      ################ ###### ",
        " ########     ####### ######         ############# ###### ",
        "                                                          "};

    final static int[][] nbrs = {{0, -1}, {1, -1}, {1, 0}, {1, 1}, {0, 1},
        {-1, 1}, {-1, 0}, {-1, -1}, {0, -1}};

    final static int[][][] nbrGroups = {{{0, 2, 4}, {2, 4, 6}}, {{0, 2, 6},
        {0, 4, 6}}};

    static List<Point> toWhite = new ArrayList<>();
    static char[][] grid;

    public static void main(String[] args) {
        grid = new char[image.length][];
        for (int r = 0; r < image.length; r++)
            grid[r] = image[r].toCharArray();

        thinImage();
    }

    static void thinImage() {
        boolean firstStep = false;
        boolean hasChanged;

        do {
            hasChanged = false;
            firstStep = !firstStep;

            for (int r = 1; r < grid.length - 1; r++) {
                for (int c = 1; c < grid[0].length - 1; c++) {

                    if (grid[r][c] != '#')
                        continue;

                    int nn = numNeighbors(r, c);
                    if (nn < 2 || nn > 6)
                        continue;

                    if (numTransitions(r, c) != 1)
                        continue;

                    if (!atLeastOneIsWhite(r, c, firstStep ? 0 : 1))
                        continue;

                    toWhite.add(new Point(c, r));
                    hasChanged = true;
                }
            }

            for (Point p : toWhite)
                grid[p.y][p.x] = ' ';
            toWhite.clear();

        } while (firstStep || hasChanged);

        printResult();
    }

    static int numNeighbors(int r, int c) {
        int count = 0;
        for (int i = 0; i < nbrs.length - 1; i++)
            if (grid[r + nbrs[i][1]][c + nbrs[i][0]] == '#')
                count++;
        return count;
    }

    static int numTransitions(int r, int c) {
        int count = 0;
        for (int i = 0; i < nbrs.length - 1; i++)
            if (grid[r + nbrs[i][1]][c + nbrs[i][0]] == ' ') {
                if (grid[r + nbrs[i + 1][1]][c + nbrs[i + 1][0]] == '#')
                    count++;
            }
        return count;
    }

    static boolean atLeastOneIsWhite(int r, int c, int step) {
        int count = 0;
        int[][] group = nbrGroups[step];
        for (int i = 0; i < 2; i++)
            for (int j = 0; j < group[i].length; j++) {
                int[] nbr = nbrs[group[i][j]];
                if (grid[r + nbr[1]][c + nbr[0]] == ' ') {
                    count++;
                    break;
                }
            }
        return count > 1;
    }

    static void printResult() {
        for (char[] row : grid)
            System.out.println(row);
    }
}