Determine if a string is squeezable

Determine if a character string is   ''squeezable''.

And if so,   squeeze the string   (by removing any number of
a   ''specified''   ''immediately repeated''   character).

This task is very similar to the task     '''Determine if a character string is collapsible'''     except
that only a specified character is   ''squeezed''   instead of any character that is ''immediately repeated''.

If a character string has a specified   ''immediately repeated''   character(s),   the repeated characters are to be
deleted (removed),   but not the primary (1st) character(s).

A specified   ''immediately repeated''   character is any specified character that is   immediately
followed by an identical character (or characters).   Another word choice could've been   ''duplicated
character'',   but that might have ruled out   (to some readers)   triplicated characters   ***   or more.

{This Rosetta Code task was inspired by a newly introduced   (as of around
November 2019)   '''PL/I'''   BIF:   '''squeeze'''.}

;Examples:
In the following character string with a specified   ''immediately repeated''   character of   '''e''':

  The better the 4-wheel drive, the further you'll be from help when ya get stuck!

Only the 2nd   '''e'''   is an specified repeated character,   indicated by an underscore
(above),   even though they (the characters) appear elsewhere in the character string.

So, after ''squeezing'' the string, the result would be:

  The better the 4-whel drive, the further you'll be from help when ya get stuck!

Another example:
In the following character string,   using a specified immediately repeated character   '''s''':

  headmistressship

The "squeezed" string would be:

  headmistreship

;Task:
Write a subroutine/function/procedure/routine***   to locate a   ''specified immediately repeated''   character
and   ''squeeze''   (delete)   them from the character string.   The
character string can be processed from either direction.

Show all output here, on this page:
:*   the   specified repeated character   (to be searched for and possibly ''squeezed''):
:*   the   original string and its length
:*   the       resultant string and its length
:*   the above strings should be "bracketed" with   '''<<<'''   and   '''>>>'''   (to delineate blanks)
;*   <<<<<<Guillemets may be used instead for "bracketing" for the more artistic programmers,   shown used here>>>>>>

Use (at least) the following five strings,   all strings are length seventy-two (characters, including blanks),   except
the 1st string:

                                                                                immediately
  string                                                                            repeated
  number                                                                            character
                                                                                ( |   a blank,  a minus,  a seven,  a period)
         ++
    1    |+-----------------------------------------------------------------------+    ' '    <######  a null string  (length zero)
    2    |"If I were two-faced, would I be wearing this one?" --- Abraham Lincoln |    '-'
    3    |..1111111111111111111111111111111111111111111111111111111111111117777888|    '7'
    4    |I never give 'em hell, I just tell the truth, and they think it's hell. |    '.'
    5    |                                                    --- Harry S Truman  |  (below)  <######  has many repeated blanks
         +------------------------------------------------------------------------+     |
                                                                                |
                                                                                |
         For the 5th string  (Truman's signature line),  use each of these  specified immediately  repeated characters:
                                   *  a blank
                                   *  a minus
                                   *  a lowercase  '''r'''

Note:   there should be seven results shown,   one each for the 1st four strings,   and three results for
the 5th string.

Solution:
//  Title:  Determine if a string is squeezable

public class StringSqueezable {

    public static void main(String[] args) {
        String[] testStrings = new String[] {
                "",
                "\"If I were two-faced, would I be wearing this one?\" --- Abraham Lincoln ",
                "..1111111111111111111111111111111111111111111111111111111111111117777888",
                "I never give 'em hell, I just tell the truth, and they think it's hell. ",
                "                                                    --- Harry S Truman  ",
                "122333444455555666666777777788888888999999999",
                "The better the 4-wheel drive, the further you'll be from help when ya get stuck!",
                "headmistressship"};

        String[] testChar = new String[] {
                " ",
                "-",
                "7",
                ".",
                " -r",
                "5",
                "e",
                "s"};
        for ( int testNum = 0 ; testNum < testStrings.length ; testNum++ ) {
            String s = testStrings[testNum];
            for ( char c : testChar[testNum].toCharArray() ) {
                String result = squeeze(s, c);
                System.out.printf("use: '%c'%nold:  %2d <<<%s>>>%nnew:  %2d <<<%s>>>%n%n", c, s.length(), s, result.length(), result);
            }
        }
    }

    private static String squeeze(String in, char include) {
        StringBuilder sb = new StringBuilder();
        for ( int i = 0 ; i < in.length() ; i++ ) {
            if ( i == 0 || in.charAt(i-1) != in.charAt(i) || (in.charAt(i-1) == in.charAt(i) && in.charAt(i) != include)) {
                sb.append(in.charAt(i));
            }
        }
        return sb.toString();
    }

}


Determine if two triangles overlap

Solution:
import java.util.function.BiFunction;

public class TriangleOverlap {
    private static class Pair {
        double first;
        double second;

        Pair(double first, double second) {
            this.first = first;
            this.second = second;
        }

        @Override
        public String toString() {
            return String.format("(%s, %s)", first, second);
        }
    }

    private static class Triangle {
        Pair p1, p2, p3;

        Triangle(Pair p1, Pair p2, Pair p3) {
            this.p1 = p1;
            this.p2 = p2;
            this.p3 = p3;
        }

        @Override
        public String toString() {
            return String.format("Triangle: %s, %s, %s", p1, p2, p3);
        }
    }

    private static double det2D(Triangle t) {
        Pair p1 = t.p1;
        Pair p2 = t.p2;
        Pair p3 = t.p3;
        return p1.first * (p2.second - p3.second)
            + p2.first * (p3.second - p1.second)
            + p3.first * (p1.second - p2.second);
    }

    private static void checkTriWinding(Triangle t, boolean allowReversed) {
        double detTri = det2D(t);
        if (detTri < 0.0) {
            if (allowReversed) {
                Pair a = t.p3;
                t.p3 = t.p2;
                t.p2 = a;
            } else throw new RuntimeException("Triangle has wrong winding direction");
        }
    }

    private static boolean boundaryCollideChk(Triangle t, double eps) {
        return det2D(t) < eps;
    }

    private static boolean boundaryDoesntCollideChk(Triangle t, double eps) {
        return det2D(t) <= eps;
    }

    private static boolean triTri2D(Triangle t1, Triangle t2) {
        return triTri2D(t1, t2, 0.0, false, true);
    }

    private static boolean triTri2D(Triangle t1, Triangle t2, double eps, boolean allowedReversed) {
        return triTri2D(t1, t2, eps, allowedReversed, true);
    }

    private static boolean triTri2D(Triangle t1, Triangle t2, double eps, boolean allowedReversed, boolean onBoundary) {
        // Triangles must be expressed anti-clockwise
        checkTriWinding(t1, allowedReversed);
        checkTriWinding(t2, allowedReversed);
        // 'onBoundary' determines whether points on boundary are considered as colliding or not
        BiFunction<Triangle, Double, Boolean> chkEdge = onBoundary ? TriangleOverlap::boundaryCollideChk : TriangleOverlap::boundaryDoesntCollideChk;
        Pair[] lp1 = new Pair[]{t1.p1, t1.p2, t1.p3};
        Pair[] lp2 = new Pair[]{t2.p1, t2.p2, t2.p3};

        // for each edge E of t1
        for (int i = 0; i < 3; ++i) {
            int j = (i + 1) % 3;
            // Check all points of t2 lay on the external side of edge E.
            // If they do, the triangles do not overlap.
            if (chkEdge.apply(new Triangle(lp1[i], lp1[j], lp2[0]), eps) &&
                chkEdge.apply(new Triangle(lp1[i], lp1[j], lp2[1]), eps) &&
                chkEdge.apply(new Triangle(lp1[i], lp1[j], lp2[2]), eps)) return false;
        }

        // for each edge E of t2
        for (int i = 0; i < 3; ++i) {
            int j = (i + 1) % 3;
            // Check all points of t1 lay on the external side of edge E.
            // If they do, the triangles do not overlap.
            if (chkEdge.apply(new Triangle(lp2[i], lp2[j], lp1[0]), eps) &&
                chkEdge.apply(new Triangle(lp2[i], lp2[j], lp1[1]), eps) &&
                chkEdge.apply(new Triangle(lp2[i], lp2[j], lp1[2]), eps)) return false;
        }

        // The triangles overlap
        return true;
    }

    public static void main(String[] args) {
        Triangle t1 = new Triangle(new Pair(0.0, 0.0), new Pair(5.0, 0.0), new Pair(0.0, 5.0));
        Triangle t2 = new Triangle(new Pair(0.0, 0.0), new Pair(5.0, 0.0), new Pair(0.0, 6.0));
        System.out.printf("%s and\n%s\n", t1, t2);
        if (triTri2D(t1, t2)) {
            System.out.println("overlap");
        } else {
            System.out.println("do not overlap");
        }

        // need to allow reversed for this pair to avoid exception
        t1 = new Triangle(new Pair(0.0, 0.0), new Pair(0.0, 5.0), new Pair(5.0, 0.0));
        t2 = t1;
        System.out.printf("\n%s and\n%s\n", t1, t2);
        if (triTri2D(t1, t2, 0.0, true)) {
            System.out.println("overlap (reversed)");
        } else {
            System.out.println("do not overlap");
        }

        t1 = new Triangle(new Pair(0.0, 0.0), new Pair(5.0, 0.0), new Pair(0.0, 5.0));
        t2 = new Triangle(new Pair(-10.0, 0.0), new Pair(-5.0, 0.0), new Pair(-1.0, 6.0));
        System.out.printf("\n%s and\n%s\n", t1, t2);
        if (triTri2D(t1, t2)) {
            System.out.println("overlap");
        } else {
            System.out.println("do not overlap");
        }

        t1.p3 = new Pair(2.5, 5.0);
        t2 = new Triangle(new Pair(0.0, 4.0), new Pair(2.5, -1.0), new Pair(5.0, 4.0));
        System.out.printf("\n%s and\n%s\n", t1, t2);
        if (triTri2D(t1, t2)) {
            System.out.println("overlap");
        } else {
            System.out.println("do not overlap");
        }

        t1 = new Triangle(new Pair(0.0, 0.0), new Pair(1.0, 1.0), new Pair(0.0, 2.0));
        t2 = new Triangle(new Pair(2.0, 1.0), new Pair(3.0, 0.0), new Pair(3.0, 2.0));
        System.out.printf("\n%s and\n%s\n", t1, t2);
        if (triTri2D(t1, t2)) {
            System.out.println("overlap");
        } else {
            System.out.println("do not overlap");
        }

        t2 = new Triangle(new Pair(2.0, 1.0), new Pair(3.0, -2.0), new Pair(3.0, 4.0));
        System.out.printf("\n%s and\n%s\n", t1, t2);
        if (triTri2D(t1, t2)) {
            System.out.println("overlap");
        } else {
            System.out.println("do not overlap");
        }

        t1 = new Triangle(new Pair(0.0, 0.0), new Pair(1.0, 0.0), new Pair(0.0, 1.0));
        t2 = new Triangle(new Pair(1.0, 0.0), new Pair(2.0, 0.0), new Pair(1.0, 1.1));
        System.out.printf("\n%s and\n%s\n", t1, t2);
        System.out.println("which have only a single corner in contact, if boundary points collide");
        if (triTri2D(t1, t2)) {
            System.out.println("overlap");
        } else {
            System.out.println("do not overlap");
        }

        System.out.printf("\n%s and\n%s\n", t1, t2);
        System.out.println("which have only a single corner in contact, if boundary points do not collide");
        if (triTri2D(t1, t2, 0.0, false, false)) {
            System.out.println("overlap");
        } else {
            System.out.println("do not overlap");
        }
    }
}


Dice game probabilities

Two players have a set of dice each. The first player has nine dice with four faces each, with numbers one to four. The second player has six normal dice with six faces each, each face has the usual numbers from one to six.

They roll their dice and sum the totals of the faces. The player with the highest total wins (it's a draw if the totals are the same). What's the probability of the first player beating the second player?

Later the two players use a different set of dice each. Now the first player has five dice with ten faces each, and the second player has six dice with seven faces each. Now what's the probability of the first player beating the second player?

This task was adapted from the Project Euler Problem n.205:
https://projecteuler.net/problem=205

Solution:
import java.util.Random;

public class Dice{
	private static int roll(int nDice, int nSides){
		int sum = 0;
		Random rand = new Random();
		for(int i = 0; i < nDice; i++){
			sum += rand.nextInt(nSides) + 1;
		}
		return sum;
	}

	private static int diceGame(int p1Dice, int p1Sides, int p2Dice, int p2Sides, int rolls){
		int p1Wins = 0;
		for(int i = 0; i < rolls; i++){
			int p1Roll = roll(p1Dice, p1Sides);
			int p2Roll = roll(p2Dice, p2Sides);
			if(p1Roll > p2Roll) p1Wins++;
		}
		return p1Wins;
	}

	public static void main(String[] args){
		int p1Dice = 9; int p1Sides = 4;
		int p2Dice = 6; int p2Sides = 6;
		int rolls = 10000;
		int p1Wins = diceGame(p1Dice, p1Sides, p2Dice, p2Sides, rolls);
		System.out.println(rolls + " rolls, p1 = " + p1Dice + "d" + p1Sides + ", p2 = " + p2Dice + "d" + p2Sides);
		System.out.println("p1 wins " + (100.0 * p1Wins / rolls) + "% of the time");

		System.out.println();

		p1Dice = 5; p1Sides = 10;
		p2Dice = 6; p2Sides = 7;
		rolls = 10000;
		p1Wins = diceGame(p1Dice, p1Sides, p2Dice, p2Sides, rolls);
		System.out.println(rolls + " rolls, p1 = " + p1Dice + "d" + p1Sides + ", p2 = " + p2Dice + "d" + p2Sides);
		System.out.println("p1 wins " + (100.0 * p1Wins / rolls) + "% of the time");

		System.out.println();

		p1Dice = 9; p1Sides = 4;
		p2Dice = 6; p2Sides = 6;
		rolls = 1000000;
		p1Wins = diceGame(p1Dice, p1Sides, p2Dice, p2Sides, rolls);
		System.out.println(rolls + " rolls, p1 = " + p1Dice + "d" + p1Sides + ", p2 = " + p2Dice + "d" + p2Sides);
		System.out.println("p1 wins " + (100.0 * p1Wins / rolls) + "% of the time");

		System.out.println();

		p1Dice = 5; p1Sides = 10;
		p2Dice = 6; p2Sides = 7;
		rolls = 1000000;
		p1Wins = diceGame(p1Dice, p1Sides, p2Dice, p2Sides, rolls);
		System.out.println(rolls + " rolls, p1 = " + p1Dice + "d" + p1Sides + ", p2 = " + p2Dice + "d" + p2Sides);
		System.out.println("p1 wins " + (100.0 * p1Wins / rolls) + "% of the time");
	}
}


Digital root

The digital root, X, of a number, n, is calculated:
: find X as the sum of the digits of n
: find a new X by summing the digits of X, repeating until X has only one digit.

The additive persistence is the number of summations required to obtain the single digit.

The task is to calculate the additive persistence and the digital root of a number, e.g.:
:627615 has additive persistence 2 and digital root of 9;
:39390 has additive persistence 2 and digital root of 6;
:588225 has additive persistence 2 and digital root of 3;
:393900588225 has additive persistence 2 and digital root of 9;

The digital root may be calculated in bases other than 10.

;See:
* [[Casting out nines]] for this wiki's use of this procedure.
* [[Digital root/Multiplicative digital root]]
* [[Sum digits of an integer]]
* Digital root sequence on OEIS
* Additive persistence sequence on OEIS
* [[Iterated digits squaring]]

Solution:
import java.math.BigInteger;

class DigitalRoot
{
  public static int[] calcDigitalRoot(String number, int base)
  {
    BigInteger bi = new BigInteger(number, base);
    int additivePersistence = 0;
    if (bi.signum() < 0)
      bi = bi.negate();
    BigInteger biBase = BigInteger.valueOf(base);
    while (bi.compareTo(biBase) >= 0)
    {
      number = bi.toString(base);
      bi = BigInteger.ZERO;
      for (int i = 0; i < number.length(); i++)
        bi = bi.add(new BigInteger(number.substring(i, i + 1), base));
      additivePersistence++;
    }
    return new int[] { additivePersistence, bi.intValue() };
  }

  public static void main(String[] args)
  {
    for (String arg : args)
    {
      int[] results = calcDigitalRoot(arg, 10);
      System.out.println(arg + " has additive persistence " + results[0] + " and digital root of " + results[1]);
    }
  }
}


Disarium numbers

A '''Disarium number''' is an integer where the sum of each digit raised to the power of its position in the number, is equal to the number.

;E.G.

'''135''' is a '''Disarium number''':

 11 + 32 + 53 == 1 + 9 + 125 == 135

There are a finite number of '''Disarium numbers'''.

;Task

* Find and display the first 18 '''Disarium numbers'''.

;Stretch

* Find and display all 20 '''Disarium numbers'''.

;See also

;* Geeks for Geeks - Disarium numbers
;* OEIS:A032799 - Numbers n such that n equals the sum of its digits raised to the consecutive powers (1,2,3,...)
;* Related task: Narcissistic decimal number
;* Related task: Own digits power sum  ''Which seems to be the same task as Narcissistic decimal number...''

Solution:
import java.lang.Math;

public class DisariumNumbers {
    public static boolean is_disarium(int num) {
        int n = num;
        int len = Integer.toString(n).length();
        int sum = 0;
        int i = 1;
        while (n > 0) {
            sum += Math.pow(n % 10, len - i + 1);
            n /= 10;
            i ++;
        }
        return sum  == num;
    }

    public static void main(String[] args) {
        int i = 0;
        int count = 0;
        while (count <= 18) {
            if (is_disarium(i)) {
                System.out.printf("%d ", i);
                count++;
            }
            i++;
        }
        System.out.printf("%s", "\n");
    }
}


Display a linear combination

Display a finite linear combination in an infinite vector basis (e_1, e_2,\ldots).

Write a function that, when given a finite list of scalars (\alpha^1,\alpha^2,\ldots), creates a string representing the linear combination \sum_i\alpha^i e_i in an explicit format often used in mathematics, that is:

:\alpha^{i_1}e_{i_1}\pm|\alpha^{i_2}|e_{i_2}\pm|\alpha^{i_3}|e_{i_3}\pm\ldots

where \alpha^{i_k}\neq 0

The output must comply to the following rules:
*   don't show null terms, unless the whole combination is null.
:::::::  '''e(1)'''     is fine,     '''e(1) + 0*e(3)'''     or     '''e(1) + 0'''     is wrong.
*   don't show scalars when they are equal to one or minus one.
:::::::  '''e(3)'''     is fine,     '''1*e(3)'''     is wrong.
*   don't prefix by a minus sign if it follows a preceding term.   Instead you use subtraction.
:::::::  '''e(4) - e(5)'''     is fine,     '''e(4) + -e(5)'''     is wrong.

Show here output for the following lists of scalars:

 1)    1,  2,  3
 2)    0,  1,  2,  3
 3)    1,  0,  3,  4
 4)    1,  2,  0
 5)    0,  0,  0
 6)    0
 7)    1,  1,  1
 8)   -1, -1, -1
 9)   -1, -2,  0, -3
10)   -1

Solution:
import java.util.Arrays;

public class LinearCombination {
    private static String linearCombo(int[] c) {
        StringBuilder sb = new StringBuilder();
        for (int i = 0; i < c.length; ++i) {
            if (c[i] == 0) continue;
            String op;
            if (c[i] < 0 && sb.length() == 0) {
                op = "-";
            } else if (c[i] < 0) {
                op = " - ";
            } else if (c[i] > 0 && sb.length() == 0) {
                op = "";
            } else {
                op = " + ";
            }
            int av = Math.abs(c[i]);
            String coeff = av == 1 ? "" : "" + av + "*";
            sb.append(op).append(coeff).append("e(").append(i + 1).append(')');
        }
        if (sb.length() == 0) {
            return "0";
        }
        return sb.toString();
    }

    public static void main(String[] args) {
        int[][] combos = new int[][]{
            new int[]{1, 2, 3},
            new int[]{0, 1, 2, 3},
            new int[]{1, 0, 3, 4},
            new int[]{1, 2, 0},
            new int[]{0, 0, 0},
            new int[]{0},
            new int[]{1, 1, 1},
            new int[]{-1, -1, -1},
            new int[]{-1, -2, 0, -3},
            new int[]{-1},
        };
        for (int[] c : combos) {
            System.out.printf("%-15s  ->  %s\n", Arrays.toString(c), linearCombo(c));
        }
    }
}


Distance and Bearing

It is very important in aviation to have knowledge of the nearby airports at any time in flight.
;Task:
Determine the distance and bearing from an Airplane to the 20 nearest Airports whenever requested.
Use the non-commercial data from openflights.org airports.dat as reference.

A request comes from an airplane at position  ( latitude, longitude ): ( '''51.514669, 2.198581''' ).

Your report should contain the following information from table airports.dat (column shown in brackets):

Name(2), Country(4), ICAO(6), Distance and Bearing calculated from Latitude(7) and Longitude(8).

Distance is measured in nautical miles (NM). Resolution is 0.1 NM.

Bearing is measured in degrees (deg). 0deg = 360deg = north then clockwise 90deg = east, 180deg = south, 270deg = west. Resolution is 1deg.

;See:
:*   openflights.org/data:  Airport, airline and route data
:*   Movable Type Scripts:  Calculate distance, bearing and more between Latitude/Longitude points

Solution:
// The Airport class holds each airport object
package distanceAndBearing;
public class Airport {
	private String airport;
	private String country;
	private String icao;
	private double lat;
	private double lon;
	public String getAirportName() {	return this.airport;	}
	public void setAirportName(String airport) {	this.airport = airport; }
	public String getCountry() {	return this.country;	}
	public void setCountry(String country) {	this.country = country;	}
	public String getIcao() { return this.icao; }
	public void setIcao(String icao) { this.icao = icao;	}
	public double getLat() {	return this.lat; }
	public void setLat(double lat) {	this.lat = lat;	}
	public double getLon() {	return this.lon; }
	public void setLon(double lon) {	this.lon = lon;	}
	@Override
	public String toString() {return "Airport: " + getAirportName() + ": ICAO: " + getIcao();}
}

// The DistanceAndBearing class does all the work.
package distanceAndBearing;
import java.io.File;
import java.text.DecimalFormat;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Scanner;
import java.util.stream.Collectors;
public class DistanceAndBearing {
	private final double earthRadius = 6371;
	private File datFile;
	private List<Airport> airports;
	public DistanceAndBearing() { this.airports = new ArrayList<Airport>(); }
	public boolean readFile(String filename) {
		this.datFile = new File(filename);
		try {
			Scanner fileScanner = new Scanner(datFile);
			String line;
			while (fileScanner.hasNextLine()) {
				line = fileScanner.nextLine();
				line = line.replace(", ", "; "); // There are some commas in airport names in the dat
													// file
				line = line.replace(",\",\"", "\",\""); // There are some airport names that
														// end in a comma in the dat file
				String[] parts = line.split(",");
				Airport airport = new Airport();
				airport.setAirportName(parts[1].replace("\"", "")); // Remove the double quotes from the string
				airport.setCountry(parts[3].replace("\"", "")); // Remove the double quotes from the string
				airport.setIcao(parts[5].replace("\"", "")); // Remove the double quotes from the string
				airport.setLat(Double.valueOf(parts[6]));
				airport.setLon(Double.valueOf(parts[7]));
				this.airports.add(airport);
			}
			fileScanner.close();
			return true; // Return true if the read was successful
		} catch (Exception e) {
			e.printStackTrace();
			return false; // Return false if the read was not successful
		}}
	public double[] calculate(double lat1, double lon1, double lat2, double lon2) {
		double[] results = new double[2];
		double dLat = Math.toRadians(lat2 - lat1);
		double dLon = Math.toRadians(lon2 - lon1);
		double rlat1 = Math.toRadians(lat1);
		double rlat2 = Math.toRadians(lat2);
		double a = Math.pow(Math.sin(dLat / 2), 2)
				+ Math.pow(Math.sin(dLon / 2), 2) * Math.cos(rlat1) * Math.cos(rlat2);
		double c = 2 * Math.asin(Math.sqrt(a));
		double distance = earthRadius * c;
		DecimalFormat df = new DecimalFormat("#0.00");
		distance = Double.valueOf(df.format(distance));
		results[0] = distance;
		double X = Math.cos(rlat2) * Math.sin(dLon);
		double Y = Math.cos(rlat1) * Math.sin(rlat2) - Math.sin(rlat1) * Math.cos(rlat2) * Math.cos(dLon);
		double heading = Math.atan2(X, Y);
		heading = Math.toDegrees(heading);
		results[1] = heading;
		return results;
	}
	public Airport searchByName(final String name) {
		Airport airport = new Airport();
		List<Airport> results = this.airports.stream().filter(ap -> ap.getAirportName().contains(name))
				.collect(Collectors.toList());
		airport = results.get(0);
		return airport;
	}
	public List<Airport> findClosestAirports(double lat, double lon) {
		// TODO Auto-generated method stub
		Map<Double, Airport> airportDistances = new HashMap<>();
		Map<Double, Airport> airportHeading = new HashMap<>();
		List<Airport> closestAirports = new ArrayList<Airport>();
		// This loop finds the distance and heading for every airport and saves them
		// into two separate Maps
		for (Airport ap : this.airports) {
			double[] result = calculate(lat, lon, ap.getLat(), ap.getLon());
			airportDistances.put(result[0], ap);
			airportHeading.put(result[1], ap);
		}
		// Get the keyset from the distance map and sort it.
		ArrayList<Double> distances = new ArrayList<>(airportDistances.keySet());
		Collections.sort(distances);
		// Get the first 20 airports by finding the value in the distance map for
		// each distance in the sorted Arraylist. Then get the airport name, and
		// use that to search for the airport in the airports List.
		// Save that into a new List
		for (int i = 0; i < 20; i++) { closestAirports.add(searchByName((airportDistances.get(distances.get(i)).getAirportName())));}
		// Find the distance and heading for each of the top 20 airports.
		Map<String, Double> distanceMap = new HashMap<>();
		for (Double d : airportDistances.keySet()) {	distanceMap.put(airportDistances.get(d).getAirportName(), d);}
		Map<String, Double> headingMap = new HashMap<>();
		for (Double d : airportHeading.keySet()) {
            double d2 = d;
            if(d2<0){d2+=360'}
            headingMap.put(airportHeading.get(d).getAirportName(), d2); }

		// Print the results.
		System.out.printf("%-4s %-40s %-25s %-6s %12s %15s\n", "Num", "Airport", "Country", "ICAO", "Distance", "Bearing");
		System.out.println("-----------------------------------------------------------------------------------------------------------");
		int i = 0;
		for (Airport a : closestAirports) {
			System.out.printf("%-4s %-40s %-25s %-6s %12.1f %15.0f\n", ++i, a.getAirportName(), a.getCountry(), a.getIcao(), distanceMap.get(a.getAirportName())*0.5399568, headingMap.get(a.getAirportName()));
		}
		return closestAirports;
	}
}


Diversity prediction theorem

The   ''wisdom of the crowd''   is the collective opinion of a group of individuals rather than that of a single expert.

Wisdom-of-the-crowds research routinely attributes the superiority of crowd averages over individual judgments to the elimination of individual noise,   an explanation that assumes independence of the individual judgments from each other.

Thus the crowd tends to make its best decisions if it is made up of diverse opinions and ideologies.

Scott E. Page introduced the diversity prediction theorem:
: ''The squared error of the collective prediction equals the average squared error minus the predictive diversity''.

Therefore,   when the diversity in a group is large,   the error of the crowd is small.

;Definitions:
::*   Average Individual Error:   Average of the individual squared errors
::*   Collective Error:           Squared error of the collective prediction
::*   Prediction Diversity:       Average squared distance from the individual predictions to the collective prediction
::*   Diversity Prediction Theorem:   ''Given a crowd of predictive models'',     then
::::::   Collective Error   =   Average Individual Error   -   Prediction Diversity

;Task:
For a given   true   value and a number of number of estimates (from a crowd),   show   (here on this page):
:::*   the true value   and   the crowd estimates
:::*   the average error
:::*   the crowd error
:::*   the prediction diversity

Use   (at least)   these two examples:
:::*   a true value of   '''49'''   with crowd estimates of:   ''' 48   47   51'''
:::*   a true value of   '''49'''   with crowd estimates of:   ''' 48   47   51   42'''

;Also see:
:*   Wikipedia entry:   Wisdom of the crowd
:*   University of Michigan: PDF paper         (exists on a web archive,   the ''Wayback Machine'').

Solution:
import java.util.Arrays;

public class DiversityPredictionTheorem {
    private static double square(double d) {
        return d * d;
    }

    private static double averageSquareDiff(double d, double[] predictions) {
        return Arrays.stream(predictions)
            .map(it -> square(it - d))
            .average()
            .orElseThrow();
    }

    private static String diversityTheorem(double truth, double[] predictions) {
        double average = Arrays.stream(predictions)
            .average()
            .orElseThrow();
        return String.format("average-error : %6.3f%n", averageSquareDiff(truth, predictions))
            + String.format("crowd-error   : %6.3f%n", square(truth - average))
            + String.format("diversity     : %6.3f%n", averageSquareDiff(average, predictions));
    }

    public static void main(String[] args) {
        System.out.println(diversityTheorem(49.0, new double[]{48.0, 47.0, 51.0}));
        System.out.println(diversityTheorem(49.0, new double[]{48.0, 47.0, 51.0, 42.0}));
    }
}


Doomsday rule

 About the task
John Conway (1937-2020), was a mathematician who also invented several mathematically
oriented computer pastimes, such as the famous Game of Life cellular automaton program.
Dr. Conway invented a simple algorithm for finding the day of the week, given any date.
The algorithm was based on calculating the distance of a given date from certain
"anchor days" which follow a pattern for the day of the week upon which they fall.

; Algorithm
The formula is calculated assuming that Sunday is 0, Monday 1, and so forth with Saturday 7, and

    doomsday = (Tuesday(or 2) + 5(y mod 4) + 4(y mod 100) + 6(y mod 400)) % 7

which, for 2021, is 0 (Sunday).

To calculate the day of the week, we then count days from a close doomsday,
with these as charted here by month, then add the doomsday for the year,
then get the remainder after dividing by 7. This should give us the number
corresponding to the day of the week for that date.

    Month	        Doomsday Dates for Month
    --------------------------------------------
    January (common years)   3, 10, 17, 24, 31
    January (leap years)     4, 11, 18, 25
    February (common years)  7, 14, 21, 28
    February (leap years)    1, 8, 15, 22, 29
    March                    7, 14, 21, 28
    April                    4, 11, 18, 25
    May                      2, 9, 16, 23, 30
    June                     6, 13, 20, 27
    July                     4, 11, 18, 25
    August                   1, 8, 15, 22, 29
    September                5, 12, 19, 26
    October                  3, 10, 17, 24, 31
    November                 7, 14, 21, 28
    December                 5, 12, 19, 26

; Task

Given the following dates:

*   1800-01-06 (January 6, 1800)
*   1875-03-29 (March 29, 1875)
*   1915-12-07 (December 7, 1915)
*   1970-12-23 (December 23, 1970)
*   2043-05-14 (May 14, 2043)
*   2077-02-12 (February 12, 2077)
*   2101-04-02 (April 2, 2101)

Use Conway's Doomsday rule to calculate the day of the week for each date.

; see also
*   Doomsday rule
*   Tomorrow is the Day After Doomsday (p.28)

Solution:
class Doom {
    public static void main(String[] args) {
        final Date[] dates = {
            new Date(1800,1,6),
            new Date(1875,3,29),
            new Date(1915,12,7),
            new Date(1970,12,23),
            new Date(2043,5,14),
            new Date(2077,2,12),
            new Date(2101,4,2)
        };

        for (Date d : dates)
            System.out.println(
                String.format("%s: %s", d.format(), d.weekday()));
    }
}

class Date {
    private int year, month, day;

    private static final int[] leapdoom = {4,1,7,4,2,6,4,1,5,3,7,5};
    private static final int[] normdoom = {3,7,7,4,2,6,4,1,5,3,7,5};
    public static final String[] weekdays = {
        "Sunday", "Monday", "Tuesday", "Wednesday",
        "Thursday", "Friday", "Saturday"
    };

    public Date(int year, int month, int day) {
        this.year = year;
        this.month = month;
        this.day = day;
    }

    public boolean isLeapYear() {
        return year%4 == 0 && (year%100 != 0 || year%400 == 0);
    }

    public String format() {
        return String.format("%02d/%02d/%04d", month, day, year);
    }

    public String weekday() {
        final int c = year/100;
        final int r = year%100;
        final int s = r/12;
        final int t = r%12;

        final int c_anchor = (5 * (c%4) + 2) % 7;
        final int doom = (s + t + t/4 + c_anchor) % 7;
        final int anchor =
            isLeapYear() ? leapdoom[month-1] : normdoom[month-1];

        return weekdays[(doom + day - anchor + 7) % 7];
    }
}


Dot product

Create a function/use an in-built function, to compute the   '''dot product''',   also known as the   '''scalar product'''   of two vectors.

If possible, make the vectors of arbitrary length.

As an example, compute the dot product of the vectors:
::::     [1,  3, -5]       and
::::     [4,      -2, -1]

If implementing the dot product of two vectors directly:
:::*   each vector must be the same length
:::*   multiply corresponding terms from each vector
:::*   sum the products   (to produce the answer)

;Related task:
*   [[Vector products]]

Solution:
public class DotProduct {

	public static void main(String[] args) {
		double[] a = {1, 3, -5};
		double[] b = {4, -2, -1};

		System.out.println(dotProd(a,b));
	}

	public static double dotProd(double[] a, double[] b){
		if(a.length != b.length){
			throw new IllegalArgumentException("The dimensions have to be equal!");
		}
		double sum = 0;
		for(int i = 0; i < a.length; i++){
			sum += a[i] * b[i];
		}
		return sum;
	}
}


Draw a clock

Draw a clock.

More specific:
# Draw a time keeping device. It can be a stopwatch, hourglass, sundial, a mouth counting "one thousand and one", anything. Only showing the seconds is required, e.g.: a watch with just a second hand will suffice. However, it must clearly change every second, and the change must cycle every so often (one minute, 30 seconds, etc.) It must be ''drawn''; printing a string of numbers to your terminal doesn't qualify. Both text-based and graphical drawing are OK.
# The clock is unlikely to be used to control space flights, so it needs not be hyper-accurate, but it should be usable, meaning if one can read the seconds off the clock, it must agree with the system clock.
# A clock is rarely (never?) a major application: don't be a CPU hog and poll the system timer every microsecond, use a proper timer/signal/event from your system or language instead. For a bad example, many OpenGL programs update the frame-buffer in a busy loop even if no redraw is needed, which is very undesirable for this task.
# A clock is rarely (never?) a major application: try to keep your code simple and to the point. Don't write something too elaborate or convoluted, instead do whatever is natural, concise and clear in your language.

;Key points
* animate simple object
* timed event
* polling system resources
* code clarity

Solution:
import java.awt.*;
import java.awt.event.*;
import static java.lang.Math.*;
import java.time.LocalTime;
import javax.swing.*;

class Clock extends JPanel {

    final float degrees06 = (float) (PI / 30);
    final float degrees30 = degrees06 * 5;
    final float degrees90 = degrees30 * 3;

    final int size = 590;
    final int spacing = 40;
    final int diameter = size - 2 * spacing;
    final int cx = diameter / 2 + spacing;
    final int cy = diameter / 2 + spacing;

    public Clock() {
        setPreferredSize(new Dimension(size, size));
        setBackground(Color.white);

        new Timer(1000, (ActionEvent e) -> {
            repaint();
        }).start();
    }

    @Override
    public void paintComponent(Graphics gg) {
        super.paintComponent(gg);
        Graphics2D g = (Graphics2D) gg;
        g.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
                RenderingHints.VALUE_ANTIALIAS_ON);

        drawFace(g);

        final LocalTime time  = LocalTime.now();
        int hour = time.getHour();
        int minute = time.getMinute();
        int second = time.getSecond();

        float angle = degrees90 - (degrees06 * second);
        drawHand(g, angle, diameter / 2 - 30, Color.red);

        float minsecs = (minute + second / 60.0F);
        angle = degrees90 - (degrees06 * minsecs);
        drawHand(g, angle, diameter / 3 + 10, Color.black);

        float hourmins = (hour + minsecs / 60.0F);
        angle = degrees90 - (degrees30 * hourmins);
        drawHand(g, angle, diameter / 4 + 10, Color.black);
    }

    private void drawFace(Graphics2D g) {
        g.setStroke(new BasicStroke(2));
        g.setColor(Color.white);
        g.fillOval(spacing, spacing, diameter, diameter);
        g.setColor(Color.black);
        g.drawOval(spacing, spacing, diameter, diameter);
    }

    private void drawHand(Graphics2D g, float angle, int radius, Color color) {
        int x = cx + (int) (radius * cos(angle));
        int y = cy - (int) (radius * sin(angle));
        g.setColor(color);
        g.drawLine(cx, cy, x, y);
    }

    public static void main(String[] args) {
        SwingUtilities.invokeLater(() -> {
            JFrame f = new JFrame();
            f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
            f.setTitle("Clock");
            f.setResizable(false);
            f.add(new Clock(), BorderLayout.CENTER);
            f.pack();
            f.setLocationRelativeTo(null);
            f.setVisible(true);
        });
    }
}


Draw a rotating cube

Task
Draw a rotating cube.

It should be oriented with one vertex pointing straight up, and its opposite vertex on the main diagonal (the one farthest away) straight down. It can be solid or wire-frame, and you can use ASCII art if your language doesn't have graphical capabilities. Perspective is optional.

;Related tasks
* Draw a cuboid
* write language name in 3D ASCII

Solution:
import java.awt.*;
import java.awt.event.ActionEvent;
import static java.lang.Math.*;
import javax.swing.*;

public class RotatingCube extends JPanel {
    double[][] nodes = {{-1, -1, -1}, {-1, -1, 1}, {-1, 1, -1}, {-1, 1, 1},
    {1, -1, -1}, {1, -1, 1}, {1, 1, -1}, {1, 1, 1}};

    int[][] edges = {{0, 1}, {1, 3}, {3, 2}, {2, 0}, {4, 5}, {5, 7}, {7, 6},
    {6, 4}, {0, 4}, {1, 5}, {2, 6}, {3, 7}};

    public RotatingCube() {
        setPreferredSize(new Dimension(640, 640));
        setBackground(Color.white);

        scale(100);
        rotateCube(PI / 4, atan(sqrt(2)));

        new Timer(17, (ActionEvent e) -> {
            rotateCube(PI / 180, 0);
            repaint();
        }).start();
    }

    final void scale(double s) {
        for (double[] node : nodes) {
            node[0] *= s;
            node[1] *= s;
            node[2] *= s;
        }
    }

    final void rotateCube(double angleX, double angleY) {
        double sinX = sin(angleX);
        double cosX = cos(angleX);

        double sinY = sin(angleY);
        double cosY = cos(angleY);

        for (double[] node : nodes) {
            double x = node[0];
            double y = node[1];
            double z = node[2];

            node[0] = x * cosX - z * sinX;
            node[2] = z * cosX + x * sinX;

            z = node[2];

            node[1] = y * cosY - z * sinY;
            node[2] = z * cosY + y * sinY;
        }
    }

    void drawCube(Graphics2D g) {
        g.translate(getWidth() / 2, getHeight() / 2);

        for (int[] edge : edges) {
            double[] xy1 = nodes[edge[0]];
            double[] xy2 = nodes[edge[1]];
            g.drawLine((int) round(xy1[0]), (int) round(xy1[1]),
                    (int) round(xy2[0]), (int) round(xy2[1]));
        }

        for (double[] node : nodes)
            g.fillOval((int) round(node[0]) - 4, (int) round(node[1]) - 4, 8, 8);
    }

    @Override
    public void paintComponent(Graphics gg) {
        super.paintComponent(gg);
        Graphics2D g = (Graphics2D) gg;
        g.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
                RenderingHints.VALUE_ANTIALIAS_ON);

        drawCube(g);
    }

    public static void main(String[] args) {
        SwingUtilities.invokeLater(() -> {
            JFrame f = new JFrame();
            f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
            f.setTitle("Rotating Cube");
            f.setResizable(false);
            f.add(new RotatingCube(), BorderLayout.CENTER);
            f.pack();
            f.setLocationRelativeTo(null);
            f.setVisible(true);
        });
    }
}


Draw a sphere

{{requires|Graphics}}

;Task:
Draw a sphere.

The sphere can be represented graphically, or in ASCII art, depending on the language capabilities.

Either static or rotational projection is acceptable for this task.

;Related tasks:
* draw a cuboid
* draw a rotating cube
* write language name in 3D ASCII
* draw a Deathstar

Solution:
public class Sphere{
    static char[] shades = {'.', ':', '!', '*', 'o', 'e', '&', '#', '%', '@'};

    static double[] light = { 30, 30, -50 };
    private static void normalize(double[] v){
        double len = Math.sqrt(v[0]*v[0] + v[1]*v[1] + v[2]*v[2]);
        v[0] /= len; v[1] /= len; v[2] /= len;
    }

    private static double dot(double[] x, double[] y){
        double d = x[0]*y[0] + x[1]*y[1] + x[2]*y[2];
        return d < 0 ? -d : 0;
    }

    public static void drawSphere(double R, double k, double ambient){
        double[] vec = new double[3];
        for(int i = (int)Math.floor(-R); i <= (int)Math.ceil(R); i++){
            double x = i + .5;
            for(int j = (int)Math.floor(-2 * R); j <= (int)Math.ceil(2 * R); j++){
                double y = j / 2. + .5;
                if(x * x + y * y <= R * R) {
                    vec[0] = x;
                    vec[1] = y;
                    vec[2] = Math.sqrt(R * R - x * x - y * y);
                    normalize(vec);
                    double b = Math.pow(dot(light, vec), k) + ambient;
                    int intensity = (b <= 0) ?
                                shades.length - 2 :
                                (int)Math.max((1 - b) * (shades.length - 1), 0);
                    System.out.print(shades[intensity]);
                } else
                    System.out.print(' ');
            }
            System.out.println();
        }
    }

    public static void main(String[] args){
        normalize(light);
        drawSphere(20, 4, .1);
        drawSphere(10, 2, .4);
    }
}


Dutch national flag problem

The Dutch national flag is composed of three coloured bands in the order:
::*   red     (top)
::*   then white,   and
::*   lastly blue   (at the bottom).

The problem posed by Edsger Dijkstra is:
:Given a number of red, blue and white balls in random order, arrange them in the order of the colours in the Dutch national flag.
When the problem was first posed, Dijkstra then went on to successively refine a solution, minimising the number of swaps and the number of times the colour of a ball needed to determined and restricting the balls to end in an array, ...

;Task
# Generate a randomized order of balls ''ensuring that they are not in the order of the Dutch national flag''.
# Sort the balls in a way idiomatic to your language.
# Check the sorted balls ''are'' in the order of the Dutch national flag.

;C.f.:
* Dutch national flag problem
* Probabilistic analysis of algorithms for the Dutch national flag problem by Wei-Mei Chen. (pdf)

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

public class DutchNationalFlag {
    enum DutchColors {
        RED, WHITE, BLUE
    }

    public static void main(String[] args){
        DutchColors[] balls = new DutchColors[12];
        DutchColors[] values = DutchColors.values();
        Random rand = new Random();

        for (int i = 0; i < balls.length; i++)
            balls[i]=values[rand.nextInt(values.length)];
        System.out.println("Before: " + Arrays.toString(balls));

        Arrays.sort(balls);
        System.out.println("After:  " + Arrays.toString(balls));

        boolean sorted = true;
        for (int i = 1; i < balls.length; i++ ){
            if (balls[i-1].compareTo(balls[i]) > 0){
                sorted=false;
                break;
            }
        }
        System.out.println("Correctly sorted: " + sorted);
    }
}


EKG sequence convergence

The sequence is from the natural numbers and is defined by:
* a(1) = 1;
* a(2) = Start = 2;
* for n > 2, a(n) shares at least one prime factor with a(n-1) and is the ''smallest'' such natural number ''not already used''.

The sequence is called the EKG sequence (after its visual similarity to an electrocardiogram when graphed).

Variants of the sequence can be generated starting 1, N where N is any natural number larger than one. For the purposes of this task let us call:
* The sequence described above , starting 1, 2, ... the EKG(2) sequence;
* the sequence starting 1, 3, ... the EKG(3) sequence;
* ... the sequence starting 1, N, ... the EKG(N) sequence.

;Convergence
If an algorithm that keeps track of the minimum amount of numbers and their corresponding prime factors used to generate the next term is used, then this may be known as the generators essential '''state'''. Two EKG generators with differing starts can converge to produce the same sequence after initial differences.
EKG(N1) and EKG(N2) are said to to have converged at and after generation a(c) if state_of(EKG(N1).a(c)) == state_of(EKG(N2).a(c)).

;Task:
# Calculate and show here the first 10 members of EKG(2).
# Calculate and show here the first 10 members of EKG(5).
# Calculate and show here the first 10 members of EKG(7).
# Calculate and show here the first 10 members of EKG(9).
# Calculate and show here the first 10 members of EKG(10).
# Calculate and show here at which term EKG(5) and EKG(7) converge   ('''stretch goal''').

;Related Tasks:
# [[Greatest common divisor]]
# [[Sieve of Eratosthenes]]

;Reference:
* The EKG Sequence and the Tree of Numbers. (Video).

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

public class EKGSequenceConvergence {

    public static void main(String[] args) {
        System.out.println("Calculate and show here the first 10 members of EKG[2], EKG[5], EKG[7], EKG[9] and EKG[10].");
        for ( int i : new int[] {2, 5, 7, 9, 10} ) {
            System.out.printf("EKG[%d] = %s%n", i, ekg(i, 10));
        }
        System.out.println("Calculate and show here at which term EKG[5] and EKG[7] converge.");
        List<Integer> ekg5 = ekg(5, 100);
        List<Integer> ekg7 = ekg(7, 100);
        for ( int i = 1 ; i < ekg5.size() ; i++ ) {
            if ( ekg5.get(i) == ekg7.get(i) && sameSeq(ekg5, ekg7, i)) {
                System.out.printf("EKG[%d](%d) = EKG[%d](%d) = %d, and are identical from this term on%n", 5, i+1, 7, i+1, ekg5.get(i));
                break;
            }
        }
    }

    //  Same last element, and all elements in sequence are identical
    private static boolean sameSeq(List<Integer> seq1, List<Integer> seq2, int n) {
        List<Integer> list1 = new ArrayList<>(seq1.subList(0, n));
        Collections.sort(list1);
        List<Integer> list2 = new ArrayList<>(seq2.subList(0, n));
        Collections.sort(list2);
        for ( int i = 0 ; i < n ; i++ ) {
            if ( list1.get(i) != list2.get(i) ) {
                return false;
            }
        }
        return true;
    }

    //  Without HashMap to identify seen terms, need to examine list.
    //    Calculating 3000 terms in this manner takes 10 seconds
    //  With HashMap to identify the seen terms, calculating 3000 terms takes .1 sec.
    private static List<Integer> ekg(int two, int maxN) {
        List<Integer> result = new ArrayList<>();
        result.add(1);
        result.add(two);
        Map<Integer,Integer> seen = new HashMap<>();
        seen.put(1, 1);
        seen.put(two, 1);
        int minUnseen = two == 2 ? 3 : 2;
        int prev = two;
        for ( int n = 3 ; n <= maxN ; n++ ) {
            int test = minUnseen - 1;
            while ( true ) {
                test++;
                if ( ! seen.containsKey(test) && gcd(test, prev) > 1 ) {

                    result.add(test);
                    seen.put(test, n);
                    prev = test;
                    if ( minUnseen == test ) {
                        do {
                            minUnseen++;
                        } while ( seen.containsKey(minUnseen) );
                    }
                    break;
                }
            }
        }
        return result;
    }

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

}


Earliest difference between prime gaps

When calculating prime numbers > 2, the difference between adjacent primes is always an even number. This difference, also referred to as the gap, varies in an random pattern; at least, no pattern has ever been discovered, and it is strongly conjectured that no pattern exists. However, it is also conjectured that between some two adjacent primes will be a gap corresponding to every positive even integer.

{|class="wikitable"
!gap!!minimalstartingprime!!endingprime
|-
|2||3||5
|-
|4||7||11
|-
|6||23||29
|-
|8||89||97
|-
|10||139||149
|-
|12||199||211
|-
|14||113||127
|-
|16||1831||1847
|-
|18||523||541
|-
|20||887||907
|-
|22||1129||1151
|-
|24||1669||1693
|-
|26||2477||2503
|-
|28||2971||2999
|-
|30||4297||4327
|}

This task involves locating the minimal primes corresponding to those gaps.

Though every gap value exists, they don't seem to come in any particular order. For example, this table shows the gaps and minimum starting value primes for 2 through 30:

For the purposes of this task, considering only primes greater than 2, consider prime gaps that differ by exactly two to be adjacent.

;Task

For each order of magnitude '''m''' from '''101''' through '''106''':

* Find the first two sets of minimum adjacent prime gaps where the absolute value of the difference between the prime gap start values is greater than '''m'''.

;E.G.

For an '''m''' of '''101''';

The start value of gap 2 is 3, the start value of gap 4 is 7, the difference is 7 - 3 or 4. 4 < '''101''' so keep going.

The start value of gap 4 is 7, the start value of gap 6 is 23, the difference is 23 - 7, or 16. 16 > '''101''' so this the earliest adjacent gap difference > '''101'''.

;Stretch goal

* Do the same for '''107''' and '''108''' (and higher?) orders of magnitude

Note: the earliest value found for each order of magnitude may not be unique, in fact, ''is'' not unique; also, with the gaps in ascending order, the minimal starting values are not strictly ascending.

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

public class PrimeGaps {
    private Map<Integer, Integer> gapStarts = new HashMap<>();
    private int lastPrime;
    private PrimeGenerator primeGenerator = new PrimeGenerator(1000, 500000);

    public static void main(String[] args) {
        final int limit = 100000000;
        PrimeGaps pg = new PrimeGaps();
        for (int pm = 10, gap1 = 2;;) {
            int start1 = pg.findGapStart(gap1);
            int gap2 = gap1 + 2;
            int start2 = pg.findGapStart(gap2);
            int diff = start2 > start1 ? start2 - start1 : start1 - start2;
            if (diff > pm) {
                System.out.printf(
                    "Earliest difference > %,d between adjacent prime gap starting primes:\n"
                    + "Gap %,d starts at %,d, gap %,d starts at %,d, difference is %,d.\n\n",
                    pm, gap1, start1, gap2, start2, diff);
                if (pm == limit)
                    break;
                pm *= 10;
            } else {
                gap1 = gap2;
            }
        }
    }

    private int findGapStart(int gap) {
        Integer start = gapStarts.get(gap);
        if (start != null)
            return start;
        for (;;) {
            int prev = lastPrime;
            lastPrime = primeGenerator.nextPrime();
            int diff = lastPrime - prev;
            gapStarts.putIfAbsent(diff, prev);
            if (diff == gap)
                return prev;
        }
    }
}


Eban numbers

Definition:
An   '''eban'''   number is a number that has no letter    '''e'''    in it when the number is spelled in English.

Or more literally,   spelled numbers that contain the letter   '''e'''   are banned.

The American version of spelling numbers will be used here   (as opposed to the British).

'''2,000,000,000'''   is two billion,   ''not''   two milliard.

Only numbers less than   '''one sextillion'''   ('''1021''')   will be considered in/for this task.

This will allow optimizations to be used.

;Task:
:::*   show all eban numbers   <=   '''1,000'''   (in a horizontal format),                   and a count
:::*   show all eban numbers between   '''1,000'''   and   '''4,000'''   (inclusive),   and a count
:::*   show a count of all eban numbers up and including            '''10,000'''
:::*   show a count of all eban numbers up and including                '''100,000'''
:::*   show a count of all eban numbers up and including                   '''1,000,000'''
:::*   show a count of all eban numbers up and including                      '''10,000,000'''
:::*   show all output here.

;See also:
:*   The MathWorld entry:    eban numbers.
:*   The OEIS      entry:   A6933,                eban numbers.
:*   [[Number names]].

Solution:
import java.util.List;

public class Main {
    private static class Range {
        int start;
        int end;
        boolean print;

        public Range(int s, int e, boolean p) {
            start = s;
            end = e;
            print = p;
        }
    }

    public static void main(String[] args) {
        List<Range> rgs = List.of(
            new Range(2, 1000, true),
            new Range(1000, 4000, true),
            new Range(2, 10_000, false),
            new Range(2, 100_000, false),
            new Range(2, 1_000_000, false),
            new Range(2, 10_000_000, false),
            new Range(2, 100_000_000, false),
            new Range(2, 1_000_000_000, false)
        );
        for (Range rg : rgs) {
            if (rg.start == 2) {
                System.out.printf("eban numbers up to and including %d\n", rg.end);
            } else {
                System.out.printf("eban numbers between %d and %d\n", rg.start, rg.end);
            }
            int count = 0;
            for (int i = rg.start; i <= rg.end; ++i) {
                int b = i / 1_000_000_000;
                int r = i % 1_000_000_000;
                int m = r / 1_000_000;
                r = i % 1_000_000;
                int t = r / 1_000;
                r %= 1_000;
                if (m >= 30 && m <= 66) m %= 10;
                if (t >= 30 && t <= 66) t %= 10;
                if (r >= 30 && r <= 66) r %= 10;
                if (b == 0 || b == 2 || b == 4 || b == 6) {
                    if (m == 0 || m == 2 || m == 4 || m == 6) {
                        if (t == 0 || t == 2 || t == 4 || t == 6) {
                            if (r == 0 || r == 2 || r == 4 || r == 6) {
                                if (rg.print) System.out.printf("%d ", i);
                                count++;
                            }
                        }
                    }
                }
            }
            if (rg.print) {
                System.out.println();
            }
            System.out.printf("count = %d\n\n", count);
        }
    }
}


Eertree

An '''eertree''' is a data structure designed for efficient processing of certain palindrome tasks, for instance counting the number of sub-palindromes in an input string.

The data structure has commonalities to both ''tries'' and ''suffix trees''.
  See links below.

;Task:
Construct an eertree for the string "eertree", then output all sub-palindromes by traversing the tree.

;See also:
*   Wikipedia entry:   trie.
*   Wikipedia entry:   suffix tree
*   Cornell University Library, Computer Science, Data Structures and Algorithms ---> EERTREE: An Efficient Data Structure for Processing Palindromes in Strings.

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

public class Eertree {
    public static void main(String[] args) {
        List<Node> tree = eertree("eertree");
        List<String> result = subPalindromes(tree);
        System.out.println(result);
    }

    private static class Node {
        int length;
        Map<Character, Integer> edges = new HashMap<>();
        int suffix;

        public Node(int length) {
            this.length = length;
        }

        public Node(int length, Map<Character, Integer> edges, int suffix) {
            this.length = length;
            this.edges = edges != null ? edges : new HashMap<>();
            this.suffix = suffix;
        }
    }

    private static final int EVEN_ROOT = 0;
    private static final int ODD_ROOT = 1;

    private static List<Node> eertree(String s) {
        List<Node> tree = new ArrayList<>();
        tree.add(new Node(0, null, ODD_ROOT));
        tree.add(new Node(-1, null, ODD_ROOT));
        int suffix = ODD_ROOT;
        int n, k;
        for (int i = 0; i < s.length(); ++i) {
            char c = s.charAt(i);
            for (n = suffix; ; n = tree.get(n).suffix) {
                k = tree.get(n).length;
                int b = i - k - 1;
                if (b >= 0 && s.charAt(b) == c) {
                    break;
                }
            }
            if (tree.get(n).edges.containsKey(c)) {
                suffix = tree.get(n).edges.get(c);
                continue;
            }
            suffix = tree.size();
            tree.add(new Node(k + 2));
            tree.get(n).edges.put(c, suffix);
            if (tree.get(suffix).length == 1) {
                tree.get(suffix).suffix = 0;
                continue;
            }
            while (true) {
                n = tree.get(n).suffix;
                int b = i - tree.get(n).length - 1;
                if (b >= 0 && s.charAt(b) == c) {
                    break;
                }
            }
            tree.get(suffix).suffix = tree.get(n).edges.get(c);
        }
        return tree;
    }

    private static List<String> subPalindromes(List<Node> tree) {
        List<String> s = new ArrayList<>();
        subPalindromes_children(0, "", tree, s);
        for (Map.Entry<Character, Integer> cm : tree.get(1).edges.entrySet()) {
            String ct = String.valueOf(cm.getKey());
            s.add(ct);
            subPalindromes_children(cm.getValue(), ct, tree, s);
        }
        return s;
    }

    // nested methods are a pain, even if lambdas make that possible for Java
    private static void subPalindromes_children(final int n, final String p, final List<Node> tree, List<String> s) {
        for (Map.Entry<Character, Integer> cm : tree.get(n).edges.entrySet()) {
            Character c = cm.getKey();
            Integer m = cm.getValue();
            String pl = c + p + c;
            s.add(pl);
            subPalindromes_children(m, pl, tree, s);
        }
    }
}


Egyptian division

Egyptian division is a method of dividing integers using addition and
doubling that is similar to the algorithm of [[Ethiopian multiplication]]

'''Algorithm:'''

Given two numbers where the '''dividend''' is to be divided by the '''divisor''':

# Start the construction of a table of two columns: '''powers_of_2''', and '''doublings'''; by a first row of a 1 (i.e. 2^0) in the first column and 1 times the divisor in the first row second column.
# Create the second row with columns of 2 (i.e 2^1), and 2 * divisor in order.
# Continue with successive i'th rows of 2^i and 2^i * divisor.
# Stop adding rows, and keep only those rows, where 2^i * divisor is less than or equal to the dividend.
# We now assemble two separate sums that both start as zero, called here '''answer''' and '''accumulator'''
# Consider each row of the table, in the ''reverse'' order of its construction.
# If the current value of the accumulator added to the doublings cell would be less than or equal to the dividend then add it to the accumulator, as well as adding the powers_of_2 cell value to the answer.
# When the first row has been considered as above, then the integer division of dividend by divisor is given by answer. (And the remainder is given by the absolute value of accumulator - dividend).

'''Example: 580 / 34'''

''' Table creation: '''

::: {| class="wikitable"
! powers_of_2
! doublings
|-
| 1
| 34
|-
| 2
| 68
|-
| 4
| 136
|-
| 8
| 272
|-
| 16
| 544
|}

''' Initialization of sums: '''

::: {| class="wikitable"
! powers_of_2
! doublings
! answer
! accumulator
|-
| 1
| 34
|

|

|-
| 2
| 68
|

|

|-
| 4
| 136
|

|

|-
| 8
| 272
|

|

|-
| 16
| 544
|

|

|-
|
|
| 0
| 0
|}

''' Considering table rows, bottom-up: '''

When a row is considered it is shown crossed out if it is not accumulated, or '''bold''' if the row causes summations.

::: {| class="wikitable"
! powers_of_2
! doublings
! answer
! accumulator
|-
| 1
| 34
|

|

|-
| 2
| 68
|

|

|-
| 4
| 136
|

|

|-
| 8
| 272
|

|

|-
| '''16'''
| '''544'''
| 16
| 544
|}

::: {| class="wikitable"
! powers_of_2
! doublings
! answer
! accumulator
|-
| 1
| 34
|

|

|-
| 2
| 68
|

|

|-
| 4
| 136
|

|

|-
| 8
| 272
| 16
| 544
|-
| '''16'''
| '''544'''
|

|

|}

::: {| class="wikitable"
! powers_of_2
! doublings
! answer
! accumulator
|-
| 1
| 34
|

|

|-
| 2
| 68
|

|

|-
| 4
| 136
| 16
| 544
|-
| 8
| 272
|

|

|-
| '''16'''
| '''544'''
|

|

|}

::: {| class="wikitable"
! powers_of_2
! doublings
! answer
! accumulator
|-
| 1
| 34
|

|

|-
| 2
| 68
| 16
| 544
|-
| 4
| 136
|

|

|-
| 8
| 272
|

|

|-
| '''16'''
| '''544'''
|

|

|}

::: {| class="wikitable"
! powers_of_2
! doublings
! answer
! accumulator
|-
| '''1'''
| '''34'''
| 17
| 578
|-
| 2
| 68
|

|

|-
| 4
| 136
|

|

|-
| 8
| 272
|

|

|-
| '''16'''
| '''544'''
|

|

|}

;Answer:
So 580 divided by 34 using the Egyptian method is '''17''' remainder (578 - 580) or '''2'''.

;Task:
The task is to create a function that does Egyptian division. The function should
closely follow the description above in using a list/array of powers of two, and
another of doublings.

* Functions should be clear interpretations of the algorithm.
* Use the function to divide 580 by 34 and show the answer '''here, on this page'''.

;Related tasks:
:*   Egyptian fractions

;References:
:*   Egyptian Number System

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

public class EgyptianDivision {

    /**
     * Runs the method and divides 580 by 34
     *
     * @param args not used
     */
    public static void main(String[] args) {

        divide(580, 34);

    }

    /**
     * Divides dividend by divisor using the Egyptian Division-Algorithm and prints the
     * result to the console
     *
     * @param dividend
     * @param divisor
     */
    public static void divide(int dividend, int divisor) {

        List<Integer> powersOf2 = new ArrayList<>();
        List<Integer> doublings = new ArrayList<>();

        //populate the powersof2- and doublings-columns
        int line = 0;
        while ((Math.pow(2, line) * divisor) <= dividend) { //<- could also be done with a for-loop
            int powerOf2 = (int) Math.pow(2, line);
            powersOf2.add(powerOf2);
            doublings.add(powerOf2 * divisor);
            line++;
        }

        int answer = 0;
        int accumulator = 0;

        //Consider the rows in reverse order of their construction (from back to front of the List<>s)
        for (int i = powersOf2.size() - 1; i >= 0; i--) {
            if (accumulator + doublings.get(i) <= dividend) {
                accumulator += doublings.get(i);
                answer += powersOf2.get(i);
            }
        }

        System.out.println(String.format("%d, remainder %d", answer, dividend - accumulator));
    }
}


Elementary cellular automaton

An '''cellular automaton where there are two possible states (labeled 0 and 1) and the rule to determine the state of a cell in the next generation depends only on the current state of the cell and its two immediate neighbors.  Those three values can be encoded with three bits.

The rules of evolution are then encoded with eight bits indicating the outcome of each of the eight possibilities 111, 110, 101, 100, 011, 010, 001 and 000 in this order.  Thus for instance the rule 13 means that a state is updated to 1 only in the cases 011, 010 and 000, since 13 in binary is 0b00001101.

;Task:
Create a subroutine, program or function that allows to create and visualize the evolution of any of the 256 possible elementary cellular automaton of arbitrary space length and for any given initial state.  You can demonstrate your solution with any automaton of your choice.

The space state should ''wrap'':  this means that the left-most cell should be considered as the right neighbor of the right-most cell, and reciprocally.

This task is basically a generalization of [[one-dimensional cellular automata]].

;See also
* Cellular automata (natureofcode.com)

Solution:
import java.awt.*;
import java.awt.event.ActionEvent;
import javax.swing.*;
import javax.swing.Timer;

public class WolframCA extends JPanel {
    final int[] ruleSet = {30, 45, 50, 57, 62, 70, 73, 75, 86, 89, 90, 99,
        101, 105, 109, 110, 124, 129, 133, 135, 137, 139, 141, 164,170, 232};
    byte[][] cells;
    int rule = 0;

    public WolframCA() {
        Dimension dim = new Dimension(900, 450);
        setPreferredSize(dim);
        setBackground(Color.white);
        setFont(new Font("SansSerif", Font.BOLD, 28));

        cells = new byte[dim.height][dim.width];
        cells[0][dim.width / 2] = 1;

        new Timer(5000, (ActionEvent e) -> {
            rule++;
            if (rule == ruleSet.length)
                rule = 0;
            repaint();
        }).start();
    }

    private byte rules(int lhs, int mid, int rhs) {
        int idx = (lhs << 2 | mid << 1 | rhs);
        return (byte) (ruleSet[rule] >> idx & 1);
    }

    void drawCa(Graphics2D g) {
        g.setColor(Color.black);
        for (int r = 0; r < cells.length - 1; r++) {
            for (int c = 1; c < cells[r].length - 1; c++) {
                byte lhs = cells[r][c - 1];
                byte mid = cells[r][c];
                byte rhs = cells[r][c + 1];
                cells[r + 1][c] = rules(lhs, mid, rhs); // next generation
                if (cells[r][c] == 1) {
                    g.fillRect(c, r, 1, 1);
                }
            }
        }
    }

    void drawLegend(Graphics2D g) {
        String s = String.valueOf(ruleSet[rule]);
        int sw = g.getFontMetrics().stringWidth(s);

        g.setColor(Color.white);
        g.fillRect(16, 5, 55, 30);

        g.setColor(Color.darkGray);
        g.drawString(s, 16 + (55 - sw) / 2, 30);
    }

    @Override
    public void paintComponent(Graphics gg) {
        super.paintComponent(gg);
        Graphics2D g = (Graphics2D) gg;
        g.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
                RenderingHints.VALUE_ANTIALIAS_ON);

        drawCa(g);
        drawLegend(g);
    }

    public static void main(String[] args) {
        SwingUtilities.invokeLater(() -> {
            JFrame f = new JFrame();
            f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
            f.setTitle("Wolfram CA");
            f.setResizable(false);
            f.add(new WolframCA(), BorderLayout.CENTER);
            f.pack();
            f.setLocationRelativeTo(null);
            f.setVisible(true);
        });
    }
}


Elliptic curve arithmetic

digital signatures.

The purpose of this task is to implement a simplified (without modular arithmetic) version of the elliptic curve arithmetic which is required by the   elliptic curve DSA   protocol.

In a nutshell, an elliptic curve is a bi-dimensional curve defined by the following relation between the '''x''' and '''y''' coordinates of any point on the curve:

::::   y^2 = x^3 + a x + b

'''a''' and '''b''' are arbitrary parameters that define the specific curve which is used.

For this particular task, we'll use the following parameters:

::::    a=0,   b=7

The most interesting thing about elliptic curves is the fact that it is possible to define a   group   structure on it.

To do so we define an   internal composition   rule with an additive notation '''+''',   such that for any three distinct points '''P''', '''Q''' and '''R''' on the curve, whenever these points are aligned, we have:

::::    P + Q + R = 0

Here   '''0'''   (zero)   is the ''infinity point'',   for which the '''x''' and '''y''' values are not defined.   It's basically the same kind of point which defines the horizon in   projective geometry.

We'll also assume here that this infinity point is unique and defines the   neutral element   of the addition.

This was not the definition of the addition, but only its desired property.    For a more accurate definition, we proceed as such:

Given any three aligned points '''P''', '''Q''' and '''R''',   we define the sum   '''S = P + Q'''   as the point (possibly the infinity point) such that   '''S''', '''R'''   and the infinity point are aligned.

Considering the symmetry of the curve around the x-axis, it's easy to convince oneself that two points '''S''' and '''R''' can be aligned with the infinity point if and only if '''S''' and '''R''' are symmetric of one another towards the x-axis   (because in that case there is no other candidate than the infinity point to complete the alignment triplet).

'''S''' is thus defined as the symmetric of '''R''' towards the '''x''' axis.

The task consists in defining the addition which, for any two points of the curve, returns the sum of these two points.   You will pick two random points on the curve, compute their sum and show that the symmetric of the sum is aligned with the two initial points.

You will use the '''a''' and '''b''' parameters of secp256k1, i.e.  respectively zero and seven.

''Hint'':   You might need to define a "doubling" function, that returns '''P+P''' for any given point '''P'''.

''Extra credit'':   define the full elliptic curve arithmetic (still not modular, though) by defining a "multiply" function that returns,
for any point '''P''' and integer '''n''',   the point '''P + P + ... + P'''     ('''n''' times).

Solution:
import static java.lang.Math.*;
import java.util.Locale;

public class Test {

    public static void main(String[] args) {
        Pt a = Pt.fromY(1);
        Pt b = Pt.fromY(2);
        System.out.printf("a = %s%n", a);
        System.out.printf("b = %s%n", b);
        Pt c = a.plus(b);
        System.out.printf("c = a + b = %s%n", c);
        Pt d = c.neg();
        System.out.printf("d = -c = %s%n", d);
        System.out.printf("c + d = %s%n", c.plus(d));
        System.out.printf("a + b + d = %s%n", a.plus(b).plus(d));
        System.out.printf("a * 12345 = %s%n", a.mult(12345));
    }
}

class Pt {
    final static int bCoeff = 7;

    double x, y;

    Pt(double x, double y) {
        this.x = x;
        this.y = y;
    }

    static Pt zero() {
        return new Pt(Double.POSITIVE_INFINITY, Double.POSITIVE_INFINITY);
    }

    boolean isZero() {
        return this.x > 1e20 || this.x < -1e20;
    }

    static Pt fromY(double y) {
        return new Pt(cbrt(pow(y, 2) - bCoeff), y);
    }

    Pt dbl() {
        if (isZero())
            return this;
        double L = (3 * this.x * this.x) / (2 * this.y);
        double x2 = pow(L, 2) - 2 * this.x;
        return new Pt(x2, L * (this.x - x2) - this.y);
    }

    Pt neg() {
        return new Pt(this.x, -this.y);
    }

    Pt plus(Pt q) {
        if (this.x == q.x && this.y == q.y)
            return dbl();

        if (isZero())
            return q;

        if (q.isZero())
            return this;

        double L = (q.y - this.y) / (q.x - this.x);
        double xx = pow(L, 2) - this.x - q.x;
        return new Pt(xx, L * (this.x - xx) - this.y);
    }

    Pt mult(int n) {
        Pt r = Pt.zero();
        Pt p = this;
        for (int i = 1; i <= n; i <<= 1) {
            if ((i & n) != 0)
                r = r.plus(p);
            p = p.dbl();
        }
        return r;
    }

    @Override
    public String toString() {
        if (isZero())
            return "Zero";
        return String.format(Locale.US, "(%.3f,%.3f)", this.x, this.y);
    }
}


Empty directory

Starting with a path to some directory, determine whether the directory is empty.

An empty directory contains no files nor subdirectories.
With [[Unix]] or [[Windows]] systems, every directory contains an entry for "." and almost every directory contains ".." (except for a root directory); an empty directory contains no other entries.

Solution:
import java.nio.file.Paths;
//... other class code here
public static boolean isEmptyDir(String dirName){
    return Paths.get(dirName).toFile().listFiles().length == 0;
}


Empty string

Languages may have features for dealing specifically with empty strings
(those containing no characters).

;Task:
::*   Demonstrate how to assign an empty string to a variable.
::*   Demonstrate how to check that a string is empty.
::*   Demonstrate how to check that a string is not empty.

Solution:
String s = "";
if(s != null && s.isEmpty()){//optionally, instead of "s.isEmpty()": "s.length() == 0" or "s.equals("")"
   System.out.println("s is empty");
}else{
   System.out.println("s is not empty");
}


Entropy/Narcissist

Write a computer program that computes and shows its own   [[entropy]].

;Related Tasks:
:*   [[Fibonacci_word]]
:*   [[Entropy]]

Solution:
import java.io.BufferedReader;
import java.io.File;
import java.io.FileReader;
import java.io.IOException;
import java.util.HashMap;
import java.util.Map;

public class EntropyNarcissist {

    private static final String FILE_NAME = "src/EntropyNarcissist.java";

    public static void main(String[] args) {
        System.out.printf("Entropy of file \"%s\" = %.12f.%n", FILE_NAME, getEntropy(FILE_NAME));
    }

    private static double getEntropy(String fileName) {
        Map<Character,Integer> characterCount = new HashMap<>();
        int length = 0;

        try (BufferedReader reader = new BufferedReader(new FileReader(new File(fileName)));) {
            int c = 0;
            while ( (c = reader.read()) != -1 ) {
                characterCount.merge((char) c, 1, (v1, v2) -> v1 + v2);
                length++;
            }
        }
        catch ( IOException e ) {
            throw new RuntimeException(e);
        }

        double entropy = 0;
        for ( char key : characterCount.keySet() ) {
            double fraction = (double) characterCount.get(key) / length;
            entropy -= fraction * Math.log(fraction);
        }

        return entropy / Math.log(2);
    }

}


Equilibrium index

An equilibrium index of a sequence is an index into the sequence such that the sum of elements at lower indices is equal to the sum of elements at higher indices.

For example, in a sequence   A:

:::::   A_0 = -7
:::::   A_1 =  1
:::::   A_2 =  5
:::::   A_3 =  2
:::::   A_4 = -4
:::::   A_5 =  3
:::::   A_6 =  0

3   is an equilibrium index, because:

:::::   A_0 + A_1 + A_2 = A_4 + A_5 + A_6

6   is also an equilibrium index, because:

:::::   A_0 + A_1 + A_2 + A_3 + A_4 + A_5 = 0

(sum of zero elements is zero)

7   is not an equilibrium index, because it is not a valid index of sequence A.

;Task;
Write a function that, given a sequence, returns its equilibrium indices (if any).

Assume that the sequence may be very long.

Solution:
public class Equlibrium {
	public static void main(String[] args) {
		int[] sequence = {-7, 1, 5, 2, -4, 3, 0};
		equlibrium_indices(sequence);
	}

	public static void equlibrium_indices(int[] sequence){
		//find total sum
		int totalSum = 0;
		for (int n : sequence) {
			totalSum += n;
		}
		//compare running sum to remaining sum to find equlibrium indices
		int runningSum = 0;
		for (int i = 0; i < sequence.length; i++) {
			int n = sequence[i];
			if (totalSum - runningSum - n == runningSum) {
				System.out.println(i);
			}
			runningSum += n;
		}
	}
}


Erdös-Selfridge categorization of primes

A prime p is in category 1 if the prime factors of p+1 are 2 and or 3. p is in category 2 if all the prime factors of p+1 are in category 1. p is in category g if all the prime factors of p+1 are in categories 1 to g-1.

The task is first to display the first 200 primes allocated to their category, then assign the first million primes to their category, displaying the smallest prime, the largest prime, and the count of primes allocated to each category.

Solution:
import java.util.*;

public class ErdosSelfridge {
    private int[] primes;
    private int[] category;

    public static void main(String[] args) {
        ErdosSelfridge es = new ErdosSelfridge(1000000);

        System.out.println("First 200 primes:");
        for (var e : es.getPrimesByCategory(200).entrySet()) {
            int category = e.getKey();
            List<Integer> primes = e.getValue();
            System.out.printf("Category %d:\n", category);
            for (int i = 0, n = primes.size(); i != n; ++i)
                System.out.printf("%4d%c", primes.get(i), (i + 1) % 15 == 0 ? '\n' : ' ');
            System.out.printf("\n\n");
        }

        System.out.println("First 1,000,000 primes:");
        for (var e : es.getPrimesByCategory(1000000).entrySet()) {
            int category = e.getKey();
            List<Integer> primes = e.getValue();
            System.out.printf("Category %2d: first = %7d  last = %8d  count = %d\n", category,
                              primes.get(0), primes.get(primes.size() - 1), primes.size());
        }
    }

    private ErdosSelfridge(int limit) {
        PrimeGenerator primeGen = new PrimeGenerator(100000, 200000);
        List<Integer> primeList = new ArrayList<>();
        for (int i = 0; i < limit; ++i)
            primeList.add(primeGen.nextPrime());
        primes = new int[primeList.size()];
        for (int i = 0; i < primes.length; ++i)
            primes[i] = primeList.get(i);
        category = new int[primes.length];
    }

    private Map<Integer, List<Integer>> getPrimesByCategory(int limit) {
        Map<Integer, List<Integer>> result = new TreeMap<>();
        for (int i = 0; i < limit; ++i) {
            var p = result.computeIfAbsent(getCategory(i), k -> new ArrayList<Integer>());
            p.add(primes[i]);
        }
        return result;
    }

    private int getCategory(int index) {
        if (category[index] != 0)
            return category[index];
        int maxCategory = 0;
        int n = primes[index] + 1;
        for (int i = 0; n > 1; ++i) {
            int p = primes[i];
            if (p * p > n)
                break;
            int count = 0;
            for (; n % p == 0; ++count)
                n /= p;
            if (count != 0) {
                int category = (p <= 3) ? 1 : 1 + getCategory(i);
                maxCategory = Math.max(maxCategory, category);
            }
        }
        if (n > 1) {
            int category = (n <= 3) ? 1 : 1 + getCategory(getIndex(n));
            maxCategory = Math.max(maxCategory, category);
        }
        category[index] = maxCategory;
        return maxCategory;
    }

    private int getIndex(int prime) {
       return Arrays.binarySearch(primes, prime);
    }
}


Erdős-Nicolas numbers

Definition
An perfect but is equal to the sum of its first '''k''' divisors (arranged in ascending order and including one) for some value of '''k''' greater than one.

;Examples
24 is an Erdos-Nicolas number because the sum of its first 6 divisors (1, 2, 3, 4, 6 and 8) is equal to 24 and it is not perfect because 12 is also a divisor.

6 is not an Erdos-Nicolas number because it is perfect (1 + 2 + 3 = 6).

48 is not an Erdos-Nicolas number because its divisors are: 1, 2, 3, 4, 6, 8, 12, 16, 24 and 48. The first seven of these add up to 36, but the first eight add up to 52 which is more than 48.

;Task

Find and show here the first 8 Erdos-Nicolas numbers and the number of divisors needed (i.e. the value of 'k') to satisfy the definition.

;Stretch
Do the same for any further Erdos-Nicolas numbers which you have the patience for.

;Note
As all known Erdos-Nicolas numbers are even you may assume this to be generally true in order to quicken up the search. However, it is not obvious (to me at least) why this should necessarily be the case.

;Reference
* OEIS:A194472 - Erdos-Nicolas numbers

Solution:
import java.util.Arrays;

public final class ErdosNicolasNumbers {

	public static void main(String[] aArgs) {
		final int limit = 100_000_000;

	    int[] divisorSum = new int[limit + 1];
	    int[] divisorCount = new int[limit + 1];
	    Arrays.fill(divisorSum, 1);
	    Arrays.fill(divisorCount, 1);

	    for ( int index = 2; index <= limit / 2; index++ ) {
	        for ( int number = 2 * index; number <= limit; number += index ) {
	            if ( divisorSum[number] == number ) {
	                System.out.println(String.format("%8d", number) + " equals the sum of its first "
	                	             + String.format("%3d", divisorCount[number]) + " divisors");
	            }

	            divisorSum[number] += index;
	            divisorCount[number]++;
	        }
	    }
	}

}


Esthetic numbers

An '''esthetic number''' is a positive integer where every adjacent digit differs from its neighbour by 1.

;E.G.

:* '''12''' is an esthetic number. One and two differ by 1.

:* '''5654''' is an esthetic number. Each digit is exactly 1 away from its neighbour.

:* '''890''' is '''not''' an esthetic number. Nine and zero differ by 9.

These examples are nominally in base 10 but the concept extends easily to numbers in other bases. Traditionally, single digit numbers ''are'' included in esthetic numbers; zero may or may not be. For our purposes, for this task, do not include zero (0) as an esthetic number. Do not include numbers with leading zeros.

Esthetic numbers are also sometimes referred to as stepping numbers.

;Task

:* Write a routine (function, procedure, whatever) to find esthetic numbers in a given base.

:* Use that routine to find esthetic numbers in bases '''2''' through '''16''' and display, here on this page, the esthectic numbers from index '''(base x 4)''' through index '''(base x 6)''', inclusive. (E.G. for base 2: 8th through 12th, for base 6: 24th through 36th, etc.)

:* Find and display, here on this page, the '''base 10''' esthetic numbers with a magnitude between '''1000''' and '''9999'''.

:* Stretch: Find and display, here on this page, the '''base 10''' esthetic numbers with a magnitude between '''1.0e8''' and '''1.3e8'''.

;Related task:
*   numbers with equal rises and falls

;See also:
:;*OEIS A033075 - Positive numbers n such that all pairs of consecutive decimal digits differ by 1
:;*Numbers Aplenty - Esthetic numbers
:;*Geeks for Geeks - Stepping numbers

Solution:
import java.util.ArrayList;
import java.util.stream.IntStream;
import java.util.stream.LongStream;

public class EstheticNumbers {
    interface RecTriConsumer<A, B, C> {
        void accept(RecTriConsumer<A, B, C> f, A a, B b, C c);
    }

    private static boolean isEsthetic(long n, long b) {
        if (n == 0) {
            return false;
        }
        var i = n % b;
        var n2 = n / b;
        while (n2 > 0) {
            var j = n2 % b;
            if (Math.abs(i - j) != 1) {
                return false;
            }
            n2 /= b;
            i = j;
        }
        return true;
    }

    private static void listEsths(long n, long n2, long m, long m2, int perLine, boolean all) {
        var esths = new ArrayList<Long>();
        var dfs = new RecTriConsumer<Long, Long, Long>() {
            public void accept(Long n, Long m, Long i) {
                accept(this, n, m, i);
            }

            @Override
            public void accept(RecTriConsumer<Long, Long, Long> f, Long n, Long m, Long i) {
                if (n <= i && i <= m) {
                    esths.add(i);
                }
                if (i == 0 || i > m) {
                    return;
                }
                var d = i % 10;
                var i1 = i * 10 + d - 1;
                var i2 = i1 + 2;
                if (d == 0) {
                    f.accept(f, n, m, i2);
                } else if (d == 9) {
                    f.accept(f, n, m, i1);
                } else {
                    f.accept(f, n, m, i1);
                    f.accept(f, n, m, i2);
                }
            }
        };

        LongStream.range(0, 10).forEach(i -> dfs.accept(n2, m2, i));

        var le = esths.size();
        System.out.printf("Base 10: %d esthetic numbers between %d and %d:%n", le, n, m);
        if (all) {
            for (int i = 0; i < esths.size(); i++) {
                System.out.printf("%d ", esths.get(i));
                if ((i + 1) % perLine == 0) {
                    System.out.println();
                }
            }
        } else {
            for (int i = 0; i < perLine; i++) {
                System.out.printf("%d ", esths.get(i));
            }
            System.out.println();
            System.out.println("............");
            for (int i = le - perLine; i < le; i++) {
                System.out.printf("%d ", esths.get(i));
            }
        }
        System.out.println();
        System.out.println();
    }

    public static void main(String[] args) {
        IntStream.rangeClosed(2, 16).forEach(b -> {
            System.out.printf("Base %d: %dth to %dth esthetic numbers:%n", b, 4 * b, 6 * b);
            var n = 1L;
            var c = 0L;
            while (c < 6 * b) {
                if (isEsthetic(n, b)) {
                    c++;
                    if (c >= 4 * b) {
                        System.out.printf("%s ", Long.toString(n, b));
                    }
                }
                n++;
            }
            System.out.println();
        });
        System.out.println();

        // the following all use the obvious range limitations for the numbers in question
        listEsths(1000, 1010, 9999, 9898, 16, true);
        listEsths((long) 1e8, 101_010_101, 13 * (long) 1e7, 123_456_789, 9, true);
        listEsths((long) 1e11, 101_010_101_010L, 13 * (long) 1e10, 123_456_789_898L, 7, false);
        listEsths((long) 1e14, 101_010_101_010_101L, 13 * (long) 1e13, 123_456_789_898_989L, 5, false);
        listEsths((long) 1e17, 101_010_101_010_101_010L, 13 * (long) 1e16, 123_456_789_898_989_898L, 4, false);
    }
}


Euclid-Mullin sequence

Definition
The Euclid-Mullin sequence is an infinite sequence of distinct prime numbers, in which each element is the least prime factor of one plus the product of all earlier elements.

The first element is usually assumed to be 2. So the second element is : (2) + 1 = 3 and the third element is : (2 x 3) + 1 = 7 as this is prime.

Although intermingled with smaller elements, the sequence can produce very large elements quite quickly and only the first 51 have been computed at the time of writing.

;Task
Compute and show here the first '''16''' elements of the sequence or, if your language does not support arbitrary precision arithmetic, as many as you can.

;Stretch goal
Compute the next '''11''' elements of the sequence.

;Reference
OEIS sequence A000945

Solution:
import java.math.BigInteger;
import java.util.ArrayList;
import java.util.BitSet;
import java.util.List;
import java.util.concurrent.ThreadLocalRandom;

public class EulerMullinSequence {

	public static void main(String[] aArgs) {
		primes = listPrimesUpTo(1_000_000);

		System.out.println("The first 27 terms of the Euler-Mullin sequence:");
		System.out.println(2);
		for ( int i = 1; i < 27; i++ ) {
			System.out.println(nextEulerMullin());
		}

	}

	private static BigInteger nextEulerMullin() {
		BigInteger smallestPrime = smallestPrimeFactor(product.add(BigInteger.ONE));
		product = product.multiply(smallestPrime);

		return smallestPrime;
	}

	private static BigInteger smallestPrimeFactor(BigInteger aNumber) {
		if ( aNumber.isProbablePrime(probabilityLevel) ) {
			return aNumber;
		}

		for ( BigInteger prime : primes ) {
			if ( aNumber.mod(prime).signum() == 0 ) {
				return prime;
			}
 		}

		BigInteger factor = pollardsRho(aNumber);
		return smallestPrimeFactor(factor);
	}

	private static BigInteger pollardsRho(BigInteger aN) {
		if ( aN.equals(BigInteger.ONE) ) {
			return BigInteger.ONE;
		}

		if ( aN.mod(BigInteger.TWO).signum() == 0 ) {
			return BigInteger.TWO;
		}

		final BigInteger core  = new BigInteger(aN.bitLength(), random);
		BigInteger x  = new BigInteger(aN.bitLength(), random);
		BigInteger xx = x;
		BigInteger divisor = null;

		do {
			x = x.multiply(x).mod(aN).add(core).mod(aN);
			xx = xx.multiply(xx).mod(aN).add(core).mod(aN);
			xx = xx.multiply(xx).mod(aN).add(core).mod(aN);
			divisor = x.subtract(xx).gcd(aN);
		} while ( divisor.equals(BigInteger.ONE) );

		return divisor;
	}

	private static List<BigInteger> listPrimesUpTo(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 = j + i ) {
				sieve.clear(j);
			}
		}

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

		return result;
	}

	private static List<BigInteger> primes;
	private static BigInteger product = BigInteger.TWO;
	private static ThreadLocalRandom random = ThreadLocalRandom.current();

	private static final int probabilityLevel = 20;

}


Euler's identity

{{Wikipedia|Euler's_identity}}

In mathematics, ''Euler's identity'' is the equality:

                ei\pi + 1 = 0

where

    e is Euler's number, the base of natural logarithms,
    ''i'' is the imaginary unit, which satisfies ''i''2 = -1, and
    \pi is pi, the ratio of the circumference of a circle to its diameter.

Euler's identity is often cited as an example of deep mathematical beauty. Three of the basic arithmetic operations occur exactly once each: addition, multiplication, and exponentiation. The identity also links five fundamental mathematical constants:

    The number 0.
    The number 1.
    The number \pi (\pi = 3.14159+),
    The number e (e = 2.71828+), which occurs widely in mathematical analysis.
    The number ''i'', the imaginary unit of the complex numbers.

;Task
Show in your language that Euler's identity is true. As much as possible and practical, mimic the Euler's identity equation.

Most languages are limited to IEEE 754 floating point calculations so will have some error in the calculation.

If that is the case, or there is some other limitation, show
that ei\pi + 1 is ''approximately'' equal to zero and
show the amount of error in the calculation.

If your language is capable of symbolic calculations, show
that ei\pi + 1 is ''exactly'' equal to zero for bonus kudos points.

Solution:
public class EulerIdentity {

    public static void main(String[] args) {
        System.out.println("e ^ (i*Pi) + 1 = " + (new Complex(0, Math.PI).exp()).add(new Complex(1, 0)));
    }

    public static class Complex {

        private double x, y;

        public Complex(double re, double im) {
            x = re;
            y = im;
        }

        public Complex exp() {
            double exp = Math.exp(x);
            return new Complex(exp * Math.cos(y), exp * Math.sin(y));
        }

        public Complex add(Complex a) {
            return new Complex(x + a.x, y + a.y);
        }

        @Override
        public String toString() {
            return x + " + " + y + "i";
        }
    }
}


Euler's sum of powers conjecture

There is a conjecture in mathematics that held for over two hundred years before it was disproved by the finding of a counterexample in 1966 by Lander and Parkin.

This conjecture is called Euler's sum of powers conjecture and can be stated as such:

:At least k positive kth powers are required to sum to a kth power, except for the trivial case of one kth power: yk = yk.

In 1966, Leon J. Lander and Thomas R. Parkin used a brute-force search on a CDC 6600 computer restricting numbers to those less than 250.

The task consists in writing a program to search for an integer solution of x_0^5 + x_1^5 + x_2^5 + x_3^5 = y^5 where all x_i and y are distinct integers between 0 and 250 (exclusive). Show an answer here.

Related tasks are:
* [[Pythagorean quadruples]].
* [[Pythagorean triples]].

Solution:
public class eulerSopConjecture
{

    static final int    MAX_NUMBER = 250;

    public static void main( String[] args )
    {
        boolean found = false;
        long[]  fifth = new long[ MAX_NUMBER ];

        for( int i = 1; i <= MAX_NUMBER; i ++ )
        {
            long i2 =  i * i;
            fifth[ i - 1 ] = i2 * i2 * i;
        } // for i

        for( int a = 0; a < MAX_NUMBER && ! found ; a ++ )
        {
            for( int b = a; b < MAX_NUMBER && ! found ; b ++ )
            {
                for( int c = b; c < MAX_NUMBER && ! found ; c ++ )
                {
                    for( int d = c; d < MAX_NUMBER && ! found ; d ++ )
                    {
                        long sum  = fifth[a] + fifth[b] + fifth[c] + fifth[d];
                        int  e = java.util.Arrays.binarySearch( fifth, sum );
                        found  = ( e >= 0 );
                        if( found )
                        {
                            // the value at e is a fifth power
                            System.out.print( (a+1) + "^5 + "
                                            + (b+1) + "^5 + "
                                            + (c+1) + "^5 + "
                                            + (d+1) + "^5 = "
                                            + (e+1) + "^5"
                                            );
                        } // if found;;
                    } // for d
                } // for c
            } // for b
        } // for a
    } // main

} // eulerSopConjecture


Even or odd

Test whether an integer is even or odd.

There is more than one way to solve this task:

* Use the even and odd predicates, if the language provides them.
* Check the least significant digit. With binary integers, ''i iff ''i'' is even, or equals 1 iff ''i'' is odd.
* Divide ''i'' by 2. The remainder equals 0 iff ''i'' is even. The remainder equals +1 or -1 iff ''i'' is odd.
* Use modular congruences:
** ''i''  0 (mod 2) iff ''i'' is even.
** ''i''  1 (mod 2) iff ''i'' is odd.

Solution:
public static boolean isEven(BigInteger i){
    return i.mod(BigInteger.valueOf(2)).equals(BigInteger.ZERO);
}