Range consolidation

Define a range of numbers   '''R''',   with bounds   '''b0'''   and   '''b1'''   covering all numbers ''between and including both bounds''.

That range can be shown as:
::::::::: '''[b0, b1]'''
::::::::    or equally as:
::::::::: '''[b1, b0]'''

Given two ranges, the act of consolidation between them compares the two ranges:
*   If one range covers all of the other then the result is that encompassing range.
*   If the ranges touch or intersect then the result is   ''one''   new single range covering the overlapping ranges.
*   Otherwise the act of consolidation is to return the two non-touching ranges.

Given   '''N'''   ranges where   '''N > 2'''   then the result is the same as repeatedly replacing all combinations of two ranges by their consolidation until no further consolidation between range pairs is possible.

If   '''N < 2'''   then range consolidation has no strict meaning and the input can be returned.

;Example 1:
:   Given the two ranges   '''[1, 2.5]'''   and   '''[3, 4.2]'''   then
:   there is no common region between the ranges and the result is the same as the input.

;Example 2:
:   Given the two ranges   '''[1, 2.5]'''   and   '''[1.8, 4.7]'''   then
:   there is :   an overlap   '''[2.5, 1.8]'''   between the ranges and
:   the result is the single range   '''[1, 4.7]'''.
:   Note that order of bounds in a range is not (yet) stated.

;Example 3:
:   Given the two ranges   '''[6.1, 7.2]'''   and   '''[7.2, 8.3]'''   then
:   they touch at   '''7.2'''   and
:   the result is the single range   '''[6.1, 8.3]'''.

;Example 4:
:   Given the three ranges   '''[1, 2]'''   and   '''[4, 8]'''   and   '''[2, 5]'''
:   then there is no intersection of the ranges   '''[1, 2]'''   and   '''[4, 8]'''
:   but the ranges   '''[1, 2]'''   and   '''[2, 5]'''   overlap and
:   consolidate to produce the range   '''[1, 5]'''.
:   This range, in turn, overlaps the other range   '''[4, 8]''',   and
:   so consolidates to the final output of the single range   '''[1, 8]'''.

;Task:
Let a normalized range display show the smaller bound to the left;   and show the
range with the smaller lower bound to the left of other ranges when showing multiple ranges.

Output the ''normalized'' result of applying consolidation to these five sets of ranges:
            [1.1, 2.2]
            [6.1, 7.2], [7.2, 8.3]
            [4, 3], [2, 1]
            [4, 3], [2, 1], [-1, -2], [3.9, 10]
            [1, 3], [-6, -1], [-4, -5], [8, 2], [-6, -6]
Show all output here.

;See also:
* [[Set consolidation]]
* [[Set of real numbers]]

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

public class RangeConsolidation {

    public static void main(String[] args) {
        displayRanges( Arrays.asList(new Range(1.1, 2.2)));
        displayRanges( Arrays.asList(new Range(6.1, 7.2), new Range(7.2, 8.3)));
        displayRanges( Arrays.asList(new Range(4, 3), new Range(2, 1)));
        displayRanges( Arrays.asList(new Range(4, 3), new Range(2, 1), new Range(-1, -2), new Range(3.9, 10)));
        displayRanges( Arrays.asList(new Range(1, 3), new Range(-6, -1), new Range(-4, -5), new Range(8, 2), new Range(-6, -6)));
        displayRanges( Arrays.asList(new Range(1, 1), new Range(1, 1)));
        displayRanges( Arrays.asList(new Range(1, 1), new Range(1, 2)));
        displayRanges( Arrays.asList(new Range(1, 2), new Range(3, 4), new Range(1.5, 3.5), new Range(1.2, 2.5)));
    }

    private static final void displayRanges(List<Range> ranges) {
        System.out.printf("ranges = %-70s, colsolidated = %s%n", ranges, Range.consolidate(ranges));
    }

    private static final class RangeSorter implements Comparator<Range> {
        @Override
        public int compare(Range o1, Range o2) {
            return (int) (o1.left - o2.left);
        }
    }

    private static class Range {
        double left;
        double right;

        public Range(double left, double right) {
            if ( left <= right ) {
                this.left = left;
                this.right = right;
            }
            else {
                this.left = right;
                this.right = left;
            }
        }

        public Range consolidate(Range range) {
            //  no overlap
            if ( this.right < range.left ) {
                return null;
            }
            //  no overlap
            if ( range.right < this.left ) {
                return null;
            }
            //  contained
            if ( this.left <= range.left && this.right >= range.right ) {
                return this;
            }
            //  contained
            if ( range.left <= this.left && range.right >= this.right ) {
                return range;
            }
            //  overlap
            if ( this.left <= range.left && this.right <= range.right ) {
                return new Range(this.left, range.right);
            }
            //  overlap
            if ( this.left >= range.left && this.right >= range.right ) {
                return new Range(range.left, this.right);
            }
            throw new RuntimeException("ERROR:  Logic invalid.");
        }

        @Override
        public String toString() {
            return "[" + left + ", " + right + "]";
        }

        private static List<Range> consolidate(List<Range> ranges) {
            List<Range> consolidated = new ArrayList<>();

            Collections.sort(ranges, new RangeSorter());

            for ( Range inRange : ranges ) {
                Range r = null;
                Range conRange = null;
                for ( Range conRangeLoop : consolidated ) {
                    r = inRange.consolidate(conRangeLoop);
                    if (r != null ) {
                        conRange = conRangeLoop;
                        break;
                    }
                }
                if ( r == null ) {
                    consolidated.add(inRange);
                }
                else {
                    consolidated.remove(conRange);
                    consolidated.add(r);
                }
            }

            Collections.sort(consolidated, new RangeSorter());

            return consolidated;
        }
    }

}


Range expansion

{{:Range extraction/Format}}

;Task:
Expand the range description:
   -6,-3--1,3-5,7-11,14,15,17-20
Note that the second element above,
is the '''range from minus 3 to ''minus'' 1'''.

;Related task:
*   [[Range extraction]]

Solution:
import java.util.*;

class RangeExpander implements Iterator<Integer>, Iterable<Integer> {

    private static final Pattern TOKEN_PATTERN = Pattern.compile("([+-]?\\d+)-([+-]?\\d+)");

    private final Iterator<String> tokensIterator;

    private boolean inRange;
    private int upperRangeEndpoint;
    private int nextRangeValue;

    public RangeExpander(String range) {
        String[] tokens = range.split("\\s*,\\s*");
        this.tokensIterator = Arrays.asList(tokens).iterator();
    }

    @Override
    public boolean hasNext() {
        return hasNextRangeValue() || this.tokensIterator.hasNext();
    }

    private boolean hasNextRangeValue() {
        return this.inRange && this.nextRangeValue <= this.upperRangeEndpoint;
    }

    @Override
    public Integer next() {
        if (!hasNext()) {
            throw new NoSuchElementException();
        }

        if (hasNextRangeValue()) {
            return this.nextRangeValue++;
        }

        String token = this.tokensIterator.next();

        Matcher matcher = TOKEN_PATTERN.matcher(token);
        if (matcher.find()) {
            this.inRange = true;
            this.upperRangeEndpoint = Integer.valueOf(matcher.group(2));
            this.nextRangeValue = Integer.valueOf(matcher.group(1));
            return this.nextRangeValue++;
        }

        this.inRange = false;
        return Integer.valueOf(token);
    }

    @Override
    public Iterator<Integer> iterator() {
        return this;
    }

}

class RangeExpanderTest {
    public static void main(String[] args) {
        RangeExpander re = new RangeExpander("-6,-3--1,3-5,7-11,14,15,17-20");
        for (int i : re) {
            System.out.print(i + " ");
        }
    }
}


Range extraction

{{:Range extraction/Format}}

;Task:
* Create a function that takes a list of integers in increasing order and returns a correctly formatted string in the range format.
* Use the function to compute and print the range formatted version of the following ordered list of integers. (The correct answer is: 0-2,4,6-8,11,12,14-25,27-33,35-39).

     0,  1,  2,  4,  6,  7,  8, 11, 12, 14,
    15, 16, 17, 18, 19, 20, 21, 22, 23, 24,
    25, 27, 28, 29, 30, 31, 32, 33, 35, 36,
    37, 38, 39
* Show the output of your program.

;Related task:
*   [[Range expansion]]

Solution:
public class RangeExtraction {

    public static void main(String[] args) {
        int[] arr = {0, 1, 2, 4, 6, 7, 8, 11, 12, 14,
            15, 16, 17, 18, 19, 20, 21, 22, 23, 24,
            25, 27, 28, 29, 30, 31, 32, 33, 35, 36,
            37, 38, 39};

        int len = arr.length;
        int idx = 0, idx2 = 0;
        while (idx < len) {
            while (++idx2 < len && arr[idx2] - arr[idx2 - 1] == 1);
            if (idx2 - idx > 2) {
                System.out.printf("%s-%s,", arr[idx], arr[idx2 - 1]);
                idx = idx2;
            } else {
                for (; idx < idx2; idx++)
                    System.out.printf("%s,", arr[idx]);
            }
        }
    }
}


Rate counter

Counting the frequency at which something occurs is a common activity in measuring performance and managing resources. In this task, we assume that there is some job which we want to perform repeatedly, and we want to know how quickly these jobs are being performed.
Of interest is the code that performs the actual measurements. Any other code (such as job implementation or dispatching) that is required to demonstrate the rate tracking is helpful, but not the focus.

Multiple approaches are allowed (even preferable), so long as they can accomplish these goals:

* Run N seconds worth of jobs and/or Y jobs.
* Report at least three distinct times.

Be aware of the precision and accuracy limitations of your timing mechanisms, and document them if you can.

'''See also:''' [[System time]], [[Time a function]]

Solution:
import java.util.function.IntConsumer;
import java.util.stream.DoubleStream;

import static java.lang.System.nanoTime;
import static java.util.stream.DoubleStream.generate;

import static java.lang.System.out;

public interface RateCounter {
  public static void main(final String... arguments) {
    benchmark(
      10,
      x -> out.print(""),
      10
    )
      .forEach(out::println)
    ;
  }

  public static DoubleStream benchmark(
    final int n,
    final IntConsumer consumer,
    final int argument
  ) {
    return generate(() -> {
      final long time = nanoTime();
      consumer.accept(argument);
      return nanoTime() - time;
    })
      .limit(n)
    ;
  }
}


Read a specific line from a file

Some languages have special semantics for obtaining a known line number from a file.

;Task:
Demonstrate how to obtain the contents of a specific line within a file.

For the purpose of this task demonstrate how the contents of the seventh line of a file can be obtained,   and store it in a variable or in memory   (for potential future use within the program if the code were to become embedded).

If the file does not contain seven lines,   or the seventh line is empty,   or too big to be retrieved,   output an appropriate message.

If no special semantics are available for obtaining the required line,   it is permissible to read line by line.

Note that empty lines are considered and should still be counted.

Also note that for functional languages or languages without variables or storage,   it is permissible to output the extracted data to standard output.

Solution:
package linenbr7;

import java.io.*;

public class LineNbr7 {

    public static void main(String[] args) throws Exception {
        File f = new File(args[0]);
        if (!f.isFile() || !f.canRead())
            throw new IOException("can't read " + args[0]);

        BufferedReader br = new BufferedReader(new FileReader(f));
        try (LineNumberReader lnr = new LineNumberReader(br)) {
            String line = null;
            int lnum = 0;
            while ((line = lnr.readLine()) != null
                    && (lnum = lnr.getLineNumber()) < 7) {
            }

            switch (lnum) {
                case 0:
                    System.out.println("the file has zero length");
                    break;
                case 7:
                    boolean empty = "".equals(line);
                    System.out.println("line 7: " + (empty ? "empty" : line));
                    break;
                default:
                    System.out.println("the file has only " + lnum + " line(s)");
            }
        }
    }
}


Recaman's sequence

The '''Recaman's sequence''' generates Natural numbers.

Starting from a(0)=0, the n'th term a(n), where n>0, is the previous term minus n i.e a(n) = a(n-1) - n but only if this is '''both''' positive ''and'' has not been previousely generated.

If the conditions ''don't'' hold then a(n) = a(n-1) + n.

;Task:
# Generate and show here the first 15 members of the sequence.
# Find and show here, the first duplicated number in the sequence.
# '''Optionally''': Find and show here, how many terms of the sequence are needed until all the integers 0..1000, inclusive, are generated.

;References:
* A005132,  The On-Line Encyclopedia of Integer Sequences.
* The Slightly Spooky Recaman Sequence, Numberphile video.
* Recaman's sequence, on Wikipedia.

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

public class RecamanSequence {
    public static void main(String[] args) {
        List<Integer> a = new ArrayList<>();
        a.add(0);

        Set<Integer> used = new HashSet<>();
        used.add(0);

        Set<Integer> used1000 = new HashSet<>();
        used1000.add(0);

        boolean foundDup = false;
        int n = 1;
        while (n <= 15 || !foundDup || used1000.size() < 1001) {
            int next = a.get(n - 1) - n;
            if (next < 1 || used.contains(next)) {
                next += 2 * n;
            }
            boolean alreadyUsed = used.contains(next);
            a.add(next);
            if (!alreadyUsed) {
                used.add(next);
                if (0 <= next && next <= 1000) {
                    used1000.add(next);
                }
            }
            if (n == 14) {
                System.out.printf("The first 15 terms of the Recaman sequence are : %s\n", a);
            }
            if (!foundDup && alreadyUsed) {
                System.out.printf("The first duplicate term is a[%d] = %d\n", n, next);
                foundDup = true;
            }
            if (used1000.size() == 1001) {
                System.out.printf("Terms up to a[%d] are needed to generate 0 to 1000\n", n);
            }
            n++;
        }
    }
}


Remove lines from a file

Remove a specific line or a number of lines from a file.

This should be implemented as a routine that takes three parameters (filename, starting line, and the number of lines to be removed).

For the purpose of this task, line numbers and the number of lines start at one, so to remove the first two lines from the file foobar.txt, the parameters should be: foobar.txt, 1, 2

Empty lines are considered and should still be counted, and if the specified line is empty, it should still be removed.

An appropriate message should appear if an attempt is made to remove lines beyond the end of the file.

Solution:
import java.io.BufferedReader;
import java.io.File;
import java.io.FileReader;
import java.io.FileWriter;

public class RemoveLines
{
	public static void main(String[] args)
	{
		//Enter name of the file here
		String filename="foobar.txt";
		//Enter starting line here
		int startline=1;
		//Enter number of lines here.
		int numlines=2;

		RemoveLines now=new RemoveLines();
		now.delete(filename,startline,numlines);
	}
	void delete(String filename, int startline, int numlines)
	{
		try
		{
			BufferedReader br=new BufferedReader(new FileReader(filename));

			//String buffer to store contents of the file
			StringBuffer sb=new StringBuffer("");

			//Keep track of the line number
			int linenumber=1;
			String line;

			while((line=br.readLine())!=null)
			{
				//Store each valid line in the string buffer
				if(linenumber<startline||linenumber>=startline+numlines)
					sb.append(line+"\n");
				linenumber++;
			}
			if(startline+numlines>linenumber)
				System.out.println("End of file reached.");
			br.close();

			FileWriter fw=new FileWriter(new File(filename));
			//Write entire string buffer into the file
			fw.write(sb.toString());
			fw.close();
		}
		catch (Exception e)
		{
			System.out.println("Something went horribly wrong: "+e.getMessage());
		}
	}
}


Rep-string

Given a series of ones and zeroes in a string, define a repeated string or ''rep-string'' as a string which is created by repeating a substring of the ''first'' N characters of the string ''truncated on the right to the length of the input string, and in which the substring appears repeated at least twice in the original''.

For example, the string '''10011001100''' is a rep-string as the leftmost four characters of '''1001''' are repeated three times and truncated on the right to give the original string.

Note that the requirement for having the repeat occur two or more times means that the repeating unit is ''never'' longer than half the length of the input string.

;Task:
* Write a function/subroutine/method/... that takes a string and returns an indication of if it is a rep-string and the repeated string.   (Either the string that is repeated, or the number of repeated characters would suffice).
* There may be multiple sub-strings that make a string a rep-string - in that case an indication of all, or the longest, or the shortest would suffice.
* Use the function to indicate the repeating substring if any, in the following:

1001110011
1110111011
0010010010
1010101010
1111111111
0100101101
0100100
101
11
00
1

* Show your output on this page.

Solution:
public class RepString {

    static final String[] input = {"1001110011", "1110111011", "0010010010",
        "1010101010", "1111111111", "0100101101", "0100100", "101", "11",
        "00", "1", "0100101"};

    public static void main(String[] args) {
        for (String s : input)
            System.out.printf("%s : %s%n", s, repString(s));
    }

    static String repString(String s) {
        int len = s.length();
        outer:
        for (int part = len / 2; part > 0; part--) {
            int tail = len % part;
            if (tail > 0 && !s.substring(0, tail).equals(s.substring(len - tail)))
                continue;
            for (int j = 0; j < len / part - 1; j++) {
                int a = j * part;
                int b = (j + 1) * part;
                int c = (j + 2) * part;
                if (!s.substring(a, b).equals(s.substring(b, c)))
                    continue outer;
            }
            return s.substring(0, part);
        }
        return "none";
    }
}


Repeat

Write a procedure which accepts as arguments another procedure and a positive integer.

The latter procedure is executed a number of times equal to the accepted integer.

Solution:
import java.lang.reflect.Method;

public class Program {
    public static void main(String[] args) throws ReflectiveOperationException {
        Method method = Program.class.getMethod("printRosettaCode");
        repeat(method, 5);
    }

    public static void printRosettaCode() {
        System.out.println("Rosetta Code");
    }

    public static void repeat(Method method, int count) throws ReflectiveOperationException {
        while (count-- > 0)
            method.invoke(null);
    }
}


Repeat

Solution:
import java.util.function.Consumer;
import java.util.stream.IntStream;

public class Repeat {

    public static void main(String[] args) {
        repeat(3, (x) -> System.out.println("Example " + x));
    }

    static void repeat (int n, Consumer<Integer> fun) {
        IntStream.range(0, n).forEach(i -> fun.accept(i + 1));
    }
}


Resistor mesh

Given    10x10    grid nodes   (as shown in the image)   interconnected by    1O    resistors as shown,
find the resistance between points   '''A'''   and   '''B'''.

;See also:
*   (humor, nerd sniping)   xkcd.com cartoon (you can solve that for extra credits)
*   An article on how to calculate this and an implementation in Mathematica

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

public class ResistorMesh {
    private static final int S = 10;

    private static class Node {
        double v;
        int fixed;

        Node(double v, int fixed) {
            this.v = v;
            this.fixed = fixed;
        }
    }

    private static void setBoundary(List<List<Node>> m) {
        m.get(1).get(1).v = 1.0;
        m.get(1).get(1).fixed = 1;

        m.get(6).get(7).v = -1.0;
        m.get(6).get(7).fixed = -1;
    }

    private static double calcDiff(List<List<Node>> m, List<List<Node>> d, int w, int h) {
        double total = 0.0;
        for (int i = 0; i < h; ++i) {
            for (int j = 0; j < w; ++j) {
                double v = 0.0;
                int n = 0;
                if (i > 0) {
                    v += m.get(i - 1).get(j).v;
                    n++;
                }
                if (j > 0) {
                    v += m.get(i).get(j - 1).v;
                    n++;
                }
                if (i + 1 < h) {
                    v += m.get(i + 1).get(j).v;
                    n++;
                }
                if (j + 1 < w) {
                    v += m.get(i).get(j + 1).v;
                    n++;
                }
                v = m.get(i).get(j).v - v / n;
                d.get(i).get(j).v = v;
                if (m.get(i).get(j).fixed == 0) {
                    total += v * v;
                }
            }
        }
        return total;
    }

    private static double iter(List<List<Node>> m, int w, int h) {
        List<List<Node>> d = new ArrayList<>(h);
        for (int i = 0; i < h; ++i) {
            List<Node> t = new ArrayList<>(w);
            for (int j = 0; j < w; ++j) {
                t.add(new Node(0.0, 0));
            }
            d.add(t);
        }

        double[] cur = new double[3];
        double diff = 1e10;

        while (diff > 1e-24) {
            setBoundary(m);
            diff = calcDiff(m, d, w, h);
            for (int i = 0; i < h; ++i) {
                for (int j = 0; j < w; ++j) {
                    m.get(i).get(j).v -= d.get(i).get(j).v;
                }
            }
        }

        for (int i = 0; i < h; ++i) {
            for (int j = 0; j < w; ++j) {
                int k = 0;
                if (i != 0) k++;
                if (j != 0) k++;
                if (i < h - 1) k++;
                if (j < w - 1) k++;
                cur[m.get(i).get(j).fixed + 1] += d.get(i).get(j).v * k;
            }
        }

        return (cur[2] - cur[0]) / 2.0;
    }

    public static void main(String[] args) {
        List<List<Node>> mesh = new ArrayList<>(S);
        for (int i = 0; i < S; ++i) {
            List<Node> t = new ArrayList<>(S);
            for (int j = 0; j < S; ++j) {
                t.add(new Node(0.0, 0));
            }
            mesh.add(t);
        }

        double r = 2.0 / iter(mesh, S, S);
        System.out.printf("R = %.15f", r);
    }
}


Reverse words in a string

Reverse the order of all tokens in each of a number of strings and display the result;   the order of characters within a token should not be modified.

;Example:
Hey you, Bub!    would be shown reversed as:    Bub! you, Hey

Tokens are any non-space characters separated by spaces (formally, white-space);   the visible punctuation form part of the word within which it is located and should not be modified.

You may assume that there are no significant non-visible characters in the input.   Multiple or superfluous spaces may be compressed into a single space.

Some strings have no tokens, so an empty string   (or one just containing spaces)   would be the result.

'''Display''' the strings in order   (1st, 2nd, 3rd, ***),   and one string per line.

(You can consider the ten strings as ten lines, and the tokens as words.)

;Input data

             (ten lines within the box)
 line
     +----------------------------------------+
   1 |  ---------- Ice and Fire ------------  |
   2 |                                        |  <--- a blank line here.
   3 |  fire, in end will world the say Some  |
   4 |  ice. in say Some                      |
   5 |  desire of tasted I've what From       |
   6 |  fire. favor who those with hold I     |
   7 |                                        |  <--- a blank line here.
   8 |  ... elided paragraph last ...         |
   9 |                                        |  <--- a blank line here.
  10 |  Frost Robert -----------------------  |
     +----------------------------------------+

;Cf.
* [[Phrase reversals]]

Solution:
public class ReverseWords {

    static final String[] lines = {
        " ----------- Ice and Fire ----------- ",
        "                                      ",
        " fire, in end will world the say Some ",
        " ice. in say Some                     ",
        " desire of tasted I've what From      ",
        " fire. favor who those with hold I    ",
        "                                      ",
        " ... elided paragraph last ...        ",
        " Frost Robert ----------------------- "};

    public static void main(String[] args) {
        for (String line : lines) {
            String[] words = line.split("\\s");
            for (int i = words.length - 1; i >= 0; i--)
                System.out.printf("%s ", words[i]);
            System.out.println();
        }
    }
}


Reverse words in a string

Solution:
package string;

import static java.util.Arrays.stream;

public interface ReverseWords {
  public static final String[] LINES = {
    " ----------- Ice and Fire ----------- ",
    "                                      ",
    " fire, in end will world the say Some ",
    " ice. in say Some                     ",
    " desire of tasted I've what From      ",
    " fire. favor who those with hold I    ",
    "                                      ",
    " ... elided paragraph last ...        ",
    " Frost Robert ----------------------- "
  };

  public static String[] reverseWords(String[] lines) {
    return stream(lines)
      .parallel()
      .map(l -> l.split("\\s"))
      .map(ws -> stream(ws)
        .parallel()
        .map(w -> " " + w)
        .reduce(
          "",
          (w1, w2) -> w2 + w1
        )
      )
      .toArray(String[]::new)
    ;
  }

  public static void main(String... arguments) {
    stream(reverseWords(LINES))
      .forEach(System.out::println)
    ;
  }
}


Rhonda numbers

A positive integer '''''n''''' is said to be a Rhonda number to base '''''b''''' if the product of the base '''''b''''' digits of '''''n''''' is equal to '''''b''''' times the sum of '''''n''''''s prime factors.

''These numbers were named by Kevin Brown after an acquaintance of his whose residence number was 25662, a member of the base 10 numbers with this property.''

'''25662''' is a Rhonda number to base-'''10'''. The prime factorization is '''2 x 3 x 7 x 13 x 47'''; the product of its base-'''10''' digits is equal to the base times the sum of its prime factors:

2 x 5 x 6 x 6 x 2 = 720 = 10 x (2 + 3 + 7 + 13 + 47)

Rhonda numbers only exist in bases that are not a prime.

''Rhonda numbers to base 10 '''always''' contain at least 1 digit 5 and '''always''' contain at least 1 even digit.''

;Task

* For the non-prime bases '''''b''''' from '''2''' through '''16''' , find and display here, on this page, at least the first '''10''' '''Rhonda numbers''' to base '''''b'''''. Display the found numbers at least in base '''10'''.

;Stretch

* Extend out to base '''36'''.

;See also

;* Wolfram Mathworld - Rhonda numbers
;* Numbers Aplenty - Rhonda numbers
;* OEIS:A100968 - Integers n that are Rhonda numbers to base 4
;* OEIS:A100969 - Integers n that are Rhonda numbers to base 6
;* OEIS:A100970 - Integers n that are Rhonda numbers to base 8
;* OEIS:A100973 - Integers n that are Rhonda numbers to base 9
;* OEIS:A099542 - Rhonda numbers to base 10
;* OEIS:A100971 - Integers n that are Rhonda numbers to base 12
;* OEIS:A100972 - Integers n that are Rhonda numbers to base 14
;* OEIS:A100974 - Integers n that are Rhonda numbers to base 15
;* OEIS:A100975 - Integers n that are Rhonda numbers to base 16

;* OEIS:A255735 - Integers n that are Rhonda numbers to base 18
;* OEIS:A255732 - Rhonda numbers in vigesimal number system (base 20)
;* OEIS:A255736 - Integers that are Rhonda numbers to base 30

;* Related Task: Smith numbers

Solution:
public class RhondaNumbers {
    public static void main(String[] args) {
        final int limit = 15;
        for (int base = 2; base <= 36; ++base) {
            if (isPrime(base))
                continue;
            System.out.printf("First %d Rhonda numbers to base %d:\n", limit, base);
            int numbers[] = new int[limit];
            for (int n = 1, count = 0; count < limit; ++n) {
                if (isRhonda(base, n))
                    numbers[count++] = n;
            }
            System.out.printf("In base 10:");
            for (int i = 0; i < limit; ++i)
                System.out.printf(" %d", numbers[i]);
            System.out.printf("\nIn base %d:", base);
            for (int i = 0; i < limit; ++i)
                System.out.printf(" %s", Integer.toString(numbers[i], base));
            System.out.printf("\n\n");
        }
    }

    private static int digitProduct(int base, int n) {
        int product = 1;
        for (; n != 0; n /= base)
            product *= n % base;
        return product;
    }

    private static int primeFactorSum(int n) {
        int sum = 0;
        for (; (n & 1) == 0; n >>= 1)
            sum += 2;
        for (int p = 3; p * p <= n; p += 2)
            for (; n % p == 0; n /= p)
                sum += p;
        if (n > 1)
            sum += n;
        return sum;
    }

    private static boolean isPrime(int n) {
        if (n < 2)
            return false;
        if (n % 2 == 0)
            return n == 2;
        if (n % 3 == 0)
            return n == 3;
        for (int p = 5; p * p <= n; p += 4) {
            if (n % p == 0)
                return false;
            p += 2;
            if (n % p == 0)
                return false;
        }
        return true;
    }

    private static boolean isRhonda(int base, int n) {
        return digitProduct(base, n) == base * primeFactorSum(n);
    }
}


Roman numerals/Decode

Create a function that takes a Roman numeral as its argument and returns its value as a numeric decimal integer.

You don't need to validate the form of the Roman numeral.

Modern Roman numerals are written by expressing each decimal digit of the number to be encoded separately,
starting with the leftmost decimal digit and skipping any '''0'''s   (zeroes).

'''1990''' is rendered as   '''MCMXC'''     (1000 = M,   900 = CM,   90 = XC)     and
'''2008''' is rendered as   '''MMVIII'''       (2000 = MM,   8 = VIII).

The Roman numeral for '''1666''',   '''MDCLXVI''',   uses each letter in descending order.

Solution:
public class Roman {
	private static int decodeSingle(char letter) {
		switch(letter) {
			case 'M': return 1000;
			case 'D': return 500;
			case 'C': return 100;
			case 'L': return 50;
			case 'X': return 10;
			case 'V': return 5;
			case 'I': return 1;
			default: return 0;
		}
	}
	public static int decode(String roman) {
		int result = 0;
		String uRoman = roman.toUpperCase(); //case-insensitive
		for(int i = 0;i < uRoman.length() - 1;i++) {//loop over all but the last character
			//if this character has a lower value than the next character
			if (decodeSingle(uRoman.charAt(i)) < decodeSingle(uRoman.charAt(i+1))) {
				//subtract it
				result -= decodeSingle(uRoman.charAt(i));
			} else {
				//add it
				result += decodeSingle(uRoman.charAt(i));
			}
		}
		//decode the last character, which is always added
		result += decodeSingle(uRoman.charAt(uRoman.length()-1));
		return result;
	}

	public static void main(String[] args) {
		System.out.println(decode("MCMXC")); //1990
		System.out.println(decode("MMVIII")); //2008
		System.out.println(decode("MDCLXVI")); //1666
	}
}


Roman numerals/Decode

Solution:
import java.util.Set;
import java.util.EnumSet;
import java.util.Collections;
import java.util.stream.Collectors;
import java.util.stream.LongStream;

public interface RomanNumerals {
  public enum Numeral {
    M(1000), CM(900), D(500), CD(400), C(100), XC(90), L(50), XL(40), X(10), IX(9), V(5), IV(4), I(1);

    public final long weight;

    private static final Set<Numeral> SET = Collections.unmodifiableSet(EnumSet.allOf(Numeral.class));

    private Numeral(long weight) {
      this.weight = weight;
    }

    public static Numeral getLargest(long weight) {
      return SET.stream()
        .filter(numeral -> weight >= numeral.weight)
        .findFirst()
        .orElse(I)
      ;
    }
  };

  public static String encode(long n) {
    return LongStream.iterate(n, l -> l - Numeral.getLargest(l).weight)
      .limit(Numeral.values().length)
      .filter(l -> l > 0)
      .mapToObj(Numeral::getLargest)
      .map(String::valueOf)
      .collect(Collectors.joining())
    ;
  }

  public static long decode(String roman) {
    long result =  new StringBuilder(roman.toUpperCase()).reverse().chars()
      .mapToObj(c -> Character.toString((char) c))
      .map(numeral -> Enum.valueOf(Numeral.class, numeral))
      .mapToLong(numeral -> numeral.weight)
      .reduce(0, (a, b) -> a + (a <= b ? b : -b))
    ;
    if (roman.charAt(0) == roman.charAt(1)) {
      result += 2 * Enum.valueOf(Numeral.class, roman.substring(0, 1)).weight;
    }
    return result;
  }

  public static void test(long n) {
    System.out.println(n + " = " + encode(n));
    System.out.println(encode(n) + " = " + decode(encode(n)));
  }

  public static void main(String[] args) {
    LongStream.of(1999, 25, 944).forEach(RomanNumerals::test);
  }
}


Roman numerals/Encode

Create a function taking a positive integer as its parameter and returning a string containing the Roman numeral representation of that integer. Modern Roman numerals are written by expressing each digit separately, starting with the left most digit and skipping any digit with a value of zero.

In Roman numerals:
* 1990  is rendered: 1000=M, 900=CM, 90=XC; resulting in MCMXC
* 2008  is written as 2000=MM, 8=VIII; or MMVIII
* 1666  uses each Roman symbol in descending order: MDCLXVI

Solution: The conversion function throws an IllegalArgumentException for non-positive numbers, since Java does not have unsigned primitives.


Roman numerals/Encode

Solution:
public class RN {

    enum Numeral {
        I(1), IV(4), V(5), IX(9), X(10), XL(40), L(50), XC(90), C(100), CD(400), D(500), CM(900), M(1000);
        int weight;

        Numeral(int weight) {
            this.weight = weight;
        }
    };

    public static String roman(long n) {

        if( n <= 0) {
            throw new IllegalArgumentException();
        }

        StringBuilder buf = new StringBuilder();

        final Numeral[] values = Numeral.values();
        for (int i = values.length - 1; i >= 0; i--) {
            while (n >= values[i].weight) {
                buf.append(values[i]);
                n -= values[i].weight;
            }
        }
        return buf.toString();
    }

    public static void test(long n) {
        System.out.println(n + " = " + roman(n));
    }

    public static void main(String[] args) {
        test(1999);
        test(25);
        test(944);
        test(0);
    }

}


Roman numerals/Encode


Runge-Kutta method

Given the example Differential equation:
:y'(t) = t \times \sqrt {y(t)}
With initial condition:
:t_0 = 0 and y_0 = y(t_0) = y(0) = 1
This equation has an exact solution:
:y(t) = \tfrac{1}{16}(t^2 +4)^2

;Task
Demonstrate the commonly used explicit   fourth-order Runge-Kutta method   to solve the above differential equation.
* Solve the given differential equation over the range t = 0 \ldots 10 with a step value of \delta t=0.1 (101 total points, the first being given)
* Print the calculated values of y at whole numbered t's (0.0, 1.0, \ldots 10.0) along with error as compared to the exact solution.

;Method summary
Starting with a given y_n and t_n calculate:
:\delta y_1 = \delta t\times y'(t_n, y_n)\quad
:\delta y_2 = \delta t\times y'(t_n + \tfrac{1}{2}\delta t , y_n + \tfrac{1}{2}\delta y_1)
:\delta y_3 = \delta t\times y'(t_n + \tfrac{1}{2}\delta t , y_n + \tfrac{1}{2}\delta y_2)
:\delta y_4 = \delta t\times y'(t_n + \delta t , y_n + \delta y_3)\quad
then:
:y_{n+1} = y_n + \tfrac{1}{6} (\delta y_1 + 2\delta y_2 + 2\delta y_3 + \delta y_4)
:t_{n+1} = t_n + \delta t\quad

Solution: Translation of [[Runge-Kutta_method#Ada|Ada]] via [[Runge-Kutta_method#D|D]]


Runge-Kutta method

Solution:
import static java.lang.Math.*;
import java.util.function.BiFunction;

public class RungeKutta {

    static void runge(BiFunction<Double, Double, Double> yp_func, double[] t,
            double[] y, double dt) {

        for (int n = 0; n < t.length - 1; n++) {
            double dy1 = dt * yp_func.apply(t[n], y[n]);
            double dy2 = dt * yp_func.apply(t[n] + dt / 2.0, y[n] + dy1 / 2.0);
            double dy3 = dt * yp_func.apply(t[n] + dt / 2.0, y[n] + dy2 / 2.0);
            double dy4 = dt * yp_func.apply(t[n] + dt, y[n] + dy3);
            t[n + 1] = t[n] + dt;
            y[n + 1] = y[n] + (dy1 + 2.0 * (dy2 + dy3) + dy4) / 6.0;
        }
    }

    static double calc_err(double t, double calc) {
        double actual = pow(pow(t, 2.0) + 4.0, 2) / 16.0;
        return abs(actual - calc);
    }

    public static void main(String[] args) {
        double dt = 0.10;
        double[] t_arr = new double[101];
        double[] y_arr = new double[101];
        y_arr[0] = 1.0;

        runge((t, y) -> t * sqrt(y), t_arr, y_arr, dt);

        for (int i = 0; i < t_arr.length; i++)
            if (i % 10 == 0)
                System.out.printf("y(%.1f) = %.8f Error: %.6f%n",
                        t_arr[i], y_arr[i],
                        calc_err(t_arr[i], y_arr[i]));
    }
}


Runtime evaluation

Demonstrate a language's ability for programs to execute code written in the language provided at runtime.

Show what kind of program fragments are permitted (e.g. expressions vs. statements), and how to get values in and out (e.g. environments, arguments, return values), if applicable what lexical/static environment the program is evaluated in, and what facilities for restricting (e.g. sandboxes, resource limits) or customizing (e.g. debugging facilities) the execution.

You may not invoke a separate evaluator program, or invoke a compiler and then its output, unless the interface of that program, and the syntax and means of executing it, are considered part of your language/library/platform.

For a more constrained task giving a specific program fragment to evaluate, see [[Eval in environment]].

Solution:
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.lang.reflect.InvocationTargetException;
import java.net.URI;
import java.util.HashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import javax.tools.FileObject;
import javax.tools.ForwardingJavaFileManager;
import javax.tools.JavaCompiler;
import javax.tools.JavaFileObject;
import javax.tools.SimpleJavaFileObject;
import javax.tools.StandardJavaFileManager;
import javax.tools.StandardLocation;
import javax.tools.ToolProvider;

public class Evaluator{
    public static void main(String[] args){
        new Evaluator().eval(
            "SayHello",
            "public class SayHello{public void speak(){System.out.println(\"Hello world\");}}",
            "speak"
        );
    }

    void eval(String className, String classCode, String methodName){
        Map<String, ByteArrayOutputStream> classCache = new HashMap<>();
        JavaCompiler                       compiler   = ToolProvider.getSystemJavaCompiler();

        if ( null == compiler )
            throw new RuntimeException("Could not get a compiler.");

        StandardJavaFileManager                            sfm  = compiler.getStandardFileManager(null, null, null);
        ForwardingJavaFileManager<StandardJavaFileManager> fjfm = new ForwardingJavaFileManager<StandardJavaFileManager>(sfm){
            @Override
            public JavaFileObject getJavaFileForOutput(Location location, String className, JavaFileObject.Kind kind, FileObject sibling)
                    throws IOException{
                if (StandardLocation.CLASS_OUTPUT == location && JavaFileObject.Kind.CLASS == kind)
                    return new SimpleJavaFileObject(URI.create("mem:///" + className + ".class"), JavaFileObject.Kind.CLASS){
                        @Override
                        public OutputStream openOutputStream()
                                throws IOException{
                            ByteArrayOutputStream baos = new ByteArrayOutputStream();
                            classCache.put(className, baos);
                            return baos;
                        }
                    };
                else
                    throw new IllegalArgumentException("Unexpected output file requested: " + location + ", " + className + ", " + kind);
            }
        };
        List<JavaFileObject> files = new LinkedList<JavaFileObject>(){{
            add(
                new SimpleJavaFileObject(URI.create("string:///" + className + ".java"), JavaFileObject.Kind.SOURCE){
                    @Override
                    public CharSequence getCharContent(boolean ignoreEncodingErrors){
                        return classCode;
                    }
                }
            );
        }};

        // Now we can compile!
        compiler.getTask(null, fjfm, null, null, null, files).call();

        try{
            Class<?> clarse = new ClassLoader(){
                @Override
                public Class<?> findClass(String name){
                    if (! name.startsWith(className))
                        throw new IllegalArgumentException("This class loader is for " + className + " - could not handle \"" + name + '"');
                    byte[] bytes = classCache.get(name).toByteArray();
                    return defineClass(name, bytes, 0, bytes.length);
                }
            }.loadClass(className);

            // Invoke a method on the thing we compiled
            clarse.getMethod(methodName).invoke(clarse.newInstance());

        }catch(ClassNotFoundException | InstantiationException | IllegalAccessException | NoSuchMethodException | InvocationTargetException x){
            throw new RuntimeException("Run failed: " + x, x);
        }
    }
}


Runtime evaluation/In an environment

Given a program in the language (as a string or AST) with a free variable named x (or another name if that is not valid syntax), evaluate it with x bound to a provided value, then evaluate it again with x bound to another provided value, then subtract the result of the first from the second and return or print it.

Do so in a way which:
* does not involve string manipulation of the input source code
* is plausibly extensible to a runtime-chosen set of bindings rather than just x
* does not make x a ''global'' variable

or note that these are impossible.

;See also:
* For more general examples and language-specific details, see [[Eval]].
* [[Dynamic variable names]] is a similar task.

Solution:
import java.io.File;
import java.lang.reflect.Method;
import java.net.URI;
import java.util.Arrays;
import javax.tools.JavaCompiler;
import javax.tools.SimpleJavaFileObject;
import javax.tools.ToolProvider;

public class Eval {
    private static final String CLASS_NAME = "TempPleaseDeleteMe";

    private static class StringCompiler
            extends SimpleJavaFileObject {
        final String m_sourceCode;

        private StringCompiler( final String sourceCode ) {
            super( URI.create( "string:///" + CLASS_NAME + Kind.SOURCE.extension ), Kind.SOURCE );
            m_sourceCode = sourceCode;
        }

        @Override
        public CharSequence getCharContent( final boolean ignoreEncodingErrors ) {
            return m_sourceCode;
        }

        private boolean compile() {
            final JavaCompiler javac = ToolProvider.getSystemJavaCompiler();

            return javac.getTask( null, javac.getStandardFileManager( null, null, null ),
                null, null, null, Arrays.asList( this )
            ).call();
        }

        private double callEval( final double x )
                throws Exception {
            final Class<?> clarse = Class.forName( CLASS_NAME );
            final Method   eval   = clarse.getMethod( "eval", double.class );

            return ( Double ) eval.invoke( null, x );
        }
    }

    public static double evalWithX( final String code, final double x )
            throws Exception {
        final StringCompiler sc = new StringCompiler(
            "class "
                + CLASS_NAME
                + "{public static double eval(double x){return ("
                + code
                + ");}}"
            );

        if ( ! sc.compile() ) throw new RuntimeException( "Compiler error" );
        return sc.callEval( x );
    }

    public static void main( final String [] args )
            throws Exception /* lazy programmer */ {
        final String expression = args [ 0 ];
        final double x1         = Double.parseDouble( args [ 1 ] );
        final double x2         = Double.parseDouble( args [ 2 ] );

        System.out.println(
            evalWithX( expression, x1 )
            - evalWithX( expression, x2 )
        );
    }
}


Ruth-Aaron numbers

A '''Ruth-Aaron''' pair consists of two consecutive integers (e.g., 714 and 715) for which the sums of the prime divisors of each integer are equal. So called because 714 is Babe Ruth's lifetime home run record; Hank Aaron's 715th home run broke this record and 714 and 715 have the same prime divisor sum.

A '''Ruth-Aaron''' triple consists of '''''three''''' consecutive integers with the same properties.

There is a second variant of '''Ruth-Aaron''' numbers, one which uses prime ''factors'' rather than prime ''divisors''. The difference; divisors are unique, factors may be repeated. The 714, 715 pair appears in both, so the name still fits.

It is common to refer to each '''Ruth-Aaron''' group by the first number in it.

;Task

* Find and show, here on this page, the first '''30''' '''Ruth-Aaron numbers''' (factors).

* Find and show, here on this page, the first '''30''' '''Ruth-Aaron numbers''' (divisors).

;Stretch

* Find and show the first '''Ruth-Aaron triple''' (factors).

* Find and show the first '''Ruth-Aaron triple''' (divisors).

;See also

;*Wikipedia: Ruth-Aaron pair
;*OEIS:A006145 - Ruth-Aaron numbers (1): sum of prime divisors of n = sum of prime divisors of n+1
;*OEIS:A039752 - Ruth-Aaron numbers (2): sum of prime divisors of n = sum of prime divisors of n+1 (both taken with multiplicity)

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

public final class RuthAaronNumbers {

	public static void main(String[] aArgs) {
		System.out.println("The first 30 Ruth-Aaron numbers (factors):");
	    firstRuthAaronNumbers(30, NumberType.FACTOR);

	    System.out.println("The first 30 Ruth-Aaron numbers (divisors):");
	    firstRuthAaronNumbers(30, NumberType.DIVISOR);

	    System.out.println("First Ruth-Aaron triple (factors): " + firstRuthAaronTriple(NumberType.FACTOR));
		System.out.println();

		System.out.println("First Ruth-Aaron triple (divisors): " + firstRuthAaronTriple(NumberType.DIVISOR));
		System.out.println();
	}

	private enum NumberType { DIVISOR, FACTOR }

	private static void firstRuthAaronNumbers(int aCount, NumberType aNumberType) {
		primeSumOne = 0;
		primeSumTwo = 0;

		for ( int n = 2, count = 0; count < aCount; n++ ) {
	        primeSumTwo = switch ( aNumberType ) {
	        	case DIVISOR -> primeDivisorSum(n);
	        	case FACTOR -> primeFactorSum(n);
	        };

	        if ( primeSumOne == primeSumTwo ) {
	            count += 1;
	            System.out.print(String.format("%6d", n - 1));
	            if ( count == aCount / 2 ) {
	            	System.out.println();
	            }
	        }

	        primeSumOne = primeSumTwo;
	    }

		System.out.println();
		System.out.println();
	}

	private static int firstRuthAaronTriple(NumberType aNumberType) {
		primeSumOne = 0;
		primeSumTwo = 0;
		primeSumThree = 0;

		int n = 2;
		boolean found = false;
		while ( ! found ) {
			primeSumThree = switch ( aNumberType ) {
				case DIVISOR -> primeDivisorSum(n);
				case FACTOR -> primeFactorSum(n);
			};

			if ( primeSumOne == primeSumTwo && primeSumTwo == primeSumThree ) {
				found = true;
			}

			n += 1;
			primeSumOne = primeSumTwo;
			primeSumTwo = primeSumThree;
		}

		return n - 2;
	}

	private static int primeDivisorSum(int aNumber) {
		return primeSum(aNumber, new HashSet<Integer>());
	}

	private static int primeFactorSum(int aNumber) {
		return primeSum(aNumber, new ArrayList<Integer>());
	}

	private static int primeSum(int aNumber, Collection<Integer> aCollection) {
		Collection<Integer> values = aCollection;

		for ( int i = 0, prime = 2; prime * prime <= aNumber; i++ ) {
			while ( aNumber % prime == 0 ) {
				aNumber /= prime;
				values.add(prime);
			}
			prime = primes.get(i + 1);
		}

		if ( aNumber > 1 ) {
			values.add(aNumber);
		}

		return values.stream().reduce(0, ( l, r ) -> l + r );
	}

	private static List<Integer> listPrimeNumbersUpTo(int aNumber) {
		BitSet sieve = new BitSet(aNumber + 1);
		sieve.set(2, aNumber + 1);

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

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

		return result;
	}

	private static int primeSumOne, primeSumTwo, primeSumThree;
	private static List<Integer> primes = listPrimeNumbersUpTo(50_000);

}


SHA-1

'''SHA-1''' or '''SHA1''' is a one-way hash function;
it computes a 160-bit message digest.
SHA-1 often appears in security protocols; for example,
many HTTPS websites use RSA with SHA-1 to secure their connections.
BitTorrent uses SHA-1 to verify downloads.
Git and Mercurial use SHA-1 digests to identify commits.

A US government standard, FIPS 180-1, defines SHA-1.

Find the SHA-1 message digest for a string of [[octet]]s. You may either call a SHA-1 library, or implement SHA-1 in your language. Both approaches interest Rosetta Code.

{{alertbox|lightgray|'''Warning:''' SHA-1 has known weaknesses. Theoretical attacks may find a collision after 252 operations, or perhaps fewer.
This is much faster than a brute force attack of 280 operations. USgovernment deprecated SHA-1.
For production-grade cryptography, users may consider a stronger alternative, such as SHA-256 (from the SHA-2 family) or the upcoming SHA-3.}}

Solution: The solution to this task would be a small modification to [[MD5#Java|MD5]] (replacing "MD5" with "SHA-1" as noted [http://docs.oracle.com/javase/7/docs/technotes/guides/security/StandardNames.html#MessageDigest here]).


Sailors, coconuts and a monkey problem

Five sailors are shipwrecked on an island and collect a large pile of coconuts during the day.

That night the first sailor wakes up and decides to take his first share early  so tries to divide the pile of coconuts equally into five piles but finds that there is one coconut left over, so he tosses it to a monkey and then hides "his" one of the five equally sized piles of coconuts and pushes the other four piles together to form a single visible pile of coconuts again and goes to bed.

To cut a long story short, each of the sailors in turn gets up once during the night and performs the same actions of dividing the coconut pile into five, finding that one coconut is left over and giving that single remainder coconut to the monkey.

In the morning (after the surreptitious and separate action of each of the five sailors during the night), the remaining coconuts are divided into five equal piles for each of the sailors, whereupon it is found that the pile of coconuts divides equally amongst the sailors with no remainder. (Nothing for the monkey in the morning.)

;The task:
# Calculate the minimum possible size of the initial pile of coconuts collected during the first day.
# Use a method that assumes an answer is possible, and then applies the constraints of the tale to see if it is correct. (I.e. no applying some formula that generates the correct answer without integer divisions and remainders and tests on remainders; but constraint solvers ''are'' allowed.)
# Calculate the size of the initial pile of coconuts if six sailors were marooned and went through a similar process (but split into six piles instead of five of course).
# Show your answers here.

;Extra credit (optional):
* Give some indication of the number of coconuts each sailor hides during the night.

;Note:
* Of course the tale is told in a world where the collection of any amount of coconuts in a day and multiple divisions of the pile, etc can occur in time fitting the story line, so as not to affect the mathematics.
* The tale is also told in a version where the monkey also gets a coconut in the morning. This is ''not'' that tale!

;C.f:
* Monkeys and Coconuts - Numberphile (Video) Analytical solution.
* A002021: Pile of coconuts problem The On-Line Encyclopedia of Integer Sequences. (Although some of its references may use the alternate form of the tale).

Solution:
public class Test {

    static boolean valid(int n, int nuts) {
        for (int k = n; k != 0; k--, nuts -= 1 + nuts / n)
            if (nuts % n != 1)
                return false;
        return nuts != 0 && (nuts % n == 0);
    }

    public static void main(String[] args) {
        int x = 0;
        for (int n = 2; n < 10; n++) {
            while (!valid(n, x))
                x++;
            System.out.printf("%d: %d%n", n, x);
        }
    }
}


Same fringe

Write a routine that will compare the leaves ("fringe") of two binary trees to determine whether they are the same list of leaves when visited left-to-right.  The structure or balance of the trees does not matter; only the number, order, and value of the leaves is important.

Any solution is allowed here, but many computer scientists will consider it inelegant to collect either fringe in its entirety before starting to collect the other one.  In fact, this problem is usually proposed in various forums as a way to show off various forms of concurrency (tree-rotation algorithms have also been used to get around the need to collect one tree first).  Thinking of it a slightly different way, an elegant solution is one that can perform the minimum amount of work to falsify the equivalence of the fringes when they differ somewhere in the middle, short-circuiting the unnecessary additional traversals and comparisons.

Any representation of a binary tree is allowed, as long as the nodes are orderable, and only downward links are used (for example, you may not use parent or sibling pointers to avoid recursion).

Solution:
import java.util.*;

class SameFringe
{
  public interface Node<T extends Comparable<? super T>>
  {
    Node<T> getLeft();
    Node<T> getRight();
    boolean isLeaf();
    T getData();
  }

  public static class SimpleNode<T extends Comparable<? super T>> implements Node<T>
  {
    private final T data;
    public SimpleNode<T> left;
    public SimpleNode<T> right;

    public SimpleNode(T data)
    {  this(data, null, null);  }

    public SimpleNode(T data, SimpleNode<T> left, SimpleNode<T> right)
    {
      this.data = data;
      this.left = left;
      this.right = right;
    }

    public Node<T> getLeft()
    {  return left;  }

    public Node<T> getRight()
    {  return right;  }

    public boolean isLeaf()
    {  return ((left == null) && (right == null));  }

    public T getData()
    {  return data;  }

    public SimpleNode<T> addToTree(T data)
    {
      int cmp = data.compareTo(this.data);
      if (cmp == 0)
        throw new IllegalArgumentException("Same data!");
      if (cmp < 0)
      {
        if (left == null)
          return (left = new SimpleNode<T>(data));
        return left.addToTree(data);
      }
      if (right == null)
        return (right = new SimpleNode<T>(data));
      return right.addToTree(data);
    }
  }

  public static <T extends Comparable<? super T>> boolean areLeavesSame(Node<T> node1, Node<T> node2)
  {
    Stack<Node<T>> stack1 = new Stack<Node<T>>();
    Stack<Node<T>> stack2 = new Stack<Node<T>>();
    stack1.push(node1);
    stack2.push(node2);
    // NOT using short-circuit operator
    while (((node1 = advanceToLeaf(stack1)) != null) & ((node2 = advanceToLeaf(stack2)) != null))
      if (!node1.getData().equals(node2.getData()))
        return false;
    // Return true if finished at same time
    return (node1 == null) && (node2 == null);
  }

  private static <T extends Comparable<? super T>> Node<T> advanceToLeaf(Stack<Node<T>> stack)
  {
    while (!stack.isEmpty())
    {
      Node<T> node = stack.pop();
      if (node.isLeaf())
        return node;
      Node<T> rightNode = node.getRight();
      if (rightNode != null)
        stack.push(rightNode);
      Node<T> leftNode = node.getLeft();
      if (leftNode != null)
        stack.push(leftNode);
    }
    return null;
  }

  public static void main(String[] args)
  {
    SimpleNode<Integer> headNode1 = new SimpleNode<Integer>(35, new SimpleNode<Integer>(25, new SimpleNode<Integer>(15, new SimpleNode<Integer>(10), new SimpleNode<Integer>(20)), new SimpleNode<Integer>(30)), new SimpleNode<Integer>(45, new SimpleNode<Integer>(40), new SimpleNode<Integer>(50)));
    SimpleNode<Integer> headNode2 = new SimpleNode<Integer>(24, new SimpleNode<Integer>(14, new SimpleNode<Integer>(10), new SimpleNode<Integer>(16, null, new SimpleNode<Integer>(20))), new SimpleNode<Integer>(34, new SimpleNode<Integer>(30), new SimpleNode<Integer>(42, new SimpleNode<Integer>(40), new SimpleNode<Integer>(56, new SimpleNode<Integer>(50), null))));
    SimpleNode<Integer> headNode3 = new SimpleNode<Integer>(24, new SimpleNode<Integer>(14, new SimpleNode<Integer>(10), new SimpleNode<Integer>(16, null, new SimpleNode<Integer>(20))), new SimpleNode<Integer>(34, new SimpleNode<Integer>(30), new SimpleNode<Integer>(42, new SimpleNode<Integer>(40), new SimpleNode<Integer>(50, null, new SimpleNode<Integer>(56)))));
    System.out.print("Leaves for set 1: ");
    simpleWalk(headNode1);
    System.out.println();
    System.out.print("Leaves for set 2: ");
    simpleWalk(headNode2);
    System.out.println();
    System.out.print("Leaves for set 3: ");
    simpleWalk(headNode3);
    System.out.println();
    System.out.println("areLeavesSame(1, 2)? " + areLeavesSame(headNode1, headNode2));
    System.out.println("areLeavesSame(2, 3)? " + areLeavesSame(headNode2, headNode3));
  }

  public static void simpleWalk(Node<Integer> node)
  {
    if (node.isLeaf())
      System.out.print(node.getData() + " ");
    else
    {
      Node<Integer> left = node.getLeft();
      if (left != null)
        simpleWalk(left);
      Node<Integer> right = node.getRight();
      if (right != null)
        simpleWalk(right);
    }
  }
}


Selectively replace multiple instances of a character within a string

Task
This is admittedly a trivial task but I thought it would be interesting to see how succinctly (or otherwise) different languages can handle it.

Given the string: "abracadabra", replace programatically:

* the first 'a' with 'A'
* the second 'a' with 'B'
* the fourth 'a' with 'C'
* the fifth 'a' with 'D'
* the first 'b' with 'E'
* the second 'r' with 'F'

Note that there is no replacement for the third 'a', second 'b' or first 'r'.

The answer should, of course, be : "AErBcadCbFD".

Solution:
int findNth(String s, char c, int n) {
    if (n == 1) return s.indexOf(c);
    return s.indexOf(c, findNth(s, c, n - 1) + 1);
}

String selectiveReplace(String s, Set... ops) {
    char[] chars = s.toCharArray();
    for (Set set : ops)
        chars[findNth(s, set.old, set.n)] = set.rep;
    return new String(chars);
}

record Set(int n, char old, char rep) { }


Self-describing numbers

{{task}}There are several so-called "self-describing" or "self-descriptive" integers.

An integer is said to be "self-describing" if it has the property that, when digit positions are labeled 0 to N-1, the digit in each position is equal to the number of times that that digit appears in the number.

For example,   '''2020'''   is a four-digit self describing number:

*   position   0   has value   2   and there are two 0s in the number;
*   position   1   has value   0   and there are no 1s in the number;
*   position   2   has value   2   and there are two 2s;
*   position   3   has value   0   and there are zero 3s.

Self-describing numbers < 100.000.000  are:     1210,   2020,   21200,   3211000,   42101000.

;Task Description
# Write a function/routine/method/... that will check whether a given positive integer is self-describing.
# As an optional stretch goal - generate and display the set of self-describing numbers.

;Related tasks:
*   [[Fours is the number of letters in the ...]]
*   [[Look-and-say sequence]]
*   [[Number names]]
*   [[Self-referential sequence]]
*   [[Spelling of ordinal numbers]]

Solution:
public class SelfDescribingNumbers{
    public static boolean isSelfDescribing(int a){
        String s = Integer.toString(a);
        for(int i = 0; i < s.length(); i++){
            String s0 = s.charAt(i) + "";
            int b = Integer.parseInt(s0); // number of times i-th digit must occur for it to be a self describing number
            int count = 0;
            for(int j = 0; j < s.length(); j++){
                int temp = Integer.parseInt(s.charAt(j) + "");
                if(temp == i){
                    count++;
                }
                if (count > b) return false;
            }
            if(count != b) return false;
        }
        return true;
    }

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


Self numbers

A number n is a self number if there is no number g such that g + the sum of g's digits = n. So 18 is not a self number because 9+9=18, 43 is not a self number because 35+5+3=43.

The task is:
  Display the first 50 self numbers;
  I believe that the 100000000th self number is 1022727208. You should either confirm or dispute my conjecture.

224036583-1 is a Mersenne prime, claimed to also be a self number. Extra credit to anyone proving it.

;See also:

;*OEIS: A003052 - Self numbers or Colombian numbers
;*Wikipedia: Self numbers

Solution:
public class SelfNumbers {
    private static final int MC = 103 * 1000 * 10000 + 11 * 9 + 1;
    private static final boolean[] SV = new boolean[MC + 1];

    private static void sieve() {
        int[] dS = new int[10_000];
        for (int a = 9, i = 9999; a >= 0; a--) {
            for (int b = 9; b >= 0; b--) {
                for (int c = 9, s = a + b; c >= 0; c--) {
                    for (int d = 9, t = s + c; d >= 0; d--) {
                        dS[i--] = t + d;
                    }
                }
            }
        }
        for (int a = 0, n = 0; a < 103; a++) {
            for (int b = 0, d = dS[a]; b < 1000; b++, n += 10000) {
                for (int c = 0, s = d + dS[b] + n; c < 10000; c++) {
                    SV[dS[c] + s++] = true;
                }
            }
        }
    }

    public static void main(String[] args) {
        sieve();
        System.out.println("The first 50 self numbers are:");
        for (int i = 0, count = 0; count <= 50; i++) {
            if (!SV[i]) {
                count++;
                if (count <= 50) {
                    System.out.printf("%d ", i);
                } else {
                    System.out.printf("%n%n       Index     Self number%n");
                }
            }
        }
        for (int i = 0, limit = 1, count = 0; i < MC; i++) {
            if (!SV[i]) {
                if (++count == limit) {
                    System.out.printf("%,12d   %,13d%n", count, i);
                    limit *= 10;
                }
            }
        }
    }
}


Semordnilap

A semordnilap is a word (or phrase) that spells a different word (or phrase) backward. "Semordnilap" is a word that itself is a semordnilap.

Example: ''lager'' and ''regal''

;Task
This task does not consider semordnilap phrases, only single words.
Using only words from this list, report the total number of unique semordnilap pairs, and print 5 examples.
Two matching semordnilaps, such as ''lager'' and ''regal'', should be counted as one unique pair.
(Note that the word "semordnilap" is not in the above dictionary.)

Solution:
import java.nio.file.*;
import java.util.*;

public class Semordnilap {

    public static void main(String[] args) throws Exception {
        List<String> lst = Files.readAllLines(Paths.get("unixdict.txt"));
        Set<String> seen = new HashSet<>();
        int count = 0;
        for (String w : lst) {
            w = w.toLowerCase();
            String r = new StringBuilder(w).reverse().toString();
            if (seen.contains(r)) {
                if (count++ < 5)
                    System.out.printf("%-10s %-10s\n", w, r);
            } else seen.add(w);
        }
        System.out.println("\nSemordnilap pairs found: " + count);
    }
}


Sequence: nth number with exactly n divisors

Calculate the sequence where each term an is the nth that has '''n''' divisors.

;Task

Show here, on this page, at least the first '''15''' terms of the sequence.

;See also

:*OEIS:A073916

;Related tasks

:*[[Sequence: smallest number greater than previous term with exactly n divisors]]
:*[[Sequence: smallest number with exactly n divisors]]

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

public class SequenceNthNumberWithExactlyNDivisors {

    public static void main(String[] args) {
        int max = 45;
        smallPrimes(max);
        for ( int n = 1; n <= max ; n++ ) {
            System.out.printf("A073916(%d) = %s%n", n, OEISA073916(n));
        }
    }

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

    private static void smallPrimes(int numPrimes) {
        smallPrimes.add(2);
        for ( int n = 3, count = 0 ; count < numPrimes ; n += 2 ) {
            if ( isPrime(n) ) {
                smallPrimes.add(n);
                count++;
            }
        }
    }

    private static final boolean isPrime(long test) {
        if ( test == 2 ) {
            return true;
        }
        if ( test % 2 == 0 ) {
            return false;
        }
        for ( long d = 3 ; d*d <= test ; d += 2 ) {
            if ( test % d == 0 ) {
                return false;
            }
        }
        return true;
    }

    private static int getDivisorCount(long n) {
        int count = 1;
        while ( n % 2 == 0 ) {
            n /= 2;
            count += 1;
        }
        for ( long d = 3 ; d*d <= n ; d += 2 ) {
            long q = n / d;
            long r = n % d;
            int dc = 0;
            while ( r == 0 ) {
                dc += count;
                n = q;
                q = n / d;
                r = n % d;
            }
            count += dc;
        }
        if ( n != 1 ) {
            count *= 2;
        }
        return count;
    }

    private static BigInteger OEISA073916(int n) {
        if ( isPrime(n) ) {
            return BigInteger.valueOf(smallPrimes.get(n-1)).pow(n - 1);
        }
        int count = 0;
        int result = 0;
        for ( int i = 1 ; count < n ; i++ ) {
            if ( n % 2 == 1 ) {
                //  The solution for an odd (non-prime) term is always a square number
                int sqrt = (int) Math.sqrt(i);
                if ( sqrt*sqrt != i ) {
                    continue;
                }
            }
            if ( getDivisorCount(i) == n ) {
                count++;
                result = i;
            }
        }
        return BigInteger.valueOf(result);
    }

}


Sequence: smallest number greater than previous term with exactly n divisors

Calculate the sequence where each term an is the '''smallest natural number''' greater than the previous term, that has exactly '''n''' divisors.

;Task
Show here, on this page, at least the first '''15''' terms of the sequence.

;See also
:* OEIS:A069654

;Related tasks
:* [[Sequence: smallest number with exactly n divisors]]
:* [[Sequence: nth number with exactly n divisors]]

Solution:
public class AntiPrimesPlus {

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

    public static void main(String[] args) {
        final int max = 15;
        System.out.printf("The first %d terms of the sequence are:\n", max);
        for (int i = 1, next = 1; next <= max; ++i) {
            if (next == count_divisors(i)) {
                System.out.printf("%d ", i);
                next++;
            }
        }
        System.out.println();
    }
}


Sequence: smallest number with exactly n divisors

Calculate the sequence where each term   an   is the '''smallest natural number''' that has exactly   '''n'''   divisors.

;Task
Show here, on this page, at least the first  '''15'''  terms of the sequence.

;Related tasks:
:* [[Sequence: smallest number greater than previous term with exactly n divisors]]
:* [[Sequence: nth number with exactly n divisors]]

;See also:
:* OEIS:A005179

Solution:
import java.util.Arrays;

public class OEIS_A005179 {

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

    public static void main(String[] args) {
        final int max = 15;
        int[] seq = new int[max];
        System.out.printf("The first %d terms of the sequence are:\n", max);
        for (int i = 1, n = 0; n < max; ++i) {
            int k = count_divisors(i);
            if (k <= max && seq[k - 1] == 0) {
                seq[k- 1] = i;
                n++;
            }
        }
        System.out.println(Arrays.toString(seq));
    }
}


Set consolidation

Given two sets of items then if any item is common to any set then the result of applying ''consolidation'' to those sets is a set of sets whose contents is:
*  The two input sets if no common item exists between the two input sets of items.
*  The single set that is the union of the two input sets if they share a common item.

Given N sets of items where N>2 then the result is the same as repeatedly replacing all combinations of two sets by their consolidation until no further consolidation between set pairs is possible.
If N<2 then consolidation has no strict meaning and the input can be returned.

;'''Example 1:'''
:Given the two sets {A,B} and {C,D} then there is no common element between the sets and the result is the same as the input.
;'''Example 2:'''
:Given the two sets {A,B} and {B,D} then there is a common element B between the sets and the result is the single set {B,D,A}.  (Note that order of items in a set is immaterial: {A,B,D} is the same as {B,D,A} and {D,A,B}, etc).
;'''Example 3:'''
:Given the three sets {A,B} and {C,D} and {D,B} then there is no common element between the sets {A,B} and {C,D} but the sets {A,B} and {D,B} do share a common element that consolidates to produce the result {B,D,A}. On examining this result with the remaining set, {C,D}, they share a common element and so consolidate to the final output of the single set {A,B,C,D}
;'''Example 4:'''
:The consolidation of the five sets:
::{H,I,K}, {A,B}, {C,D}, {D,B}, and {F,G,H}
:Is the two sets:
::{A, C, B, D}, and {G, F, I, H, K}

'''See also'''
* Connected component (graph theory)
* [[Range consolidation]]

Solution:
import java.util.*;

public class SetConsolidation {

    public static void main(String[] args) {
        List<Set<Character>> h1 = hashSetList("AB", "CD");
        System.out.println(consolidate(h1));

        List<Set<Character>> h2 = hashSetList("AB", "BD");
        System.out.println(consolidateR(h2));

        List<Set<Character>> h3 = hashSetList("AB", "CD", "DB");
        System.out.println(consolidate(h3));

        List<Set<Character>> h4 = hashSetList("HIK", "AB", "CD", "DB", "FGH");
        System.out.println(consolidateR(h4));
    }

    // iterative
    private static <E> List<Set<E>>
                consolidate(Collection<? extends Set<E>> sets) {
	List<Set<E>> r = new ArrayList<>();
	for (Set<E> s : sets) {
	    List<Set<E>> new_r = new ArrayList<>();
	    new_r.add(s);
	    for (Set<E> x : r) {
		if (!Collections.disjoint(s, x)) {
		    s.addAll(x);
		} else {
		    new_r.add(x);
		}
	    }
	    r = new_r;
	}
	return r;
    }

    // recursive
    private static <E> List<Set<E>> consolidateR(List<Set<E>> sets) {
        if (sets.size() < 2)
            return sets;
        List<Set<E>> r = new ArrayList<>();
        r.add(sets.get(0));
        for (Set<E> x : consolidateR(sets.subList(1, sets.size()))) {
            if (!Collections.disjoint(r.get(0), x)) {
                r.get(0).addAll(x);
            } else {
                r.add(x);
            }
        }
        return r;
    }

    private static List<Set<Character>> hashSetList(String... set) {
        List<Set<Character>> r = new ArrayList<>();
        for (int i = 0; i < set.length; i++) {
            r.add(new HashSet<Character>());
            for (int j = 0; j < set[i].length(); j++)
                r.get(i).add(set[i].charAt(j));
        }
        return r;
    }
}


Set of real numbers

All real numbers form the uncountable set R.  Among its subsets, relatively simple are the convex sets, each expressed as a range between two real numbers ''a'' and ''b'' where ''a'' <= ''b''.  There are actually four cases for the meaning of "between", depending on open or closed boundary:
* [''a'', ''b'']: {''x'' | ''a'' <= ''x'' and ''x'' <= ''b'' }
* (''a'', ''b''): {''x'' | ''a'' < ''x'' and ''x'' < ''b'' }
* [''a'', ''b''): {''x'' | ''a'' <= ''x'' and ''x'' < ''b'' }
* (''a'', ''b'']: {''x'' | ''a'' < ''x'' and ''x'' <= ''b'' }
Note that if ''a'' = ''b'', of the four only [''a'', ''a''] would be non-empty.

'''Task'''
* Devise a way to represent any set of real numbers, for the definition of 'any' in the implementation notes below.
* Provide methods for these common set operations (''x'' is a real number; ''A'' and ''B'' are sets):
:* ''x''  ''A'': determine if ''x'' is an element of ''A''
:: example: 1 is in [1, 2), while 2, 3, ... are not.
:* ''A''  ''B'': union of ''A'' and ''B'', i.e. {''x'' | ''x''  ''A'' or ''x''  ''B''}
:: example: [0, 2)  (1, 3) = [0, 3); [0, 1)  (2, 3] = well, [0, 1)  (2, 3]
:* ''A''  ''B'': intersection of ''A'' and ''B'', i.e. {''x'' | ''x''  ''A'' and ''x''  ''B''}
:: example: [0, 2)  (1, 3) = (1, 2); [0, 1)  (2, 3] = empty set
:* ''A'' - ''B'': difference between ''A'' and ''B'', also written as ''A'' \ ''B'', i.e. {''x'' | ''x''  ''A'' and ''x''  ''B''}
:: example: [0, 2) - (1, 3) = [0, 1]
* Test your implementation by checking if numbers 0, 1, and 2 are in any of the following sets:
:* (0, 1]  [0, 2)
:* [0, 2)  (1, 2]
:* [0, 3) - (0, 1)
:* [0, 3) - [0, 1]

'''Implementation notes'''
* 'Any' real set means 'sets that can be expressed as the union of a finite number of convex real sets'.  Cantor's set needs not apply.
* Infinities should be handled gracefully; indeterminate numbers (NaN) can be ignored.
* You can use your machine's native real number representation, which is probably IEEE floating point, and assume it's good enough (it usually is).

'''Optional work'''
* Create a function to determine if a given set is empty (contains no element).
* Define ''A'' = {''x'' | 0 < ''x'' < 10 and |sin(p ''x''2)| > 1/2 }, ''B'' = {''x'' | 0 < ''x'' < 10 and |sin(p ''x'')| > 1/2}, calculate the length of the real axis covered by the set ''A'' - ''B''.  Note that
|sin(p ''x'')| > 1/2 is the same as ''n'' + 1/6 < ''x'' < ''n'' + 5/6 for all integers ''n''; your program does not need to derive this by itself.

Solution:
import java.util.Objects;
import java.util.function.Predicate;

public class RealNumberSet {
    public enum RangeType {
        CLOSED,
        BOTH_OPEN,
        LEFT_OPEN,
        RIGHT_OPEN,
    }

    public static class RealSet {
        private Double low;
        private Double high;
        private Predicate<Double> predicate;
        private double interval = 0.00001;

        public RealSet(Double low, Double high, Predicate<Double> predicate) {
            this.low = low;
            this.high = high;
            this.predicate = predicate;
        }

        public RealSet(Double start, Double end, RangeType rangeType) {
            this(start, end, d -> {
                switch (rangeType) {
                    case CLOSED:
                        return start <= d && d <= end;
                    case BOTH_OPEN:
                        return start < d && d < end;
                    case LEFT_OPEN:
                        return start < d && d <= end;
                    case RIGHT_OPEN:
                        return start <= d && d < end;
                    default:
                        throw new IllegalStateException("Unhandled range type encountered.");
                }
            });
        }

        public boolean contains(Double d) {
            return predicate.test(d);
        }

        public RealSet union(RealSet other) {
            double low2 = Math.min(low, other.low);
            double high2 = Math.max(high, other.high);
            return new RealSet(low2, high2, d -> predicate.or(other.predicate).test(d));
        }

        public RealSet intersect(RealSet other) {
            double low2 = Math.min(low, other.low);
            double high2 = Math.max(high, other.high);
            return new RealSet(low2, high2, d -> predicate.and(other.predicate).test(d));
        }

        public RealSet subtract(RealSet other) {
            return new RealSet(low, high, d -> predicate.and(other.predicate.negate()).test(d));
        }

        public double length() {
            if (low.isInfinite() || high.isInfinite()) return -1.0; // error value
            if (high <= low) return 0.0;
            Double p = low;
            int count = 0;
            do {
                if (predicate.test(p)) count++;
                p += interval;
            } while (p < high);
            return count * interval;
        }

        public boolean isEmpty() {
            if (Objects.equals(high, low)) {
                return predicate.negate().test(low);
            }
            return length() == 0.0;
        }
    }

    public static void main(String[] args) {
        RealSet a = new RealSet(0.0, 1.0, RangeType.LEFT_OPEN);
        RealSet b = new RealSet(0.0, 2.0, RangeType.RIGHT_OPEN);
        RealSet c = new RealSet(1.0, 2.0, RangeType.LEFT_OPEN);
        RealSet d = new RealSet(0.0, 3.0, RangeType.RIGHT_OPEN);
        RealSet e = new RealSet(0.0, 1.0, RangeType.BOTH_OPEN);
        RealSet f = new RealSet(0.0, 1.0, RangeType.CLOSED);
        RealSet g = new RealSet(0.0, 0.0, RangeType.CLOSED);

        for (int i = 0; i <= 2; i++) {
            Double dd = (double) i;
            System.out.printf("(0, 1] ∪ [0, 2) contains %d is %s\n", i, a.union(b).contains(dd));
            System.out.printf("[0, 2) ∩ (1, 2] contains %d is %s\n", i, b.intersect(c).contains(dd));
            System.out.printf("[0, 3) − (0, 1) contains %d is %s\n", i, d.subtract(e).contains(dd));
            System.out.printf("[0, 3) − [0, 1] contains %d is %s\n", i, d.subtract(f).contains(dd));
            System.out.println();
        }

        System.out.printf("[0, 0] is empty is %s\n", g.isEmpty());
        System.out.println();

        RealSet aa = new RealSet(
            0.0, 10.0,
            x -> (0.0 < x && x < 10.0) && Math.abs(Math.sin(Math.PI * x * x)) > 0.5
        );
        RealSet bb = new RealSet(
            0.0, 10.0,
            x -> (0.0 < x && x < 10.0) && Math.abs(Math.sin(Math.PI * x)) > 0.5
        );
        RealSet cc = aa.subtract(bb);
        System.out.printf("Approx length of A - B is %f\n", cc.length());
    }
}


Set right-adjacent bits

Given a left-to-right ordered collection of e bits, b, where 1 <= e <= 10000,
and a zero or more integer n :
* Output the result of setting the n bits to the right of any set bit in b
(if those bits are present in b and therefore also preserving the width, e).

'''Some examples:'''

    Set of examples showing how one bit in a nibble gets changed:

        n = 2; Width e = 4:

             Input b: 1000
              Result: 1110

             Input b: 0100
              Result: 0111

             Input b: 0010
              Result: 0011

             Input b: 0000
              Result: 0000

    Set of examples with the same input with set bits of varying distance apart:

        n = 0; Width e = 66:

             Input b: 010000000000100000000010000000010000000100000010000010000100010010
              Result: 010000000000100000000010000000010000000100000010000010000100010010

        n = 1; Width e = 66:

             Input b: 010000000000100000000010000000010000000100000010000010000100010010
              Result: 011000000000110000000011000000011000000110000011000011000110011011

        n = 2; Width e = 66:

             Input b: 010000000000100000000010000000010000000100000010000010000100010010
              Result: 011100000000111000000011100000011100000111000011100011100111011111

        n = 3; Width e = 66:

             Input b: 010000000000100000000010000000010000000100000010000010000100010010
              Result: 011110000000111100000011110000011110000111100011110011110111111111

'''Task:'''

* Implement a routine to perform the setting of right-adjacent bits on representations of bits that will scale over the given range of input width e.
* Use it to show, here, the results for the input examples above.
* Print the output aligned in a way that allows easy checking by eye of the binary input vs output.

Solution:
public final class SetRightAdjacentBits {

	public static void main(String[] aArgs) {
		setRightAdjacent("1000", 2);
		setRightAdjacent("0100", 2);
		setRightAdjacent("0010", 2);
		setRightAdjacent("0000", 2);

		String test = "010000000000100000000010000000010000000100000010000010000100010010";
		setRightAdjacent(test, 0);
		setRightAdjacent(test, 1);
		setRightAdjacent(test, 2);
		setRightAdjacent(test, 3);
	}

	private static void setRightAdjacent(String aText, int aNumber) {
		System.out.println("n = " + aNumber + ", Width = " + aText.length() + ", Input: " + aText);

		char[] text = aText.toCharArray();
		char[] result = aText.toCharArray();
	    for ( int i = 0; i < result.length; i++ ) {
	    	if ( text[i] == '1' ) {
	    		for ( int j = i + 1; j <= i + aNumber && j < result.length; j++ ) {
	    			result[j] = '1';
	    		}
	    	}
	    }

	    String spaces = " ".repeat(16 + String.valueOf(aText.length()).length());
		System.out.println(spaces + "Result: " + new String(result) + System.lineSeparator());
	}

}


Shoelace formula for polygonal area

Given the n + 1 vertices x[0], y[0] .. x[N], y[N] of a simple polygon described in a clockwise direction, then the polygon's area can be calculated by:

abs( (sum(x[0]*y[1] + ... x[n-1]*y[n]) + x[N]*y[0]) -
     (sum(x[1]*y[0] + ... x[n]*y[n-1]) + x[0]*y[N])
   ) / 2
(Where abs returns the absolute value)

;Task:
Write a function/method/routine to use the the Shoelace formula to calculate the area of the polygon described by the ordered points:
      (3,4), (5,11), (12,8), (9,5), and (5,6)

Show the answer here, on this page.

Solution:
import java.util.List;

public class ShoelaceFormula {
    private static class Point {
        int x, y;

        Point(int x, int y) {
            this.x = x;
            this.y = y;
        }

        @Override
        public String toString() {
            return String.format("(%d, %d)", x, y);
        }
    }

    private static double shoelaceArea(List<Point> v) {
        int n = v.size();
        double a = 0.0;
        for (int i = 0; i < n - 1; i++) {
            a += v.get(i).x * v.get(i + 1).y - v.get(i + 1).x * v.get(i).y;
        }
        return Math.abs(a + v.get(n - 1).x * v.get(0).y - v.get(0).x * v.get(n - 1).y) / 2.0;
    }

    public static void main(String[] args) {
        List<Point> v = List.of(
            new Point(3, 4),
            new Point(5, 11),
            new Point(12, 8),
            new Point(9, 5),
            new Point(5, 6)
        );
        double area = shoelaceArea(v);
        System.out.printf("Given a polygon with vertices %s,%n", v);
        System.out.printf("its area is %f,%n", area);
    }
}


Shortest common supersequence

The   '''shortest common supersequence'''   is a problem closely related to the   [[longest common subsequence]],   which you can use as an external function for this task.

;;Task:
Given two strings u and v, find the shortest possible sequence s, which is the shortest common super-sequence of u and v where both u and v are a subsequence of s.  Defined as such, s is not necessarily unique.

Demonstrate this by printing s where u = "abcbdab" and v = "bdcaba".

;Also see:
* Wikipedia: shortest common supersequence

Solution:
public class ShortestCommonSuperSequence {
    private static boolean isEmpty(String s) {
        return null == s || s.isEmpty();
    }

    private static String scs(String x, String y) {
        if (isEmpty(x)) {
            return y;
        }
        if (isEmpty(y)) {
            return x;
        }

        if (x.charAt(0) == y.charAt(0)) {
            return x.charAt(0) + scs(x.substring(1), y.substring(1));
        }

        if (scs(x, y.substring(1)).length() <= scs(x.substring(1), y).length()) {
            return y.charAt(0) + scs(x, y.substring(1));
        } else {
            return x.charAt(0) + scs(x.substring(1), y);
        }
    }

    public static void main(String[] args) {
        System.out.println(scs("abcbdab", "bdcaba"));
    }
}


Show ASCII table

Show  the ASCII character set  from values   '''32'''   to   '''127'''   (decimal)   in a table format.

Solution:
public class ShowAsciiTable {

    public static void main(String[] args) {
        for ( int i = 32 ; i <= 127 ; i++ ) {
            if ( i == 32 || i == 127 ) {
                String s = i == 32 ? "Spc" : "Del";
                System.out.printf("%3d: %s ", i, s);
            }
            else {
                System.out.printf("%3d: %c   ", i, i);
            }
            if ( (i-1) % 6 == 0 ) {
                System.out.println();
            }
        }
    }

}


Show the epoch

Choose popular date libraries used by your language and show the   epoch   those libraries use.

A demonstration is preferable   (e.g. setting the internal representation of the date to 0 ms/ns/etc.,   or another way that will still show the epoch even if it is changed behind the scenes by the implementers),   but text from (with links to) documentation is also acceptable where a demonstration is impossible/impractical.

For consistency's sake, show the date in UTC time where possible.

;Related task:
*   [[Date format]]

Solution:
import java.text.DateFormat;
import java.util.Date;
import java.util.TimeZone;

public class DateTest{
    public static void main(String[] args) {
        Date date = new Date(0);
        DateFormat format = DateFormat.getDateTimeInstance();
        format.setTimeZone(TimeZone.getTimeZone("UTC"));
        System.out.println(format.format(date));
    }
}


Sierpinski pentagon

Produce a graphical or ASCII-art representation of a Sierpinski pentagon (aka a Pentaflake) of order 5. Your code should also be able to correctly generate representations of lower orders: 1 to 4.

;See also
* Sierpinski pentagon

Solution:
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.geom.Path2D;
import static java.lang.Math.*;
import java.util.Random;
import javax.swing.*;

public class SierpinskiPentagon extends JPanel {
    // exterior angle
    final double degrees072 = toRadians(72);

    /* After scaling we'll have 2 sides plus a gap occupying the length
       of a side before scaling. The gap is the base of an isosceles triangle
       with a base angle of 72 degrees. */
    final double scaleFactor = 1 / (2 + cos(degrees072) * 2);

    final int margin = 20;
    int limit = 0;
    Random r = new Random();

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

        new Timer(3000, (ActionEvent e) -> {
            limit++;
            if (limit >= 5)
                limit = 0;
            repaint();
        }).start();
    }

    void drawPentagon(Graphics2D g, double x, double y, double side, int depth) {
        double angle = 3 * degrees072; // starting angle

        if (depth == 0) {

            Path2D p = new Path2D.Double();
            p.moveTo(x, y);

            // draw from the top
            for (int i = 0; i < 5; i++) {
                x = x + cos(angle) * side;
                y = y - sin(angle) * side;
                p.lineTo(x, y);
                angle += degrees072;
            }

            g.setColor(RandomHue.next());
            g.fill(p);

        } else {

            side *= scaleFactor;

            /* Starting at the top of the highest pentagon, calculate
               the top vertices of the other pentagons by taking the
               length of the scaled side plus the length of the gap. */
            double distance = side + side * cos(degrees072) * 2;

            /* The top positions form a virtual pentagon of their own,
               so simply move from one to the other by changing direction. */
            for (int i = 0; i < 5; i++) {
                x = x + cos(angle) * distance;
                y = y - sin(angle) * distance;
                drawPentagon(g, x, y, side, depth - 1);
                angle += degrees072;
            }
        }
    }

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

        int w = getWidth();
        double radius = w / 2 - 2 * margin;
        double side = radius * sin(PI / 5) * 2;

        drawPentagon(g, w / 2, 3 * margin, side, limit);
    }

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

class RandomHue {
    /* Try to avoid random color values clumping together */
    final static double goldenRatioConjugate = (sqrt(5) - 1) / 2;
    private static double hue = Math.random();

    static Color next() {
        hue = (hue + goldenRatioConjugate) % 1;
        return Color.getHSBColor((float) hue, 1, 1);
    }
}


Sierpinski triangle/Graphical

Produce a graphical representation of a Sierpinski triangle of order N in any orientation.

An example of Sierpinski's triangle (order = 8) looks like this:
[[File:Sierpinski_Triangle_Unicon.PNG]]

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

/**
* SierpinskyTriangle.java
* Draws a SierpinskyTriangle in a JFrame
* The order of complexity is given from command line, but
* defaults to 3
*
* @author Istarnion
*/

class SierpinskyTriangle {

	public static void main(String[] args) {
		int i = 3;		// Default to 3
		if(args.length >= 1) {
			try {
				i = Integer.parseInt(args[0]);
			}
			catch(NumberFormatException e) {
				System.out.println("Usage: 'java SierpinskyTriangle [level]'\nNow setting level to "+i);
			}
		}
		final int level = i;

		JFrame frame = new JFrame("Sierpinsky Triangle - Java");
		frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

		JPanel panel = new JPanel() {
			@Override
			public void paintComponent(Graphics g) {
				g.setColor(Color.BLACK);
				drawSierpinskyTriangle(level, 20, 20, 360, (Graphics2D)g);
			}
		};

		panel.setPreferredSize(new Dimension(400, 400));

		frame.add(panel);
		frame.pack();
		frame.setResizable(false);
		frame.setLocationRelativeTo(null);
		frame.setVisible(true);
	}

	private static void drawSierpinskyTriangle(int level, int x, int y, int size, Graphics2D g) {
		if(level <= 0) return;

		g.drawLine(x, y, x+size, y);
		g.drawLine(x, y, x, y+size);
		g.drawLine(x+size, y, x, y+size);

		drawSierpinskyTriangle(level-1, x, y, size/2, g);
		drawSierpinskyTriangle(level-1, x+size/2, y, size/2, g);
		drawSierpinskyTriangle(level-1, x, y+size/2, size/2, g);
	}
}


Sierpinski triangle/Graphical

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

public class SierpinskiTriangle extends JPanel {
    private final int dim = 512;
    private final int margin = 20;

    private int limit = dim;

    public SierpinskiTriangle() {
        setPreferredSize(new Dimension(dim + 2 * margin, dim + 2 * margin));
        setBackground(Color.white);
        setForeground(Color.green.darker());

        new Timer(2000, (ActionEvent e) -> {
            limit /= 2;
            if (limit <= 2)
                limit = dim;
            repaint();
        }).start();
    }

    void drawTriangle(Graphics2D g, int x, int y, int size) {
        if (size <= limit) {
            Path2D p = new Path2D.Float();
            p.moveTo(x, y);
            p.lineTo(x + size / 2, y + size);
            p.lineTo(x - size / 2, y + size);
            g.fill(p);
        } else {
            size /= 2;
            drawTriangle(g, x, y, size);
            drawTriangle(g, x + size / 2, y + size, size);
            drawTriangle(g, x - size / 2, y + size, size);
        }
    }

    @Override
    public void paintComponent(Graphics gg) {
        super.paintComponent(gg);
        Graphics2D g = (Graphics2D) gg;
        g.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
                RenderingHints.VALUE_ANTIALIAS_ON);
        g.translate(margin, margin);
        drawTriangle(g, dim / 2, 0, dim);
    }

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


Smith numbers

sum of the decimal digits of the integers that make up that number is the same as the sum of the decimal digits of its prime factors excluding 1.

By definition, all primes are ''excluded'' as they (naturally) satisfy this condition!

Smith numbers are also known as   ''joke''   numbers.

;Example
Using the number '''166'''
Find the prime factors of '''166''' which are: '''2''' x '''83'''
Then, take those two prime factors and sum all their decimal digits: '''2 + 8 + 3''' which is '''13'''
Then, take the decimal digits of '''166''' and add their decimal digits: '''1 + 6 + 6''' which is '''13'''
Therefore, the number '''166''' is a Smith number.

;Task
Write a program to find all Smith numbers ''below'' 10000.

;See also
* from Wikipedia:   [Smith number].
* from MathWorld:   [Smith number].
* from OEIS A6753:   [OEIS sequence A6753].
* from OEIS A104170:   [Number of Smith numbers below 10^n].
* from The Prime pages:   [Smith numbers].

Solution:
import java.util.*;

public class SmithNumbers {

    public static void main(String[] args) {
        for (int n = 1; n < 10_000; n++) {
            List<Integer> factors = primeFactors(n);
            if (factors.size() > 1) {
                int sum = sumDigits(n);
                for (int f : factors)
                    sum -= sumDigits(f);
                if (sum == 0)
                    System.out.println(n);
            }
        }
    }

    static List<Integer> primeFactors(int n) {
        List<Integer> result = new ArrayList<>();

        for (int i = 2; n % i == 0; n /= i)
            result.add(i);

        for (int i = 3; i * i <= n; i += 2) {
            while (n % i == 0) {
                result.add(i);
                n /= i;
            }
        }

        if (n != 1)
            result.add(n);

        return result;
    }

    static int sumDigits(int n) {
        int sum = 0;
        while (n > 0) {
            sum += (n % 10);
            n /= 10;
        }
        return sum;
    }
}