Angle difference between two bearings

Finding the angle between two bearings is often confusing.[https://stackoverflow.com/questions/16180595/find-the-angle-between-two-bearings]

;Task:
Find the angle which is the result of the subtraction '''b2 - b1''', where '''b1''' and '''b2''' are the bearings.

Input bearings are expressed in the range   '''-180'''   to   '''+180'''   degrees.
The  result  is also expressed in the range   '''-180'''   to   '''+180'''   degrees.

Compute the angle for the following pairs:
*  20 degrees ('''b1''') and 45 degrees ('''b2''')
* -45 and  45
* -85 and  90
* -95 and  90
* -45 and 125
* -45 and 145
*  29.4803 and  -88.6381
* -78.3251 and -159.036

;Optional extra:
Allow the input bearings to be any (finite) value.

;Test cases:
*  -70099.74233810938   and   29840.67437876723
* -165313.6666297357    and   33693.9894517456
*    1174.8380510598456 and -154146.66490124757
*   60175.77306795546   and   42213.07192354373

Solution:
public class AngleDifference {

    public static double getDifference(double b1, double b2) {
        double r = (b2 - b1) % 360.0;
        if (r < -180.0)
            r += 360.0;
        if (r >= 180.0)
            r -= 360.0;
        return r;
    }

    public static void main(String[] args) {
        System.out.println("Input in -180 to +180 range");
        System.out.println(getDifference(20.0, 45.0));
        System.out.println(getDifference(-45.0, 45.0));
        System.out.println(getDifference(-85.0, 90.0));
        System.out.println(getDifference(-95.0, 90.0));
        System.out.println(getDifference(-45.0, 125.0));
        System.out.println(getDifference(-45.0, 145.0));
        System.out.println(getDifference(-45.0, 125.0));
        System.out.println(getDifference(-45.0, 145.0));
        System.out.println(getDifference(29.4803, -88.6381));
        System.out.println(getDifference(-78.3251, -159.036));

        System.out.println("Input in wider range");
        System.out.println(getDifference(-70099.74233810938, 29840.67437876723));
        System.out.println(getDifference(-165313.6666297357, 33693.9894517456));
        System.out.println(getDifference(1174.8380510598456, -154146.66490124757));
        System.out.println(getDifference(60175.77306795546, 42213.07192354373));
    }
}


Anti-primes

The anti-primes
(or highly composite numbers, sequence A002182 in the OEIS)
are the natural numbers with more factors than any smaller than itself.

;Task:
Generate and show here, the first twenty anti-primes.

;Related tasks:
:*   [[Factors of an integer]]
:*   [[Sieve of Eratosthenes]]

Solution:
public class Antiprime {

    static int countDivisors(int n) {
        if (n < 2) return 1;
        int count = 2; // 1 and n
        for (int i = 2; i <= n/2; ++i) {
            if (n%i == 0) ++count;
        }
        return count;
    }

    public static void main(String[] args) {
        int maxDiv = 0, count = 0;
        System.out.println("The first 20 anti-primes are:");
        for (int n = 1; count < 20; ++n) {
            int d = countDivisors(n);
            if (d > maxDiv) {
                System.out.printf("%d ", n);
                maxDiv = d;
                count++;
            }
        }
        System.out.println();
    }
}


Apply a digital filter (direct form II transposed)

Digital filters are used to apply a mathematical operation to a sampled signal. One of the common formulations is the "direct form II transposed" which can represent both infinite impulse response (IIR) and finite impulse response (FIR) filters, as well as being more numerically stable than other forms. [https://ccrma.stanford.edu/~jos/fp/Transposed_Direct_Forms.html]

;Task:

Filter a signal using an order 3 low-pass Butterworth filter. The coefficients for the filter are a=[1.00000000, -2.77555756e-16, 3.33333333e-01, -1.85037171e-17] and b = [0.16666667, 0.5, 0.5, 0.16666667]

The signal that needs filtering is the following vector: [-0.917843918645, 0.141984778794, 1.20536903482, 0.190286794412, -0.662370894973, -1.00700480494, -0.404707073677 ,0.800482325044, 0.743500089861, 1.01090520172, 0.741527555207, 0.277841675195, 0.400833448236, -0.2085993586, -0.172842103641, -0.134316096293, 0.0259303398477, 0.490105989562, 0.549391221511, 0.9047198589]

;See also:
[Wikipedia on Butterworth filters]

Solution:
public class DigitalFilter {
    private static double[] filter(double[] a, double[] b, double[] signal) {
        double[] result = new double[signal.length];
        for (int i = 0; i < signal.length; ++i) {
            double tmp = 0.0;
            for (int j = 0; j < b.length; ++j) {
                if (i - j < 0) continue;
                tmp += b[j] * signal[i - j];
            }
            for (int j = 1; j < a.length; ++j) {
                if (i - j < 0) continue;
                tmp -= a[j] * result[i - j];
            }
            tmp /= a[0];
            result[i] = tmp;
        }
        return result;
    }

    public static void main(String[] args) {
        double[] a = new double[]{1.00000000, -2.77555756e-16, 3.33333333e-01, -1.85037171e-17};
        double[] b = new double[]{0.16666667, 0.5, 0.5, 0.16666667};

        double[] signal = new double[]{
            -0.917843918645, 0.141984778794, 1.20536903482, 0.190286794412,
            -0.662370894973, -1.00700480494, -0.404707073677, 0.800482325044,
            0.743500089861, 1.01090520172, 0.741527555207, 0.277841675195,
            0.400833448236, -0.2085993586, -0.172842103641, -0.134316096293,
            0.0259303398477, 0.490105989562, 0.549391221511, 0.9047198589
        };

        double[] result = filter(a, b, signal);
        for (int i = 0; i < result.length; ++i) {
            System.out.printf("% .8f", result[i]);
            System.out.print((i + 1) % 5 != 0 ? ", " : "\n");
        }
    }
}


Approximate equality

Sometimes, when testing whether the solution to a task (for example, here on Rosetta Code) is correct, the
difference in floating point calculations between different language implementations becomes significant.

For example, a difference between '''32''' bit and '''64''' bit floating point calculations may appear by
about the 8th significant digit in base 10 arithmetic.

;Task:
Create a function which returns true if two floating point numbers are approximately equal.

The function should allow for differences in the magnitude of numbers, so that, for example,
'''100000000000000.01'''   may be approximately equal to   '''100000000000000.011''',
even though   '''100.01'''   is not approximately equal to   '''100.011'''.

If the language has such a feature in its standard library, this may be used instead of a custom function.

Show the function results with comparisons on the following pairs of values:
:#     100000000000000.01,                        100000000000000.011       (note: should return ''true'')
:#     100.01,                                    100.011                                                     (note: should return ''false'')
:#     10000000000000.001 / 10000.0,   1000000000.0000001000
:#     0.001,                                     0.0010000001
:#     0.000000000000000000000101,                0.0
:#      sqrt(2) * sqrt(2),                    2.0
:#     -sqrt(2) * sqrt(2),                        -2.0
:#     3.14159265358979323846,                    3.14159265358979324

Answers should be true for the first example and false in the second, so that just rounding the numbers to a fixed number of decimals should not be enough. Otherwise answers may vary and still be correct. See the Python code for one type of solution.

__TOC__

Solution:
public class Approximate {
    private static boolean approxEquals(double value, double other, double epsilon) {
        return Math.abs(value - other) < epsilon;
    }

    private static void test(double a, double b) {
        double epsilon = 1e-18;
        System.out.printf("%f, %f => %s\n", a, b, approxEquals(a, b, epsilon));
    }

    public static void main(String[] args) {
        test(100000000000000.01, 100000000000000.011);
        test(100.01, 100.011);
        test(10000000000000.001 / 10000.0, 1000000000.0000001000);
        test(0.001, 0.0010000001);
        test(0.000000000000000000000101, 0.0);
        test(Math.sqrt(2.0) * Math.sqrt(2.0), 2.0);
        test(-Math.sqrt(2.0) * Math.sqrt(2.0), -2.0);
        test(3.14159265358979323846, 3.14159265358979324);
    }
}


Archimedean spiral

The Archimedean spiral is a spiral named after the Greek mathematician Archimedes.

An Archimedean spiral can be described by the equation:

:\, r=a+b\theta

with real numbers ''a'' and ''b''.

;Task
Draw an Archimedean spiral.

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

public class ArchimedeanSpiral extends JPanel {

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

    void drawGrid(Graphics2D g) {
        g.setColor(new Color(0xEEEEEE));
        g.setStroke(new BasicStroke(2));

        double angle = toRadians(45);

        int w = getWidth();
        int center = w / 2;
        int margin = 10;
        int numRings = 8;

        int spacing = (w - 2 * margin) / (numRings * 2);

        for (int i = 0; i < numRings; i++) {
            int pos = margin + i * spacing;
            int size = w - (2 * margin + i * 2 * spacing);
            g.drawOval(pos, pos, size, size);

            double ia = i * angle;
            int x2 = center + (int) (cos(ia) * (w - 2 * margin) / 2);
            int y2 = center - (int) (sin(ia) * (w - 2 * margin) / 2);

            g.drawLine(center, center, x2, y2);
        }
    }

    void drawSpiral(Graphics2D g) {
        g.setStroke(new BasicStroke(2));
        g.setColor(Color.orange);

        double degrees = toRadians(0.1);
        double center = getWidth() / 2;
        double end = 360 * 2 * 10 * degrees;
        double a = 0;
        double b = 20;
        double c = 1;

        for (double theta = 0; theta < end; theta += degrees) {
            double r = a + b * pow(theta, 1 / c);
            double x = r * cos(theta);
            double y = r * sin(theta);
            plot(g, (int) (center + x), (int) (center - y));
        }
    }

    void plot(Graphics2D g, int x, int y) {
        g.drawOval(x, y, 1, 1);
    }

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

        drawGrid(g);
        drawSpiral(g);
    }

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


Arithmetic-geometric mean

{{wikipedia|Arithmetic-geometric mean}}

;Task:
Write a function to compute the arithmetic-geometric mean of two numbers.

The arithmetic-geometric mean of two numbers can be (usefully) denoted as \mathrm{agm}(a,g), and is equal to the limit of the sequence:
: a_0 = a; \qquad g_0 = g
: a_{n+1} = \tfrac{1}{2}(a_n + g_n); \quad g_{n+1} = \sqrt{a_n g_n}.
Since the limit of a_n-g_n tends (rapidly) to zero with iterations, this is an efficient method.

Demonstrate the function by calculating:
:\mathrm{agm}(1,1/\sqrt{2})

;Also see:
*   mathworld.wolfram.com/Arithmetic-Geometric Mean

Solution:
/*
 * Arithmetic-Geometric Mean of 1 & 1/sqrt(2)
 * Brendan Shaklovitz
 * 5/29/12
 */
public class ArithmeticGeometricMean {

    public static double agm(double a, double g) {
        double a1 = a;
        double g1 = g;
        while (Math.abs(a1 - g1) >= 1.0e-14) {
            double arith = (a1 + g1) / 2.0;
            double geom = Math.sqrt(a1 * g1);
            a1 = arith;
            g1 = geom;
        }
        return a1;
    }

    public static void main(String[] args) {
        System.out.println(agm(1.0, 1.0 / Math.sqrt(2.0)));
    }
}


Arithmetic-geometric mean/Calculate Pi

Almkvist Berndt 1988 begins with an investigation of why the agm is such an efficient algorithm, and proves that it converges quadratically. This is an efficient method to calculate \pi.

With the same notations used in [[Arithmetic-geometric mean]], we can summarize the paper by writing:

\pi =
\frac{4\; \mathrm{agm}(1, 1/\sqrt{2})^2}
{1 - \sum\limits_{n=1}^{\infty} 2^{n+1}(a_n^2-g_n^2)}

This allows you to make the approximation, for any large   '''N''':

\pi \approx
\frac{4\; a_N^2}
{1 - \sum\limits_{k=1}^N 2^{k+1}(a_k^2-g_k^2)}

The purpose of this task is to demonstrate how to use this approximation in order to compute a large number of decimals of \pi.

Solution:
import java.math.BigDecimal;
import java.math.MathContext;
import java.util.Objects;

public class Calculate_Pi {
    private static final MathContext con1024 = new MathContext(1024);
    private static final BigDecimal bigTwo = new BigDecimal(2);
    private static final BigDecimal bigFour = new BigDecimal(4);

    private static BigDecimal bigSqrt(BigDecimal bd, MathContext con) {
        BigDecimal x0 = BigDecimal.ZERO;
        BigDecimal x1 = BigDecimal.valueOf(Math.sqrt(bd.doubleValue()));
        while (!Objects.equals(x0, x1)) {
            x0 = x1;
            x1 = bd.divide(x0, con).add(x0).divide(bigTwo, con);
        }
        return x1;
    }

    public static void main(String[] args) {
        BigDecimal a = BigDecimal.ONE;
        BigDecimal g = a.divide(bigSqrt(bigTwo, con1024), con1024);
        BigDecimal t;
        BigDecimal sum = BigDecimal.ZERO;
        BigDecimal pow = bigTwo;
        while (!Objects.equals(a, g)) {
            t = a.add(g).divide(bigTwo, con1024);
            g = bigSqrt(a.multiply(g), con1024);
            a = t;
            pow = pow.multiply(bigTwo);
            sum = sum.add(a.multiply(a).subtract(g.multiply(g)).multiply(pow));
        }
        BigDecimal pi = bigFour.multiply(a.multiply(a)).divide(BigDecimal.ONE.subtract(sum), con1024);
        System.out.println(pi);
    }
}


Arithmetic evaluation

Create a program which parses and evaluates arithmetic expressions.
;Requirements:
* An abstract-syntax tree (AST) for the expression must be created from parsing the input.
* The AST must be used in evaluation, also, so the input may not be directly evaluated (e.g. by calling eval or a similar language feature.)
* The expression will be a string or list of symbols like "(1+3)*7".
* The four symbols + - * / must be supported as binary operators with conventional precedence rules.
* Precedence-control parentheses must also be supported.

;Note:
For those who don't remember, mathematical precedence is as follows:
* Parentheses
* Multiplication/Division (left to right)
* Addition/Subtraction (left to right)

;C.f:
* [[24 game Player]].
* [[Parsing/RPN calculator algorithm]].
* [[Parsing/RPN to infix conversion]].

Solution:
import java.util.Stack;

public class ArithmeticEvaluation {

    public interface Expression {
        BigRational eval();
    }

    public enum Parentheses {LEFT}

    public enum BinaryOperator {
        ADD('+', 1),
        SUB('-', 1),
        MUL('*', 2),
        DIV('/', 2);

        public final char symbol;
        public final int precedence;

        BinaryOperator(char symbol, int precedence) {
            this.symbol = symbol;
            this.precedence = precedence;
        }

        public BigRational eval(BigRational leftValue, BigRational rightValue) {
            switch (this) {
                case ADD:
                    return leftValue.add(rightValue);
                case SUB:
                    return leftValue.subtract(rightValue);
                case MUL:
                    return leftValue.multiply(rightValue);
                case DIV:
                    return leftValue.divide(rightValue);
            }
            throw new IllegalStateException();
        }

        public static BinaryOperator forSymbol(char symbol) {
            for (BinaryOperator operator : values()) {
                if (operator.symbol == symbol) {
                    return operator;
                }
            }
            throw new IllegalArgumentException(String.valueOf(symbol));
        }
    }

    public static class Number implements Expression {
        private final BigRational number;

        public Number(BigRational number) {
            this.number = number;
        }

        @Override
        public BigRational eval() {
            return number;
        }

        @Override
        public String toString() {
            return number.toString();
        }
    }

    public static class BinaryExpression implements Expression {
        public final Expression leftOperand;
        public final BinaryOperator operator;
        public final Expression rightOperand;

        public BinaryExpression(Expression leftOperand, BinaryOperator operator, Expression rightOperand) {
            this.leftOperand = leftOperand;
            this.operator = operator;
            this.rightOperand = rightOperand;
        }

        @Override
        public BigRational eval() {
            BigRational leftValue = leftOperand.eval();
            BigRational rightValue = rightOperand.eval();
            return operator.eval(leftValue, rightValue);
        }

        @Override
        public String toString() {
            return "(" + leftOperand + " " + operator.symbol + " " + rightOperand + ")";
        }
    }

    private static void createNewOperand(BinaryOperator operator, Stack<Expression> operands) {
        Expression rightOperand = operands.pop();
        Expression leftOperand = operands.pop();
        operands.push(new BinaryExpression(leftOperand, operator, rightOperand));
    }

    public static Expression parse(String input) {
        int curIndex = 0;
        boolean afterOperand = false;
        Stack<Expression> operands = new Stack<>();
        Stack<Object> operators = new Stack<>();
        while (curIndex < input.length()) {
            int startIndex = curIndex;
            char c = input.charAt(curIndex++);

            if (Character.isWhitespace(c))
                continue;

            if (afterOperand) {
                if (c == ')') {
                    Object operator;
                    while (!operators.isEmpty() && ((operator = operators.pop()) != Parentheses.LEFT))
                        createNewOperand((BinaryOperator) operator, operands);
                    continue;
                }
                afterOperand = false;
                BinaryOperator operator = BinaryOperator.forSymbol(c);
                while (!operators.isEmpty() && (operators.peek() != Parentheses.LEFT) && (((BinaryOperator) operators.peek()).precedence >= operator.precedence))
                    createNewOperand((BinaryOperator) operators.pop(), operands);
                operators.push(operator);
                continue;
            }

            if (c == '(') {
                operators.push(Parentheses.LEFT);
                continue;
            }

            afterOperand = true;
            while (curIndex < input.length()) {
                c = input.charAt(curIndex);
                if (((c < '0') || (c > '9')) && (c != '.'))
                    break;
                curIndex++;
            }
            operands.push(new Number(BigRational.valueOf(input.substring(startIndex, curIndex))));
        }

        while (!operators.isEmpty()) {
            Object operator = operators.pop();
            if (operator == Parentheses.LEFT)
                throw new IllegalArgumentException();
            createNewOperand((BinaryOperator) operator, operands);
        }

        Expression expression = operands.pop();
        if (!operands.isEmpty())
            throw new IllegalArgumentException();
        return expression;
    }

    public static void main(String[] args) {
        String[] testExpressions = {
                "2+3",
                "2+3/4",
                "2*3-4",
                "2*(3+4)+5/6",
                "2 * (3 + (4 * 5 + (6 * 7) * 8) - 9) * 10",
                "2*-3--4+-.25"};
        for (String testExpression : testExpressions) {
            Expression expression = parse(testExpression);
            System.out.printf("Input: \"%s\", AST: \"%s\", value=%s%n", testExpression, expression, expression.eval());
        }
    }
}


Array length

Determine the amount of elements in an array.

As an example use an array holding the strings 'apple' and 'orange'.

Solution:
String[] strings = { "apple", "orange" };
int length = strings.length;


Ascending primes

Generate and show all primes with strictly ascending decimal digits.

Aside: Try solving without peeking at existing solutions. I had a weird idea for generating
a prime sieve faster, which needless to say didn't pan out. The solution may be p(r)etty trivial
but generating them quickly is at least mildly interesting.
Tip: filtering all 7,027,260 primes below 123,456,789 probably won't kill you, but there is
at least one significantly better and much faster way, needing a mere 511 odd/prime tests.

;See also
;* OEIS:A052015 - Primes with distinct digits in ascending order

;Related:
*[[Primes with digits in nondecreasing order]] (infinite series allowing duplicate digits, whereas this isn't and doesn't)
*[[Pandigital prime]] (whereas this is the smallest, with gaps in the used digits being permitted)

Solution:
/*
 *  Ascending primes
 *
 *  Generate and show all primes with strictly ascending decimal digits.
 *
 *
 *  Solution
 *
 *  We only consider positive numbers in the range 1 to 123456789. We would
 *  get 7027260 primes, because there are so many primes smaller than 123456789
 *  (see also Wolfram Alpha).On the other hand, there are only 511 distinct
 *  positive integers having their digits arranged in ascending order.
 *  Therefore, it is better to start with numbers that have properly arranged
 *  digits and then check if they are prime numbers.The method of generating
 *  a sequence of such numbers is not indifferent.We want this sequence to be
 *  monotonically increasing, because then additional sorting of results will
 *  be unnecessary. It turns out that by using a queue we can easily get the
 *  desired effect. Additionally, the algorithm then does not use recursion
 *  (although the program probably does not have to comply with the MISRA
 *  standard). The problem to be solved is the queue size, the a priori
 *  assumption that 1000 is good enough, but a bit magical.
 */

package example.rossetacode.ascendingprimes;

import java.util.Arrays;

public class Program implements Runnable {

    public static void main(String[] args) {
        long t1 = System.nanoTime();
        new Program().run();
        long t2 = System.nanoTime();
        System.out.println(
                "total time consumed = " + (t2 - t1) * 1E-6 + " milliseconds");
    }

    public void run() {

        final int MAX_SIZE = 1000;
        final int[] queue = new int[MAX_SIZE];
        int begin = 0;
        int end = 0;

        for (int k = 1; k <= 9; k++) {
            queue[end++] = k;
        }

        while (begin < end) {
            int n = queue[begin++];
            for (int k = n % 10 + 1; k <= 9; k++) {
                queue[end++] = n * 10 + k;
            }
        }

        // We can use a parallel stream (and then sort the results)
        // to use multiple cores.
        //
        System.out.println(Arrays.stream(queue).filter(this::isPrime).boxed().toList());
    }

    private boolean isPrime(int n) {
        if (n == 2) {
            return true;
        }
        if (n == 1 || n % 2 == 0) {
            return false;
        }
        int root = (int) Math.sqrt(n);
        for (int k = 3; k <= root; k += 2) {
            if (n % k == 0) {
                return false;
            }
        }
        return true;
    }
}


Associative array/Merging

Define two associative arrays, where one represents the following "base" data:

::::: {| class="wikitable"
|+
| '''Key''' || '''Value'''
|-
| "name" || "Rocket Skates"
|-
| "price" || 12.75
|-
| "color" || "yellow"
|}

And the other represents "update" data:

::::: {| class="wikitable"
|+
| '''Key''' || '''Value'''
|-
| "price" || 15.25
|-
| "color" || "red"
|-
| "year" || 1974
|}

Merge these into a new associative array that contains every key found in either of the source ones.  Each key should map to the value in the second (update) table if that exists, or else to the value in the first (base) table.  If possible, do this in a way that does not mutate the original two associative arrays.  Obviously this should be done in a way that would work for any data, not just the specific data given here, but in this example the result should be:

::::: {| class="wikitable"
|+
| '''Key''' || '''Value'''
|-
| "name" || "Rocket Skates"
|-
| "price" || 15.25
|-
| "color" || "red"
|-
| "year" || 1974
|}

Solution:
for(Map.Entry<String, String> entry : mapA.entrySet())
    System.out.printf("%-20s%s%n", entry.getKey(), entry.getValue());

for(Map.Entry<String, String> entry : mapB.entrySet())
    System.out.printf("%-20s%s%n", entry.getKey(), entry.getValue());

for(Map.Entry<String, String> entry : mapC.entrySet())
    System.out.printf("%-20s%s%n", entry.getKey(), entry.getValue());


Attractive numbers

A number is an   ''attractive number''   if the number of its prime factors (whether distinct or not) is also prime.

;Example:
The number   '''20''',   whose prime decomposition is   '''2 x 2 x 5''',   is an   ''attractive number''   because the number of its prime factors   ('''3''')   is also prime.

;Task:
Show sequence items up to   '''120'''.

;Reference:
:*   The OEIS entry:   A063989: Numbers with a prime number of prime divisors.

Solution:
public class Attractive {

    static boolean is_prime(int n) {
        if (n < 2) return false;
        if (n % 2 == 0) return n == 2;
        if (n % 3 == 0) return n == 3;
        int d = 5;
        while (d *d <= n) {
            if (n % d == 0) return false;
            d += 2;
            if (n % d == 0) return false;
            d += 4;
        }
        return true;
    }

    static int count_prime_factors(int n) {
        if (n == 1) return 0;
        if (is_prime(n)) return 1;
        int count = 0, f = 2;
        while (true) {
            if (n % f == 0) {
                count++;
                n /= f;
                if (n == 1) return count;
                if (is_prime(n)) f = n;
            }
            else if (f >= 3) f += 2;
            else f = 3;
        }
    }

    public static void main(String[] args) {
        final int max = 120;
        System.out.printf("The attractive numbers up to and including %d are:\n", max);
        for (int i = 1, count = 0; i <= max; ++i) {
            int n = count_prime_factors(i);
            if (is_prime(n)) {
                System.out.printf("%4d", i);
                if (++count % 20 == 0) System.out.println();
            }
        }
        System.out.println();
    }
}


Average loop length

Let f be a uniformly-randomly chosen mapping from the numbers 1..N to the numbers 1..N (note: not necessarily a permutation of 1..N; the mapping could produce a number in more than one way or not at all). At some point, the sequence 1, f(1), f(f(1))... will contain a repetition, a number that occurring for the second time in the sequence.

;Task:
Write a program or a script that estimates, for each N, the average length until the first such repetition.

Also calculate this expected length using an analytical formula, and optionally compare the simulated result with the theoretical one.

This problem comes from the end of Donald Knuth's Christmas tree lecture 2011.

Example of expected output:

 N    average    analytical    (error)
===  =========  ============  =========
  1     1.0000        1.0000  (  0.00%)
  2     1.4992        1.5000  (  0.05%)
  3     1.8784        1.8889  (  0.56%)
  4     2.2316        2.2188  (  0.58%)
  5     2.4982        2.5104  (  0.49%)
  6     2.7897        2.7747  (  0.54%)
  7     3.0153        3.0181  (  0.09%)
  8     3.2429        3.2450  (  0.07%)
  9     3.4536        3.4583  (  0.14%)
 10     3.6649        3.6602  (  0.13%)
 11     3.8091        3.8524  (  1.12%)
 12     3.9986        4.0361  (  0.93%)
 13     4.2074        4.2123  (  0.12%)
 14     4.3711        4.3820  (  0.25%)
 15     4.5275        4.5458  (  0.40%)
 16     4.6755        4.7043  (  0.61%)
 17     4.8877        4.8579  (  0.61%)
 18     4.9951        5.0071  (  0.24%)
 19     5.1312        5.1522  (  0.41%)
 20     5.2699        5.2936  (  0.45%)

Solution:
import java.util.HashSet;
import java.util.Random;
import java.util.Set;

public class AverageLoopLength {

    private static final int N = 100000;

    //analytical(n) = sum_(i=1)^n (n!/(n-i)!/n**i)
    private static double analytical(int n) {
        double[] factorial = new double[n + 1];
        double[] powers = new double[n + 1];
        powers[0] = 1.0;
        factorial[0] = 1.0;
        for (int i = 1; i <= n; i++) {
            factorial[i] = factorial[i - 1] * i;
            powers[i] = powers[i - 1] * n;
        }
        double sum = 0;
        //memoized factorial and powers
        for (int i = 1; i <= n; i++) {
            sum += factorial[n] / factorial[n - i] / powers[i];
        }
        return sum;
    }

    private static double average(int n) {
        Random rnd = new Random();
        double sum = 0.0;
        for (int a = 0; a < N; a++) {
            int[] random = new int[n];
            for (int i = 0; i < n; i++) {
                random[i] = rnd.nextInt(n);
            }
            Set<Integer> seen = new HashSet<>(n);
            int current = 0;
            int length = 0;
            while (seen.add(current)) {
                length++;
                current = random[current];
            }
            sum += length;
        }
        return sum / N;
    }

    public static void main(String[] args) {
        System.out.println(" N    average    analytical    (error)");
        System.out.println("===  =========  ============  =========");
        for (int i = 1; i <= 20; i++) {
            double avg = average(i);
            double ana = analytical(i);
            System.out.println(String.format("%3d  %9.4f  %12.4f  (%6.2f%%)", i, avg, ana, ((ana - avg) / ana * 100)));
        }
    }
}


Averages/Mean angle

Solution:
import java.util.Arrays;

public class AverageMeanAngle {

    public static void main(String[] args) {
        printAverageAngle(350.0, 10.0);
        printAverageAngle(90.0, 180.0, 270.0, 360.0);
        printAverageAngle(10.0, 20.0, 30.0);
        printAverageAngle(370.0);
        printAverageAngle(180.0);
    }

    private static void printAverageAngle(double... sample) {
        double meanAngle = getMeanAngle(sample);
        System.out.printf("The mean angle of %s is %s%n", Arrays.toString(sample), meanAngle);
    }

    public static double getMeanAngle(double... anglesDeg) {
        double x = 0.0;
        double y = 0.0;

        for (double angleD : anglesDeg) {
            double angleR = Math.toRadians(angleD);
            x += Math.cos(angleR);
            y += Math.sin(angleR);
        }
        double avgR = Math.atan2(y / anglesDeg.length, x / anglesDeg.length);
        return Math.toDegrees(avgR);
    }
}


Averages/Pythagorean means

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

public class PythagoreanMeans {
    public static double arithmeticMean(List<Double> numbers) {
        if (numbers.isEmpty()) return Double.NaN;
        double mean = 0.0;
        for (Double number : numbers) {
            mean += number;
        }
        return mean / numbers.size();
    }

    public static double geometricMean(List<Double> numbers) {
        if (numbers.isEmpty()) return Double.NaN;
        double mean = 1.0;
        for (Double number : numbers) {
            mean *= number;
        }
        return Math.pow(mean, 1.0 / numbers.size());
    }

    public static double harmonicMean(List<Double> numbers) {
        if (numbers.isEmpty() || numbers.contains(0.0)) return Double.NaN;
        double mean = 0.0;
        for (Double number : numbers) {
            mean += (1.0 / number);
        }
        return numbers.size() / mean;
    }

    public static void main(String[] args) {
        Double[] array = {1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0, 9.0, 10.0};
        List<Double> list = Arrays.asList(array);
        double arithmetic = arithmeticMean(list);
        double geometric = geometricMean(list);
        double harmonic = harmonicMean(list);
        System.out.format("A = %f  G = %f  H = %f%n", arithmetic, geometric, harmonic);
        System.out.format("A >= G is %b, G >= H is %b%n", (arithmetic >= geometric), (geometric >= harmonic));
    }
}


Averages/Pythagorean means

Solution:
public static double arithmAverage(double array[]){
       if (array == null ||array.length == 0) {
         return 0.0;
      }
      else {
         return DoubleStream.of(array).average().getAsDouble();
      }
   }

    public static double geomAverage(double array[]){
      if (array == null ||array.length == 0) {
         return 0.0;
      }
      else {
         double aver = DoubleStream.of(array).reduce(1, (x, y) -> x * y);
         return   Math.pow(aver, 1.0 / array.length);
      }
   }

     public static double harmAverage(double array[]){
         if (array == null ||array.length == 0) {
         return 0.0;
      }
      else {
         double aver = DoubleStream.of(array)
                  // remove null values
                  .filter(n -> n > 0.0)
                  // generate 1/n array
                  .map( n-> 1.0/n)
                  // accumulating
                  .reduce(0, (x, y) -> x + y);
                  // just this reduce is not working- need to do in 2 steps
                 // .reduce(0, (x, y) -> 1.0/x + 1.0/y);
         return   array.length / aver ;
      }
   }


Averages/Root mean square

Task

Compute the   Root mean square   of the numbers 1..10.

The   ''root mean square''   is also known by its initials RMS (or rms), and as the '''quadratic mean'''.

The RMS is calculated as the mean of the squares of the numbers, square-rooted:

::: x_{\mathrm{rms}} = \sqrt {{{x_1}^2 + {x_2}^2 + \cdots + {x_n}^2} \over n}.

;See also

{{Related tasks/Statistical measures}}

Solution:
public class RootMeanSquare {

    public static double rootMeanSquare(double... nums) {
        double sum = 0.0;
        for (double num : nums)
            sum += num * num;
        return Math.sqrt(sum / nums.length);
    }

    public static void main(String[] args) {
        double[] nums = {1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0, 9.0, 10.0};
        System.out.println("The RMS of the numbers from 1 to 10 is " + rootMeanSquare(nums));
    }
}


Babbage problem

Charles Babbage
Charles Babbage's analytical engine.

Charles Babbage, looking ahead to the sorts of problems his Analytical Engine would be able to solve, gave this example:
{{quote
 | What is the smallest positive integer whose square ends in the digits 269,696?
 | Babbage, letter to Lord Bowden, 1837; see Hollingdale and Tootill, Electronic Computers, second edition, 1970, p. 125.
}}
He thought the answer might be 99,736, whose square is 9,947,269,696; but he couldn't be certain.

;Task

The task is to find out if Babbage had the right answer -- and to do so, as far as your language allows it, in code that Babbage himself would have been able to read and understand.
As Babbage evidently solved the task with pencil and paper, a similar efficient solution is preferred.

For these purposes, Charles Babbage may be taken to be an intelligent person, familiar with mathematics and with the idea of a computer; he has written the first drafts of simple computer programmes in tabular form. [Babbage Archive Series L].

;Motivation

The aim of the task is to write a program that is sufficiently clear and well-documented for such a person to be able to read it and be confident that it does indeed solve the specified problem.

Solution:
public class Test {

    public static void main(String[] args) {

        // let n be zero
        int n = 0;

        // repeat the following action
        do {

            // increase n by 1
            n++;

        // while the modulo of n times n is not equal to 269696
        } while (n * n % 1000_000 != 269696);

        // show the result
        System.out.println(n);
    }
}


Balanced brackets

'''Task''':
* Generate a string with   '''N'''   opening brackets   '''['''   and with   '''N'''   closing brackets   ''']''',   in some arbitrary order.
* Determine whether the generated string is ''balanced''; that is, whether it consists entirely of pairs of opening/closing brackets (in that order), none of which mis-nest.

;Examples:
    (empty)      OK
    []           OK
    [][]         OK
    [[][]]       OK
    ][         NOT OK
    ][][       NOT OK
    []][[]     NOT OK

Solution:
import java.util.ArrayDeque;
import java.util.Deque;

public class BalancedBrackets {

	public static boolean areSquareBracketsBalanced(String expr) {
		return isBalanced(expr, "", "", "[", "]", false);
	}
	public static boolean areBracketsBalanced(String expr) {
		return isBalanced(expr, "", "", "{([", "})]", false);
	}
	public static boolean areStringAndBracketsBalanced(String expr) {
		return isBalanced(expr, "'\"", "\\\\", "{([", "})]", true);
	}
	public static boolean isBalanced(String expr, String lit, String esc, String obr, String cbr, boolean other) {
		boolean[] inLit = new boolean[lit.length()];
		Deque<Character> stack = new ArrayDeque<Character>();
		for (int i=0; i<expr.length(); i+=1) {
			char c = get(expr, i);
			int x;
			if ((x = indexOf(inLit, true)) != -1) {
				if (c == get(lit, x) && get(expr, i-1) != get(esc, x)) inLit[x] = false;
			}
			else if ((x = indexOf(lit, c)) != -1)
				inLit[x] = true;
			else if ((x = indexOf(obr, c)) != -1)
				stack.push(get(cbr, x));
			else if (indexOf(cbr, c) != -1) {
				if (stack.isEmpty() || stack.pop() != c) return false;
			}
			else if (!other)
				return false;
		}
		return stack.isEmpty();
	}

	static int indexOf(boolean[] a, boolean b) {
		for (int i=0; i<a.length; i+=1) if (a[i] == b) return i;
		return -1;
	}
	static int indexOf(String s, char c) {
		return s.indexOf(c);
	}
	static char get(String s, int i) {
		return s.charAt(i);
	}

	public static void main(String[] args) {
		System.out.println("With areSquareBracketsBalanced:");
		for (String s: new String[] {
				"", "[]", "[][]", "[[][]]", "][", "][][", "[]][[]", "[", "]"
			}
		) {
			System.out.printf("%s: %s\n", s, areSquareBracketsBalanced(s));
		}
		System.out.println("\nBut also with areStringAndBracketsBalanced:");
		for (String s: new String[] {
				"x[]", "[x]", "[]x", "([{}])", "([{}]()", "([{ '([{\\'([{' \"([{\\\"([{\" }])",
			}
		) {
			System.out.printf("%s: %s\n", s, areStringAndBracketsBalanced(s));
		}
	}
}


Balanced ternary

Balanced ternary is a way of representing numbers.  Unlike the prevailing binary representation, a balanced ternary integer is in base 3, and each digit can have the values 1, 0, or -1.

;Examples:
Decimal 11 = 32 + 31 - 30, thus it can be written as "++-"

Decimal  6 = 32 - 31 + 0 x 30, thus it can be written as "+-0"

;Task:
Implement balanced ternary representation of integers with the following:
# Support arbitrarily large integers, both positive and negative;
# Provide ways to convert to and from text strings, using digits '+', '-' and '0' (unless you are already using strings to represent balanced ternary; but see requirement 5).
# Provide ways to convert to and from native integer type (unless, improbably, your platform's native integer type ''is'' balanced ternary).  If your native integers can't support arbitrary length, overflows during conversion must be indicated.
# Provide ways to perform addition, negation and multiplication directly on balanced ternary integers; do ''not'' convert to native integers first.
# Make your implementation efficient, with a reasonable definition of "efficient" (and with a reasonable definition of "reasonable").

'''Test case''' With balanced ternaries ''a'' from string "+-0++0+", ''b'' from native integer -436, ''c'' "+-++-":
* write out ''a'', ''b'' and ''c'' in decimal notation;
* calculate ''a'' x (''b'' - ''c''), write out the result in both ternary and decimal notations.

'''Note:''' The pages floating point balanced ternary.

Solution:
/*
 * Test case
 * With balanced ternaries a from string "+-0++0+", b from native integer -436, c "+-++-":
 * Write out a, b and c in decimal notation;
 * Calculate a × (b − c), write out the result in both ternary and decimal notations.
 */
public class BalancedTernary
{
	public static void main(String[] args)
	{
 		BTernary a=new BTernary("+-0++0+");
		BTernary b=new BTernary(-436);
		BTernary c=new BTernary("+-++-");

		System.out.println("a="+a.intValue());
		System.out.println("b="+b.intValue());
		System.out.println("c="+c.intValue());
		System.out.println();

		//result=a*(b-c)
		BTernary result=a.mul(b.sub(c));

		System.out.println("result= "+result+" "+result.intValue());
	}

	public static class BTernary
	{
		String value;
		public BTernary(String s)
		{
			int i=0;
			while(s.charAt(i)=='0')
				i++;
			this.value=s.substring(i);
		}
		public BTernary(int v)
		{
			this.value="";
			this.value=convertToBT(v);
		}

		private String convertToBT(int v)
		{
			if(v<0)
				return flip(convertToBT(-v));
			if(v==0)
				return "";
			int rem=mod3(v);
			if(rem==0)
				return convertToBT(v/3)+"0";
			if(rem==1)
				return convertToBT(v/3)+"+";
			if(rem==2)
				return convertToBT((v+1)/3)+"-";
			return "You can't see me";
		}
		private String flip(String s)
		{
			String flip="";
			for(int i=0;i<s.length();i++)
			{
				if(s.charAt(i)=='+')
					flip+='-';
				else if(s.charAt(i)=='-')
					flip+='+';
				else
					flip+='0';
			}
			return flip;
		}
		private int mod3(int v)
		{
			if(v>0)
				return v%3;
			v=v%3;
			return (v+3)%3;
		}

		public int intValue()
		{
			int sum=0;
			String s=this.value;
			for(int i=0;i<s.length();i++)
			{
				char c=s.charAt(s.length()-i-1);
				int dig=0;
				if(c=='+')
					dig=1;
				else if(c=='-')
					dig=-1;
				sum+=dig*Math.pow(3, i);
			}
			return sum;
		}

		public BTernary add(BTernary that)
		{
			String a=this.value;
			String b=that.value;

			String longer=a.length()>b.length()?a:b;
			String shorter=a.length()>b.length()?b:a;

			while(shorter.length()<longer.length())
				shorter=0+shorter;

			a=longer;
			b=shorter;

			char carry='0';
			String sum="";
			for(int i=0;i<a.length();i++)
			{
				int place=a.length()-i-1;
				String digisum=addDigits(a.charAt(place),b.charAt(place),carry);
				if(digisum.length()!=1)
					carry=digisum.charAt(0);
				else
					carry='0';
				sum=digisum.charAt(digisum.length()-1)+sum;
			}
			sum=carry+sum;

			return new BTernary(sum);
		}
		private String addDigits(char a,char b,char carry)
		{
			String sum1=addDigits(a,b);
			String sum2=addDigits(sum1.charAt(sum1.length()-1),carry);
			//System.out.println(carry+" "+sum1+" "+sum2);
			if(sum1.length()==1)
				return sum2;
			if(sum2.length()==1)
				return sum1.charAt(0)+sum2;
			return sum1.charAt(0)+"";
		}
		private String addDigits(char a,char b)
		{
			String sum="";
			if(a=='0')
				sum=b+"";
			else if (b=='0')
				sum=a+"";
			else if(a=='+')
			{
				if(b=='+')
					sum="+-";
				else
					sum="0";
			}
			else
			{
				if(b=='+')
					sum="0";
				else
					sum="-+";
			}
			return sum;
		}

		public BTernary neg()
		{
			return new BTernary(flip(this.value));
		}

		public BTernary sub(BTernary that)
		{
			return this.add(that.neg());
		}

		public BTernary mul(BTernary that)
		{
			BTernary one=new BTernary(1);
			BTernary zero=new BTernary(0);
			BTernary mul=new BTernary(0);

			int flipflag=0;
			if(that.compareTo(zero)==-1)
			{
				that=that.neg();
				flipflag=1;
			}
			for(BTernary i=new BTernary(1);i.compareTo(that)<1;i=i.add(one))
				mul=mul.add(this);

			if(flipflag==1)
				mul=mul.neg();
			return mul;
		}

		public boolean equals(BTernary that)
		{
			return this.value.equals(that.value);
		}
		public int compareTo(BTernary that)
		{
			if(this.intValue()>that.intValue())
				return 1;
			else if(this.equals(that))
				return 0;
			 return -1;
		}

		public String toString()
		{
			return value;
		}
	}
}


Barnsley fern

A Barnsley fern is a fractal named after British mathematician Michael Barnsley and can be created using an iterated function system (IFS).

;Task:
Create this fractal fern, using the following transformations:
* f1   (chosen 1% of the time)
         xn + 1 = 0
         yn + 1 = 0.16 yn

* f2   (chosen 85% of the time)
         xn + 1 = 0.85 xn + 0.04 yn
         yn + 1 = -0.04 xn + 0.85 yn + 1.6

* f3   (chosen 7% of the time)
         xn + 1 = 0.2 xn - 0.26 yn
         yn + 1 = 0.23 xn + 0.22 yn + 1.6

* f4   (chosen 7% of the time)
         xn + 1 = -0.15 xn + 0.28 yn
         yn + 1 = 0.26 xn + 0.24 yn + 0.44.

Starting position: x = 0, y = 0

Solution:
import java.awt.*;
import java.awt.image.BufferedImage;
import javax.swing.*;

public class BarnsleyFern extends JPanel {

    BufferedImage img;

    public BarnsleyFern() {
        final int dim = 640;
        setPreferredSize(new Dimension(dim, dim));
        setBackground(Color.white);
        img = new BufferedImage(dim, dim, BufferedImage.TYPE_INT_ARGB);
        createFern(dim, dim);
    }

    void createFern(int w, int h) {
        double x = 0;
        double y = 0;

        for (int i = 0; i < 200_000; i++) {
            double tmpx, tmpy;
            double r = Math.random();

            if (r <= 0.01) {
                tmpx = 0;
                tmpy = 0.16 * y;
            } else if (r <= 0.08) {
                tmpx = 0.2 * x - 0.26 * y;
                tmpy = 0.23 * x + 0.22 * y + 1.6;
            } else if (r <= 0.15) {
                tmpx = -0.15 * x + 0.28 * y;
                tmpy = 0.26 * x + 0.24 * y + 0.44;
            } else {
                tmpx = 0.85 * x + 0.04 * y;
                tmpy = -0.04 * x + 0.85 * y + 1.6;
            }
            x = tmpx;
            y = tmpy;

            img.setRGB((int) Math.round(w / 2 + x * w / 11),
                    (int) Math.round(h - y * h / 11), 0xFF32CD32);
        }
    }

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

        g.drawImage(img, 0, 0, null);
    }

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


Base64 decode data

See [[Base64 encode data]].

Now write a program that takes the output of the [[Base64 encode data]] task as input and regenerate the original file.

When working on the VBA implementation I found several 'solutions' on the net, including one from the software maker himself, that showed output with incorrect padding. Obviously with incorrect padding in the output you can not decode correctly to the original file again.

Solution:
void decodeToFile(String path, byte[] bytes) throws IOException {
    try (FileOutputStream stream = new FileOutputStream(path)) {
        byte[] decoded = Base64.getDecoder().decode(bytes);
        stream.write(decoded, 0, decoded.length);
    }
}


Base64 decode data

Solution:
import java.nio.charset.StandardCharsets;
import java.util.Base64;

public class Decode {
    public static void main(String[] args) {
        String data = "VG8gZXJyIGlzIGh1bWFuLCBidXQgdG8gcmVhbGx5IGZvdWwgdGhpbmdzIHVwIHlvdSBuZWVkIGEgY29tcHV0ZXIuCiAgICAtLSBQYXVsIFIuIEVocmxpY2g=";
        Base64.Decoder decoder = Base64.getDecoder();
        byte[] decoded = decoder.decode(data);
        String decodedStr = new String(decoded, StandardCharsets.UTF_8);
        System.out.println(decodedStr);
    }
}


Bell numbers

Bell or exponential numbers are enumerations of the number of different ways to partition a set that has exactly '''n''' elements. Each element of the sequence '''Bn''' is the number of partitions of a set of size '''n''' where order of the elements and order of the partitions are non-significant. E.G.: '''{a b}''' is the same as '''{b a}''' and '''{a} {b}''' is the same as '''{b} {a}'''.

;So:

:'''B0 = 1''' trivially. There is only one way to partition a set with zero elements. '''{ }'''

:'''B1 = 1''' There is only one way to partition a set with one element. '''{a}'''

:'''B2 = 2''' Two elements may be partitioned in two ways. '''{a} {b}, {a b}'''

:'''B3 = 5''' Three elements may be partitioned in five ways '''{a} {b} {c}, {a b} {c}, {a} {b c}, {a c} {b}, {a b c}'''

: and so on.

A simple way to find the Bell numbers is construct a '''Bell triangle''', also known as an '''Aitken's array''' or '''Peirce triangle''', and read off the numbers in the first column of each row. There are other generating algorithms though, and you are free to choose the best / most appropriate for your case.

;Task:

Write a routine (function, generator, whatever) to generate the Bell number sequence and call the routine to show here, on this page at least the '''first 15''' and (if your language supports big Integers) '''50th''' elements of the sequence.

If you ''do'' use the Bell triangle method to generate the numbers, also show the '''first ten rows''' of the Bell triangle.

;See also:

:* '''OEIS:A000110 Bell or exponential numbers'''
:* '''OEIS:A011971 Aitken's array'''

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

public class Bell {
    private static class BellTriangle {
        private List<Integer> arr;

        BellTriangle(int n) {
            int length = n * (n + 1) / 2;
            arr = new ArrayList<>(length);
            for (int i = 0; i < length; ++i) {
                arr.add(0);
            }

            set(1, 0, 1);
            for (int i = 2; i <= n; ++i) {
                set(i, 0, get(i - 1, i - 2));
                for (int j = 1; j < i; ++j) {
                    int value = get(i, j - 1) + get(i - 1, j - 1);
                    set(i, j, value);
                }
            }
        }

        private int index(int row, int col) {
            if (row > 0 && col >= 0 && col < row) {
                return row * (row - 1) / 2 + col;
            } else {
                throw new IllegalArgumentException();
            }
        }

        public int get(int row, int col) {
            int i = index(row, col);
            return arr.get(i);
        }

        public void set(int row, int col, int value) {
            int i = index(row, col);
            arr.set(i, value);
        }
    }

    public static void main(String[] args) {
        final int rows = 15;
        BellTriangle bt = new BellTriangle(rows);

        System.out.println("First fifteen Bell numbers:");
        for (int i = 0; i < rows; ++i) {
            System.out.printf("%2d: %d\n", i + 1, bt.get(i + 1, 0));
        }

        for (int i = 1; i <= 10; ++i) {
            System.out.print(bt.get(i, 0));
            for (int j = 1; j < i; ++j) {
                System.out.printf(", %d", bt.get(i, j));
            }
            System.out.println();
        }
    }
}


Benford's law

{{Wikipedia|Benford's_law}}

'''Benford's law''', also called the '''first-digit law''', refers to the frequency distribution of digits in many (but not all) real-life sources of data.

In this distribution, the number 1 occurs as the first digit about 30% of the time, while larger numbers occur in that position less frequently: 9 as the first digit less than 5% of the time. This distribution of first digits is the same as the widths of gridlines on a logarithmic scale.

Benford's law also concerns the expected distribution for digits beyond the first, which approach a uniform distribution.

This result has been found to apply to a wide variety of data sets, including electricity bills, street addresses, stock prices, population numbers, death rates, lengths of rivers, physical and mathematical constants, and processes described by power laws (which are very common in nature). It tends to be most accurate when values are distributed across multiple orders of magnitude.

A set of numbers is said to satisfy Benford's law if the leading digit d  (d \in \{1, \ldots, 9\}) occurs with probability

:::: P(d) = \log_{10}(d+1)-\log_{10}(d) = \log_{10}\left(1+\frac{1}{d}\right)

For this task, write (a) routine(s) to calculate the distribution of first significant (non-zero) digits in a collection of numbers, then display the actual vs. expected distribution in the way most convenient for your language (table / graph / histogram / whatever).

Use the first 1000 numbers from the Fibonacci sequence as your data set. No need to show how the Fibonacci numbers are obtained.

You can generate them or load them from a file; whichever is easiest.

Display your actual vs expected distribution.

''For extra credit:'' Show the distribution for one other set of numbers from a page on Wikipedia. State which Wikipedia page it can be obtained from and what the set enumerates. Again, no need to display the actual list of numbers or the code to load them.

;See also:
* numberphile.com.
* A starting page on Wolfram Mathworld is {{Wolfram|Benfords|Law}}.

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

public class BenfordsLaw {

    private static BigInteger[] generateFibonacci(int n) {
        BigInteger[] fib = new BigInteger[n];
        fib[0] = BigInteger.ONE;
        fib[1] = BigInteger.ONE;
        for (int i = 2; i < fib.length; i++) {
            fib[i] = fib[i - 2].add(fib[i - 1]);
        }
        return fib;
    }

    public static void main(String[] args) {
        BigInteger[] numbers = generateFibonacci(1000);

        int[] firstDigits = new int[10];
        for (BigInteger number : numbers) {
            firstDigits[Integer.valueOf(number.toString().substring(0, 1))]++;
        }

        for (int i = 1; i < firstDigits.length; i++) {
            System.out.printf(Locale.ROOT, "%d %10.6f %10.6f%n",
                    i, (double) firstDigits[i] / numbers.length, Math.log10(1.0 + 1.0 / i));
        }
    }
}


Best shuffle

Shuffle the characters of a string in such a way that as many of the character values are in a different position as possible.

A shuffle that produces a randomized result among the best choices is to be preferred. A deterministic approach that produces the same sequence every time is acceptable as an alternative.

Display the result as follows:

 original string, shuffled string, (score)

The score gives the number of positions whose character value did ''not'' change.

;Example:
 tree, eetr, (0)

;Test cases:
 abracadabra
 seesaw
 elk
 grrrrrr
 up
 a

;Related tasks
*   [[Anagrams/Deranged anagrams]]
*   [[Permutations/Derangements]]

Solution:
import java.util.Random;

public class BestShuffle {
    private final static Random rand = new Random();

    public static void main(String[] args) {
        String[] words = {"abracadabra", "seesaw", "grrrrrr", "pop", "up", "a"};
        for (String w : words)
            System.out.println(bestShuffle(w));
    }

    public static String bestShuffle(final String s1) {
        char[] s2 = s1.toCharArray();
        shuffle(s2);
        for (int i = 0; i < s2.length; i++) {
            if (s2[i] != s1.charAt(i))
                continue;
            for (int j = 0; j < s2.length; j++) {
                if (s2[i] != s2[j] && s2[i] != s1.charAt(j) && s2[j] != s1.charAt(i)) {
                    char tmp = s2[i];
                    s2[i] = s2[j];
                    s2[j] = tmp;
                    break;
                }
            }
        }
        return s1 + " " + new String(s2) + " (" + count(s1, s2) + ")";
    }

    public static void shuffle(char[] text) {
        for (int i = text.length - 1; i > 0; i--) {
            int r = rand.nextInt(i + 1);
            char tmp = text[i];
            text[i] = text[r];
            text[r] = tmp;
        }
    }

    private static int count(final String s1, final char[] s2) {
        int count = 0;
        for (int i = 0; i < s2.length; i++)
            if (s1.charAt(i) == s2[i])
                count++;
        return count;
    }
}


Bin given limits

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

public class Bins {
    public static <T extends Comparable<? super T>> int[] bins(
            List<? extends T> limits, Iterable<? extends T> data) {
        int[] result = new int[limits.size() + 1];
        for (T n : data) {
            int i = Collections.binarySearch(limits, n);
            if (i >= 0) {
                // n == limits[i]; we put it in right-side bin (i+1)
                i = i+1;
            } else {
                // n is not in limits and i is ~(insertion point)
                i = ~i;
            }
            result[i]++;
        }
        return result;
    }

    public static void printBins(List<?> limits, int[] bins) {
        int n = limits.size();
        if (n == 0) {
            return;
        }
        assert n+1 == bins.length;
        System.out.printf("           < %3s: %2d\n", limits.get(0), bins[0]);
        for (int i = 1; i < n; i++) {
            System.out.printf(">= %3s and < %3s: %2d\n", limits.get(i-1), limits.get(i), bins[i]);
        }
        System.out.printf(">= %3s          : %2d\n", limits.get(n-1), bins[n]);
    }

    public static void main(String[] args) {
        List<Integer> limits = Arrays.asList(23, 37, 43, 53, 67, 83);
        List<Integer> data = Arrays.asList(
            95, 21, 94, 12, 99, 4,  70, 75, 83, 93, 52, 80, 57, 5,  53, 86, 65,
            17, 92, 83, 71, 61, 54, 58, 47, 16, 8,  9,  32, 84, 7,  87, 46, 19,
            30, 37, 96, 6,  98, 40, 79, 97, 45, 64, 60, 29, 49, 36, 43, 55);

        System.out.println("Example 1:");
        printBins(limits, bins(limits, data));

        limits = Arrays.asList(14,  18,  249, 312, 389,
                               392, 513, 591, 634, 720);
        data = Arrays.asList(
            445, 814, 519, 697, 700, 130, 255, 889, 481, 122, 932, 77,  323, 525,
            570, 219, 367, 523, 442, 933, 416, 589, 930, 373, 202, 253, 775, 47,
            731, 685, 293, 126, 133, 450, 545, 100, 741, 583, 763, 306, 655, 267,
            248, 477, 549, 238, 62,  678, 98,  534, 622, 907, 406, 714, 184, 391,
            913, 42,  560, 247, 346, 860, 56,  138, 546, 38,  985, 948, 58,  213,
            799, 319, 390, 634, 458, 945, 733, 507, 916, 123, 345, 110, 720, 917,
            313, 845, 426, 9,   457, 628, 410, 723, 354, 895, 881, 953, 677, 137,
            397, 97,  854, 740, 83,  216, 421, 94,  517, 479, 292, 963, 376, 981,
            480, 39,  257, 272, 157, 5,   316, 395, 787, 942, 456, 242, 759, 898,
            576, 67,  298, 425, 894, 435, 831, 241, 989, 614, 987, 770, 384, 692,
            698, 765, 331, 487, 251, 600, 879, 342, 982, 527, 736, 795, 585, 40,
            54,  901, 408, 359, 577, 237, 605, 847, 353, 968, 832, 205, 838, 427,
            876, 959, 686, 646, 835, 127, 621, 892, 443, 198, 988, 791, 466, 23,
            707, 467, 33,  670, 921, 180, 991, 396, 160, 436, 717, 918, 8,   374,
            101, 684, 727, 749);

        System.out.println();
        System.out.println("Example 2:");
        printBins(limits, bins(limits, data));
    }
}


Bioinformatics/Sequence mutation

Given a string of characters A, C, G, and T representing a DNA sequence write a routine to mutate the sequence, (string) by:
# Choosing a random base position in the sequence.
# Mutate the sequence by  doing one of either:
## '''S'''wap the base at that position by changing it to one of A, C, G, or T. (which has a chance of swapping the base for the same base)
## '''D'''elete the chosen base at the position.
## '''I'''nsert another base randomly chosen from A,C, G, or T into the sequence at that position.
# Randomly generate a test DNA sequence of at least 200 bases
# "Pretty print" the sequence and a count of its size, and the count of each base in the sequence
# Mutate the sequence ten times.
# "Pretty print" the sequence after all mutations, and a count of its size, and the count of each base in the sequence.

;Extra credit:
* Give more information on the individual mutations applied.
* Allow mutations to be weighted and/or chosen.

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

public class SequenceMutation {
    public static void main(String[] args) {
        SequenceMutation sm = new SequenceMutation();
        sm.setWeight(OP_CHANGE, 3);
        String sequence = sm.generateSequence(250);
        System.out.println("Initial sequence:");
        printSequence(sequence);
        int count = 10;
        for (int i = 0; i < count; ++i)
            sequence = sm.mutateSequence(sequence);
        System.out.println("After " + count + " mutations:");
        printSequence(sequence);
    }

    public SequenceMutation() {
        totalWeight_ = OP_COUNT;
        Arrays.fill(operationWeight_, 1);
    }

    public String generateSequence(int length) {
        char[] ch = new char[length];
        for (int i = 0; i < length; ++i)
            ch[i] = getRandomBase();
        return new String(ch);
    }

    public void setWeight(int operation, int weight) {
        totalWeight_ -= operationWeight_[operation];
        operationWeight_[operation] = weight;
        totalWeight_ += weight;
    }

    public String mutateSequence(String sequence) {
        char[] ch = sequence.toCharArray();
        int pos = random_.nextInt(ch.length);
        int operation = getRandomOperation();
        if (operation == OP_CHANGE) {
            char b = getRandomBase();
            System.out.println("Change base at position " + pos + " from "
                               + ch[pos] + " to " + b);
            ch[pos] = b;
        } else if (operation == OP_ERASE) {
            System.out.println("Erase base " + ch[pos] + " at position " + pos);
            char[] newCh = new char[ch.length - 1];
            System.arraycopy(ch, 0, newCh, 0, pos);
            System.arraycopy(ch, pos + 1, newCh, pos, ch.length - pos - 1);
            ch = newCh;
        } else if (operation == OP_INSERT) {
            char b = getRandomBase();
            System.out.println("Insert base " + b + " at position " + pos);
            char[] newCh = new char[ch.length + 1];
            System.arraycopy(ch, 0, newCh, 0, pos);
            System.arraycopy(ch, pos, newCh, pos + 1, ch.length - pos);
            newCh[pos] = b;
            ch = newCh;
        }
        return new String(ch);
    }

    public static void printSequence(String sequence) {
        int[] count = new int[BASES.length];
        for (int i = 0, n = sequence.length(); i < n; ++i) {
            if (i % 50 == 0) {
                if (i != 0)
                    System.out.println();
                System.out.printf("%3d: ", i);
            }
            char ch = sequence.charAt(i);
            System.out.print(ch);
            for (int j = 0; j < BASES.length; ++j) {
                if (BASES[j] == ch) {
                    ++count[j];
                    break;
                }
            }
        }
        System.out.println();
        System.out.println("Base counts:");
        int total = 0;
        for (int j = 0; j < BASES.length; ++j) {
            total += count[j];
            System.out.print(BASES[j] + ": " + count[j] + ", ");
        }
        System.out.println("Total: " + total);
    }

    private char getRandomBase() {
        return BASES[random_.nextInt(BASES.length)];
    }

    private int getRandomOperation() {
        int n = random_.nextInt(totalWeight_), op = 0;
        for (int weight = 0; op < OP_COUNT; ++op) {
            weight += operationWeight_[op];
            if (n < weight)
                break;
        }
        return op;
    }

    private final Random random_ = new Random();
    private int[] operationWeight_ = new int[OP_COUNT];
    private int totalWeight_ = 0;

    private static final int OP_CHANGE = 0;
    private static final int OP_ERASE = 1;
    private static final int OP_INSERT = 2;
    private static final int OP_COUNT = 3;
    private static final char[] BASES = {'A', 'C', 'G', 'T'};
}


Bioinformatics/base count

Given this string representing ordered DNA bases:

CGTAAAAAATTACAACGTCCTTTGGCTATCTCTTAAACTCCTGCTAAATG
CTCGTGCTTTCCAATTATGTAAGCGTTCCGAGACGGGGTGGTCGATTCTG
AGGACAAAGGTCAAGATGGAGCGCATCGAACGCAATAAGGATCATTTGAT
GGGACGTTTCGTCGACAAAGTCTTGTTTCGAGAGTAACGGCTACCGTCTT
CGATTCTGCTTATAACACTATGTTCTTATGAAATGGATGTTCTGAGTTGG
TCAGTCCCAATGTGCGGGGTTTCTTTTAGTACGTCGGGAGTGGTATTATA
TTTAATTTTTCTATATAGCGATCTGTATTTAAGCAATTCATTTAGGTTAT
CGCCGCGATGCTCGGTTCGGACCGCCAAGCATCTGGCTCCACTGCTAGTG
TCCTAAATTTGAATGGCAAACACAAATAAGATTTAGCAATTCGTGTAGAC
GACCGGGGACTTGCATGATGGGAGCAGCTTTGTTAAACTACGAACGTAAT

;Task:
:*   "Pretty print" the sequence followed by a summary of the counts of each of the bases:   ('''A''', '''C''', '''G''', and '''T''')   in the sequence
:*   print the total count of each base in the string.

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

public class orderedSequence {
    public static void main(String[] args) {
        Sequence gene = new Sequence("CGTAAAAAATTACAACGTCCTTTGGCTATCTCTTAAACTCCTGCTAAATGCTCGTGCTTTCCAATTATGTAAGCGTTCCGAGACGGGGTGGTCGATTCTGAGGACAAAGGTCAAGATGGAGCGCATCGAACGCAATAAGGATCATTTGATGGGACGTTTCGTCGACAAAGTCTTGTTTCGAGAGTAACGGCTACCGTCTTCGATTCTGCTTATAACACTATGTTCTTATGAAATGGATGTTCTGAGTTGGTCAGTCCCAATGTGCGGGGTTTCTTTTAGTACGTCGGGAGTGGTATTATATTTAATTTTTCTATATAGCGATCTGTATTTAAGCAATTCATTTAGGTTATCGCCGCGATGCTCGGTTCGGACCGCCAAGCATCTGGCTCCACTGCTAGTGTCCTAAATTTGAATGGCAAACACAAATAAGATTTAGCAATTCGTGTAGACGACCGGGGACTTGCATGATGGGAGCAGCTTTGTTAAACTACGAACGTAAT");
        gene.runSequence();
    }
}

/** Separate class for defining behaviors */
public class Sequence {

    private final String seq;

    public Sequence(String sq) {
        this.seq = sq;
    }

    /** print the organized structure of the sequence */
    public void prettyPrint() {
        System.out.println("Sequence:");
        int i = 0;
        for ( ; i < seq.length() - 50 ; i += 50) {
            System.out.printf("%5s : %s\n", i + 50, seq.substring(i, i + 50));
        }
        System.out.printf("%5s : %s\n", seq.length(), seq.substring(i));
    }

    /** display a base vs. frequency chart */
    public void displayCount() {
        Map<Character, Integer> counter = new HashMap<>();
        for (int i = 0 ; i < seq.length() ; ++i) {
            counter.merge(seq.charAt(i), 1, Integer::sum);
        }

        System.out.println("Base vs. Count:");
        counter.forEach(
            key, value -> System.out.printf("%5s : %s\n", key, value));
        System.out.printf("%5s: %s\n", "SUM", seq.length());
    }

    public void runSequence() {
        this.prettyPrint();
        this.displayCount();
    }
}


Bitcoin/address validation

Write a program that takes a bitcoin address as argument,
and checks whether or not this address is valid.

A bitcoin address uses a base58 encoding, which uses an alphabet of the characters 0 .. 9, A ..Z, a .. z, but without the four characters:
:::*   0   zero
:::*   O   uppercase oh
:::*   I   uppercase eye
:::*   l   lowercase ell

With this encoding, a bitcoin address encodes 25 bytes:
* the first byte is the version number, which will be zero for this task ;
* the next twenty bytes are a [[RIPEMD-160]] digest, but you don't have to know that for this task:  you can consider them a pure arbitrary data ;
* the last four bytes are a checksum check.  They are the first four bytes of a double [[SHA-256]] digest of the previous 21 bytes.

To check the bitcoin address, you must read the first twenty-one bytes, compute the checksum, and check that it corresponds to the last four bytes.

The program can either return a boolean value or throw an exception when not valid.

You can use a digest library for [[SHA-256]].

;Example of a bitcoin address:

 1AGNa15ZQXAZUgFiqJ2i7Z2DPU2J6hW62i

It doesn't belong to anyone and is part of the test suite of the bitcoin software.
You can change a few characters in this string and check that it'll fail the test.

Solution:
import java.math.BigInteger;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.Arrays;

public class BitcoinAddressValidator {

    private static final String ALPHABET = "123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz";

    public static boolean validateBitcoinAddress(String addr) {
        if (addr.length() < 26 || addr.length() > 35)
            return false;
        byte[] decoded = decodeBase58To25Bytes(addr);
        if (decoded == null)
            return false;

        byte[] hash1 = sha256(Arrays.copyOfRange(decoded, 0, 21));
        byte[] hash2 = sha256(hash1);

        return Arrays.equals(Arrays.copyOfRange(hash2, 0, 4), Arrays.copyOfRange(decoded, 21, 25));
    }

    private static byte[] decodeBase58To25Bytes(String input) {
        BigInteger num = BigInteger.ZERO;
        for (char t : input.toCharArray()) {
            int p = ALPHABET.indexOf(t);
            if (p == -1)
                return null;
            num = num.multiply(BigInteger.valueOf(58)).add(BigInteger.valueOf(p));
        }

        byte[] result = new byte[25];
        byte[] numBytes = num.toByteArray();
        System.arraycopy(numBytes, 0, result, result.length - numBytes.length, numBytes.length);
        return result;
    }

    private static byte[] sha256(byte[] data) {
        try {
            MessageDigest md = MessageDigest.getInstance("SHA-256");
            md.update(data);
            return md.digest();
        } catch (NoSuchAlgorithmException e) {
            throw new IllegalStateException(e);
        }
    }

    public static void main(String[] args) {
        assertBitcoin("1AGNa15ZQXAZUgFiqJ2i7Z2DPU2J6hW62i", true);
        assertBitcoin("1AGNa15ZQXAZUgFiqJ2i7Z2DPU2J6hW62j", false);
        assertBitcoin("1Q1pE5vPGEEMqRcVRMbtBK842Y6Pzo6nK9", true);
        assertBitcoin("1AGNa15ZQXAZUgFiqJ2i7Z2DPU2J6hW62X", false);
        assertBitcoin("1ANNa15ZQXAZUgFiqJ2i7Z2DPU2J6hW62i", false);
        assertBitcoin("1A Na15ZQXAZUgFiqJ2i7Z2DPU2J6hW62i", false);
        assertBitcoin("BZbvjr", false);
        assertBitcoin("i55j", false);
        assertBitcoin("1AGNa15ZQXAZUgFiqJ2i7Z2DPU2J6hW62!", false);
        assertBitcoin("1AGNa15ZQXAZUgFiqJ2i7Z2DPU2J6hW62iz", false);
        assertBitcoin("1AGNa15ZQXAZUgFiqJ2i7Z2DPU2J6hW62izz", false);
        assertBitcoin("1Q1pE5vPGEEMqRcVRMbtBK842Y6Pzo6nJ9", false);
        assertBitcoin("1AGNa15ZQXAZUgFiqJ2i7Z2DPU2J6hW62I", false);
    }

    private static void assertBitcoin(String address, boolean expected) {
        boolean actual = validateBitcoinAddress(address);
        if (actual != expected)
            throw new AssertionError(String.format("Expected %s for %s, but got %s.", expected, address, actual));
    }
}


Box the compass

Avast me hearties!
There be many a land lubber that knows naught of the pirate ways and gives direction by degree!
They know not how to box the compass!

;Task description:
# Create a function that takes a heading in degrees and returns the correct 32-point compass heading.
# Use the function to print and display a table of Index, Compass point, and Degree; rather like the corresponding columns from, the first table of the wikipedia article, but use only the following 33 headings as input:
:[0.0, 16.87, 16.88, 33.75, 50.62, 50.63, 67.5, 84.37, 84.38, 101.25, 118.12, 118.13, 135.0, 151.87, 151.88, 168.75, 185.62, 185.63, 202.5, 219.37, 219.38, 236.25, 253.12, 253.13, 270.0, 286.87, 286.88, 303.75, 320.62, 320.63, 337.5, 354.37, 354.38]. (They should give the same order of points but are spread throughout the ranges of acceptance).

;Notes;
* The headings and indices can be calculated from this pseudocode:
for i in 0..32 inclusive:
    heading = i * 11.25
    case i %3:
      if 1: heading += 5.62; break
      if 2: heading -= 5.62; break
    end
    index = ( i mod 32) + 1
* The column of indices can be thought of as an enumeration of the thirty two cardinal points (see talk page)..

Solution:
enum Compass {
    N, NbE, NNE, NEbN, NE, NEbE, ENE, EbN,
    E, EbS, ESE, SEbE, SE, SEbS, SSE, SbE,
    S, SbW, SSW, SWbS, SW, SWbW, WSW, WbS,
    W, WbN, WNW, NWbW, NW, NWbN, NNW, NbW;

    float midpoint() {
        float midpoint = (360 / 32f) * ordinal();
        return midpoint == 0 ? 360 : midpoint;
    }

    float[] bounds() {
        float bound = (360 / 32f) / 2f;
        float midpoint = midpoint();
        float boundA = midpoint - bound;
        float boundB = midpoint + bound;
        if (boundB > 360) boundB -= 360;
        return new float[] { boundA, boundB };
    }

    static Compass parse(float degrees) {
        float[] bounds;
        float[] boundsN = N.bounds();
        for (Compass value : Compass.values()) {
            bounds = value.bounds();
            if (degrees >= boundsN[0] || degrees < boundsN[1])
                return N;
            if (degrees >= bounds[0] && degrees < bounds[1])
                return value;
        }
        return null;
    }

    @Override
    public String toString() {
        String[] strings = new String[name().length()];
        int index = 0;
        for (char letter : name().toCharArray()) {
            switch (letter) {
                case 'N' -> strings[index] = "north";
                case 'E' -> strings[index] = "east";
                case 'S' -> strings[index] = "south";
                case 'W' -> strings[index] = "west";
                case 'b' -> strings[index] = "by";
            }
            index++;
        }
        String string
            = strings[0].substring(0, 1).toUpperCase() +
              strings[0].substring(1);
        switch (strings.length) {
            case 2 -> string += strings[1];
            case 3 -> {
                if (strings[1].equals("by")) {
                    string += " %s %s".formatted(strings[1], strings[2]);
                } else {
                    string += "-%s%s".formatted(strings[1], strings[2]);
                }
            }
            case 4 -> {
                string += String.join(" ", strings[1], strings[2], strings[3]);
            }
        }
        return string;
    }
}


Brazilian numbers

Brazilian numbers are so called as they were first formally presented at the 1994 math Olympiad ''Olimpiada Iberoamericana de Matematica'' in Fortaleza, Brazil.

Brazilian numbers are defined as:

The set of positive integer numbers where each number '''N''' has at least one natural number '''B''' where '''1 < B < N-1''' where the representation of '''N''' in '''base B''' has all equal digits.

;E.G.:

:* '''1, 2 & 3''' can not be Brazilian; there is no base '''B''' that satisfies the condition '''1 < B < N-1'''.
:* '''4''' is not Brazilian; '''4''' in '''base 2''' is '''100'''. The digits are not all the same.
:* '''5''' is not Brazilian; '''5''' in '''base 2''' is '''101''', in '''base 3''' is '''12'''. There is no representation where the digits are the same.
:* '''6''' is not Brazilian; '''6''' in '''base 2''' is '''110''', in '''base 3''' is '''20''', in '''base 4''' is '''12'''. There is no representation where the digits are the same.
:* '''7''' ''is'' Brazilian; '''7''' in '''base 2''' is '''111'''. There is at least one representation where the digits are all the same.
:* '''8''' ''is'' Brazilian; '''8''' in '''base 3''' is '''22'''. There is at least one representation where the digits are all the same.
:* ''and so on...''

All even integers '''2P >= 8''' are Brazilian because '''2P = 2(P-1) + 2''', which is '''22''' in '''base P-1''' when '''P-1 > 2'''. That becomes true when '''P >= 4'''.
More common: for all all integers '''R''' and '''S''', where '''R > 1''' and also '''S-1 > R''', then '''R*S''' is Brazilian because '''R*S = R(S-1) + R''', which is '''RR''' in '''base S-1'''
The only problematic numbers are squares of primes, where R = S. Only 11^2 is brazilian to base 3.
All prime integers, that are brazilian, can only have the digit '''1'''. Otherwise one could factor out the digit, therefore it cannot be a prime number. Mostly in form of '''111''' to base Integer(sqrt(prime number)). Must be an odd count of '''1''' to stay odd like primes >  2

;Task:

Write a routine (function, whatever) to determine if a number is Brazilian and use the routine to show here, on this page;

:* the first '''20''' Brazilian numbers;
:* the first '''20 odd''' Brazilian numbers;
:* the first '''20 prime''' Brazilian numbers;

;See also:

:* '''OEIS:A125134 - Brazilian numbers'''
:* '''OEIS:A257521 - Odd Brazilian numbers'''
:* '''OEIS:A085104 - Prime Brazilian numbers'''

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

public class Brazilian {
    private static final List<Integer> primeList = List.of(
        2, 3, 5, 7, 9, 11, 13, 17, 19, 23, 29, 31, 37, 41, 43, 47, 53, 59, 61, 67, 71, 73, 79, 83, 89,
        97, 101, 103, 107, 109, 113, 127, 131, 137, 139, 149, 151, 157, 163, 167, 169, 173, 179, 181,
        191, 193, 197, 199, 211, 223, 227, 229, 233, 239, 241, 247, 251, 257, 263, 269, 271, 277, 281,
        283, 293, 299, 307, 311, 313, 317, 331, 337, 347, 349, 353, 359, 367, 373, 377, 379, 383, 389,
        397, 401, 403, 409, 419, 421, 431, 433, 439, 443, 449, 457, 461, 463, 467, 479, 481, 487, 491,
        499, 503, 509, 521, 523, 533, 541, 547, 557, 559, 563, 569, 571, 577, 587, 593, 599, 601, 607,
        611, 613, 617, 619, 631, 641, 643, 647, 653, 659, 661, 673, 677, 683, 689, 691, 701, 709, 719,
        727, 733, 739, 743, 751, 757, 761, 767, 769, 773, 787, 793, 797, 809, 811, 821, 823, 827, 829,
        839, 853, 857, 859, 863, 871, 877, 881, 883, 887, 907, 911, 919, 923, 929, 937, 941, 947, 949,
        953, 967, 971, 977, 983, 991, 997
    );

    public static boolean isPrime(int n) {
        if (n < 2) {
            return false;
        }

        for (Integer prime : primeList) {
            if (n == prime) {
                return true;
            }
            if (n % prime == 0) {
                return false;
            }
            if (prime * prime > n) {
                return true;
            }
        }

        BigInteger bi = BigInteger.valueOf(n);
        return bi.isProbablePrime(10);
    }

    private static boolean sameDigits(int n, int b) {
        int f = n % b;
        while ((n /= b) > 0) {
            if (n % b != f) {
                return false;
            }
        }
        return true;
    }

    private static boolean isBrazilian(int n) {
        if (n < 7) return false;
        if (n % 2 == 0) return true;
        for (int b = 2; b < n - 1; ++b) {
            if (sameDigits(n, b)) {
                return true;
            }
        }
        return false;
    }

    public static void main(String[] args) {
        for (String kind : List.of("", "odd ", "prime ")) {
            boolean quiet = false;
            int bigLim = 99_999;
            int limit = 20;
            System.out.printf("First %d %sBrazilian numbers:\n", limit, kind);
            int c = 0;
            int n = 7;
            while (c < bigLim) {
                if (isBrazilian(n)) {
                    if (!quiet) System.out.printf("%d ", n);
                    if (++c == limit) {
                        System.out.println("\n");
                        quiet = true;
                    }
                }
                if (quiet && !"".equals(kind)) continue;
                switch (kind) {
                    case "":
                        n++;
                        break;
                    case "odd ":
                        n += 2;
                        break;
                    case "prime ":
                        do {
                            n += 2;
                        } while (!isPrime(n));
                        break;
                    default:
                        throw new AssertionError("Oops");
                }
            }
            if ("".equals(kind)) {
                System.out.printf("The %dth Brazilian number is: %d\n\n", bigLim + 1, n);
            }
        }
    }
}


Break OO privacy

Show how to access private or protected members of a class in an object-oriented language from outside an instance of the class, without calling non-private or non-protected members of the class as a proxy.
The intent is to show how a debugger, serializer, or other meta-programming tool might access information that is barred by normal access methods to the object  but can nevertheless be accessed from within the language by some provided escape hatch or reflection mechanism.
The intent is specifically not to demonstrate heroic measures such as peeking and poking raw memory.

Note that cheating on your type system is almost universally regarded
as unidiomatic at best, and poor programming practice at worst.
Nonetheless, if your language intentionally maintains a double-standard for OO privacy, here's where you can show it off.

Solution:
Example example = new Example();
Method method = example.getClass().getDeclaredMethod("stringB");
method.setAccessible(true);
String stringA = example.stringA;
String stringB = (String) method.invoke(example);
System.out.println(stringA + " " + stringB);


Brilliant numbers

'''Brilliant numbers''' are a subset of semiprime numbers. Specifically, they are numbers that are the product of exactly two prime numbers '''that both have the same number of digits when expressed in base 10'''.

''Brilliant numbers are useful in cryptography and when testing prime factoring algorithms.''

;E.G.
* '''3 x 3''' (9) is a brilliant number.
* '''2 x 7''' (14) is a brilliant number.
* '''113 x 691''' (78083) is a brilliant number.
* '''2 x 31''' (62) is semiprime, but is '''not''' a brilliant number (different number of digits in the two factors).

;Task
* Find and display the first 100 brilliant numbers.
* For the orders of magnitude 1 through 6, find and show the first brilliant number greater than or equal to the order of magnitude, and, its position in the series (or the count of brilliant numbers up to that point).

;Stretch
* Continue for larger orders of magnitude.

;See also
;* Numbers Aplenty - Brilliant numbers
;* OEIS:A078972 - Brilliant numbers: semiprimes whose prime factors have the same number of decimal digits

Solution:
import java.util.*;

public class BrilliantNumbers {
    public static void main(String[] args) {
        var primesByDigits = getPrimesByDigits(100000000);
        System.out.println("First 100 brilliant numbers:");
        List<Integer> brilliantNumbers = new ArrayList<>();
        for (var primes : primesByDigits) {
            int n = primes.size();
            for (int i = 0; i < n; ++i) {
                int prime1 = primes.get(i);
                for (int j = i; j < n; ++j) {
                    int prime2 = primes.get(j);
                    brilliantNumbers.add(prime1 * prime2);
                }
            }
            if (brilliantNumbers.size() >= 100)
                break;
        }
        Collections.sort(brilliantNumbers);
        for (int i = 0; i < 100; ++i) {
            char c = (i + 1) % 10 == 0 ? '\n' : ' ';
            System.out.printf("%,5d%c", brilliantNumbers.get(i), c);
        }
        System.out.println();
        long power = 10;
        long count = 0;
        for (int p = 1; p < 2 * primesByDigits.size(); ++p) {
            var primes = primesByDigits.get(p / 2);
            long position = count + 1;
            long minProduct = 0;
            int n = primes.size();
            for (int i = 0; i < n; ++i) {
                long prime1 = primes.get(i);
                var primes2 = primes.subList(i, n);
                int q = (int)((power + prime1 - 1) / prime1);
                int j = Collections.binarySearch(primes2, q);
                if (j == n)
                    continue;
                if (j < 0)
                    j = -(j + 1);
                long prime2 = primes2.get(j);
                long product = prime1 * prime2;
                if (minProduct == 0 || product < minProduct)
                    minProduct = product;
                position += j;
                if (prime1 >= prime2)
                    break;
            }
            System.out.printf("First brilliant number >= 10^%d is %,d at position %,d\n",
                                p, minProduct, position);
            power *= 10;
            if (p % 2 == 1) {
                long size = primes.size();
                count += size * (size + 1) / 2;
            }
        }
    }

    private static List<List<Integer>> getPrimesByDigits(int limit) {
        PrimeGenerator primeGen = new PrimeGenerator(100000, 100000);
        List<List<Integer>> primesByDigits = new ArrayList<>();
        List<Integer> primes = new ArrayList<>();
        for (int p = 10; p <= limit; ) {
            int prime = primeGen.nextPrime();
            if (prime > p) {
                primesByDigits.add(primes);
                primes = new ArrayList<>();
                p *= 10;
            }
            primes.add(prime);
        }
        return primesByDigits;
    }
}


Burrows–Wheeler transform

{{Wikipedia|Burrows-Wheeler_transform}}

The Burrows-Wheeler transform (BWT, also called block-sorting compression) rearranges a character string into runs of similar characters.

This is useful for compression, since it tends to be easy to compress a string that has runs of repeated characters by techniques such as move-to-front transform and run-length encoding.

More importantly, the transformation is reversible, without needing to store any additional data.

The BWT is thus a "free" method of improving the efficiency of text compression algorithms, costing only some extra computation.

Source: Burrows-Wheeler transform

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

public class BWT {
    private static final String STX = "\u0002";
    private static final String ETX = "\u0003";

    private static String bwt(String s) {
        if (s.contains(STX) || s.contains(ETX)) {
            throw new IllegalArgumentException("String cannot contain STX or ETX");
        }

        String ss = STX + s + ETX;
        List<String> table = new ArrayList<>();
        for (int i = 0; i < ss.length(); i++) {
            String before = ss.substring(i);
            String after = ss.substring(0, i);
            table.add(before + after);
        }
        table.sort(String::compareTo);

        StringBuilder sb = new StringBuilder();
        for (String str : table) {
            sb.append(str.charAt(str.length() - 1));
        }
        return sb.toString();
    }

    private static String ibwt(String r) {
        int len = r.length();
        List<String> table = new ArrayList<>();
        for (int i = 0; i < len; ++i) {
            table.add("");
        }
        for (int j = 0; j < len; ++j) {
            for (int i = 0; i < len; ++i) {
                table.set(i, r.charAt(i) + table.get(i));
            }
            table.sort(String::compareTo);
        }
        for (String row : table) {
            if (row.endsWith(ETX)) {
                return row.substring(1, len - 1);
            }
        }
        return "";
    }

    private static String makePrintable(String s) {
        // substitute ^ for STX and | for ETX to print results
        return s.replace(STX, "^").replace(ETX, "|");
    }

    public static void main(String[] args) {
        List<String> tests = List.of(
            "banana",
            "appellee",
            "dogwood",
            "TO BE OR NOT TO BE OR WANT TO BE OR NOT?",
            "SIX.MIXED.PIXIES.SIFT.SIXTY.PIXIE.DUST.BOXES",
            "\u0002ABC\u0003"
        );
        for (String test : tests) {
            System.out.println(makePrintable(test));
            System.out.print(" --> ");
            String t = "";
            try {
                t = bwt(test);
                System.out.println(makePrintable(t));
            } catch (IllegalArgumentException e) {
                System.out.println("ERROR: " + e.getMessage());
            }
            String r = ibwt(t);
            System.out.printf(" --> %s\n\n", r);
        }
    }
}


CSV data manipulation

CSV spreadsheet files are suitable for storing tabular data in a relatively portable way.

The CSV format is flexible but somewhat ill-defined.

For present purposes, authors may assume that the data fields contain no commas, backslashes, or quotation marks.

;Task:
Read a CSV file, change some values and save the changes back to a file.

For this task we will use the following CSV file:

 C1,C2,C3,C4,C5
 1,5,9,13,17
 2,6,10,14,18
 3,7,11,15,19
 4,8,12,16,20

Suggestions

 Show how to add a column, headed 'SUM', of the sums of the rows.
 If possible, illustrate the use of built-in or standard functions, methods, or libraries, that handle generic CSV files.

Solution:
import java.io.*;
import java.awt.Point;
import java.util.HashMap;
import java.util.Scanner;

public class CSV {

    private HashMap<Point, String> _map = new HashMap<Point, String>();
    private int _cols;
    private int _rows;

    public void open(File file) throws FileNotFoundException, IOException {
        open(file, ',');
    }

    public void open(File file, char delimiter)
            throws FileNotFoundException, IOException {
        Scanner scanner = new Scanner(file);
        scanner.useDelimiter(Character.toString(delimiter));

        clear();

        while(scanner.hasNextLine()) {
            String[] values = scanner.nextLine().split(Character.toString(delimiter));

            int col = 0;
            for ( String value: values ) {
                _map.put(new Point(col, _rows), value);
                _cols = Math.max(_cols, ++col);
            }
            _rows++;
        }
        scanner.close();
    }

    public void save(File file) throws IOException {
        save(file, ',');
    }

    public void save(File file, char delimiter) throws IOException {
        FileWriter fw = new FileWriter(file);
        BufferedWriter bw = new BufferedWriter(fw);

        for (int row = 0; row < _rows; row++) {
            for (int col = 0; col < _cols; col++) {
                Point key = new Point(col, row);
                if (_map.containsKey(key)) {
                    bw.write(_map.get(key));
                }

                if ((col + 1) < _cols) {
                    bw.write(delimiter);
                }
            }
            bw.newLine();
        }
        bw.flush();
        bw.close();
    }

    public String get(int col, int row) {
        String val = "";
        Point key = new Point(col, row);
        if (_map.containsKey(key)) {
            val = _map.get(key);
        }
        return val;
    }

    public void put(int col, int row, String value) {
        _map.put(new Point(col, row), value);
        _cols = Math.max(_cols, col+1);
        _rows = Math.max(_rows, row+1);
    }

    public void clear() {
        _map.clear();
        _cols = 0;
        _rows = 0;
    }

    public int rows() {
        return _rows;
    }

    public int cols() {
        return _cols;
    }

    public static void main(String[] args) {
        try {
            CSV csv = new CSV();

            csv.open(new File("test_in.csv"));
            csv.put(0, 0, "Column0");
            csv.put(1, 1, "100");
            csv.put(2, 2, "200");
            csv.put(3, 3, "300");
            csv.put(4, 4, "400");
            csv.save(new File("test_out.csv"));
        } catch (Exception e) {
        }
    }
}


CSV to HTML translation

Consider a simplified CSV format where all rows are separated by a newline
and all columns are separated by commas.

No commas are allowed as field data, but the data may contain
other characters and character sequences that would
normally be   ''escaped''   when converted to HTML

;Task:
Create a function that takes a string representation of the CSV data
and returns a text string of an HTML table representing the CSV data.

Use the following  data as the CSV text to convert, and show your output.
: Character,Speech
: The multitude,The messiah! Show us the messiah!
: Brians mother,Now you listen here! He's not the messiah; he's a very naughty boy! Now go away!
: The multitude,Who are you?
: Brians mother,I'm his mother; that's who!
: The multitude,Behold his mother! Behold his mother!

;Extra credit:
''Optionally'' allow special formatting for the first row of the table as if it is the tables header row
(via  preferably; CSS if you must).

Solution:
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.io.PrintStream;

class Csv2Html {

	public static String escapeChars(String lineIn) {
		StringBuilder sb = new StringBuilder();
		int lineLength = lineIn.length();
		for (int i = 0; i < lineLength; i++) {
			char c = lineIn.charAt(i);
			switch (c) {
				case '"':
					sb.append(""");
					break;
				case '&':
					sb.append("&");
					break;
				case '\'':
					sb.append("'");
					break;
				case '<':
					sb.append("<");
					break;
				case '>':
					sb.append(">");
					break;
				default: sb.append(c);
			}
		}
		return sb.toString();
	}

	public static void tableHeader(PrintStream ps, String[] columns) {
		ps.print("
");
		for (int i = 0; i < columns.length; i++) {
			ps.print("");
			ps.print(columns[i]);
			ps.print("	");
		}
		ps.println("
");
	}

	public static void tableRow(PrintStream ps, String[] columns) {
		ps.print("
");
		for (int i = 0; i < columns.length; i++) {
			ps.print("");
			ps.print(columns[i]);
			ps.print("	");
		}
		ps.println("
");
	}

	public static void main(String[] args) throws Exception {
		boolean withTableHeader = (args.length != 0);

		InputStreamReader isr = new InputStreamReader(System.in);
		BufferedReader br = new BufferedReader(isr);
		PrintStream stdout = System.out;

		stdout.println("<!DOCTYPE html PUBLIC \"-//W3C//DTD XHTML 1.0 Strict//EN\" \"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd\">");
		stdout.println("");
		stdout.println("<meta http-equiv=\"Content-type\" content=\"text/html;charset=UTF-8\"/>");
		stdout.println("<title>Csv2Html</title>");
		stdout.println("");
		stdout.println("
Csv2Html
");

		stdout.println("
");
		String stdinLine;
		boolean firstLine = true;
		while ((stdinLine = br.readLine()) != null) {
			String[] columns = escapeChars(stdinLine).split(",");
			if (withTableHeader == true && firstLine == true) {
				tableHeader(stdout, columns);
				firstLine = false;
			} else {
				tableRow(stdout, columns);
			}
		}
		stdout.println("
");
	}
}


Calculating the value of e

Calculate the value of   ''e''.

(''e''   is also known as   ''Euler's number''   and   ''Napier's constant''.)

See details: Calculating the value of e

Solution:
BigDecimal e(BigInteger limit, int scale) {
    BigDecimal e = BigDecimal.ONE.setScale(scale, HALF_UP);
    BigDecimal n;
    BigInteger term = BigInteger.ONE;
    while (term.compareTo(limit) <= 0) {
        n = new BigDecimal(String.valueOf(factorial(term)));
        e = e.add(BigDecimal.ONE.divide(n, scale, HALF_UP));
        term = term.add(BigInteger.ONE);
    }
    return e;
}

BigInteger factorial(BigInteger value) {
    if (value.compareTo(BigInteger.ONE) > 0) {
        return value.multiply(factorial(value.subtract(BigInteger.ONE)));
    } else {
        return BigInteger.ONE;
    }
}


Calculating the value of e

Solution:
public class CalculateE {
    public static final double EPSILON = 1.0e-15;

    public static void main(String[] args) {
        long fact = 1;
        double e = 2.0;
        int n = 2;
        double e0;
        do {
            e0 = e;
            fact *= n++;
            e += 1.0 / fact;
        } while (Math.abs(e - e0) >= EPSILON);
        System.out.printf("e = %.15f\n", e);
    }
}