Flipping bits game

The game:
Given an   '''NxN'''   square array of zeroes or ones in an initial configuration,   and a target configuration of zeroes and ones.

The game is to transform one to the other in as few moves as possible by inverting whole numbered rows or whole lettered
columns at once   (as one move).

In an inversion.   any  '''1'''  becomes  '''0''',   and any  '''0'''  becomes  '''1'''  for that whole row or column.

;Task:
Create a program to score for the Flipping bits game.
# The game should create an original random target configuration and a starting configuration.
# Ensure that the starting position is ''never'' the target position.
# The target position must be guaranteed as reachable from the starting position.   (One possible way to do this is to generate the start position by legal flips from a random target position.   The flips will always be reversible back to the target from the given start position).
# The number of moves taken so far should be shown.

Show an example of a short game here, on this page, for a   '''3x3'''   array of bits.

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

public class FlippingBitsGame extends JPanel {
    final int maxLevel = 7;
    final int minLevel = 3;

    private Random rand = new Random();
    private int[][] grid, target;
    private Rectangle box;
    private int n = maxLevel;
    private boolean solved = true;

    FlippingBitsGame() {
        setPreferredSize(new Dimension(640, 640));
        setBackground(Color.white);
        setFont(new Font("SansSerif", Font.PLAIN, 18));

        box = new Rectangle(120, 90, 400, 400);

        startNewGame();

        addMouseListener(new MouseAdapter() {
            @Override
            public void mousePressed(MouseEvent e) {
                if (solved) {
                    startNewGame();
                } else {
                    int x = e.getX();
                    int y = e.getY();

                    if (box.contains(x, y))
                        return;

                    if (x > box.x && x < box.x + box.width) {
                        flipCol((x - box.x) / (box.width / n));

                    } else if (y > box.y && y < box.y + box.height)
                        flipRow((y - box.y) / (box.height / n));

                    if (solved(grid, target))
                        solved = true;

                    printGrid(solved ? "Solved!" : "The board", grid);
                }
                repaint();
            }
        });
    }

    void startNewGame() {
        if (solved) {

            n = (n == maxLevel) ? minLevel : n + 1;

            grid = new int[n][n];
            target = new int[n][n];

            do {
                shuffle();

                for (int i = 0; i < n; i++)
                    target[i] = Arrays.copyOf(grid[i], n);

                shuffle();

            } while (solved(grid, target));

            solved = false;
            printGrid("The target", target);
            printGrid("The board", grid);
        }
    }

    void printGrid(String msg, int[][] g) {
        System.out.println(msg);
        for (int[] row : g)
            System.out.println(Arrays.toString(row));
        System.out.println();
    }

    boolean solved(int[][] a, int[][] b) {
        for (int i = 0; i < n; i++)
            if (!Arrays.equals(a[i], b[i]))
                return false;
        return true;
    }

    void shuffle() {
        for (int i = 0; i < n * n; i++) {
            if (rand.nextBoolean())
                flipRow(rand.nextInt(n));
            else
                flipCol(rand.nextInt(n));
        }
    }

    void flipRow(int r) {
        for (int c = 0; c < n; c++) {
            grid[r][c] ^= 1;
        }
    }

    void flipCol(int c) {
        for (int[] row : grid) {
            row[c] ^= 1;
        }
    }

    void drawGrid(Graphics2D g) {
        g.setColor(getForeground());

        if (solved)
            g.drawString("Solved! Click here to play again.", 180, 600);
        else
            g.drawString("Click next to a row or a column to flip.", 170, 600);

        int size = box.width / n;

        for (int r = 0; r < n; r++)
            for (int c = 0; c < n; c++) {
                g.setColor(grid[r][c] == 1 ? Color.blue : Color.orange);
                g.fillRect(box.x + c * size, box.y + r * size, size, size);
                g.setColor(getBackground());
                g.drawRect(box.x + c * size, box.y + r * size, size, size);
                g.setColor(target[r][c] == 1 ? Color.blue : Color.orange);
                g.fillRect(7 + box.x + c * size, 7 + box.y + r * size, 10, 10);
            }
    }

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

        drawGrid(g);
    }

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


Floyd's triangle

Floyd's triangle   lists the natural numbers in a right triangle aligned to the left where
* the first row is   '''1'''     (unity)
* successive rows start towards the left with the next number followed by successive naturals listing one more number than the line above.

The first few lines of a Floyd triangle looks like this:

 1
 2  3
 4  5  6
 7  8  9 10
11 12 13 14 15

;Task:
:# Write a program to generate and display here the first   n   lines of a Floyd triangle. (Use   n=5   and   n=14   rows).
:# Ensure that when displayed in a mono-space font, the numbers line up in vertical columns as shown and that only one space separates numbers of the last row.

Solution:
public class Floyd {
	public static void main(String[] args){
		printTriangle(5);
		printTriangle(14);
	}

	private static void printTriangle(int n){
		System.out.println(n + " rows:");
		for(int rowNum = 1, printMe = 1, numsPrinted = 0;
				rowNum <= n; printMe++){
			int cols = (int)Math.ceil(Math.log10(n*(n-1)/2 + numsPrinted + 2));
			System.out.printf("%"+cols+"d ", printMe);
			if(++numsPrinted == rowNum){
				System.out.println();
				rowNum++;
				numsPrinted = 0;
			}
		}
	}
}


Four bit adder

"''Simulate''" a four-bit adder.

This design can be realized using four 1-bit full adders.
Each of these 1-bit full adders can be built with two gate. ;

Finally a half adder can be made using an   ''xor''   gate and an   ''and''   gate.

The   ''xor''   gate can be made using two   ''not''s,   two   ''and''s   and one   ''or''.

'''Not''',   '''or'''   and   '''and''',   the only allowed "gates" for the task, can be "imitated" by using the bitwise operators of your language.

If there is not a ''bit type'' in your language, to be sure that the   ''not''   does not "invert" all the other bits of the basic type   (e.g. a byte)   we are not interested in,   you can use an extra   ''nand''   (''and''   then   ''not'')   with the constant   '''1'''   on one input.

Instead of optimizing and reducing the number of gates used for the final 4-bit adder,   build it in the most straightforward way,   ''connecting'' the other "constructive blocks",   in turn made of "simpler" and "smaller" ones.

{|
|+Schematics of the "constructive blocks"
!(Xor gate with ANDs, ORs and NOTs)
!   (A half adder)
!          (A full adder)
!                (A 4-bit adder)
|-
|Xor gate done with ands, ors and nots
|A half adder
|A full adder
|A 4-bit adder
|}

Solutions should try to be as descriptive as possible, making it as easy as possible to identify "connections" between higher-order "blocks".

It is not mandatory to replicate the syntax of higher-order blocks in the atomic "gate" blocks, i.e. basic "gate" operations can be performed as usual bitwise operations, or they can be "wrapped" in a ''block'' in order to expose the same syntax of higher-order blocks, at implementers' choice.

To test the implementation, show the sum of two four-bit numbers (in binary).

Solution:
public class GateLogic
{
  // Basic gate interfaces
  public interface OneInputGate
  {  boolean eval(boolean input);  }

  public interface TwoInputGate
  {  boolean eval(boolean input1, boolean input2);  }

  public interface MultiGate
  {  boolean[] eval(boolean... inputs);  }

  // Create NOT
  public static OneInputGate NOT = new OneInputGate() {
    public boolean eval(boolean input)
    {  return !input;  }
  };

  // Create AND
  public static TwoInputGate AND = new TwoInputGate() {
    public boolean eval(boolean input1, boolean input2)
    {  return input1 && input2;  }
  };

  // Create OR
  public static TwoInputGate OR = new TwoInputGate() {
    public boolean eval(boolean input1, boolean input2)
    {  return input1 || input2;  }
  };

  // Create XOR
  public static TwoInputGate XOR = new TwoInputGate() {
    public boolean eval(boolean input1, boolean input2)
    {
      return OR.eval(
               AND.eval(input1, NOT.eval(input2)),
               AND.eval(NOT.eval(input1), input2)
             );
    }
  };

  // Create HALF_ADDER
  public static MultiGate HALF_ADDER = new MultiGate() {
    public boolean[] eval(boolean... inputs)
    {
      if (inputs.length != 2)
        throw new IllegalArgumentException();
      return new boolean[] {
        XOR.eval(inputs[0], inputs[1]),  // Output bit
        AND.eval(inputs[0], inputs[1])   // Carry bit
      };
    }
  };

  // Create FULL_ADDER
  public static MultiGate FULL_ADDER = new MultiGate() {
    public boolean[] eval(boolean... inputs)
    {
      if (inputs.length != 3)
        throw new IllegalArgumentException();
      // Inputs: CarryIn, A, B
      // Outputs: S, CarryOut
      boolean[] haOutputs1 = HALF_ADDER.eval(inputs[0], inputs[1]);
      boolean[] haOutputs2 = HALF_ADDER.eval(haOutputs1[0], inputs[2]);
      return new boolean[] {
        haOutputs2[0],                         // Output bit
        OR.eval(haOutputs1[1], haOutputs2[1])  // Carry bit
      };
    }
  };

  public static MultiGate buildAdder(final int numBits)
  {
    return new MultiGate() {
      public boolean[] eval(boolean... inputs)
      {
        // Inputs: A0, A1, A2..., B0, B1, B2...
        if (inputs.length != (numBits << 1))
          throw new IllegalArgumentException();
        boolean[] outputs = new boolean[numBits + 1];
        boolean[] faInputs = new boolean[3];
        boolean[] faOutputs = null;
        for (int i = 0; i < numBits; i++)
        {
          faInputs[0] = (faOutputs == null) ? false : faOutputs[1];  // CarryIn
          faInputs[1] = inputs[i];                                   // Ai
          faInputs[2] = inputs[numBits + i];                         // Bi
          faOutputs = FULL_ADDER.eval(faInputs);
          outputs[i] = faOutputs[0];                                 // Si
        }
        if (faOutputs != null)
          outputs[numBits] = faOutputs[1];                           // CarryOut
        return outputs;
      }
    };
  }

  public static void main(String[] args)
  {
    int numBits = Integer.parseInt(args[0]);
    int firstNum = Integer.parseInt(args[1]);
    int secondNum = Integer.parseInt(args[2]);
    int maxNum = 1 << numBits;
    if ((firstNum < 0) || (firstNum >= maxNum))
    {
      System.out.println("First number is out of range");
      return;
    }
    if ((secondNum < 0) || (secondNum >= maxNum))
    {
      System.out.println("Second number is out of range");
      return;
    }

    MultiGate multiBitAdder = buildAdder(numBits);
    // Convert input numbers into array of bits
    boolean[] inputs = new boolean[numBits << 1];
    String firstNumDisplay = "";
    String secondNumDisplay = "";
    for (int i = 0; i < numBits; i++)
    {
      boolean firstBit = ((firstNum >>> i) & 1) == 1;
      boolean secondBit = ((secondNum >>> i) & 1) == 1;
      inputs[i] = firstBit;
      inputs[numBits + i] = secondBit;
      firstNumDisplay = (firstBit ? "1" : "0") + firstNumDisplay;
      secondNumDisplay = (secondBit ? "1" : "0") + secondNumDisplay;
    }

    boolean[] outputs = multiBitAdder.eval(inputs);
    int outputNum = 0;
    String outputNumDisplay = "";
    String outputCarryDisplay = null;
    for (int i = numBits; i >= 0; i--)
    {
      outputNum = (outputNum << 1) | (outputs[i] ? 1 : 0);
      if (i == numBits)
        outputCarryDisplay = outputs[i] ? "1" : "0";
      else
        outputNumDisplay += (outputs[i] ? "1" : "0");
    }
    System.out.println("numBits=" + numBits);
    System.out.println("A=" + firstNumDisplay + " (" + firstNum + "), B=" + secondNumDisplay + " (" + secondNum + "), S=" + outputCarryDisplay + " " + outputNumDisplay + " (" + outputNum + ")");
    return;
  }

}


Four is magic

Write a subroutine, function, whatever it may be called in your language, that takes an integer number and returns an English text sequence starting with the English cardinal representation of that integer, the word 'is' and then the English cardinal representation of the count of characters that made up the first word, followed by a comma.

Continue the sequence by using the previous count word as the first word of the next phrase, append 'is' and the cardinal count of the letters in ''that'' word.

Continue until you reach four. Since four has four characters, finish by adding the words 'four is magic' and a period. All integers will eventually wind up at four.

For instance, suppose your are given the integer '''3'''. Convert '''3''' to '''Three''', add ''' is ''', then the cardinal character count of three, or '''five''', with a comma to separate if from the next phrase. Continue the sequence '''five is four,''' (five has four letters), and finally, '''four is magic.'''

      '''Three is five, five is four, four is magic.'''

For reference, here are outputs for 0 through 9.

      Zero is four, four is magic.
      One is three, three is five, five is four, four is magic.
      Two is three, three is five, five is four, four is magic.
      Three is five, five is four, four is magic.
      Four is magic.
      Five is four, four is magic.
      Six is three, three is five, five is four, four is magic.
      Seven is five, five is four, four is magic.
      Eight is five, five is four, four is magic.
      Nine is four, four is magic.

;Some task guidelines:
:* You may assume the input will only contain integer numbers.
:* Cardinal numbers between 20 and 100 may use either hyphens or spaces as word separators but they must use a word separator. ('''23''' is '''twenty three''' or '''twenty-three''' not '''twentythree'''.)
:* Cardinal number conversions should follow the  English short scale. (billion is 1e9, trillion is 1e12, etc.)
:* Cardinal numbers should not include commas. ('''20140''' is '''twenty thousand one hundred forty''' not '''twenty thousand, one hundred forty'''.)
:* When converted to a string, '''100''' should be '''one hundred''', not '''a hundred''' or '''hundred''', '''1000''' should be '''one thousand''', not '''a thousand''' or '''thousand'''.
:* When converted to a string, there should be no '''and''' in the cardinal string. '''130''' should be '''one hundred thirty''' not '''one hundred and thirty'''.
:* When counting characters, count ''all'' of the characters in the cardinal number including spaces and hyphens. '''One hundred fifty-one''' should be '''21''' not '''18'''.
:* The output should follow the format "N is K, K is M, M is ... four is magic." (unless the input is 4, in which case the output should simply be "four is magic.")
:* The output can either be the return value from the function, or be displayed from within the function.
:* You are encouraged, though not mandated to use proper sentence capitalization.
:* You may optionally support negative numbers. '''-7''' is '''negative seven'''.
:* Show the output here for a small representative sample of values, at least 5 but no more than 25. You are free to choose which which numbers to use for output demonstration.

You can choose to use a library, (module, external routine, whatever) to do the cardinal conversions as long as the code is easily and freely available to the public.

If you roll your own, make the routine accept at minimum any integer from 0 up to 999999. If you use a pre-made library, support at least up to unsigned 64 bit integers. (or the largest integer supported in your language if it is less.)

Four is magic is a popular code-golf task. '''This is not code golf.''' Write legible, idiomatic and well formatted code.

;Related tasks:
:*   [[Four is the number of_letters in the ...]]
:*   [[Look-and-say sequence]]
:*   [[Number names]]
:*   [[Self-describing numbers]]
:*   [[Summarize and say sequence]]
:*   [[Spelling of ordinal numbers]]
:*   [[De Bruijn sequences]]

Solution:
public class FourIsMagic {

    public static void main(String[] args) {
        for ( long n : new long[] {6, 60, 89, 300, 670, 2000, 2467, 20000, 24500,200000, 230000, 246571, 2300000, 2465712, 20000000, 24657123, 230000000, 245000000, -246570000, 123456789712345l, 8777777777777777777L, Long.MAX_VALUE}) {
            String magic = fourIsMagic(n);
            System.out.printf("%d = %s%n", n, toSentence(magic));
        }
    }

    private static final String toSentence(String s) {
        return s.substring(0,1).toUpperCase() + s.substring(1) + ".";
    }

    private static final String[] nums = new String[] {
            "zero", "one", "two", "three", "four", "five", "six", "seven", "eight", "nine",
            "ten", "eleven", "twelve", "thirteen", "fourteen", "fifteen", "sixteen", "seventeen", "eighteen", "nineteen"
    };

    private static final String[] tens = new String[] {"zero", "ten", "twenty", "thirty", "forty", "fifty", "sixty", "seventy", "eighty", "ninety"};

    private static final String fourIsMagic(long n) {
        if ( n == 4 ) {
            return numToString(n) + " is magic";
        }
        String result = numToString(n);
        return result + " is " + numToString(result.length()) + ", " + fourIsMagic(result.length());
    }

    private static final String numToString(long n) {
        if ( n < 0 ) {
            return "negative " + numToString(-n);
        }
        int index = (int) n;
        if ( n <= 19 ) {
            return nums[index];
        }
        if ( n <= 99 ) {
            return tens[index/10] + (n % 10 > 0 ? " " + numToString(n % 10) : "");
        }
        String label = null;
        long factor = 0;
        if ( n <= 999 ) {
            label = "hundred";
            factor = 100;
        }
        else if ( n <= 999999) {
            label = "thousand";
            factor = 1000;
        }
        else if ( n <= 999999999) {
            label = "million";
            factor = 1000000;
        }
        else if ( n <= 999999999999L) {
            label = "billion";
            factor = 1000000000;
        }
        else if ( n <= 999999999999999L) {
            label = "trillion";
            factor = 1000000000000L;
        }
        else if ( n <= 999999999999999999L) {
            label = "quadrillion";
            factor = 1000000000000000L;
        }
        else {
            label = "quintillion";
            factor = 1000000000000000000L;
        }
        return numToString(n / factor) + " " + label + (n % factor > 0 ? " " + numToString(n % factor ) : "");
    }

}


Four is the number of letters in the ...

The      '''Four is ...'''      sequence is based on the counting of the number of
letters in the words of the (never-ending) sentence:
   Four is the number of letters in the first word of this sentence, two in the second,
   three in the third, six in the fourth, two in the fifth, seven in the sixth, ***

;Definitions and directives:
:*   English is to be used in spelling numbers.
:*   '''Letters'''   are defined as the upper- and lowercase letters in the Latin alphabet   ('''A-->Z'''   and   '''a-->z''').
:*   Commas are not counted,   nor are hyphens (dashes or minus signs).
:*   '''twenty-three'''   has eleven letters.
:*   '''twenty-three'''   is considered one word   (which is hyphenated).
:*   no   ''' ''and'' '''   words are to be used when spelling a (English) word for a number.
:*   The American version of numbers will be used here in this task   (as opposed to the British version).
          '''2,000,000,000'''   is two billion,   ''not''   two milliard.

;Task:
:*   Write a driver (invoking routine) and a function (subroutine/routine***) that returns the sequence (for any positive integer) of the number of letters in the first   '''N'''    words in the never-ending sentence.   For instance, the portion of the never-ending sentence shown above (2nd sentence of this task's preamble),   the sequence would be:
          '''4  2  3  6  2  7'''
:*   Only construct as much as is needed for the never-ending sentence.
:*   Write a driver (invoking routine) to show the number of letters in the   Nth   word,   ''as well as''   showing the   Nth   word itself.
:*   After each test case, show the total number of characters   (including blanks, commas, and punctuation)   of the sentence that was constructed.
:*   Show all output here.

;Test cases:
  Display the first  201  numbers in the sequence   (and the total number of characters in the sentence).
  Display the number of letters  (and the word itself)  of the       1,000th  word.
  Display the number of letters  (and the word itself)  of the      10,000th  word.
  Display the number of letters  (and the word itself)  of the     100,000th  word.
  Display the number of letters  (and the word itself)  of the   1,000,000th  word.
  Display the number of letters  (and the word itself)  of the  10,000,000th  word  (optional).

;Related tasks:
:*   [[Four is magic]]
:*   [[Look-and-say sequence]]
:*   [[Number names]]
:*   [[Self-describing numbers]]
:*   [[Self-referential sequence]]
:*   [[Spelling of ordinal numbers]]

;Also see:
:*   See the OEIS sequence  A72425  "Four is the number of letters...".
:*   See the OEIS sequence  A72424  "Five's the number of letters..."

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

public class FourIsTheNumberOfLetters {

    public static void main(String[] args) {
        String [] words = neverEndingSentence(201);
        System.out.printf("Display the first 201 numbers in the sequence:%n%3d: ", 1);
        for ( int i = 0 ; i < words.length ; i++ ) {
            System.out.printf("%2d ", numberOfLetters(words[i]));
            if ( (i+1) % 25 == 0 ) {
                System.out.printf("%n%3d: ", i+2);
            }
        }
        System.out.printf("%nTotal number of characters in the sentence is %d%n", characterCount(words));
        for ( int i = 3 ; i <= 7 ; i++ ) {
            int index = (int) Math.pow(10, i);
            words = neverEndingSentence(index);
            String last = words[words.length-1].replace(",", "");
            System.out.printf("Number of letters of the %s word is %d. The word is \"%s\".  The sentence length is %,d characters.%n", toOrdinal(index), numberOfLetters(last), last, characterCount(words));
        }
    }

    @SuppressWarnings("unused")
    private static void displaySentence(String[] words, int lineLength) {
        int currentLength = 0;
        for ( String word : words ) {
            if ( word.length() + currentLength > lineLength ) {
                String first = word.substring(0, lineLength-currentLength);
                String second = word.substring(lineLength-currentLength);
                System.out.println(first);
                System.out.print(second);
                currentLength = second.length();
            }
            else {
                System.out.print(word);
                currentLength += word.length();
            }
            if ( currentLength == lineLength ) {
                System.out.println();
                currentLength = 0;
            }
            System.out.print(" ");
            currentLength++;
            if ( currentLength == lineLength ) {
                System.out.println();
                currentLength = 0;
            }
        }
        System.out.println();
    }

    private static int numberOfLetters(String word) {
        return word.replace(",","").replace("-","").length();
    }

    private static long characterCount(String[] words) {
        int characterCount = 0;
        for ( int i = 0 ; i < words.length ; i++ ) {
            characterCount += words[i].length() + 1;
        }
        //  Extra space counted in last loop iteration
        characterCount--;
        return characterCount;
    }

    private static String[] startSentence = new String[] {"Four", "is", "the", "number", "of", "letters", "in", "the", "first", "word", "of", "this", "sentence,"};

    private static String[] neverEndingSentence(int wordCount) {
        String[] words = new String[wordCount];
        int index;
        for ( index = 0 ; index < startSentence.length && index < wordCount ; index++ ) {
            words[index] = startSentence[index];
        }
        int sentencePosition = 1;
        while ( index < wordCount ) {
            //  X in the Y
            //  X
            sentencePosition++;
            String word = words[sentencePosition-1];
            for ( String wordLoop : numToString(numberOfLetters(word)).split(" ") ) {
                words[index] = wordLoop;
                index++;
                if ( index == wordCount ) {
                    break;
                }
            }
            // in
            words[index] = "in";
            index++;
            if ( index == wordCount ) {
                break;
            }
            //  the
            words[index] = "the";
            index++;
            if ( index == wordCount ) {
                break;
            }
            //  Y
            for ( String wordLoop : (toOrdinal(sentencePosition) + ",").split(" ") ) {
                words[index] = wordLoop;
                index++;
                if ( index == wordCount ) {
                    break;
                }
            }
        }
        return words;
    }

    private static final String[] nums = new String[] {
            "zero", "one", "two", "three", "four", "five", "six", "seven", "eight", "nine",
            "ten", "eleven", "twelve", "thirteen", "fourteen", "fifteen", "sixteen", "seventeen", "eighteen", "nineteen"
    };

    private static final String[] tens = new String[] {"zero", "ten", "twenty", "thirty", "forty", "fifty", "sixty", "seventy", "eighty", "ninety"};

    private static final String numToString(long n) {
        return numToStringHelper(n);
    }

    private static final String numToStringHelper(long n) {
        if ( n < 0 ) {
            return "negative " + numToStringHelper(-n);
        }
        int index = (int) n;
        if ( n <= 19 ) {
            return nums[index];
        }
        if ( n <= 99 ) {
            return tens[index/10] + (n % 10 > 0 ? "-" + numToStringHelper(n % 10) : "");
        }
        String label = null;
        long factor = 0;
        if ( n <= 999 ) {
            label = "hundred";
            factor = 100;
        }
        else if ( n <= 999999) {
            label = "thousand";
            factor = 1000;
        }
        else if ( n <= 999999999) {
            label = "million";
            factor = 1000000;
        }
        else if ( n <= 999999999999L) {
            label = "billion";
            factor = 1000000000;
        }
        else if ( n <= 999999999999999L) {
            label = "trillion";
            factor = 1000000000000L;
        }
        else if ( n <= 999999999999999999L) {
            label = "quadrillion";
            factor = 1000000000000000L;
        }
        else {
            label = "quintillion";
            factor = 1000000000000000000L;
        }
        return numToStringHelper(n / factor) + " " + label + (n % factor > 0 ? " " + numToStringHelper(n % factor ) : "");
    }

    private static Map<String,String> ordinalMap = new HashMap<>();
    static {
        ordinalMap.put("one", "first");
        ordinalMap.put("two", "second");
        ordinalMap.put("three", "third");
        ordinalMap.put("five", "fifth");
        ordinalMap.put("eight", "eighth");
        ordinalMap.put("nine", "ninth");
        ordinalMap.put("twelve", "twelfth");
    }

    private static String toOrdinal(long n) {
        String spelling = numToString(n);
        String[] split = spelling.split(" ");
        String last = split[split.length - 1];
        String replace = "";
        if ( last.contains("-") ) {
            String[] lastSplit = last.split("-");
            String lastWithDash = lastSplit[1];
            String lastReplace = "";
            if ( ordinalMap.containsKey(lastWithDash) ) {
                lastReplace = ordinalMap.get(lastWithDash);
            }
            else if ( lastWithDash.endsWith("y") ) {
                lastReplace = lastWithDash.substring(0, lastWithDash.length() - 1) + "ieth";
            }
            else {
                lastReplace = lastWithDash + "th";
            }
            replace = lastSplit[0] + "-" + lastReplace;
        }
        else {
            if ( ordinalMap.containsKey(last) ) {
                replace = ordinalMap.get(last);
            }
            else if ( last.endsWith("y") ) {
                replace = last.substring(0, last.length() - 1) + "ieth";
            }
            else {
                replace = last + "th";
            }
        }
        split[split.length - 1] = replace;
        return String.join(" ", split);
    }

}


Fusc sequence

Definitions:
The   '''fusc'''   integer sequence is defined as:
::*   fusc(0) = 0
::*   fusc(1) = 1
::*   for '''n'''>1,   the   '''n'''th   term is defined as:
::::*   if   '''n'''   is       even;     fusc(n) = fusc(n/2)
::::*   if   '''n'''   is   odd;     fusc(n) = fusc((n-1)/2)   +   fusc((n+1)/2)

Note that MathWorld's definition starts with unity, not zero.   This task will be using the OEIS' version   (above).

;An observation:
:::::*   fusc(A) = fusc(B)

where   '''A'''   is some non-negative integer expressed in binary,   and
where   '''B'''   is the binary value of   '''A'''   reversed.

Fusc numbers are also known as:
::*   fusc function   (named by Dijkstra, 1982)
::*   Stern's Diatomic series   (although it starts with unity, not zero)
::*   Stern-Brocot sequence   (although it starts with unity, not zero)

;Task:
::*   show the first   '''61'''   fusc numbers (starting at zero) in a horizontal format.
::*   show the fusc number (and its index) whose length is greater than any previous fusc number length.
::::*   (the length is the number of decimal digits when the fusc number is expressed in base ten.)
::*   show all numbers with commas   (if appropriate).
::*   show all output here.

;Related task:
::*   RosettaCode Stern-Brocot sequence

;Also see:
::*   the MathWorld entry:   Stern's Diatomic Series.
::*   the OEIS      entry:   A2487.

Solution:
public class FuscSequence {

    public static void main(String[] args) {
        System.out.println("Show the first 61 fusc numbers (starting at zero) in a horizontal format");
        for ( int n = 0 ; n < 61 ; n++ ) {
            System.out.printf("%,d ", fusc[n]);
        }

        System.out.printf("%n%nShow the fusc number (and its index) whose length is greater than any previous fusc number length.%n");
        int start = 0;
        for (int i = 0 ; i <= 5 ; i++ ) {
            int val = i != 0 ? (int) Math.pow(10, i) : -1;
            for ( int j = start ; j < FUSC_MAX ; j++ ) {
                if ( fusc[j] > val ) {
                    System.out.printf("fusc[%,d] = %,d%n", j, fusc[j] );
                    start = j;
                    break;
                }
            }
        }
    }

    private static final int FUSC_MAX = 30000000;
    private static int[] fusc = new int[FUSC_MAX];

    static {
        fusc[0] = 0;
        fusc[1] = 1;
        for ( int n = 2 ; n < FUSC_MAX ; n++ ) {
            fusc[n] = (n % 2 == 0 ? fusc[n/2] : fusc[(n-1)/2] + fusc[(n+1)/2]);
        }
    }
}


Gapful numbers

Numbers   (positive integers expressed in base ten)   that are (evenly) divisible by the number formed by the
first and last digit are known as   '''gapful numbers'''.

''Evenly divisible''   means divisible with   no   remainder.

All   one-   and two-digit   numbers have this property and are trivially excluded.   Only
numbers    >=  '''100'''   will be considered for this Rosetta Code task.

;Example:
'''187'''   is a   '''gapful'''   number because it is evenly divisible by the
number   '''17'''   which is formed by the first and last decimal digits
of    '''187'''.

About   7.46%   of positive integers are   ''gapful''.

;Task:
:*   Generate and show all sets of numbers (below) on one line (horizontally) with a title,   here on this page
:*   Show the first   '''30'''   gapful numbers
:*   Show the first   '''15'''   gapful numbers    >=           '''1,000,000'''
:*   Show the first   '''10'''   gapful numbers    >=                               '''1,000,000,000'''

;Related tasks:
:*   Harshad or Niven series.
:*   palindromic gapful numbers.
:*   largest number divisible by its digits.

;Also see:
:*   The OEIS entry:   A108343 gapful numbers.
:*   numbersaplenty gapful numbers

Solution:
import java.util.List;

public class GapfulNumbers {
    private static String commatize(long n) {
        StringBuilder sb = new StringBuilder(Long.toString(n));
        int le = sb.length();
        for (int i = le - 3; i >= 1; i -= 3) {
            sb.insert(i, ',');
        }
        return sb.toString();
    }

    public static void main(String[] args) {
        List<Long> starts = List.of((long) 1e2, (long) 1e6, (long) 1e7, (long) 1e9, (long) 7123);
        List<Integer> counts = List.of(30, 15, 15, 10, 25);
        for (int i = 0; i < starts.size(); ++i) {
            int count = 0;
            Long j = starts.get(i);
            long pow = 100;
            while (j >= pow * 10) {
                pow *= 10;
            }
            System.out.printf("First %d gapful numbers starting at %s:\n", counts.get(i), commatize(starts.get(i)));
            while (count < counts.get(i)) {
                long fl = (j / pow) * 10 + (j % 10);
                if (j % fl == 0) {
                    System.out.printf("%d ", j);
                    count++;
                }
                j++;
                if (j >= 10 * pow) {
                    pow *= 10;
                }
            }
            System.out.println('\n');
        }
    }
}


Gauss-Jordan matrix inversion

Invert matrix   '''A'''   using Gauss-Jordan method.

'''A'''   being an   '''n''' x '''n'''   matrix.

Solution:
// Matrix.java

public class Matrix {
    private int rows;
    private int columns;
    private double[][] elements;

    public Matrix(int rows, int columns) {
        this.rows = rows;
        this.columns = columns;
        elements = new double[rows][columns];
    }

    public void set(int row, int column, double value) {
        elements[row][column] = value;
    }

    public double get(int row, int column) {
        return elements[row][column];
    }

    public void print() {
        for (int row = 0; row < rows; ++row) {
            for (int column = 0; column < columns; ++column) {
                if (column > 0)
                    System.out.print(' ');
                System.out.printf("%7.3f", elements[row][column]);
            }
            System.out.println();
        }
    }

    // Returns the inverse of this matrix
    public Matrix inverse() {
        assert(rows == columns);
        // Augment by identity matrix
        Matrix tmp = new Matrix(rows, columns * 2);
        for (int row = 0; row < rows; ++row) {
            System.arraycopy(elements[row], 0, tmp.elements[row], 0, columns);
            tmp.elements[row][row + columns] = 1;
        }
        tmp.toReducedRowEchelonForm();
        Matrix inv = new Matrix(rows, columns);
        for (int row = 0; row < rows; ++row)
            System.arraycopy(tmp.elements[row], columns, inv.elements[row], 0, columns);
        return inv;
    }

    // Converts this matrix into reduced row echelon form
    public void toReducedRowEchelonForm() {
        for (int row = 0, lead = 0; row < rows && lead < columns; ++row, ++lead) {
            int i = row;
            while (elements[i][lead] == 0) {
                if (++i == rows) {
                    i = row;
                    if (++lead == columns)
                        return;
                }
            }
            swapRows(i, row);
            if (elements[row][lead] != 0) {
                double f = elements[row][lead];
                for (int column = 0; column < columns; ++column)
                    elements[row][column] /= f;
            }
            for (int j = 0; j < rows; ++j) {
                if (j == row)
                    continue;
                double f = elements[j][lead];
                for (int column = 0; column < columns; ++column)
                    elements[j][column] -= f * elements[row][column];
            }
        }
    }

    // Returns the matrix product of a and b
    public static Matrix product(Matrix a, Matrix b) {
        assert(a.columns == b.rows);
        Matrix result = new Matrix(a.rows, b.columns);
        for (int i = 0; i < a.rows; ++i) {
            double[] resultRow = result.elements[i];
            double[] aRow = a.elements[i];
            for (int j = 0; j < a.columns; ++j) {
                double[] bRow = b.elements[j];
                for (int k = 0; k < b.columns; ++k)
                    resultRow[k] += aRow[j] * bRow[k];
            }
        }
        return result;
    }

    private void swapRows(int i, int j) {
        double[] tmp = elements[i];
        elements[i] = elements[j];
        elements[j] = tmp;
    }
}


Gaussian elimination

Solve   '''Ax=b'''   using Gaussian elimination then backwards substitution.

'''A'''   being an   '''n''' by '''n'''   matrix.

Also,   '''x''' and '''b'''   are   '''n''' by '''1'''   vectors.

To improve accuracy, please use partial pivoting and scaling.

;See also:
:*   the Wikipedia entry:   Gaussian elimination

Solution:
import java.util.Locale;

public class GaussianElimination {
    public static double solve(double[][] a, double[][] b) {
        if (a == null || b == null || a.length == 0 || b.length == 0) {
            throw new IllegalArgumentException("Invalid dimensions");
        }

        int n = b.length, p = b[0].length;
        if (a.length != n || a[0].length != n) {
            throw new IllegalArgumentException("Invalid dimensions");
        }

        double det = 1.0;

        for (int i = 0; i < n - 1; i++) {
            int k = i;
            for (int j = i + 1; j < n; j++) {
                if (Math.abs(a[j][i]) > Math.abs(a[k][i])) {
                    k = j;
                }
            }

            if (k != i) {
                det = -det;

                for (int j = i; j < n; j++) {
                    double s = a[i][j];
                    a[i][j] = a[k][j];
                    a[k][j] = s;
                }

                for (int j = 0; j < p; j++) {
                    double s = b[i][j];
                    b[i][j] = b[k][j];
                    b[k][j] = s;
                }
            }

            for (int j = i + 1; j < n; j++) {
                double s = a[j][i] / a[i][i];
                for (k = i + 1; k < n; k++) {
                    a[j][k] -= s * a[i][k];
                }

                for (k = 0; k < p; k++) {
                    b[j][k] -= s * b[i][k];
                }
            }
        }

        for (int i = n - 1; i >= 0; i--) {
            for (int j = i + 1; j < n; j++) {
                double s = a[i][j];
                for (int k = 0; k < p; k++) {
                    b[i][k] -= s * b[j][k];
                }
            }
            double s = a[i][i];
            det *= s;
            for (int k = 0; k < p; k++) {
                b[i][k] /= s;
            }
        }

        return det;
    }

    public static void main(String[] args) {
        double[][] a = new double[][] {{4.0, 1.0, 0.0, 0.0, 0.0},
                                       {1.0, 4.0, 1.0, 0.0, 0.0},
                                       {0.0, 1.0, 4.0, 1.0, 0.0},
                                       {0.0, 0.0, 1.0, 4.0, 1.0},
                                       {0.0, 0.0, 0.0, 1.0, 4.0}};

        double[][] b = new double[][] {{1.0 / 2.0},
                                       {2.0 / 3.0},
                                       {3.0 / 4.0},
                                       {4.0 / 5.0},
                                       {5.0 / 6.0}};

        double[] x = {39.0 / 400.0,
                      11.0 / 100.0,
                      31.0 / 240.0,
                      37.0 / 300.0,
                      71.0 / 400.0};

        System.out.println("det: " + solve(a, b));

        for (int i = 0; i < 5; i++) {
            System.out.printf(Locale.US, "%12.8f %12.4e\n", b[i][0], b[i][0] - x[i]);
        }
    }
}


Generate Chess960 starting position

Bobby Fischer.  Unlike other variants of the game, Chess960 does not require a different material, but instead relies on a random initial position, with a few constraints:

* as in the standard chess game, all eight white pawns must be placed on the second rank.
* White pieces must stand on the first rank as in the standard game, in random column order but with the two following constraints:
** the bishops must be placed on opposite color squares (i.e. they must be an odd number of spaces apart or there must be an even number of spaces between them)
** the King must be between two rooks (with any number of other pieces between them all)
* Black pawns and pieces must be placed respectively on the seventh and eighth ranks, mirroring the white pawns and pieces, just as in the standard game.  (That is, their positions are not independently randomized.)

With those constraints there are '''960''' possible starting positions, thus the name of the variant.

;Task:
The purpose of this task is to write a program that can randomly generate any one of the 960 Chess960 initial positions. You will show the result as the first rank displayed with Chess symbols in Unicode:  or with the letters '''K'''ing '''Q'''ueen '''R'''ook '''B'''ishop k'''N'''ight.

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

public class Chess960{
	private static List<Character> pieces = Arrays.asList('R','B','N','Q','K','N','B','R');

	public static List<Character> generateFirstRank(){
		do{
			Collections.shuffle(pieces);
		}while(!check(pieces.toString().replaceAll("[^\\p{Upper}]", ""))); //List.toString adds some human stuff, remove that

		return pieces;
	}

	private static boolean check(String rank){
		if(!rank.matches(".*R.*K.*R.*")) return false;			//king between rooks
		if(!rank.matches(".*B(..|....|......|)B.*")) return false;	//all possible ways bishops can be placed
		return true;
	}

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


Generate random chess position

Generate a random chess position in FEN format.

The position does not have to be realistic or even balanced,  but it must comply to the following rules:
:* there is one and only one king of each color  (one black king and one white king);
:* the kings must not be placed on adjacent squares;
:* there can not be any pawn in the promotion square  (no white pawn in the eighth rank, and no black pawn in the first rank);
:* including the kings, up to 32 pieces of either color can be placed.
:* There is no requirement for material balance between sides.
:* The picking of pieces does not have to comply to a regular chess set --- there can be five knights, twenty rooks, whatever ... as long as the total number of pieces do not exceed thirty-two.
:* it is white's turn.
:* It's assumed that both sides have lost castling rights and that there is no possibility for   ''en passant''   (the FEN should thus end in w - - 0 1).

No requirement is made regarding the probability distribution of your method, but your program should be able to span a reasonably representative sample of all possible positions.  For instance, programs that would always generate positions with say five pieces on the board, or with kings on a corner, would not be considered truly random.

Solution:
import static java.lang.Math.abs;
import java.util.Random;

public class Fen {
    static Random rand = new Random();

    public static void main(String[] args) {
        System.out.println(createFen());
    }

    static String createFen() {
        char[][] grid = new char[8][8];

        placeKings(grid);
        placePieces(grid, "PPPPPPPP", true);
        placePieces(grid, "pppppppp", true);
        placePieces(grid, "RNBQBNR", false);
        placePieces(grid, "rnbqbnr", false);

        return toFen(grid);
    }

    static void placeKings(char[][] grid) {
        int r1, c1, r2, c2;
        while (true) {
            r1 = rand.nextInt(8);
            c1 = rand.nextInt(8);
            r2 = rand.nextInt(8);
            c2 = rand.nextInt(8);
            if (r1 != r2 && abs(r1 - r2) > 1 && abs(c1 - c2) > 1)
                break;
        }
        grid[r1][c1] = 'K';
        grid[r2][c2] = 'k';
    }

    static void placePieces(char[][] grid, String pieces, boolean isPawn) {
        int numToPlace = rand.nextInt(pieces.length());
        for (int n = 0; n < numToPlace; n++) {
            int r, c;
            do {
                r = rand.nextInt(8);
                c = rand.nextInt(8);

            } while (grid[r][c] != 0 || (isPawn && (r == 7 || r == 0)));

            grid[r][c] = pieces.charAt(n);
        }
    }

    static String toFen(char[][] grid) {
        StringBuilder fen = new StringBuilder();
        int countEmpty = 0;
        for (int r = 0; r < 8; r++) {
            for (int c = 0; c < 8; c++) {
                char ch = grid[r][c];
                System.out.printf("%2c ", ch == 0 ? '.' : ch);
                if (ch == 0) {
                    countEmpty++;
                } else {
                    if (countEmpty > 0) {
                        fen.append(countEmpty);
                        countEmpty = 0;
                    }
                    fen.append(ch);
                }
            }
            if (countEmpty > 0) {
                fen.append(countEmpty);
                countEmpty = 0;
            }
            fen.append("/");
            System.out.println();
        }
        return fen.append(" w - - 0 1").toString();
    }
}


Generator/Exponential

A generator is an executable entity (like a function or procedure) that contains code that yields a sequence of values, one at a time, so that each time you call the generator, the next value in the sequence is provided.

Generators are often built on top of coroutines or objects so that the internal state of the object is handled "naturally".

Generators are often used in situations where a sequence is potentially infinite, and where it is possible to construct the next value of the sequence with only minimal state.

;Task:
* Create a function that returns a generation of the m'th powers of the positive integers starting from zero, in order, and without obvious or simple upper limit. (Any upper limit to the generator should not be stated in the source but should be down to factors such as the languages natural integer size limit or computational time/size).
* Use it to create a generator of:
:::*   Squares.
:::*   Cubes.
* Create a new generator that filters all cubes from the generator of squares.
* Drop the first 20 values from this last generator of filtered results, and then show the next 10 values.

Note that this task ''requires'' the use of generators in the calculation of the result.

;Also see:
* Generator

Solution:
import java.util.function.LongSupplier;
import static java.util.stream.LongStream.generate;

public class GeneratorExponential implements LongSupplier {
    private LongSupplier source, filter;
    private long s, f;

    public GeneratorExponential(LongSupplier source, LongSupplier filter) {
        this.source = source;
        this.filter = filter;
        f = filter.getAsLong();
    }

    @Override
    public long getAsLong() {
        s = source.getAsLong();

        while (s == f) {
            s = source.getAsLong();
            f = filter.getAsLong();
        }

        while (s > f) {
            f = filter.getAsLong();
        }

        return s;
    }

    public static void main(String[] args) {
        generate(new GeneratorExponential(new SquaresGen(), new CubesGen()))
                .skip(20).limit(10)
                .forEach(n -> System.out.printf("%d ", n));
    }
}

class SquaresGen implements LongSupplier {
    private long n;

    @Override
    public long getAsLong() {
        return n * n++;
    }
}

class CubesGen implements LongSupplier {
    private long n;

    @Override
    public long getAsLong() {
        return n * n * n++;
    }
}


Get system command output

Task
Execute a system command and get its output into the program. The output may be stored in any kind of collection (array, list, etc.).

;Related task
*  Execute a system command

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

public class SystemCommand {

    public static void main(String args[]) throws IOException {

        String command = "cmd /c dir";
        Process p = Runtime.getRuntime().exec(command);

        try (Scanner sc = new Scanner(p.getInputStream())) {

            System.out.printf("Output of the command: %s %n%n", command);
            while (sc.hasNext()) {
                System.out.println(sc.nextLine());
            }
        }
    }
}


Giuga numbers

Definition
A '''Giuga number''' is a composite number '''n''' which is such that each of its distinct prime factors
'''f''' divide (n/f - 1) exactly.

All known Giuga numbers are even though it is not known for certain that there are no odd examples.

;Example
30 is a Giuga number because its distinct prime factors are 2, 3 and 5 and:
* 30/2 - 1 = 14 is divisible by 2
* 30/3 - 1 = 9 is divisible by 3
* 30/5 - 1 = 5 is divisible by 5

;Task
Determine and show here the first four Giuga numbers.

;Stretch
Determine the fifth Giuga number and any more you have the patience for.

;References

* Wikipedia: Giuga number
* OEIS:A007850 - Giuga numbers

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

public final class GiugaNumbers {

	public static void main(String[] aArgs) {
        primes = List.of( 2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41, 43, 47, 53, 59 );

        List<Integer> primeCounts = List.of( 3, 4, 5 );
        for ( int primeCount : primeCounts ) {
        	primeFactors = new ArrayList<Integer>(Collections.nCopies(primeCount, 0));
        	combinations(primeCount, 0, 0);
        }

        Collections.sort(results);
        System.out.println("Found Giuga numbers: " + results);
    }

	private static void checkIfGiugaNumber(List<Integer> aPrimeFactors) {
		final int product = aPrimeFactors.stream().reduce(1, Math::multiplyExact);

		for ( int factor : aPrimeFactors ) {
			final int divisor = factor * factor;
			if ( ( product - factor ) % divisor != 0 ) {
				return;
			}
		}

		results.add(product);
	}

    private static void combinations(int aPrimeCount, int aIndex, int aLevel) {
        if ( aLevel == aPrimeCount ) {
        	checkIfGiugaNumber(primeFactors);
            return;
        }

        for ( int i = aIndex; i < primes.size(); i++ ) {
            primeFactors.set(aLevel, primes.get(i));
            combinations(aPrimeCount, i + 1, aLevel + 1);
        }
    }

    private static List<Integer> primes;
    private static List<Integer> primeFactors;
    private static List<Integer> results = new ArrayList<Integer>();

}


Globally replace text in several files

Replace every occurring instance of a piece of text in a group of text files with another one.

For this task we want to replace the text   "'''Goodbye London!'''"   with   "'''Hello New York!'''"   for a list of files.

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

public class GloballyReplaceText {

    public static void main(String[] args) throws IOException {

        for (String fn : new String[]{"test1.txt", "test2.txt"}) {
            String s = new String(Files.readAllBytes(Paths.get(fn)));
            s = s.replace("Goodbye London!", "Hello New York!");
            try (FileWriter fw = new FileWriter(fn)) {
                fw.write(s);
            }
        }
    }
}


Gray code

Karnaugh maps in order from left to right or top to bottom.
Create functions to encode a number to and decode a number from Gray code.

Display the normal binary representations, Gray code representations, and decoded Gray code values for all 5-bit binary numbers (0-31 inclusive, leading 0's not necessary).

There are many possible Gray codes. The following encodes what is called "binary reflected Gray code."

Encoding (MSB is bit 0, b is binary, g is Gray code):

if b[i-1] = 1
   g[i] = not b[i]
else
   g[i] = b[i]

Or:

g = b xor (b logically right shifted 1 time)

Decoding (MSB is bit 0, b is binary, g is Gray code):

b[0] = g[0]

for other bits:
b[i] = g[i] xor b[i-1]

;Reference
* Converting Between Gray and Binary Codes. It includes step-by-step animations.

Solution:
public class Gray {
	public static long grayEncode(long n){
		return n ^ (n >>> 1);
	}

	public static long grayDecode(long n) {
		long p = n;
		while ((n >>>= 1) != 0)
			p ^= n;
		return p;
	}
	public static void main(String[] args){
		System.out.println("i\tBinary\tGray\tDecoded");
		for(int i = -1; i < 32;i++){
			System.out.print(i +"\t");
			System.out.print(Integer.toBinaryString(i) + "\t");
			System.out.print(Long.toBinaryString(grayEncode(i))+ "\t");
			System.out.println(grayDecode(grayEncode(i)));
		}
	}
}


Greatest subsequential sum

Given a sequence of integers, find a continuous subsequence which maximizes the sum of its elements, that is, the elements of no other single subsequence add up to a value larger than this one.

An empty subsequence is considered to have the sum of   '''0''';   thus if all elements are negative, the result must be the empty sequence.

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

public class Sub{
    private static int[] indices;

    public static void main(String[] args){
        ArrayList<Long> array= new ArrayList<Long>(); //the main set
        Scanner in = new Scanner(System.in);
        while(in.hasNextLong()) array.add(in.nextLong());
        long highSum= Long.MIN_VALUE;//start the sum at the lowest possible value
        ArrayList<Long> highSet= new ArrayList<Long>();
        //loop through all possible subarray sizes including 0
        for(int subSize= 0;subSize<= array.size();subSize++){
            indices= new int[subSize];
            for(int i= 0;i< subSize;i++) indices[i]= i;
            do{
                long sum= 0;//this subarray sum variable
                ArrayList<Long> temp= new ArrayList<Long>();//this subarray
                //sum it and save it
                for(long index:indices) {sum+= array.get(index); temp.add(array.get(index));}
                if(sum > highSum){//if we found a higher sum
                    highSet= temp;    //keep track of it
                    highSum= sum;
                }
            }while(nextIndices(array));//while we haven't tested all subarrays
        }
        System.out.println("Sum: " + highSum + "\nSet: " +
        		highSet);
    }
    /**
     * Computes the next set of choices from the previous. The
     * algorithm tries to increment the index of the final choice
     * first. Should that fail (index goes out of bounds), it
     * tries to increment the next-to-the-last index, and resets
     * the last index to one more than the next-to-the-last.
     * Should this fail the algorithm keeps starting at an earlier
     * choice until it runs off the start of the choice list without
     * Finding a legal set of indices for all the choices.
     *
     * @return true unless all choice sets have been exhausted.
     * @author James Heliotis
     */

    private static boolean nextIndices(ArrayList<Long> a) {
        for(int i= indices.length-1;i >= 0;--i){
            indices[i]++;
            for(int j=i+1;j < indices.length;++j){
                indices[j]= indices[j - 1] + 1;//reset the last failed try
            }
            if(indices[indices.length - 1] < a.size()){//if this try went out of bounds
                return true;
            }
        }
        return false;
    }
}


Greedy algorithm for Egyptian fractions

An   Egyptian fraction   is the sum of distinct unit fractions such as:

::::   \tfrac{1}{2} + \tfrac{1}{3} + \tfrac{1}{16} \,(= \tfrac{43}{48})

Each fraction in the expression has a numerator equal to   '''1'''   (unity)   and a denominator that is a positive integer,   and all the denominators are distinct   (i.e., no repetitions).

Fibonacci's   Greedy algorithm for Egyptian fractions   expands the fraction     \tfrac{x}{y}     to be represented by repeatedly performing the replacement

::::   \frac{x}{y} = \frac{1}{\lceil y/x\rceil} + \frac{(-y)\!\!\!\!\mod x}{y\lceil y/x\rceil}

(simplifying the 2nd term in this replacement as necessary, and where     \lceil x \rceil     is the   ''ceiling''   function).

For this task,   Proper and improper fractions   must be able to be expressed.

Proper  fractions   are of the form    \tfrac{a}{b}    where    a    and    b    are positive integers, such that    a < b,     and

improper fractions are of the form    \tfrac{a}{b}    where    a    and    b    are positive integers, such that    ''a'' >= ''b''.

(See the REXX programming example to view one method of expressing the whole number part of an improper fraction.)

For improper fractions, the integer part of any improper fraction should be first isolated and shown preceding the Egyptian unit fractions, and be surrounded by square brackets [''n''].

;Task requirements:
*   show the Egyptian fractions for:  \tfrac{43}{48}  and  \tfrac{5}{121}  and  \tfrac{2014}{59}
*   for all proper fractions,    \tfrac{a}{b}    where    a    and    b    are positive one-or two-digit (decimal) integers, find and show an Egyptian fraction that has:
::*   the largest number of terms,
::*   the largest denominator.
*   for all one-, two-, and three-digit integers,   find and show (as above).     {extra credit}

;Also see:
*   Wolfram MathWorld(tm) entry: Egyptian fraction

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

public class EgyptianFractions {
    private static BigInteger gcd(BigInteger a, BigInteger b) {
        if (b.equals(BigInteger.ZERO)) {
            return a;
        }
        return gcd(b, a.mod(b));
    }

    private static class Frac implements Comparable<Frac> {
        private BigInteger num, denom;

        public Frac(BigInteger n, BigInteger d) {
            if (d.equals(BigInteger.ZERO)) {
                throw new IllegalArgumentException("Parameter d may not be zero.");
            }

            BigInteger nn = n;
            BigInteger dd = d;
            if (nn.equals(BigInteger.ZERO)) {
                dd = BigInteger.ONE;
            } else if (dd.compareTo(BigInteger.ZERO) < 0) {
                nn = nn.negate();
                dd = dd.negate();
            }
            BigInteger g = gcd(nn, dd).abs();
            if (g.compareTo(BigInteger.ZERO) > 0) {
                nn = nn.divide(g);
                dd = dd.divide(g);
            }
            num = nn;
            denom = dd;
        }

        public Frac(int n, int d) {
            this(BigInteger.valueOf(n), BigInteger.valueOf(d));
        }

        public Frac plus(Frac rhs) {
            return new Frac(
                num.multiply(rhs.denom).add(denom.multiply(rhs.num)),
                rhs.denom.multiply(denom)
            );
        }

        public Frac unaryMinus() {
            return new Frac(num.negate(), denom);
        }

        public Frac minus(Frac rhs) {
            return plus(rhs.unaryMinus());
        }

        @Override
        public int compareTo(Frac rhs) {
            BigDecimal diff = this.toBigDecimal().subtract(rhs.toBigDecimal());
            if (diff.compareTo(BigDecimal.ZERO) < 0) {
                return -1;
            }
            if (BigDecimal.ZERO.compareTo(diff) < 0) {
                return 1;
            }
            return 0;
        }

        @Override
        public boolean equals(Object obj) {
            if (null == obj || !(obj instanceof Frac)) {
                return false;
            }
            Frac rhs = (Frac) obj;
            return compareTo(rhs) == 0;
        }

        @Override
        public String toString() {
            if (denom.equals(BigInteger.ONE)) {
                return num.toString();
            }
            return String.format("%s/%s", num, denom);
        }

        public BigDecimal toBigDecimal() {
            BigDecimal bdn = new BigDecimal(num);
            BigDecimal bdd = new BigDecimal(denom);
            return bdn.divide(bdd, MathContext.DECIMAL128);
        }

        public List<Frac> toEgyptian() {
            if (num.equals(BigInteger.ZERO)) {
                return Collections.singletonList(this);
            }
            List<Frac> fracs = new ArrayList<>();
            if (num.abs().compareTo(denom.abs()) >= 0) {
                Frac div = new Frac(num.divide(denom), BigInteger.ONE);
                Frac rem = this.minus(div);
                fracs.add(div);
                toEgyptian(rem.num, rem.denom, fracs);
            } else {
                toEgyptian(num, denom, fracs);
            }
            return fracs;
        }

        public void toEgyptian(BigInteger n, BigInteger d, List<Frac> fracs) {
            if (n.equals(BigInteger.ZERO)) {
                return;
            }
            BigDecimal n2 = new BigDecimal(n);
            BigDecimal d2 = new BigDecimal(d);
            BigDecimal[] divRem = d2.divideAndRemainder(n2, MathContext.UNLIMITED);
            BigInteger div = divRem[0].toBigInteger();
            if (divRem[1].compareTo(BigDecimal.ZERO) > 0) {
                div = div.add(BigInteger.ONE);
            }
            fracs.add(new Frac(BigInteger.ONE, div));
            BigInteger n3 = d.negate().mod(n);
            if (n3.compareTo(BigInteger.ZERO) < 0) {
                n3 = n3.add(n);
            }
            BigInteger d3 = d.multiply(div);
            Frac f = new Frac(n3, d3);
            if (f.num.equals(BigInteger.ONE)) {
                fracs.add(f);
                return;
            }
            toEgyptian(f.num, f.denom, fracs);
        }
    }

    public static void main(String[] args) {
        List<Frac> fracs = List.of(
            new Frac(43, 48),
            new Frac(5, 121),
            new Frac(2014, 59)
        );
        for (Frac frac : fracs) {
            List<Frac> list = frac.toEgyptian();
            Frac first = list.get(0);
            if (first.denom.equals(BigInteger.ONE)) {
                System.out.printf("%s -> [%s] + ", frac, first);
            } else {
                System.out.printf("%s -> %s", frac, first);
            }
            for (int i = 1; i < list.size(); ++i) {
                System.out.printf(" + %s", list.get(i));
            }
            System.out.println();
        }

        for (Integer r : List.of(98, 998)) {
            if (r == 98) {
                System.out.println("\nFor proper fractions with 1 or 2 digits:");
            } else {
                System.out.println("\nFor proper fractions with 1, 2 or 3 digits:");
            }

            int maxSize = 0;
            List<Frac> maxSizeFracs = new ArrayList<>();
            BigInteger maxDen = BigInteger.ZERO;
            List<Frac> maxDenFracs = new ArrayList<>();
            boolean[][] sieve = new boolean[r + 1][];
            for (int i = 0; i < r + 1; ++i) {
                sieve[i] = new boolean[r + 2];
            }
            for (int i = 1; i < r; ++i) {
                for (int j = i + 1; j < r + 1; ++j) {
                    if (sieve[i][j]) continue;
                    Frac f = new Frac(i, j);
                    List<Frac> list = f.toEgyptian();
                    int listSize = list.size();
                    if (listSize > maxSize) {
                        maxSize = listSize;
                        maxSizeFracs.clear();
                        maxSizeFracs.add(f);
                    } else if (listSize == maxSize) {
                        maxSizeFracs.add(f);
                    }
                    BigInteger listDen = list.get(list.size() - 1).denom;
                    if (listDen.compareTo(maxDen) > 0) {
                        maxDen = listDen;
                        maxDenFracs.clear();
                        maxDenFracs.add(f);
                    } else if (listDen.equals(maxDen)) {
                        maxDenFracs.add(f);
                    }
                    if (i < r / 2) {
                        int k = 2;
                        while (true) {
                            if (j * k > r + 1) break;
                            sieve[i * k][j * k] = true;
                            k++;
                        }
                    }
                }
            }
            System.out.printf("  largest number of items = %s\n", maxSize);
            System.out.printf("fraction(s) with this number : %s\n", maxSizeFracs);
            String md = maxDen.toString();
            System.out.printf("  largest denominator = %s digits, ", md.length());
            System.out.printf("%s...%s\n", md.substring(0, 20), md.substring(md.length() - 20, md.length()));
            System.out.printf("fraction(s) with this denominator : %s\n", maxDenFracs);
        }
    }
}


Greyscale bars/Display

The task is to display a series of vertical greyscale bars (contrast bars) with a sufficient number of bars to span the entire width of the display.

For the top quarter of the display, the left hand bar should be black, and we then incrementally step through six shades of grey until we have a white bar on the right hand side of the display. (This gives a total of 8 bars)

For the second quarter down, we start with white and step down through 14 shades of gray, getting darker until we have black on the right hand side of the display. (This gives a total of 16 bars).

Halfway down the display, we start with black, and produce 32 bars, ending in white, and for the last quarter, we start with white and step through 62 shades of grey, before finally arriving at black in the bottom right hand corner, producing a total of 64 bars for the bottom quarter.

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

public class Greybars extends JFrame {
   private int width ;
   private int height ;

   public Greybars( )  {
      super( "grey bars example!" ) ;
      width = 640 ;
      height = 320 ;
      setSize( width , height ) ;
      setDefaultCloseOperation( JFrame.EXIT_ON_CLOSE ) ;
      setVisible( true ) ;
    }

    public void paint ( Graphics g ) {
      int run = 0 ;
      double colorcomp = 0.0 ; //component of the color
      for ( int columncount = 8 ; columncount < 128 ; columncount *= 2 ) {
	 double colorgap = 255.0 / (columncount - 1) ; //by this gap we change the background color
	 int columnwidth = width / columncount ;
	 int columnheight = height / 4 ;
	 if ( run % 2 == 0 ) //switches color directions with every for loop
	    colorcomp = 0.0 ;
	 else {
	    colorcomp = 255.0 ;
	    colorgap *= -1.0 ;
	 }
	 int ystart = 0 + columnheight * run ;
	 int xstart = 0 ;
	 for ( int i = 0 ; i < columncount ; i++ ) {
            int icolor = (int)Math.round(colorcomp) ; //round to nearer integer
	    Color nextColor = new Color( icolor , icolor, icolor ) ;
	    g.setColor( nextColor ) ;
	    g.fillRect( xstart , ystart , columnwidth , columnheight ) ;
	    xstart += columnwidth ;
	    colorcomp += colorgap ;
	 }
	 run++ ;
      }
    }

    public static void main( String[ ] args ) {
       Greybars gb = new Greybars( ) ;
    }
}


Hailstone sequence

The Hailstone sequence of numbers can be generated from a starting positive integer,   n   by:
*   If   n   is     '''1'''     then the sequence ends.
*   If   n   is   '''even''' then the next   n   of the sequence    = n/2
*   If   n   is   '''odd'''    then the next   n   of the sequence    = (3 * n) + 1

The (unproven) Collatz conjecture is that the hailstone sequence for any starting number always terminates.

This sequence was named by Lothar Collatz in 1937   (or possibly in 1939),   and is also known as (the):
:::*   hailstone sequence,   hailstone numbers
:::*   3x + 2 mapping,   3n + 1 problem
:::*   Collatz sequence
:::*   Hasse's algorithm
:::*   Kakutani's problem
:::*   Syracuse algorithm,   Syracuse problem
:::*   Thwaites conjecture
:::*   Ulam's problem

The hailstone sequence is also known as   ''hailstone numbers''   (because the values are usually subject to multiple descents and ascents like hailstones in a cloud).

;Task:
# Create a routine to generate the hailstone sequence for a number.
# Use the routine to show that the hailstone sequence for the number 27 has 112 elements starting with 27, 82, 41, 124 and ending with 8, 4, 2, 1
# Show the number less than 100,000 which has the longest hailstone sequence together with that sequence's length.    (But don't show the actual sequence!)

;See also:
*   xkcd (humourous).
*   The Notorious Collatz conjecture Terence Tao, UCLA (Presentation, pdf).
*   The Simplest Math Problem No One Can Solve Veritasium (video, sponsored).

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

class Hailstone {

  public static List<Long> getHailstoneSequence(long n) {
    if (n <= 0)
      throw new IllegalArgumentException("Invalid starting sequence number");
    List<Long> list = new ArrayList<Long>();
    list.add(Long.valueOf(n));
    while (n != 1) {
      if ((n & 1) == 0)
        n = n / 2;
      else
        n = 3 * n + 1;
      list.add(Long.valueOf(n));
    }
    return list;
  }

  public static void main(String[] args) {
    List<Long> sequence27 = getHailstoneSequence(27);
    System.out.println("Sequence for 27 has " + sequence27.size() + " elements: " + sequence27);

    long MAX = 100000;
    // Simple way
    {
      long highestNumber = 1;
      int highestCount = 1;
      for (long i = 2; i < MAX; i++) {
        int count = getHailstoneSequence(i).size();
        if (count > highestCount) {
          highestCount = count;
          highestNumber = i;
        }
      }
      System.out.println("Method 1, number " + highestNumber + " has the longest sequence, with a length of " + highestCount);
    }

    // More memory efficient way
    {
      long highestNumber = 1;
      int highestCount = 1;
      for (long i = 2; i < MAX; i++) {
        int count = 1;
        long n = i;
        while (n != 1) {
          if ((n & 1) == 0)
            n = n / 2;
          else
            n = 3 * n + 1;
          count++;
        }
        if (count > highestCount) {
          highestCount = count;
          highestNumber = i;
        }
      }
      System.out.println("Method 2, number " + highestNumber + " has the longest sequence, with a length of " + highestCount);
    }

    // Efficient for analyzing all sequences
    {
      long highestNumber = 1;
      long highestCount = 1;
      Map<Long, Integer> sequenceMap = new HashMap<Long, Integer>();
      sequenceMap.put(Long.valueOf(1), Integer.valueOf(1));

      List<Long> currentList = new ArrayList<Long>();
      for (long i = 2; i < MAX; i++) {
        currentList.clear();
        Long n = Long.valueOf(i);
        Integer count = null;
        while ((count = sequenceMap.get(n)) == null) {
          currentList.add(n);
          long nValue = n.longValue();
          if ((nValue & 1) == 0)
            n = Long.valueOf(nValue / 2);
          else
            n = Long.valueOf(3 * nValue + 1);
        }
        int curCount = count.intValue();
        for (int j = currentList.size() - 1; j >= 0; j--)
          sequenceMap.put(currentList.get(j), Integer.valueOf(++curCount));
        if (curCount > highestCount) {
          highestCount = curCount;
          highestNumber = i;
        }
      }
      System.out.println("Method 3, number " + highestNumber + " has the longest sequence, with a length of " + highestCount);
    }
    return;
  }
}


Harshad or Niven series

The Harshad or Niven numbers are positive integers >= 1 that are divisible by the sum of their digits.

For example,   '''42'''   is a Harshad number as   '''42'''   is divisible by   ('''4''' + '''2''')   without remainder.

Assume that the series is defined as the numbers in increasing order.

;Task:
The task is to create a function/method/procedure to generate successive members of the Harshad sequence.

Use it to:
::*   list the first '''20''' members of the sequence,   and
::*   list the first Harshad number greater than '''1000'''.

Show your output here.

;Related task
:*   Increasing gaps between consecutive Niven numbers

;See also
*    OEIS: A005349

Solution:
public class Harshad{
    private static long sumDigits(long n){
        long sum = 0;
        for(char digit:Long.toString(n).toCharArray()){
            sum += Character.digit(digit, 10);
        }
        return sum;
    }
    public static void main(String[] args){
        for(int count = 0, i = 1; count < 20;i++){
            if(i % sumDigits(i) == 0){
                System.out.println(i);
                count++;
            }
        }
        System.out.println();
        for(int i = 1001; ; i++){
            if(i % sumDigits(i) == 0){
                System.out.println(i);
                break;
            }
        }
    }
}


Hash join

{| class="wikitable"
|-
! Input
! Output
|-
|

{| style="border:none; border-collapse:collapse;"
|-
| style="border:none" | ''A'' =
| style="border:none" |

{| class="wikitable"
|-
! Age !! Name
|-
| 27 || Jonah
|-
| 18 || Alan
|-
| 28 || Glory
|-
| 18 || Popeye
|-
| 28 || Alan
|}

| style="border:none; padding-left:1.5em;" rowspan="2" |
| style="border:none" | ''B'' =
| style="border:none" |

{| class="wikitable"
|-
! Character !! Nemesis
|-
| Jonah || Whales
|-
| Jonah || Spiders
|-
| Alan || Ghosts
|-
| Alan || Zombies
|-
| Glory || Buffy
|}

|-
| style="border:none" | ''jA'' =
| style="border:none" | Name (i.e. column 1)

| style="border:none" | ''jB'' =
| style="border:none" | Character (i.e. column 0)
|}

|

{| class="wikitable" style="margin-left:1em"
|-
! A.Age !! A.Name !! B.Character !! B.Nemesis
|-
| 27 || Jonah || Jonah || Whales
|-
| 27 || Jonah || Jonah || Spiders
|-
| 18 || Alan || Alan || Ghosts
|-
| 18 || Alan || Alan || Zombies
|-
| 28 || Glory || Glory || Buffy
|-
| 28 || Alan || Alan || Ghosts
|-
| 28 || Alan || Alan || Zombies
|}

|}

The order of the rows in the output table is not significant.
If you're using numerically indexed arrays to represent table rows (rather than referring to columns by name), you could represent the output rows in the form [[27, "Jonah"], ["Jonah", "Whales"]].

Solution:
import java.util.*;

public class HashJoin {

    public static void main(String[] args) {
        String[][] table1 = {{"27", "Jonah"}, {"18", "Alan"}, {"28", "Glory"},
        {"18", "Popeye"}, {"28", "Alan"}};

        String[][] table2 = {{"Jonah", "Whales"}, {"Jonah", "Spiders"},
        {"Alan", "Ghosts"}, {"Alan", "Zombies"}, {"Glory", "Buffy"},
        {"Bob", "foo"}};

        hashJoin(table1, 1, table2, 0).stream()
                .forEach(r -> System.out.println(Arrays.deepToString(r)));
    }

    static List<String[][]> hashJoin(String[][] records1, int idx1,
            String[][] records2, int idx2) {

        List<String[][]> result = new ArrayList<>();
        Map<String, List<String[]>> map = new HashMap<>();

        for (String[] record : records1) {
            List<String[]> v = map.getOrDefault(record[idx1], new ArrayList<>());
            v.add(record);
            map.put(record[idx1], v);
        }

        for (String[] record : records2) {
            List<String[]> lst = map.get(record[idx2]);
            if (lst != null) {
                lst.stream().forEach(r -> {
                    result.add(new String[][]{r, record});
                });
            }
        }

        return result;
    }
}


Haversine formula

{{Wikipedia}}

The '''haversine formula''' is an equation important in navigation, giving great-circle distances between two points on a sphere from their longitudes and latitudes.

It is a special case of a more general formula  in spherical trigonometry, the '''law of haversines''', relating the sides and angles of spherical "triangles".

;Task:
Implement a great-circle distance function, or use a library function,
to show the great-circle distance between:
* Nashville International Airport (BNA)   in Nashville, TN, USA,   which is:
    '''N''' 36deg7.2',   '''W''' 86deg40.2'     (36.12,   -86.67)           -and-
* Los Angeles International Airport (LAX)  in Los Angeles, CA, USA,   which is:
    '''N''' 33deg56.4',  '''W''' 118deg24.0'    (33.94,  -118.40)

User Kaimbridge clarified on the Talk page:

 -- 6371.0 km is the authalic radius based on/extracted from surface area;
 -- 6372.8 km is an approximation of the radius of the average circumference
    (i.e., the average great-elliptic or great-circle radius), where the
     boundaries are the meridian (6367.45 km) and the equator (6378.14 km).

Using either of these values results, of course, in differing distances:

 6371.0 km -> 2886.44444283798329974715782394574671655 km;
 6372.8 km -> 2887.25995060711033944886005029688505340 km;
 (results extended for accuracy check:  Given that the radii are only
  approximations anyways, .01'  1.0621333 km and .001"  .00177 km,
  practical precision required is certainly no greater than about
  .0000001----i.e., .1 mm!)

As distances are segments of great circles/circumferences, it is
recommended that the latter value (r = 6372.8 km) be used (which
most of the given solutions have already adopted, anyways).

Most of the examples below adopted Kaimbridge's recommended value of
6372.8 km for the earth radius.  However, the derivation of this
ellipsoidal quadratic mean radius
is wrong (the averaging over azimuth is biased).  When applying these
examples in real applications, it is better to use the
mean earth radius,
6371 km.  This value is recommended by the International Union of
Geodesy and Geophysics and it minimizes the RMS relative error between the
great circle and geodesic distance.

Solution:
public class Haversine {
    public static final double R = 6372.8; // In kilometers

    public static double haversine(double lat1, double lon1, double lat2, double lon2) {
        lat1 = Math.toRadians(lat1);
        lat2 = Math.toRadians(lat2);
        double dLat = lat2 - lat1;
        double dLon = Math.toRadians(lon2 - lon1);

        double a = Math.pow(Math.sin(dLat / 2), 2) + Math.pow(Math.sin(dLon / 2), 2) * Math.cos(lat1) * Math.cos(lat2);
        double c = 2 * Math.asin(Math.sqrt(a));
        return R * c;
    }

    public static void main(String[] args) {
        System.out.println(haversine(36.12, -86.67, 33.94, -118.40));
    }
}


Hello world/Line printer

Cause a line printer attached to the computer to print a line containing the message:    Hello World!

;Note:
A line printer is not the same as standard output.

A   line printer   was an older-style printer which prints one line at a time to a continuous ream of paper.

With some systems, a line printer can be any device attached to an appropriate port (such as a parallel port).

Solution:
import java.io.FileWriter;
import java.io.IOException;

public class LinePrinter {
  public static void main(String[] args) {
    try {
      FileWriter lp0 = new FileWriter("/dev/lp0");
      lp0.write("Hello World!");
      lp0.close();
    } catch (IOException ioe) {
      ioe.printStackTrace();
    }
  }
}


Hello world/Newbie

Guide a new user of a language through the steps necessary
to install the programming language and selection of a text editor if needed,
to run the languages' example in the [[Hello world/Text]] task.
* Assume the language-newbie is a programmer in another language.
* Assume the language-newbie is competent in installing software for the platform.
* Assume the language-newbie can use one simple text editor for the OS/platform, (but that may not necessarily be a particular one if the installation needs a particular editor).
* Refer to, (and link to), already existing documentation as much as possible (but provide a summary here).
* Remember to state where to view the output.
* If particular IDE's or editors are required that are not standard, then point to/explain their installation too.

;Note:
* If it is more natural for a language to give output via a GUI or to a file etc, then use that method of output rather than as text to a terminal/command-line, but remember to give instructions on how to view the output generated.
* You may use sub-headings if giving instructions for multiple platforms.

Solution:
public class HelloWorld {
    public static void main(String[]args){
        HelloWorld hw = new HelloWorld();
        hw.run();
    }

    void run(){
        //Print 'Hello world!' to console/terminal
        System.out.println("Hello world!");
    }
}


Heronian triangles

Hero's formula for the area of a triangle given the length of its three sides    ''a'',   ''b'',   and   ''c''   is given by:

:::: A = \sqrt{s(s-a)(s-b)(s-c)},

where   ''s''   is half the perimeter of the triangle; that is,

:::: s=\frac{a+b+c}{2}.

'''Heronian triangles'''
are triangles whose sides ''and area'' are all integers.
: An example is the triangle with sides   '''3, 4, 5'''   whose area is   '''6'''   (and whose perimeter is   '''12''').

Note that any triangle whose sides are all an integer multiple of   '''3, 4, 5''';   such as   '''6, 8, 10,'''   will also be a Heronian triangle.

Define a '''Primitive Heronian triangle''' as a Heronian triangle where the greatest common divisor
of all three sides is   '''1'''   (unity).

This will exclude, for example, triangle   '''6, 8, 10.'''

;Task:
# Create a named function/method/procedure/... that implements Hero's formula.
# Use the function to generate all the ''primitive'' Heronian triangles with sides <= 200.
# Show the count of how many triangles are found.
# Order the triangles by first increasing area, then by increasing perimeter, then by increasing maximum side lengths
# Show the first ten ordered triangles in a table of sides, perimeter, and area.
# Show a similar ordered table for those triangles with area = 210

Show all output here.

'''Note''': when generating triangles it may help to restrict a <= b <= c

Solution:
import java.util.ArrayList;

public class Heron {
    public static void main(String[] args) {
        ArrayList<int[]> list = new ArrayList<>();

        for (int c = 1; c <= 200; c++) {
            for (int b = 1; b <= c; b++) {
                for (int a = 1; a <= b; a++) {

                    if (gcd(gcd(a, b), c) == 1 && isHeron(heronArea(a, b, c))){
                        int area = (int) heronArea(a, b, c);
                        list.add(new int[]{a, b, c, a + b + c, area});
                    }
                }
            }
        }
        sort(list);

        System.out.printf("Number of primitive Heronian triangles with sides up "
                + "to 200: %d\n\nFirst ten when ordered by increasing area, then"
                + " perimeter:\nSides       Perimeter   Area", list.size());

        for (int i = 0; i < 10; i++) {
            System.out.printf("\n%d x %d x %d   %d      %d",
                    list.get(i)[0], list.get(i)[1], list.get(i)[2],
                    list.get(i)[3], list.get(i)[4]);
        }

        System.out.printf("\n\nArea = 210\nSides        Perimeter   Area");
        for (int i = 0; i < list.size(); i++) {
            if (list.get(i)[4] == 210)
                System.out.printf("\n%d x %d x %d   %d      %d",
                        list.get(i)[0], list.get(i)[1], list.get(i)[2],
                        list.get(i)[3], list.get(i)[4]);
        }
    }

    public static double heronArea(int a, int b, int c) {
        double s = (a + b + c) / 2f;
        return Math.sqrt(s * (s - a) * (s - b) * (s - c));
    }

    public static boolean isHeron(double h) {
        return h % 1 == 0 && h > 0;
    }

    public static int gcd(int a, int b) {
        int leftover = 1, dividend = a > b ? a : b, divisor = a > b ? b : a;
        while (leftover != 0) {
            leftover = dividend % divisor;
            if (leftover > 0) {
                dividend = divisor;
                divisor = leftover;
            }
        }
        return divisor;
    }

    public static void sort(ArrayList<int[]> list) {
        boolean swapped = true;
        int[] temp;
        while (swapped) {
            swapped = false;
            for (int i = 1; i < list.size(); i++) {
                if (list.get(i)[4] < list.get(i - 1)[4] ||
                        list.get(i)[4] == list.get(i - 1)[4] &&
                        list.get(i)[3] < list.get(i - 1)[3]) {
                    temp = list.get(i);
                    list.set(i, list.get(i - 1));
                    list.set(i - 1, temp);
                    swapped = true;
                }
            }
        }
    }
}


Hickerson series of almost integers

The following function,   due to D. Hickerson,   is said to generate "Almost integers" by the
"Almost Integer" page of Wolfram MathWorld,   (December 31 2013).   (See formula numbered   '''51'''.)

The function is:           h(n) = {\operatorname{n}!\over2(\ln{2})^{n+1}}

It is said to produce "almost integers" for   '''n'''   between   '''1'''   and   '''17'''.
The purpose of the task is to verify this assertion.

Assume that an "almost integer" has '''either a nine or a zero as its first digit after the decimal point''' of its decimal string representation

;Task:
Calculate all values of the function checking and stating which are "almost integers".

Note: Use extended/arbitrary precision numbers in your calculation if necessary to ensure you have adequate precision of results as for example:
                h(18) = 3385534663256845326.39...

Solution:
import java.math.*;

public class Hickerson {

    final static String LN2 = "0.693147180559945309417232121458";

    public static void main(String[] args) {
        for (int n = 1; n <= 17; n++)
            System.out.printf("%2s is almost integer: %s%n", n, almostInteger(n));
    }

    static boolean almostInteger(int n) {
        BigDecimal a = new BigDecimal(LN2);
        a = a.pow(n + 1).multiply(BigDecimal.valueOf(2));

        long f = n;
        while (--n > 1)
            f *= n;

        BigDecimal b = new BigDecimal(f);
        b = b.divide(a, MathContext.DECIMAL128);

        BigInteger c = b.movePointRight(1).toBigInteger().mod(BigInteger.TEN);

        return c.toString().matches("0|9");
    }
}


History variables

''Storing the history of objects in a program is a common task.
Maintaining the history of an object in a program has traditionally required programmers either to write specific code for handling the historical data, or to use a library which supports history logging.''

''History variables are variables in a programming language which store not only their current value, but also the values they have contained in the past. Some existing languages do provide support for history variables. However these languages typically have many limits and restrictions on use of history variables.
''

"History Variables:
The Semantics, Formal Correctness, and Implementation of History Variables
in an Imperative Programming Language" by Mallon and Takaoka

Concept also discussed on LtU and Patents.com.

;Task:
Demonstrate History variable support:
* enable history variable support (if needed)
* define a history variable
* assign three values
* non-destructively display the history
* recall the three values.

For extra points, if the language of choice does not support history variables,
demonstrate how this might be implemented.

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

/**
 * A class for an "Integer with a history".
 * <p>
 * Note that it is not possible to create an empty Variable (so there is no "null") with this type. This is a design
 * choice, because if "empty" variables were allowed, reading of empty variables must return a value. Null is a
 * bad idea, and Java 8's Optional<T> (which is somewhat like the the official fix for the null-bad-idea) would
 * make things more complicated than an example should be.
 */
public class IntegerWithHistory {

    /**
     * The "storage Backend" is a list of all values that have been ever assigned to this variable. The List is
     * populated front to back, so a new value is inserted at the start (position 0), and older values move toward the end.
     */
    private final List<Integer> history;

    /**
     * Creates this variable and assigns the initial value
     *
     * @param value initial value
     */
    public IntegerWithHistory(Integer value) {
        history = new LinkedList<>();
        history.add(value);
    }

    /**
     * Sets a new value, pushing the older ones back in the history
     *
     * @param value the new value to be assigned
     */
    public void set(Integer value) {
        //History is populated from the front to the back, so the freshest value is stored a position 0
        history.add(0, value);
    }

    /**
     * Gets the current value. Since history is populuated front to back, the current value is the first element
     * of the history.
     *
     * @return the current value
     */
    public Integer get() {
        return history.get(0);
    }

    /**
     * Gets the entire history all values that have been assigned to this variable.
     *
     * @return a List of all values, including the current one, ordered new to old
     */
    public List<Integer> getHistory() {
        return Collections.unmodifiableList(this.history);
    }

    /**
     * Rolls back the history one step, so the current value is removed from the history and replaced by it's predecessor.
     * This is a destructive operation! It is not possible to rollback() beyond the initial value!
     *
     * @return the value that had been the current value until history was rolled back.
     */
    public Integer rollback() {
        if (history.size() > 1) {
            return history.remove(0);
        } else {
            return history.get(0);
        }
    }
}


Hofstadter-Conway $10,000 sequence

The definition of the sequence is colloquially described as:
*   Starting with the list [1,1],
*   Take the last number in the list so far: 1, I'll call it x.
*   Count forward x places from the beginning of the list to find the first number to add (1)
*   Count backward x places from the end of the list to find the second number to add (1)
*   Add the two indexed numbers from the list and the result becomes the next number in the list (1+1)
*   This would then produce [1,1,2] where 2 is the third element of the sequence.

Note that indexing for the description above starts from alternately the left and right ends of the list and starts from an index of ''one''.

A less wordy description of the sequence is:
    a(1)=a(2)=1
    a(n)=a(a(n-1))+a(n-a(n-1))

The sequence begins:
    1, 1, 2, 2, 3, 4, 4, 4, 5, ...

Interesting features of the sequence are that:
*   a(n)/n   tends to   0.5   as   n   grows towards infinity.
*   a(n)/n   where   n   is a power of   2   is   0.5
*   For   n>4   the maximal value of   a(n)/n   between successive powers of 2 decreases.

a(n) / n   for   n   in   1..256

The sequence is so named because John Conway offered a prize of $10,000 to the first person who could
find the first position,   p   in the sequence where
    |a(n)/n| < 0.55  for all  n > p
It was later found that Hofstadter had also done prior work on the sequence.

The 'prize' was won quite quickly by Dr. Colin L. Mallows who proved the properties of the sequence and allowed him to find the value of   n   (which is much smaller than the 3,173,375,556 quoted in the NYT article).

;Task:
#   Create a routine to generate members of the Hofstadter-Conway $10,000 sequence.
#   Use it to show the maxima of   a(n)/n   between successive powers of two up to   2**20
#   As a stretch goal:   compute the value of   n   that would have won the prize and confirm it is true for   n   up to 2**20

;Also see:
*   Conways Challenge Sequence, Mallows' own account.
*   Mathworld Article.

Solution:
//  Title:  Hofstadter-Conway $10,000 sequence

public class HofstadterConwaySequence {

    private static int MAX = (int) Math.pow(2, 20) + 1;
    private static int[] HCS = new int[MAX];
    static {
        HCS[1] = 1;
        HCS[2] = 1;
        for ( int n = 3 ; n < MAX ; n++ ) {
            int nm1 = HCS[n - 1];
            HCS[n] = HCS[nm1] + HCS[n - nm1];
        }
    }

    public static void main(String[] args) {
        int mNum = 0;
        for ( int m = 1 ; m < 20 ; m++ ) {
            int min = (int) Math.pow(2, m);
            int max = min * 2;
            double maxRatio = 0.0;
            int nVal = 0;
            for ( int n = min ; n <= max ; n ++ ) {
                double ratio = (double) HCS[n] / n;
                if ( ratio > maxRatio ) {
                    maxRatio = Math.max(ratio,  maxRatio);
                    nVal = n;
                }
                if ( ratio >= 0.55 ) {
                    mNum = n;
                }
            }
            System.out.printf("Max ratio between 2^%d and 2^%d is %f at n = %,d%n", m, m+1, maxRatio, nVal);
        }
        System.out.printf("Mallow's number is %d.%n", mNum);
    }

}


Hofstadter Figure-Figure sequences

These two sequences of positive integers are defined as:
:::: \begin{align}
R(1)&=1\ ;\ S(1)=2 \\
R(n)&=R(n-1)+S(n-1), \quad n>1.
\end{align}

The sequence S(n) is further defined as the sequence of positive integers '''''not''''' present in R(n).

Sequence R starts:
    1, 3, 7, 12, 18, ...
Sequence S starts:
    2, 4, 5, 6, 8, ...

;Task:
# Create two functions named '''ffr''' and '''ffs''' that when given '''n''' return '''R(n)''' or '''S(n)''' respectively.(Note that R(1) = 1 and S(1) = 2 to avoid off-by-one errors).
# No maximum value for '''n''' should be assumed.
# Calculate and show that the first ten values of '''R''' are: 1, 3, 7, 12, 18, 26, 35, 45, 56, and 69
# Calculate and show that the first 40 values of '''ffr''' plus the first 960 values of '''ffs''' include all the integers from 1 to 1000 exactly once.

;References:
* Sloane's A005228 and A030124.
* Wolfram MathWorld
* Wikipedia: Hofstadter Figure-Figure sequences.

Solution:
import java.util.*;

class Hofstadter
{
  private static List<Integer> getSequence(int rlistSize, int slistSize)
  {
    List<Integer> rlist = new ArrayList<Integer>();
    List<Integer> slist = new ArrayList<Integer>();
    Collections.addAll(rlist, 1, 3, 7);
    Collections.addAll(slist, 2, 4, 5, 6);
    List<Integer> list = (rlistSize > 0) ? rlist : slist;
    int targetSize = (rlistSize > 0) ? rlistSize : slistSize;
    while (list.size() > targetSize)
      list.remove(list.size() - 1);
    while (list.size() < targetSize)
    {
      int lastIndex = rlist.size() - 1;
      int lastr = rlist.get(lastIndex).intValue();
      int r = lastr + slist.get(lastIndex).intValue();
      rlist.add(Integer.valueOf(r));
      for (int s = lastr + 1; (s < r) && (list.size() < targetSize); s++)
        slist.add(Integer.valueOf(s));
    }
    return list;
  }

  public static int ffr(int n)
  {  return getSequence(n, 0).get(n - 1).intValue();  }

  public static int ffs(int n)
  {  return getSequence(0, n).get(n - 1).intValue();  }

  public static void main(String[] args)
  {
    System.out.print("R():");
    for (int n = 1; n <= 10; n++)
      System.out.print(" " + ffr(n));
    System.out.println();

    Set<Integer> first40R = new HashSet<Integer>();
    for (int n = 1; n <= 40; n++)
      first40R.add(Integer.valueOf(ffr(n)));

    Set<Integer> first960S = new HashSet<Integer>();
    for (int n = 1; n <= 960; n++)
      first960S.add(Integer.valueOf(ffs(n)));

    for (int i = 1; i <= 1000; i++)
    {
      Integer n = Integer.valueOf(i);
      if (first40R.contains(n) == first960S.contains(n))
        System.out.println("Integer " + i + " either in both or neither set");
    }
    System.out.println("Done");
  }
}


Hofstadter Q sequence

The Hofstadter Q sequence is defined as:
:: \begin{align}
Q(1)&=Q(2)=1, \\
Q(n)&=Q\big(n-Q(n-1)\big)+Q\big(n-Q(n-2)\big), \quad n>2.
\end{align}

It is defined like the [[Fibonacci sequence]], but whereas the next term in the Fibonacci sequence is the sum of the previous two terms, in the Q sequence the previous two terms tell you how far to go back in the Q sequence to find the two numbers to sum to make the next term of the sequence.

;Task:
* Confirm and display that the first ten terms of the sequence are: 1, 1, 2, 3, 3, 4, 5, 5, 6, and 6
* Confirm and display that the 1000th term is:   502

;Optional extra credit
* Count and display how many times a member of the sequence is less than its preceding term for terms up to and including the 100,000th term.
* Ensure that the extra credit solution   ''safely''   handles being initially asked for an '''n'''th term where   '''n'''   is large.
(This point is to ensure that caching and/or recursion limits, if it is a concern, is correctly handled).

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

public class HofQ {
	private static Map<Integer, Integer> q = new HashMap<Integer, Integer>(){{
		put(1, 1);
		put(2, 1);
	}};

	private static int[] nUses = new int[100001];//not part of the task

	public static int Q(int n){
		nUses[n]++;//not part of the task
		if(q.containsKey(n)){
			return q.get(n);
		}
		int ans = Q(n - Q(n - 1)) + Q(n - Q(n - 2));
		q.put(n, ans);
		return ans;
	}

	public static void main(String[] args){
		for(int i = 1; i <= 10; i++){
			System.out.println("Q(" + i + ") = " + Q(i));
		}
		int last = 6;//value for Q(10)
		int count = 0;
		for(int i = 11; i <= 100000; i++){
			int curr = Q(i);
			if(curr < last) count++;
			last = curr;
			if(i == 1000) System.out.println("Q(1000) = " + curr);
		}
		System.out.println("Q(i) is less than Q(i-1) for i <= 100000 " + count + " times");

		//Optional stuff below here
		int maxUses = 0, maxN = 0;
		for(int i = 1; i<nUses.length;i++){
			if(nUses[i] > maxUses){
				maxUses = nUses[i];
				maxN = i;
			}
		}
		System.out.println("Q(" + maxN + ") was called the most with " + maxUses + " calls");
	}
}