Permutations/Rank of a permutation

A particular ranking of a permutation associates an integer with a particular ordering of all the permutations of a set of distinct items.
For our purposes the ranking will assign integers 0 .. (n! - 1) to an ordering of all the permutations of the integers 0 .. (n - 1).

For example, the permutations of the digits zero to 3 arranged lexicographically have the following rank:

  PERMUTATION      RANK
  (0, 1, 2, 3) ->  0
  (0, 1, 3, 2) ->  1
  (0, 2, 1, 3) ->  2
  (0, 2, 3, 1) ->  3
  (0, 3, 1, 2) ->  4
  (0, 3, 2, 1) ->  5
  (1, 0, 2, 3) ->  6
  (1, 0, 3, 2) ->  7
  (1, 2, 0, 3) ->  8
  (1, 2, 3, 0) ->  9
  (1, 3, 0, 2) -> 10
  (1, 3, 2, 0) -> 11
  (2, 0, 1, 3) -> 12
  (2, 0, 3, 1) -> 13
  (2, 1, 0, 3) -> 14
  (2, 1, 3, 0) -> 15
  (2, 3, 0, 1) -> 16
  (2, 3, 1, 0) -> 17
  (3, 0, 1, 2) -> 18
  (3, 0, 2, 1) -> 19
  (3, 1, 0, 2) -> 20
  (3, 1, 2, 0) -> 21
  (3, 2, 0, 1) -> 22
  (3, 2, 1, 0) -> 23

Algorithms exist that can generate a rank from a permutation for some particular ordering of permutations, and that can generate the same rank from the given individual permutation (i.e. given a rank of 17 produce (2, 3, 1, 0) in the example above).

One use of such algorithms could be in generating a small, random, sample of permutations of n items without duplicates when the total number of permutations is large. Remember that the total number of permutations of n items is given by n! which grows large very quickly: A 32 bit integer can only hold 12!, a 64 bit integer only 20!. It becomes difficult to take the straight-forward approach of generating all permutations then taking a random sample of them.

A question on the Stack Overflow site asked how to generate one million random and indivudual permutations of 144 items.

;Task:
# Create a function to generate a permutation from a rank.
# Create the inverse function that given the permutation generates its rank.
# Show that for n=3 the two functions are indeed inverses of each other.
# Compute and show here 4 random, individual, samples of permutations of 12 objects.

;Stretch goal:
* State how reasonable it would be to use your program to address the limits of the Stack Overflow question.

;References:
# Ranking and Unranking Permutations in Linear Time by Myrvold & Ruskey. (Also available via Google here).
# Ranks on the DevData site.
# Another answer on Stack Overflow to a different question that explains its algorithm in detail.

;Related tasks:
#[[Factorial_base_numbers_indexing_permutations_of_a_collection]]

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

class RankPermutation
{
  public static BigInteger getRank(int[] permutation)
  {
    int n = permutation.length;
    BitSet usedDigits = new BitSet();
    BigInteger rank = BigInteger.ZERO;
    for (int i = 0; i < n; i++)
    {
      rank = rank.multiply(BigInteger.valueOf(n - i));
      int digit = 0;
      int v = -1;
      while ((v = usedDigits.nextClearBit(v + 1)) < permutation[i])
        digit++;
      usedDigits.set(v);
      rank = rank.add(BigInteger.valueOf(digit));
    }
    return rank;
  }

  public static int[] getPermutation(int n, BigInteger rank)
  {
    int[] digits = new int[n];
    for (int digit = 2; digit <= n; digit++)
    {
      BigInteger divisor = BigInteger.valueOf(digit);
      digits[n - digit] = rank.mod(divisor).intValue();
      if (digit < n)
        rank = rank.divide(divisor);
    }
    BitSet usedDigits = new BitSet();
    int[] permutation = new int[n];
    for (int i = 0; i < n; i++)
    {
      int v = usedDigits.nextClearBit(0);
      for (int j = 0; j < digits[i]; j++)
        v = usedDigits.nextClearBit(v + 1);
      permutation[i] = v;
      usedDigits.set(v);
    }
    return permutation;
  }

  public static void main(String[] args)
  {
    for (int i = 0; i < 6; i++)
    {
      int[] permutation = getPermutation(3, BigInteger.valueOf(i));
      System.out.println(String.valueOf(i) + " --> " + Arrays.toString(permutation) + " --> " + getRank(permutation));
    }
    Random rnd = new Random();
    for (int n : new int[] { 12, 144 })
    {
      BigInteger factorial = BigInteger.ONE;
      for (int i = 2; i <= n; i++)
        factorial = factorial.multiply(BigInteger.valueOf(i));
      // Create 5 random samples
      System.out.println("n = " + n);
      for (int i = 0; i < 5; i++)
      {
        BigInteger rank = new BigInteger((factorial.bitLength() + 1) << 1, rnd);
        rank = rank.mod(factorial);
        int[] permutation = getPermutation(n, rank);
        System.out.println("  " + rank + " --> " + Arrays.toString(permutation) + " --> " + getRank(permutation));
      }
    }
  }

}


Permutations by swapping

Generate permutations of n items in which successive permutations differ from each other by the swapping of any two items.

Also generate the sign of the permutation which is +1 when the permutation is generated from an even number of swaps from the initial state, and -1 for odd.

Show the permutations and signs of three items, in order of generation ''here''.

Such data are of use in generating the determinant of a square matrix and any functions created should bear this in mind.

Note: The Steinhaus-Johnson-Trotter algorithm generates successive permutations where ''adjacent'' items are swapped, but from this discussion adjacency is not a requirement.

;References:
* Steinhaus-Johnson-Trotter algorithm
* Johnson-Trotter Algorithm Listing All Permutations
* Heap's algorithm
* Tintinnalogia

;Related tasks:
*   [[Matrix arithmetic]
*   [[Gray code]]

Solution:
package org.rosettacode.java;

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

public class HeapsAlgorithm {

	public static void main(String[] args) {
		Object[] array = IntStream.range(0, 4)
				.boxed()
				.toArray();
		HeapsAlgorithm algorithm = new HeapsAlgorithm();
		algorithm.recursive(array);
		System.out.println();
		algorithm.loop(array);
	}

	void recursive(Object[] array) {
		recursive(array, array.length, true);
	}

	void recursive(Object[] array, int n, boolean plus) {
		if (n == 1) {
			output(array, plus);
		} else {
			for (int i = 0; i < n; i++) {
				recursive(array, n - 1, i == 0);
				swap(array, n % 2 == 0 ? i : 0, n - 1);
			}
		}
	}

	void output(Object[] array, boolean plus) {
		System.out.println(Arrays.toString(array) + (plus ? " +1" : " -1"));
	}

	void swap(Object[] array, int a, int b) {
		Object o = array[a];
		array[a] = array[b];
		array[b] = o;
	}

	void loop(Object[] array) {
		loop(array, array.length);
	}

	void loop(Object[] array, int n) {
		int[] c = new int[n];
		output(array, true);
		boolean plus = false;
		for (int i = 0; i < n; ) {
			if (c[i] < i) {
				if (i % 2 == 0) {
					swap(array, 0, i);
				} else {
					swap(array, c[i], i);
				}
				output(array, plus);
				plus = !plus;
				c[i]++;
				i = 0;
			} else {
				c[i] = 0;
				i++;
			}
		}
	}
}


Phrase reversals

Given a string of space separated words containing the following phrase:
  rosetta code phrase reversal

:# Reverse the characters of the string.
:# Reverse the characters of each individual word in the string, maintaining original word order within the string.
:# Reverse the order of each word of the string, maintaining the order of characters in each word.

Show your output here.

Solution:
import java.util.Arrays;

public class PhraseRev{
	private static String reverse(String x){
		return new StringBuilder(x).reverse().toString();
	}

	private static <T> T[] reverse(T[] x){
		T[] rev = Arrays.copyOf(x, x.length);
		for(int i = x.length - 1; i >= 0; i--){
			rev[x.length - 1 - i] = x[i];
		}
		return rev;
	}

	private static String join(String[] arr, String joinStr){
		StringBuilder joined = new StringBuilder();
		for(int i = 0; i < arr.length; i++){
			joined.append(arr[i]);
			if(i < arr.length - 1) joined.append(joinStr);
		}
		return joined.toString();
	}

	public static void main(String[] args){
		String str = "rosetta code phrase reversal";

		System.out.println("Straight-up reversed: " + reverse(str));
		String[] words = str.split(" ");
		for(int i = 0; i < words.length; i++){
			words[i] = reverse(words[i]);
		}
		System.out.println("Reversed words: " + join(words, " "));
		System.out.println("Reversed word order: " + join(reverse(str.split(" ")), " "));
	}
}


Pig the dice game

The   game of Pig   is a multiplayer game played with a single six-sided die.   The
object of the game is to reach   '''100'''   points or more.
Play is taken in turns.   On each person's turn that person has the option of either:

:# '''Rolling the dice''':   where a roll of two to six is added to their score for that turn and the player's turn continues as the player is given the same choice again;   or a roll of   '''1'''   loses the player's total points   ''for that turn''   and their turn finishes with play passing to the next player.
:# '''Holding''':   the player's score for that round is added to their total and becomes safe from the effects of throwing a   '''1'''   (one).   The player's turn finishes with play passing to the next player.

;Task:
Create a program to score for, and simulate dice throws for, a two-person game.

;Related task:
*   [[Pig the dice game/Player]]

Solution:
import java.util.*;

public class PigDice {

    public static void main(String[] args) {
        final int maxScore = 100;
        final int playerCount = 2;
        final String[] yesses = {"y", "Y", ""};

        int[] safeScore = new int[2];
        int player = 0, score = 0;

        Scanner sc = new Scanner(System.in);
        Random rnd = new Random();

        while (true) {
            System.out.printf(" Player %d: (%d, %d) Rolling? (y/n) ", player,
                    safeScore[player], score);
            if (safeScore[player] + score < maxScore
                    && Arrays.asList(yesses).contains(sc.nextLine())) {
                final int rolled = rnd.nextInt(6) + 1;
                System.out.printf(" Rolled %d\n", rolled);
                if (rolled == 1) {
                    System.out.printf(" Bust! You lose %d but keep %d\n\n",
                            score, safeScore[player]);
                } else {
                    score += rolled;
                    continue;
                }
            } else {
                safeScore[player] += score;
                if (safeScore[player] >= maxScore)
                    break;
                System.out.printf(" Sticking with %d\n\n", safeScore[player]);
            }
            score = 0;
            player = (player + 1) % playerCount;
        }
        System.out.printf("\n\nPlayer %d wins with a score of %d",
                player, safeScore[player]);
    }
}


Pig the dice game

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

public interface PigDice {
  public static void main(String... arguments) {
    final int maxScore = 100;
    final int playerCount = 2;
    final String[] yesses = {"y", "Y", ""};

    final Scanner scanner = new Scanner(System.in);
    final Random random = new Random();

    final int[] safeScore = new int[2];
    final int[] score = new int[2];

    IntStream.iterate(0, player -> (player + 1) % playerCount)
      .map(player -> {
        boolean isRolling = true;
        while (isRolling) {
          System.out.printf(
            "Player %d: (%d, %d) Rolling? (y/n) ",
            player,
            safeScore[player],
            score[player]
          );
          isRolling =
            safeScore[player] + score[player] < maxScore
              && Arrays.asList(yesses).contains(scanner.nextLine())
          ;
          if (isRolling) {
            final int rolled = random.nextInt(6) + 1;
            System.out.printf("Rolled %d\n", rolled);
            if (rolled == 1) {
              System.out.printf(
                "Bust! You lose %d but keep %d\n\n",
                score[player],
                safeScore[player]
              );
              return -1;
            } else {
              score[player] += rolled;
            }
          } else {
            safeScore[player] += score[player];
            if (safeScore[player] >= maxScore) {
              return player;
            }
            System.out.printf("Sticking with %d\n\n", safeScore[player]);
          }
        }
        score[player] = 0;
        return -1;
      })
      .filter(player -> player > -1)
      .findFirst()
      .ifPresent(player ->
        System.out.printf(
          "\n\nPlayer %d wins with a score of %d",
          player,
          safeScore[player]
        )
      )
    ;
  }
}


Pig the dice game/Player

Create a dice simulator and scorer of [[Pig the dice game]] and add to it the ability to play the game to at least one strategy.
* State here the play strategies involved.
* Show play during a game here.

As a stretch goal:
* Simulate playing the game a number of times with two players of given strategies and report here summary statistics such as, but not restricted to, the influence of going first or which strategy seems stronger.

;Game Rules:
The game of Pig is a multiplayer game played with a single six-sided die. The
object of the game is to reach 100 points or more.
Play is taken in turns. On each person's turn that person has the option of either

# '''Rolling the dice''': where a roll of two to six is added to their score for that turn and the player's turn continues as the player is given the same choice again; or a roll of 1 loses the player's total points ''for that turn'' and their turn finishes with play passing to the next player.
# '''Holding''': The player's score for that round is added to their total and becomes safe from the effects of throwing a one. The player's turn finishes with play passing to the next player.

;References
* Pig (dice)
* The Math of Being a Pig and Pigs (extra) - Numberphile videos featuring Ben Sparks.

Solution:
import java.util.Scanner;

public class Pigdice {

	public static void main(String[] args) {
		Scanner scan = new Scanner(System.in);
		int players = 0;

		//Validate the input
		while(true) {
			//Get the number of players
			System.out.println("Hello, welcome to Pig Dice the game! How many players? ");
			if(scan.hasNextInt()) {

				//Gotta be more than 0
				int nextInt = scan.nextInt();
				if(nextInt > 0) {
					players = nextInt;
					break;
				}
			}
			else {
				System.out.println("That wasn't an integer. Try again. \n");
				scan.next();
			}
		}
		System.out.println("Alright, starting with " + players + " players. \n");

		//Start the game
		play(players, scan);

		scan.close();
	}

	public static void play(int group, Scanner scan) {
		//Set the number of strategies available.
		final int STRATEGIES = 5;

		//Construct the dice- accepts an int as an arg for number of sides, but defaults to 6.
		Dice dice = new Dice();

		//Create an array of players and initialize them to defaults.
		Player[] players = new Player[group];
		for(int count = 0; count < group; count++) {
			players[count] = new Player(count);
			System.out.println("Player " + players[count].getNumber() + "  is alive! ");
		}

		/*****Print strategy options here. Modify Player.java to add strategies. *****/
		System.out.println("Each strategy is numbered 0 - " + (STRATEGIES - 1) + ". They are as follows: ");
		System.out.println(">> Enter '0' for a human player. ");
		System.out.println(">> Strategy 1 is a basic strategy where the AI rolls until 20+ points and holds unless the current max is 75+.");
		System.out.println(">> Strategy 2 is a basic strategy where the AI, after 3 successful rolls, will randomly decide to roll or hold. ");
		System.out.println(">> Strategy 3 is similar to strategy 2, except it's a little gutsier and will attempt 5 successful rolls. ");
		System.out.println(">> Strategy 4 is like a mix between strategies 1 and 3. After turn points are >= 20 and while max points are still less than 75, it will randomly hold or roll. ");

		//Get the strategy for each player
		for(Player player : players) {
			System.out.println("\nWhat strategy would you like player " + player.getNumber() + " to use? ");

			//Validate the strategy is a real strategy.
			while(true) {
				if(scan.hasNextInt()) {
					int nextInt = scan.nextInt();
					if (nextInt < Strategy.STRATEGIES.length) {
						player.setStrategy(Strategy.STRATEGIES[nextInt]);
						break;
					}
				}
				else {
					System.out.println("That wasn't an option. Try again. ");
					scan.next();
				}
			}
		}

		//Here is where the rules for the game are programmatically defined.
		int max = 0;
		while(max < 100) {

			//Begin the round
			for(Player player : players) {
				System.out.println(">> Beginning Player " + player.getNumber() + "'s turn. ");

				//Set the points for the turn to 0
				player.setTurnPoints(0);

				//Determine whether the player chooses to roll or hold.
				player.setMax(max);
				while(true) {
					Move choice = player.choose();
					if(choice == Move.ROLL) {
						int roll = dice.roll();
						System.out.println("   A " + roll + " was rolled. ");
						player.setTurnPoints(player.getTurnPoints() + roll);

						//Increment the player's built in iterator.
						player.incIter();

						//If the player rolls a 1, their turn is over and they gain 0 points this round.
						if(roll == 1) {
							player.setTurnPoints(0);
							break;
						}
					}
					//Check if the player held or not.
					else {
						System.out.println("   The player has held. ");
						break;
					}
				}

				//End the turn and add any accumulated points to the player's pool.
				player.addPoints(player.getTurnPoints());
				System.out.println("   Player " + player.getNumber() + "'s turn is now over. Their total is " + player.getPoints() + ". \n");

				//Reset the player's built in iterator.
				player.resetIter();

				//Update the max score if necessary.
				if(max < player.getPoints()) {
					max = player.getPoints();
				}

				//If someone won, stop the game and announce the winner.
				if(max >= 100) {
					System.out.println("Player " + player.getNumber() + " wins with " + max + " points! End scores: ");

					//Announce the final scores.
					for(Player p : players) {
						System.out.println("Player " + p.getNumber() + " had " + p.getPoints() + " points. ");
					}
					break;
				}
			}
		}

	}

}


Plasma effect

The plasma effect is a visual effect created by applying various functions, notably sine and cosine, to the color values of screen pixels. When animated (not a task requirement) the effect may give the impression of a colorful flowing liquid.

;Task
Create a plasma effect.

;See also
* Computer Graphics Tutorial (lodev.org)
* Plasma (bidouille.org)

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

public class PlasmaEffect extends JPanel {
    float[][] plasma;
    float hueShift = 0;
    BufferedImage img;

    public PlasmaEffect() {
        Dimension dim = new Dimension(640, 640);
        setPreferredSize(dim);
        setBackground(Color.white);

        img = new BufferedImage(dim.width, dim.height, TYPE_INT_RGB);
        plasma = createPlasma(dim.height, dim.width);

        // animate about 24 fps and shift hue value with every frame
        new Timer(42, (ActionEvent e) -> {
            hueShift = (hueShift + 0.02f) % 1;
            repaint();
        }).start();
    }

    float[][] createPlasma(int w, int h) {
        float[][] buffer = new float[h][w];

        for (int y = 0; y < h; y++)
            for (int x = 0; x < w; x++) {

                double value = sin(x / 16.0);
                value += sin(y / 8.0);
                value += sin((x + y) / 16.0);
                value += sin(sqrt(x * x + y * y) / 8.0);
                value += 4; // shift range from -4 .. 4 to 0 .. 8
                value /= 8; // bring range down to 0 .. 1

                // requires VM option -ea
                assert (value >= 0.0 && value <= 1.0) : "Hue value out of bounds";

                buffer[y][x] = (float) value;
            }
        return buffer;
    }

    void drawPlasma(Graphics2D g) {
        int h = plasma.length;
        int w = plasma[0].length;
        for (int y = 0; y < h; y++)
            for (int x = 0; x < w; x++) {
                float hue = hueShift + plasma[y][x] % 1;
                img.setRGB(x, y, Color.HSBtoRGB(hue, 1, 1));
            }
        g.drawImage(img, 0, 0, null);
    }

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

        drawPlasma(g);
    }

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


Playfair cipher

Implement a  Playfair cipher for encryption and decryption.

The user must be able to choose   '''J'''  =  '''I'''      or   no   '''Q'''   in the alphabet.

The output of the encrypted and decrypted message must be in capitalized digraphs, separated by spaces.

;Output example:
                 HI DE TH EG OL DI NT HE TR EX ES TU MP

Solution:
import java.util.Scanner;

public class PlayfairCipherEncryption
{
    private String KeyWord        = new String();
    private String Key            = new String();
    private char   matrix_arr[][] = new char[5][5];

    public void setKey(String k)
    {
        String K_adjust = new String();
        boolean flag = false;
        K_adjust = K_adjust + k.charAt(0);
        for (int i = 1; i < k.length(); i++)
        {
            for (int j = 0; j < K_adjust.length(); j++)
            {
                if (k.charAt(i) == K_adjust.charAt(j))
                {
                    flag = true;
                }
            }
            if (flag == false)
                K_adjust = K_adjust + k.charAt(i);
            flag = false;
        }
        KeyWord = K_adjust;
    }

    public void KeyGen()
    {
        boolean flag = true;
        char current;
        Key = KeyWord;
        for (int i = 0; i < 26; i++)
        {
            current = (char) (i + 97);
            if (current == 'j')
                continue;
            for (int j = 0; j < KeyWord.length(); j++)
            {
                if (current == KeyWord.charAt(j))
                {
                    flag = false;
                    break;
                }
            }
            if (flag)
                Key = Key + current;
            flag = true;
        }
        System.out.println(Key);
        matrix();
    }

    private void matrix()
    {
        int counter = 0;
        for (int i = 0; i < 5; i++)
        {
            for (int j = 0; j < 5; j++)
            {
                matrix_arr[i][j] = Key.charAt(counter);
                System.out.print(matrix_arr[i][j] + " ");
                counter++;
            }
            System.out.println();
        }
    }

    private String format(String old_text)
    {
        int i = 0;
        int len = 0;
        String text = new String();
        len = old_text.length();
        for (int tmp = 0; tmp < len; tmp++)
        {
            if (old_text.charAt(tmp) == 'j')
            {
                text = text + 'i';
            }
            else
                text = text + old_text.charAt(tmp);
        }
        len = text.length();
        for (i = 0; i < len; i = i + 2)
        {
            if (text.charAt(i + 1) == text.charAt(i))
            {
                text = text.substring(0, i + 1) + 'x' + text.substring(i + 1);
            }
        }
        return text;
    }

    private String[] Divid2Pairs(String new_string)
    {
        String Original = format(new_string);
        int size = Original.length();
        if (size % 2 != 0)
        {
            size++;
            Original = Original + 'x';
        }
        String x[] = new String[size / 2];
        int counter = 0;
        for (int i = 0; i < size / 2; i++)
        {
            x[i] = Original.substring(counter, counter + 2);
            counter = counter + 2;
        }
        return x;
    }

    public int[] GetDiminsions(char letter)
    {
        int[] key = new int[2];
        if (letter == 'j')
            letter = 'i';
        for (int i = 0; i < 5; i++)
        {
            for (int j = 0; j < 5; j++)
            {
                if (matrix_arr[i][j] == letter)
                {
                    key[0] = i;
                    key[1] = j;
                    break;
                }
            }
        }
        return key;
    }

    public String encryptMessage(String Source)
    {
        String src_arr[] = Divid2Pairs(Source);
        String Code = new String();
        char one;
        char two;
        int part1[] = new int[2];
        int part2[] = new int[2];
        for (int i = 0; i < src_arr.length; i++)
        {
            one = src_arr[i].charAt(0);
            two = src_arr[i].charAt(1);
            part1 = GetDiminsions(one);
            part2 = GetDiminsions(two);
            if (part1[0] == part2[0])
            {
                if (part1[1] < 4)
                    part1[1]++;
                else
                    part1[1] = 0;
                if (part2[1] < 4)
                    part2[1]++;
                else
                    part2[1] = 0;
            }
            else if (part1[1] == part2[1])
            {
                if (part1[0] < 4)
                    part1[0]++;
                else
                    part1[0] = 0;
                if (part2[0] < 4)
                    part2[0]++;
                else
                    part2[0] = 0;
            }
            else
            {
                int temp = part1[1];
                part1[1] = part2[1];
                part2[1] = temp;
            }
            Code = Code + matrix_arr[part1[0]][part1[1]]
                    + matrix_arr[part2[0]][part2[1]];
        }
        return Code;
    }

    public static void main(String[] args)
    {
        PlayfairCipherEncryption x = new PlayfairCipherEncryption();
        Scanner sc = new Scanner(System.in);
        System.out.println("Enter a keyword:");
        String keyword = sc.next();
        x.setKey(keyword);
        x.KeyGen();
        System.out
                .println("Enter word to encrypt: (Make sure length of message is even)");
        String key_input = sc.next();
        if (key_input.length() % 2 == 0)
        {
            System.out.println("Encryption: " + x.encryptMessage(key_input));
        }
        else
        {
            System.out.println("Message length should be even");
        }
        sc.close();
    }
}


Plot coordinate pairs

Plot a function represented as     x,  y     numerical arrays.

Post the resulting image for the following input arrays (taken from Python's Example section on ''Time a function''):
       x = {0,   1,    2,    3,    4,    5,     6,     7,     8,     9};
       y = {2.7, 2.8, 31.4, 38.1, 58.0, 76.2, 100.5, 130.0, 149.3, 180.0};

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

Solution:
import java.awt.*;
  import java.awt.event.*;
  import java.awt.geom.*;
  import javax.swing.JApplet;
  import javax.swing.JFrame;
  public class Plot2d extends JApplet {
    double[] xi;
    double[] yi;
    public Plot2d(double[] x, double[] y) {
        this.xi = x;
        this.yi = y;
    }
    public static double max(double[] t) {
        double maximum = t[0];
        for (int i = 1; i < t.length; i++) {
            if (t[i] > maximum) {
                maximum = t[i];
            }
        }
        return maximum;
    }
    public static double min(double[] t) {
        double minimum = t[0];
        for (int i = 1; i < t.length; i++) {
            if (t[i] < minimum) {
                minimum = t[i];
            }
        }
        return minimum;
    }
    public void init() {
        setBackground(Color.white);
        setForeground(Color.white);
    }
    public void paint(Graphics g) {
        Graphics2D g2 = (Graphics2D) g;
        g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
                RenderingHints.VALUE_ANTIALIAS_ON);
        g2.setPaint(Color.black);
        int x0 = 70;
        int y0 = 10;
        int xm = 670;
        int ym = 410;
        int xspan = xm - x0;
        int yspan = ym - y0;
        double xmax = max(xi);
        double xmin = min(xi);
        double ymax = max(yi);
        double ymin = min(yi);
        g2.draw(new Line2D.Double(x0, ym, xm, ym));
        g2.draw(new Line2D.Double(x0, ym, x0, y0));
        for (int j = 0; j < 5; j++) {
            int interv = 4;
            g2.drawString("" + (j * (xmax - xmin) / interv + xmin), j * xspan / interv + x0 - 10, ym + 20);
            g2.drawString("" + (j * (ymax - ymin) / interv + ymin), x0 - 20 - (int) (9 * Math.log10(ymax)),
 ym - j * yspan / interv + y0 - 5);
            g2.draw(new Line2D.Double(j * xspan / interv + x0, ym, j * xspan / interv + x0, ym + 5));
            g2.draw(new Line2D.Double(x0 - 5, j * yspan / interv + y0, x0, j * yspan / interv + y0));
        }
        for (int i = 0; i < xi.length; i++) {
            int f = (int) ((xi[i] - xmin) * xspan / (xmax - xmin));
            int h = (int) (((ymax - ymin) - (yi[i] - ymin)) * yspan / (ymax - ymin));
            g2.drawString("o", x0 + f - 3, h + 14);
        }
        for (int i = 0; i < xi.length - 1; i++) {
            int f = (int) ((xi[i] - xmin) * xspan / (xmax - xmin));
            int f2 = (int) ((xi[i + 1] - xmin) * xspan / (xmax - xmin));
            int h = (int) (((ymax - ymin) - (yi[i] - ymin)) * yspan / (ymax - ymin));
            int h2 = (int) (((ymax - ymin) - (yi[i + 1] - ymin)) * yspan / (ymax - ymin));
            g2.draw(new Line2D.Double(f + x0, h + y0, f2 + x0, h2 + y0));
        }
    }
    public static void main(String args[]) {
        JFrame f = new JFrame("ShapesDemo2D");
        f.addWindowListener(new WindowAdapter() {
            public void windowClosing(WindowEvent e) {
                System.exit(0);
            }
        });
        double[] r = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9};
        double[] t = {2.7, 2.8, 31.4, 38.1, 58.0, 76.2, 100.5, 130.0, 149.3, 180.09};
        JApplet applet = new Plot2d(r, t);
        f.getContentPane().add("Center", applet);
        applet.init();
        f.pack();
        f.setSize(new Dimension(720, 480));
        f.show();
    }
  }


Poker hand analyser

Create a program to parse a single five card poker hand and rank it according to this list of poker hands.

A poker hand is specified as a space separated list of five playing cards.

Each input card has two characters indicating face and suit.

;Example:
::::'''2d'''       (two of diamonds).

Faces are:    '''a''', '''2''', '''3''', '''4''', '''5''', '''6''', '''7''', '''8''', '''9''', '''10''', '''j''', '''q''', '''k'''

Suits are:    '''h''' (hearts),   '''d''' (diamonds),   '''c''' (clubs),   and   '''s''' (spades),   or
alternatively,   the unicode card-suit characters:

Duplicate cards are illegal.

The program should analyze a single hand and produce one of the following outputs:
  straight-flush
  four-of-a-kind
  full-house
  flush
  straight
  three-of-a-kind
  two-pair
  one-pair
  high-card
  invalid

;Examples:
    2 2 2 k q:   three-of-a-kind
    2 5 7 8 9:   high-card
    a 2 3 4 5:   straight
    2 3 2 3 3:   full-house
    2 7 2 3 3:   two-pair
    2 7 7 7 7:   four-of-a-kind
    10 j q k a:  straight-flush
    4 4 k 5 10:  one-pair
    q 10 7 6 q:  invalid

The programs output for the above examples should be displayed here on this page.

;Extra credit:
# use the playing card characters introduced with Unicode 6.0 (U+1F0A1 - U+1F0DE).
# allow two jokers
::* use the symbol   '''joker'''
::* duplicates would be allowed (for jokers only)
::* five-of-a-kind would then be the highest hand

;More extra credit examples:
    joker  2  2  k  q:     three-of-a-kind
    joker  5  7  8  9:     straight
    joker  2  3  4  5:     straight
    joker  3  2  3  3:     four-of-a-kind
    joker  7  2  3  3:     three-of-a-kind
    joker  7  7  7  7:     five-of-a-kind
    joker  j  q  k  A:     straight-flush
    joker  4  k  5 10:     one-pair
    joker  k  7  6  4:     flush
    joker  2  joker  4  5:  straight
    joker  Q  joker  A 10:  straight
    joker  Q  joker  A 10:  straight-flush
    joker  2  2  joker  q:  four-of-a-kind

;Related tasks:
* [[Playing cards]]
* [[Card shuffles]]
* [[Deal cards_for_FreeCell]]
* [[War Card_Game]]
* [[Go Fish]]

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

public class PokerHandAnalyzer {

    final static String faces = "AKQJT98765432";
    final static String suits = "HDSC";
    final static String[] deck = buildDeck();

    public static void main(String[] args) {
        System.out.println("Regular hands:\n");
        for (String input : new String[]{"2H 2D 2S KS QD",
            "2H 5H 7D 8S 9D",
            "AH 2D 3S 4S 5S",
            "2H 3H 2D 3S 3D",
            "2H 7H 2D 3S 3D",
            "2H 7H 7D 7S 7C",
            "TH JH QH KH AH",
            "4H 4C KC 5D TC",
            "QC TC 7C 6C 4C",
            "QC TC 7C 7C TD"}) {
            System.out.println(analyzeHand(input.split(" ")));
        }

        System.out.println("\nHands with wildcards:\n");
        for (String input : new String[]{"2H 2D 2S KS WW",
            "2H 5H 7D 8S WW",
            "AH 2D 3S 4S WW",
            "2H 3H 2D 3S WW",
            "2H 7H 2D 3S WW",
            "2H 7H 7D WW WW",
            "TH JH QH WW WW",
            "4H 4C KC WW WW",
            "QC TC 7C WW WW",
            "QC TC 7H WW WW"}) {
            System.out.println(analyzeHandWithWildcards(input.split(" ")));
        }
    }

    private static Score analyzeHand(final String[] hand) {
        if (hand.length != 5)
            return new Score("invalid hand: wrong number of cards", -1, hand);

        if (new HashSet<>(Arrays.asList(hand)).size() != hand.length)
            return new Score("invalid hand: duplicates", -1, hand);

        int[] faceCount = new int[faces.length()];
        long straight = 0, flush = 0;
        for (String card : hand) {

            int face = faces.indexOf(card.charAt(0));
            if (face == -1)
                return new Score("invalid hand: non existing face", -1, hand);
            straight |= (1 << face);

            faceCount[face]++;

            if (suits.indexOf(card.charAt(1)) == -1)
                return new Score("invalid hand: non-existing suit", -1, hand);
            flush |= (1 << card.charAt(1));
        }

        // shift the bit pattern to the right as far as possible
        while (straight % 2 == 0)
            straight >>= 1;

        // straight is 00011111; A-2-3-4-5 is 1111000000001
        boolean hasStraight = straight == 0b11111 || straight == 0b1111000000001;

        // unsets right-most 1-bit, which may be the only one set
        boolean hasFlush = (flush & (flush - 1)) == 0;

        if (hasStraight && hasFlush)
            return new Score("straight-flush", 9, hand);

        int total = 0;
        for (int count : faceCount) {
            if (count == 4)
                return new Score("four-of-a-kind", 8, hand);
            if (count == 3)
                total += 3;
            else if (count == 2)
                total += 2;
        }

        if (total == 5)
            return new Score("full-house", 7, hand);

        if (hasFlush)
            return new Score("flush", 6, hand);

        if (hasStraight)
            return new Score("straight", 5, hand);

        if (total == 3)
            return new Score("three-of-a-kind", 4, hand);

        if (total == 4)
            return new Score("two-pair", 3, hand);

        if (total == 2)
            return new Score("one-pair", 2, hand);

        return new Score("high-card", 1, hand);
    }

    private static WildScore analyzeHandWithWildcards(String[] hand) {
        if (Collections.frequency(Arrays.asList(hand), "WW") > 2)
            throw new IllegalArgumentException("too many wildcards");

        return new WildScore(analyzeHandWithWildcardsR(hand, null), hand.clone());
    }

    private static Score analyzeHandWithWildcardsR(String[] hand,
            Score best) {

        for (int i = 0; i < hand.length; i++) {
            if (hand[i].equals("WW")) {
                for (String card : deck) {
                    if (!Arrays.asList(hand).contains(card)) {
                        hand[i] = card;
                        best = analyzeHandWithWildcardsR(hand, best);
                    }
                }
                hand[i] = "WW";
                break;
            }
        }
        Score result = analyzeHand(hand);
        if (best == null || result.weight > best.weight)
            best = result;
        return best;
    }

    private static String[] buildDeck() {
        String[] dck = new String[suits.length() * faces.length()];
        int i = 0;
        for (char s : suits.toCharArray()) {
            for (char f : faces.toCharArray()) {
                dck[i] = "" + f + s;
                i++;
            }
        }
        return dck;
    }

    private static class Score {
        final int weight;
        final String name;
        final String[] hand;

        Score(String n, int w, String[] h) {
            weight = w;
            name = n;
            hand = h != null ? h.clone() : h;
        }

        @Override
        public String toString() {
            return Arrays.toString(hand) + " " + name;
        }
    }

    private static class WildScore {
        final String[] wild;
        final Score score;

        WildScore(Score s, String[] w) {
            score = s;
            wild = w;
        }

        @Override
        public String toString() {
            return String.format("%s%n%s%n", Arrays.toString(wild),
                    score.toString());
        }
    }
}


Polyspiral

A Polyspiral is a spiral made of multiple line segments, whereby each segment is larger (or smaller) than the previous one by a given amount. Each segment also changes direction at a given angle.

;Task
Animate a series of polyspirals, by drawing a complete spiral then incrementing the angle, and (after clearing the background) drawing the next, and so on. Every spiral will be a frame of the animation. The animation may stop as it goes full circle or continue indefinitely. The given input values may be varied.

If animation is not practical in your programming environment, you may show a single frame instead.

;Pseudo code

    set incr to 0.0

    // animation loop
    WHILE true

        incr = (incr + 0.05) MOD 360
        x = width / 2
        y = height / 2
        length = 5
        angle = incr

        // spiral loop
        FOR 1 TO 150
            drawline
            change direction by angle
            length = length + 3
            angle = (angle + incr) MOD 360
        ENDFOR

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

public class PolySpiral extends JPanel {
    double inc = 0;

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

        new Timer(40, (ActionEvent e) -> {
            inc = (inc + 0.05) % 360;
            repaint();
        }).start();
    }

    void drawSpiral(Graphics2D g, int len, double angleIncrement) {

        double x1 = getWidth() / 2;
        double y1 = getHeight() / 2;
        double angle = angleIncrement;

        for (int i = 0; i < 150; i++) {

            g.setColor(Color.getHSBColor(i / 150f, 1.0f, 1.0f));

            double x2 = x1 + Math.cos(angle) * len;
            double y2 = y1 - Math.sin(angle) * len;
            g.drawLine((int) x1, (int) y1, (int) x2, (int) y2);
            x1 = x2;
            y1 = y2;

            len += 3;

            angle = (angle + angleIncrement) % (Math.PI * 2);
        }
    }

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

        drawSpiral(g, 5, Math.toRadians(inc));
    }

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


Population count

The   ''population count''   is the number of   '''1'''s   (ones)   in the binary representation of a non-negative integer.

''Population count''   is also known as:
::::*   ''pop count''
::::*   ''popcount''
::::*   ''sideways sum''
::::*   ''bit summation''
::::*   ''Hamming weight''

For example,   '''5'''   (which is   '''101'''   in binary)   has a population count of   '''2'''.

''Evil numbers''   are non-negative integers  that have an   ''even''   population count.

''Odious numbers''      are  positive integers that have an    ''odd''   population count.

;Task:
* write a function (or routine) to return the population count of a non-negative integer.
* all computation of the lists below should start with   '''0'''   (zero indexed).
:* display the   ''pop count''   of the   1st   thirty powers of   '''3'''       ('''30''',   '''31''',   '''32''',   '''33''',   '''34''',      '''329''').
:* display the   1st   thirty     ''evil''        numbers.
:* display the   1st   thirty          ''odious''           numbers.
* display each list of integers on one line   (which may or may not include a title),   each set of integers being shown should be properly identified.

;See also
* The On-Line Encyclopedia of Integer Sequences:   A000120 population count.
* The On-Line Encyclopedia of Integer Sequences:   A000069 odious numbers.
* The On-Line Encyclopedia of Integer Sequences:   A001969 evil numbers.

Solution:
import java.math.BigInteger;

public class PopCount {
    public static void main(String[] args) {
	{ // with int
	    System.out.print("32-bit integer: ");
	    int n = 1;
	    for (int i = 0; i < 20; i++) {
		System.out.printf("%d ", Integer.bitCount(n));
		n *= 3;
	    }
	    System.out.println();
	}
	{ // with long
	    System.out.print("64-bit integer: ");
	    long n = 1;
	    for (int i = 0; i < 30; i++) {
		System.out.printf("%d ", Long.bitCount(n));
		n *= 3;
	    }
	    System.out.println();
	}
	{ // with BigInteger
	    System.out.print("big integer   : ");
	    BigInteger n = BigInteger.ONE;
	    BigInteger three = BigInteger.valueOf(3);
	    for (int i = 0; i < 30; i++) {
		System.out.printf("%d ", n.bitCount());
		n = n.multiply(three);
	    }
	    System.out.println();
	}

	int[] od = new int[30];
	int ne = 0, no = 0;
	System.out.print("evil   : ");
	for (int n = 0; ne+no < 60; n++) {
	    if ((Integer.bitCount(n) & 1) == 0) {
		if (ne < 30) {
		    System.out.printf("%d ", n);
		    ne++;
		}
	    } else {
		if (no < 30) {
		    od[no++] = n;
		}
	    }
	}
	System.out.println();
	System.out.print("odious : ");
	for (int n : od) {
	    System.out.printf("%d ", n);
	}
	System.out.println();
    }
}


Prime triangle

You will require a function f which when given an integer S will return a list of the arrangements of the integers 1 to S such that g1=1 gS=S and generally for n=1 to n=S-1 gn+gn+1 is prime. S=1 is undefined. For S=2 to S=20 print f(S) to form a triangle. Then again for S=2 to S=20 print the number of possible arrangements of 1 to S meeting these requirements.

;See also
:* OEIS:A036440

Solution:
public class PrimeTriangle {
    public static void main(String[] args) {
        long start = System.currentTimeMillis();
        for (int i = 2; i <= 20; ++i) {
            int[] a = new int[i];
            for (int j = 0; j < i; ++j)
                a[j] = j + 1;
            if (findRow(a, 0, i))
                printRow(a);
        }
        System.out.println();
        StringBuilder s = new StringBuilder();
        for (int i = 2; i <= 20; ++i) {
            int[] a = new int[i];
            for (int j = 0; j < i; ++j)
                a[j] = j + 1;
            if (i > 2)
                s.append(" ");
            s.append(countRows(a, 0, i));
        }
        System.out.println(s);
        long finish = System.currentTimeMillis();
        System.out.printf("\nElapsed time: %d milliseconds\n", finish - start);
    }

    private static void printRow(int[] a) {
        for (int i = 0; i < a.length; ++i) {
            if (i != 0)
                System.out.print(" ");
            System.out.printf("%2d", a[i]);
        }
        System.out.println();
    }

    private static boolean findRow(int[] a, int start, int length) {
        if (length == 2)
            return isPrime(a[start] + a[start + 1]);
        for (int i = 1; i + 1 < length; i += 2) {
            if (isPrime(a[start] + a[start + i])) {
                swap(a, start + i, start + 1);
                if (findRow(a, start + 1, length - 1))
                    return true;
                swap(a, start + i, start + 1);
            }
        }
        return false;
    }

    private static int countRows(int[] a, int start, int length) {
        int count = 0;
        if (length == 2) {
            if (isPrime(a[start] + a[start + 1]))
                ++count;
        } else {
            for (int i = 1; i + 1 < length; i += 2) {
                if (isPrime(a[start] + a[start + i])) {
                    swap(a, start + i, start + 1);
                    count += countRows(a, start + 1, length - 1);
                    swap(a, start + i, start + 1);
                }
            }
        }
        return count;
    }

    private static void swap(int[] a, int i, int j) {
        int tmp = a[i];
        a[i] = a[j];
        a[j] = tmp;
    }

    private static boolean isPrime(int n) {
        return ((1L << n) & 0x28208a20a08a28acL) != 0;
    }
}


Priority queue

A queue, with an important distinction: each item is added to a priority queue with a priority level, and will be later removed from the queue with the highest priority element first. That is, the items are (conceptually) stored in the queue in priority order instead of in insertion order.

;Task:
Create a priority queue.   The queue must support at least two operations:
:#   Insertion.   An element is added to the queue with a priority (a numeric value).
:#   Top item removal.   Deletes the element or one of the elements with the current top priority and return it.

Optionally, other operations may be defined, such as peeking (find what current top priority/top element is), merging (combining two priority queues into one), etc.

To test your implementation, insert a number of elements into the queue, each with some random priority.

Then dequeue them sequentially; now the elements should be sorted by priority.

You can use the following task/priority items as input data:
         '''Priority'''         '''Task'''
        ----------   ----------------
            3         Clear drains
            4         Feed cat
            5         Make tea
            1         Solve RC tasks
            2         Tax return

The implementation should try to be efficient.   A typical implementation has   '''O(log n)'''   insertion and extraction time,   where   '''n'''   is the number of items in the queue.

You may choose to impose certain limits such as small range of allowed priority levels, limited capacity, etc.   If so, discuss the reasons behind it.

Solution:
import java.util.PriorityQueue;

class Task implements Comparable<Task> {
    final int priority;
    final String name;

    public Task(int p, String n) {
        priority = p;
        name = n;
    }

    public String toString() {
        return priority + ", " + name;
    }

    public int compareTo(Task other) {
        return priority < other.priority ? -1 : priority > other.priority ? 1 : 0;
    }

    public static void main(String[] args) {
        PriorityQueue<Task> pq = new PriorityQueue<Task>();
        pq.add(new Task(3, "Clear drains"));
        pq.add(new Task(4, "Feed cat"));
        pq.add(new Task(5, "Make tea"));
        pq.add(new Task(1, "Solve RC tasks"));
        pq.add(new Task(2, "Tax return"));

        while (!pq.isEmpty())
            System.out.println(pq.remove());
    }
}


Pseudo-random numbers/Combined recursive generator MRG32k3a

MRG32k3a Combined recursive generator (pseudo-code):

    /* Constants */
    /* First generator */
    a1 = [0, 1403580, -810728]
    m1 = 2**32 - 209
    /* Second Generator */
    a2 = [527612, 0, -1370589]
    m2 = 2**32 - 22853

    d = m1 + 1

    class MRG32k3a
        x1 = [0, 0, 0]  /* list of three last values of gen #1 */
        x2 = [0, 0, 0]  /* list of three last values of gen #2 */

        method seed(u64 seed_state)
            assert seed_state in range >0 and < d
            x1 = [seed_state, 0, 0]
            x2 = [seed_state, 0, 0]
        end method

        method next_int()
            x1i = (a1[0]*x1[0] + a1[1]*x1[1] + a1[2]*x1[2]) mod m1
            x2i = (a2[0]*x2[0] + a2[1]*x2[1] + a2[2]*x2[2]) mod m2
            x1 = [x1i, x1[0], x1[1]]    /* Keep last three */
            x2 = [x2i, x2[0], x2[1]]    /* Keep last three */
            z = (x1i - x2i) % m1
            answer = (z + 1)

            return answer
        end method

        method next_float():
            return float next_int() / d
        end method

    end class

:MRG32k3a Use:
    random_gen = instance MRG32k3a
    random_gen.seed(1234567)
    print(random_gen.next_int())   /* 1459213977 */
    print(random_gen.next_int())   /* 2827710106 */
    print(random_gen.next_int())   /* 4245671317 */
    print(random_gen.next_int())   /* 3877608661 */
    print(random_gen.next_int())   /* 2595287583 */

;Task

* Generate a class/set of functions that generates pseudo-random
numbers as shown above.

* Show that the first five integers generated with the seed `1234567`
are as shown above

* Show that for an initial seed of '987654321' the counts of 100_000
repetitions of

    floor(random_gen.next_float() * 5)

Is as follows:

    0: 20002, 1: 20060, 2: 19948, 3: 20059, 4: 19931

* Show your output here, on this page.

Solution:
public class App {
    private static long mod(long x, long y) {
        long m = x % y;
        if (m < 0) {
            if (y < 0) {
                return m - y;
            } else {
                return m + y;
            }
        }
        return m;
    }

    public static class RNG {
        // first generator
        private final long[] a1 = {0, 1403580, -810728};
        private static final long m1 = (1L << 32) - 209;
        private long[] x1;
        // second generator
        private final long[] a2 = {527612, 0, -1370589};
        private static final long m2 = (1L << 32) - 22853;
        private long[] x2;
        // other
        private static final long d = m1 + 1;

        public void seed(long state) {
            x1 = new long[]{state, 0, 0};
            x2 = new long[]{state, 0, 0};
        }

        public long nextInt() {
            long x1i = mod(a1[0] * x1[0] + a1[1] * x1[1] + a1[2] * x1[2], m1);
            long x2i = mod(a2[0] * x2[0] + a2[1] * x2[1] + a2[2] * x2[2], m2);
            long z = mod(x1i - x2i, m1);

            // keep the last three values of the first generator
            x1 = new long[]{x1i, x1[0], x1[1]};
            // keep the last three values of the second generator
            x2 = new long[]{x2i, x2[0], x2[1]};

            return z + 1;
        }

        public double nextFloat() {
            return 1.0 * nextInt() / d;
        }
    }

    public static void main(String[] args) {
        RNG rng = new RNG();

        rng.seed(1234567);
        System.out.println(rng.nextInt());
        System.out.println(rng.nextInt());
        System.out.println(rng.nextInt());
        System.out.println(rng.nextInt());
        System.out.println(rng.nextInt());
        System.out.println();

        int[] counts = {0, 0, 0, 0, 0};
        rng.seed(987654321);
        for (int i = 0; i < 100_000; i++) {
            int value = (int) Math.floor(rng.nextFloat() * 5.0);
            counts[value]++;
        }
        for (int i = 0; i < counts.length; i++) {
            System.out.printf("%d: %d%n", i, counts[i]);
        }
    }
}


Pseudo-random numbers/Middle-square method

{{Wikipedia|Middle-square method|en}}
; The Method:
To generate a sequence of n-digit pseudorandom numbers, an n-digit starting value is created and squared, producing a 2n-digit number. If the result has fewer than 2n digits, leading zeroes are added to compensate. The middle n digits of the result would be the next number in the sequence and returned as the result. This process is then repeated to generate more numbers.
; Pseudo code:

var seed = 675248
function random()
    var s = str(seed * seed) 'str: turn a number into string
    do while not len(s) = 12
        s = "0" + s          'add zeroes before the string
    end do
    seed = val(mid(s, 4, 6)) 'mid: string variable, start, length
                             'val: turn a string into number
    return seed
end function

; Middle-square method use:

for i = 1 to 5
    print random()
end for

;Task:

* Generate a class/set of functions that generates pseudo-random
numbers (6 digits) as shown above.

* Show the first five integers generated with the seed 675248 as shown above.

* Show your output here, on this page.

Solution:
public final class MiddleSquareTask {

	public static void main(String[] aArgs) {
		MiddleSquare random = new MiddleSquare(675248);

		for ( int i = 0; i < 5; i++ ) {
	        System.out.println(random.nextInt());
		}
	}

}

final class MiddleSquare {

	public MiddleSquare(int aSeed) {
		final int length = String.valueOf(aSeed).length();
		if ( length % 2 == 1 ) {
			throw new IllegalArgumentException("Seed must have an even number of digits");
		}

		state = aSeed;
		divisor = (int) Math.pow(10, length / 2);
		modulus = (int) Math.pow(10, length);
	}

	public int nextInt() {
		state = ( ( state * state ) / divisor ) % modulus;
		return (int) state;
	}

	private long state;

	private final int divisor, modulus;

}


Pseudo-random numbers/PCG32

Some definitions to help in the explanation:

:Floor operation
::https://en.wikipedia.org/wiki/Floor_and_ceiling_functions
::Greatest integer less than or equal to a real number.

:Bitwise Logical shift operators (c-inspired)
::https://en.wikipedia.org/wiki/Bitwise_operation#Bit_shifts
::Binary bits of value shifted left or right, with zero bits shifted in where appropriate.
::Examples are shown for 8 bit binary numbers; most significant bit to the left.

:: '''<<''' Logical shift left by given number of bits.
:::E.g Binary 00110101 '''<<''' 2 == Binary 11010100

:: '''>>''' Logical shift right by given number of bits.
:::E.g Binary 00110101 '''>>''' 2 == Binary 00001101

:'''^''' Bitwise exclusive-or operator
::https://en.wikipedia.org/wiki/Exclusive_or
::Bitwise comparison for if bits differ
:::E.g Binary 00110101 '''^''' Binary 00110011 == Binary 00000110

:'''|''' Bitwise or operator
::https://en.wikipedia.org/wiki/Bitwise_operation#OR
::Bitwise comparison gives 1 if any of corresponding bits are 1
:::E.g Binary 00110101 '''|''' Binary 00110011 == Binary 00110111

;PCG32 Generator (pseudo-code):

PCG32 has two unsigned 64-bit integers of internal state:
# '''state''': All 2**64 values may be attained.
# '''sequence''': Determines which of 2**63 sequences that state iterates through. (Once set together with state at time of seeding will stay constant for this generators lifetime).

Values of sequence allow 2**63 ''different'' sequences of random numbers from the same state.

The algorithm is given 2 U64 inputs called seed_state, and seed_sequence. The algorithm proceeds in accordance with the following pseudocode:-

const N<-U64 6364136223846793005
const inc<-U64 (seed_sequence << 1) | 1
state<-U64 ((inc+seed_state)*N+inc
do forever
  xs<-U32 (((state>>18)^state)>>27)
  rot<-INT (state>>59)
  OUTPUT U32 (xs>>rot)|(xs<<((-rot)&31))
  state<-state*N+inc
end do

Note that this an anamorphism - dual to catamorphism, and encoded in some languages as a general higher-order `unfold` function, dual to `fold` or `reduce`.

;Task:

* Generate a class/set of functions that generates pseudo-random
numbers using the above.

* Show that the first five integers generated with the seed 42, 54
are: 2707161783 2068313097 3122475824 2211639955 3215226955

* Show that for an initial seed of 987654321, 1 the counts of 100_000 repetitions of

    floor(random_gen.next_float() * 5)

:Is as follows:

    0: 20049, 1: 20022, 2: 20115, 3: 19809, 4: 20005

* Show your output here, on this page.

Solution:
public class PCG32 {
    private static final long N = 6364136223846793005L;

    private long state = 0x853c49e6748fea9bL;
    private long inc = 0xda3e39cb94b95bdbL;

    public void seed(long seedState, long seedSequence) {
        state = 0;
        inc = (seedSequence << 1) | 1;
        nextInt();
        state = state + seedState;
        nextInt();
    }

    public int nextInt() {
        long old = state;
        state = old * N + inc;
        int shifted = (int) (((old >>> 18) ^ old) >>> 27);
        int rot = (int) (old >>> 59);
        return (shifted >>> rot) | (shifted << ((~rot + 1) & 31));
    }

    public double nextFloat() {
        var u = Integer.toUnsignedLong(nextInt());
        return (double) u / (1L << 32);
    }

    public static void main(String[] args) {
        var r = new PCG32();

        r.seed(42, 54);
        System.out.println(Integer.toUnsignedString(r.nextInt()));
        System.out.println(Integer.toUnsignedString(r.nextInt()));
        System.out.println(Integer.toUnsignedString(r.nextInt()));
        System.out.println(Integer.toUnsignedString(r.nextInt()));
        System.out.println(Integer.toUnsignedString(r.nextInt()));
        System.out.println();

        int[] counts = {0, 0, 0, 0, 0};
        r.seed(987654321, 1);
        for (int i = 0; i < 100_000; i++) {
            int j = (int) Math.floor(r.nextFloat() * 5.0);
            counts[j]++;
        }

        System.out.println("The counts for 100,000 repetitions are:");
        for (int i = 0; i < counts.length; i++) {
            System.out.printf("  %d : %d\n", i, counts[i]);
        }
    }
}


Pseudo-random numbers/Xorshift star

Some definitions to help in the explanation:

:Floor operation
::https://en.wikipedia.org/wiki/Floor_and_ceiling_functions
::Greatest integer less than or equal to a real number.

:Bitwise Logical shift operators (c-inspired)
::https://en.wikipedia.org/wiki/Bitwise_operation#Bit_shifts
::Binary bits of value shifted left or right, with zero bits shifted in where appropriate.
::Examples are shown for 8 bit binary numbers; most significant bit to the left.

:: '''<<''' Logical shift left by given number of bits.
:::E.g Binary 00110101 '''<<''' 2 == Binary 11010100

:: '''>>''' Logical shift right by given number of bits.
:::E.g Binary 00110101 '''>>''' 2 == Binary 00001101

:'''^''' Bitwise exclusive-or operator
::https://en.wikipedia.org/wiki/Exclusive_or
::Bitwise comparison for if bits differ
:::E.g Binary 00110101 '''^''' Binary 00110011 == Binary 00000110

;Xorshift_star Generator (pseudo-code):

    /* Let u64 denote an unsigned 64 bit integer type. */
    /* Let u32 denote an unsigned 32 bit integer type. */

    class Xorshift_star
        u64 state       /* Must be seeded to non-zero initial value */
        u64 const = HEX '2545F4914F6CDD1D'

        method seed(u64 num):
            state =  num
        end method

        method next_int():
            u64 x = state
            x = x ^ (x >> 12)
            x = x ^ (x << 25)
            x = x ^ (x >> 27)
            state = x
            u32 answer = ((x * const) >> 32)

            return answer
        end method

        method next_float():
            return float next_int() / (1 << 32)
        end method

    end class

:;Xorshift use:

    random_gen = instance Xorshift_star
    random_gen.seed(1234567)
    print(random_gen.next_int())   /* 3540625527 */
    print(random_gen.next_int())   /* 2750739987 */
    print(random_gen.next_int())   /* 4037983143 */
    print(random_gen.next_int())   /* 1993361440 */
    print(random_gen.next_int())   /* 3809424708 */

;Task:

* Generate a class/set of functions that generates pseudo-random
numbers as shown above.

* Show that the first five integers genrated with the seed 1234567
are as shown above

* Show that for an initial seed of 987654321, the counts of 100_000 repetitions of

    floor(random_gen.next_float() * 5)

:Is as follows:

    0: 20103, 1: 19922, 2: 19937, 3: 20031, 4: 20007

* Show your output here, on this page.

Solution:
public class XorShiftStar {
    private static final long MAGIC = Long.parseUnsignedLong("2545F4914F6CDD1D", 16);
    private long state;

    public void seed(long num) {
        state = num;
    }

    public int nextInt() {
        long x;
        int answer;

        x = state;
        x = x ^ (x >>> 12);
        x = x ^ (x << 25);
        x = x ^ (x >>> 27);
        state = x;
        answer = (int) ((x * MAGIC) >> 32);

        return answer;
    }

    public float nextFloat() {
        return (float) Integer.toUnsignedLong(nextInt()) / (1L << 32);
    }

    public static void main(String[] args) {
        var rng = new XorShiftStar();
        rng.seed(1234567);
        System.out.println(Integer.toUnsignedString(rng.nextInt()));
        System.out.println(Integer.toUnsignedString(rng.nextInt()));
        System.out.println(Integer.toUnsignedString(rng.nextInt()));
        System.out.println(Integer.toUnsignedString(rng.nextInt()));
        System.out.println(Integer.toUnsignedString(rng.nextInt()));
        System.out.println();

        int[] counts = {0, 0, 0, 0, 0};
        rng.seed(987654321);
        for (int i = 0; i < 100_000; i++) {
            int j = (int) Math.floor(rng.nextFloat() * 5.0);
            counts[j]++;
        }
        for (int i = 0; i < counts.length; i++) {
            System.out.printf("%d: %d\n", i, counts[i]);
        }
    }
}


Pythagoras tree

The Pythagoras tree is a fractal tree constructed from squares.  It is named after Pythagoras because each triple of touching squares encloses a right triangle, in a configuration traditionally used to represent the Pythagorean theorem.

;Task
Construct a Pythagoras tree of order 7 using only vectors (no rotation or trigonometric functions).

;Related tasks
* Fractal tree

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

public class PythagorasTree extends JPanel {
    final int depthLimit = 7;
    float hue = 0.15f;

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

    private void drawTree(Graphics2D g, float x1, float y1, float x2, float y2,
            int depth) {

        if (depth == depthLimit)
            return;

        float dx = x2 - x1;
        float dy = y1 - y2;

        float x3 = x2 - dy;
        float y3 = y2 - dx;
        float x4 = x1 - dy;
        float y4 = y1 - dx;
        float x5 = x4 + 0.5F * (dx - dy);
        float y5 = y4 - 0.5F * (dx + dy);

        Path2D square = new Path2D.Float();
        square.moveTo(x1, y1);
        square.lineTo(x2, y2);
        square.lineTo(x3, y3);
        square.lineTo(x4, y4);
        square.closePath();

        g.setColor(Color.getHSBColor(hue + depth * 0.02f, 1, 1));
        g.fill(square);
        g.setColor(Color.lightGray);
        g.draw(square);

        Path2D triangle = new Path2D.Float();
        triangle.moveTo(x3, y3);
        triangle.lineTo(x4, y4);
        triangle.lineTo(x5, y5);
        triangle.closePath();

        g.setColor(Color.getHSBColor(hue + depth * 0.035f, 1, 1));
        g.fill(triangle);
        g.setColor(Color.lightGray);
        g.draw(triangle);

        drawTree(g, x4, y4, x5, y5, depth + 1);
        drawTree(g, x5, y5, x3, y3, depth + 1);
    }

    @Override
    public void paintComponent(Graphics g) {
        super.paintComponent(g);
        drawTree((Graphics2D) g, 275, 500, 375, 500, 0);
    }

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


Pythagorean quadruples

One form of   '''Pythagorean quadruples'''   is   (for positive integers   '''a''',   '''b''',   '''c''',   and   '''d'''):

::::::::    a2   +   b2   +   c2     =     d2

An example:

::::::::    22   +   32   +   62     =     72

::::: which is:

::::::::    4    +   9    +   36     =     49

;Task:

For positive integers up   '''2,200'''   (inclusive),   for all values of   '''a''',
'''b''',   '''c''',   and   '''d''',
find   (and show here)   those values of   '''d'''   that   ''can't''   be represented.

Show the values of   '''d'''   on one line of output   (optionally with a title).

;Related tasks:
*   [[Euler's sum of powers conjecture]].
*   [[Pythagorean triples]].

;Reference:
:*   the Wikipedia article:   Pythagorean quadruple.

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

public class PythagoreanQuadruples {

    public static void main(String[] args) {
        long d = 2200;
        System.out.printf("Values of d < %d where a, b, and c are non-zero and a^2 + b^2 + c^2 = d^2 has no solutions:%n%s%n", d, getPythagoreanQuadruples(d));
    }

    //  See:  https://oeis.org/A094958
    private static List<Long> getPythagoreanQuadruples(long max) {
        List<Long> list = new ArrayList<>();
        long n = -1;
        long m = -1;
        while ( true ) {
            long nTest = (long) Math.pow(2, n+1);
            long mTest = (long) (5L * Math.pow(2, m+1));
            long test = 0;
            if ( nTest > mTest ) {
                test = mTest;
                m++;
            }
            else {
                test = nTest;
                n++;
            }
            if ( test < max ) {
                list.add(test);
            }
            else {
                break;
            }
        }
        return list;
    }

}


Pythagorean triples

A Pythagorean triple is defined as three positive integers (a, b, c) where a < b < c, and a^2+b^2=c^2.

They are called primitive triples if a, b, c are co-prime, that is, if their pairwise greatest common divisors {\rm gcd}(a, b) = {\rm gcd}(a, c) = {\rm gcd}(b, c) = 1.

Because of their relationship through the Pythagorean theorem, a, b, and c are co-prime if a and b are co-prime ({\rm gcd}(a, b) = 1).

Each triple forms the length of the sides of a right triangle, whose perimeter is P=a+b+c.

;Task:
The task is to determine how many Pythagorean triples there are with a perimeter no larger than 100 and the number of these that are primitive.

;Extra credit:
Deal with large values.   Can your program handle a maximum perimeter of 1,000,000?   What about 10,000,000?   100,000,000?

Note: the extra credit is not for you to demonstrate how fast your language is compared to others;   you need a proper algorithm to solve them in a timely manner.

;Related tasks:
*   [[Euler's sum of powers conjecture]]
*   [[List comprehensions]]
*   [[Pythagorean quadruples]]

Solution:
import java.math.BigInteger;
import static java.math.BigInteger.ONE;

public class PythTrip{

    public static void main(String[] args){
        long tripCount = 0, primCount = 0;

        //change this to whatever perimeter limit you want;the RAM's the limit
        BigInteger periLimit = BigInteger.valueOf(100),
                peri2 = periLimit.divide(BigInteger.valueOf(2)),
                peri3 = periLimit.divide(BigInteger.valueOf(3));

        for(BigInteger a = ONE; a.compareTo(peri3) < 0; a = a.add(ONE)){
            BigInteger aa = a.multiply(a);

            for(BigInteger b = a.add(ONE);
                    b.compareTo(peri2) < 0; b = b.add(ONE)){
                BigInteger bb = b.multiply(b);
                BigInteger ab = a.add(b);
                BigInteger aabb = aa.add(bb);

                for(BigInteger c = b.add(ONE);
                        c.compareTo(peri2) < 0; c = c.add(ONE)){

                    int compare = aabb.compareTo(c.multiply(c));
                    //if a+b+c > periLimit
                    if(ab.add(c).compareTo(periLimit) > 0){
                        break;
                    }
                    //if a^2 + b^2 != c^2
                    if(compare < 0){
                        break;
                    }else if (compare == 0){
                        tripCount++;
                        System.out.print(a + ", " + b + ", " + c);

                        //does binary GCD under the hood
                        if(a.gcd(b).equals(ONE)){
                            System.out.print(" primitive");
                            primCount++;
                        }
                        System.out.println();
                    }
                }
            }
        }
        System.out.println("Up to a perimeter of " + periLimit + ", there are "
                + tripCount + " triples, of which " + primCount + " are primitive.");
    }
}


Pythagorean triples

Solution:
import java.math.BigInteger;

public class Triples{
    public static BigInteger LIMIT;
    public static final BigInteger TWO = BigInteger.valueOf(2);
    public static final BigInteger THREE = BigInteger.valueOf(3);
    public static final BigInteger FOUR = BigInteger.valueOf(4);
    public static final BigInteger FIVE = BigInteger.valueOf(5);
    public static long primCount = 0;
    public static long tripCount = 0;

    //I don't know Japanese :p
    public static void parChild(BigInteger a, BigInteger b, BigInteger c){
        BigInteger perim = a.add(b).add(c);
        if(perim.compareTo(LIMIT) > 0) return;
        primCount++; tripCount += LIMIT.divide(perim).longValue();
        BigInteger a2 = TWO.multiply(a), b2 = TWO.multiply(b), c2 = TWO.multiply(c),
                   c3 = THREE.multiply(c);
        parChild(a.subtract(b2).add(c2),
                 a2.subtract(b).add(c2),
                 a2.subtract(b2).add(c3));
        parChild(a.add(b2).add(c2),
                 a2.add(b).add(c2),
                 a2.add(b2).add(c3));
        parChild(a.negate().add(b2).add(c2),
                 a2.negate().add(b).add(c2),
                 a2.negate().add(b2).add(c3));
    }

    public static void main(String[] args){
        for(long i = 100; i <= 10000000; i*=10){
            LIMIT = BigInteger.valueOf(i);
            primCount = tripCount = 0;
            parChild(THREE, FOUR, FIVE);
            System.out.println(LIMIT + ": " + tripCount + " triples, " + primCount + " primitive.");
        }
    }
}


Quaternion type

complex numbers.

A complex number has a real and complex part,   sometimes written as     a + bi,
where     a     and     b     stand for real numbers, and     i     stands for the square root of minus 1.

An example of a complex number might be     -3 + 2i,
where the real part,     a     is     '''-3.0'''     and the complex part,     b     is     '''+2.0'''.

A quaternion has one real part and ''three'' imaginary parts,     i,       j,     and     k.

A quaternion might be written as     a + bi + cj + dk.

In the quaternion numbering system:
:::*     ii = jj = kk = ijk = -1,         or more simply,
:::*     ii  = jj  = kk  = ijk   = -1.

The order of multiplication is important, as, in general, for two quaternions:
::::     q1     and     q2:         q1q2  q2q1.

An example of a quaternion might be     1 +2i +3j +4k

There is a list form of notation where just the numbers are shown and the imaginary multipliers    i,       j,     and     k     are assumed by position.

So the example above would be written as     (1, 2, 3, 4)

;Task:
Given the three quaternions and their components:
    q  = (1, 2, 3, 4) = (a,  b,  c,  d)
    q1 = (2, 3, 4, 5) = (a1, b1, c1, d1)
    q2 = (3, 4, 5, 6) = (a2, b2, c2, d2)
And a wholly real number     r = 7.

Create functions   (or classes)   to perform simple maths with quaternions including computing:
# The norm of a quaternion: = \sqrt{a^2 + b^2 + c^2 + d^2}
# The negative of a quaternion:    = (-a, -b, -c, -d)
# The conjugate of a quaternion:    = ( a, -b, -c, -d)
# Addition of a real number     r     and a quaternion     q:      r + q = q + r = (a+r, b, c, d)
# Addition of two quaternions:    q1 + q2 = (a1+a2, b1+b2, c1+c2, d1+d2)
# Multiplication of a real number and a quaternion:    qr = rq = (ar, br, cr, dr)
# Multiplication of two quaternions     q1     and   q2     is given by:    ( a1a2 - b1b2 - c1c2 - d1d2,      a1b2 + b1a2 + c1d2 - d1c2,      a1c2 - b1d2 + c1a2 + d1b2,      a1d2 + b1c2 - c1b2 + d1a2 )
# Show that, for the two quaternions     q1     and     q2:  q1q2  q2q1

If a language has built-in support for quaternions, then use it.

;C.f.:
*   [[Vector products]]
*   On Quaternions;   or on a new System of Imaginaries in Algebra.   By Sir William Rowan Hamilton LL.D, P.R.I.A., F.R.A.S., Hon. M. R. Soc. Ed. and Dub., Hon. or Corr. M. of the Royal or Imperial Academies of St. Petersburgh, Berlin, Turin and Paris, Member of the American Academy of Arts and Sciences, and of other Scientific Societies at Home and Abroad, Andrews' Prof. of Astronomy in the University of Dublin, and Royal Astronomer of Ireland.

Solution:
public class Quaternion {
    private final double a, b, c, d;

    public Quaternion(double a, double b, double c, double d) {
        this.a = a;
        this.b = b;
        this.c = c;
        this.d = d;
    }
    public Quaternion(double r) {
        this(r, 0.0, 0.0, 0.0);
    }

    public double norm() {
        return Math.sqrt(a * a + b * b + c * c + d * d);
    }

    public Quaternion negative() {
        return new Quaternion(-a, -b, -c, -d);
    }

    public Quaternion conjugate() {
        return new Quaternion(a, -b, -c, -d);
    }

    public Quaternion add(double r) {
        return new Quaternion(a + r, b, c, d);
    }
    public static Quaternion add(Quaternion q, double r) {
        return q.add(r);
    }
    public static Quaternion add(double r, Quaternion q) {
        return q.add(r);
    }
    public Quaternion add(Quaternion q) {
        return new Quaternion(a + q.a, b + q.b, c + q.c, d + q.d);
    }
    public static Quaternion add(Quaternion q1, Quaternion q2) {
        return q1.add(q2);
    }

    public Quaternion times(double r) {
        return new Quaternion(a * r, b * r, c * r, d * r);
    }
    public static Quaternion times(Quaternion q, double r) {
        return q.times(r);
    }
    public static Quaternion times(double r, Quaternion q) {
        return q.times(r);
    }
    public Quaternion times(Quaternion q) {
        return new Quaternion(
            a * q.a - b * q.b - c * q.c - d * q.d,
            a * q.b + b * q.a + c * q.d - d * q.c,
            a * q.c - b * q.d + c * q.a + d * q.b,
            a * q.d + b * q.c - c * q.b + d * q.a
        );
    }
    public static Quaternion times(Quaternion q1, Quaternion q2) {
        return q1.times(q2);
    }

    @Override
    public boolean equals(Object obj) {
        if (!(obj instanceof Quaternion)) return false;
        final Quaternion other = (Quaternion) obj;
        if (Double.doubleToLongBits(this.a) != Double.doubleToLongBits(other.a)) return false;
        if (Double.doubleToLongBits(this.b) != Double.doubleToLongBits(other.b)) return false;
        if (Double.doubleToLongBits(this.c) != Double.doubleToLongBits(other.c)) return false;
        if (Double.doubleToLongBits(this.d) != Double.doubleToLongBits(other.d)) return false;
        return true;
    }
    @Override
    public String toString() {
        return String.format("%.2f + %.2fi + %.2fj + %.2fk", a, b, c, d).replaceAll("\\+ -", "- ");
    }

    public String toQuadruple() {
        return String.format("(%.2f, %.2f, %.2f, %.2f)", a, b, c, d);
    }

    public static void main(String[] args) {
        Quaternion q = new Quaternion(1.0, 2.0, 3.0, 4.0);
        Quaternion q1 = new Quaternion(2.0, 3.0, 4.0, 5.0);
        Quaternion q2 = new Quaternion(3.0, 4.0, 5.0, 6.0);
        double r = 7.0;
        System.out.format("q       = %s%n", q);
        System.out.format("q1      = %s%n", q1);
        System.out.format("q2      = %s%n", q2);
        System.out.format("r       = %.2f%n%n", r);
        System.out.format("\u2016q\u2016     = %.2f%n", q.norm());
        System.out.format("-q      = %s%n", q.negative());
        System.out.format("q*      = %s%n", q.conjugate());
        System.out.format("q + r   = %s%n", q.add(r));
        System.out.format("q1 + q2 = %s%n", q1.add(q2));
        System.out.format("q \u00d7 r   = %s%n", q.times(r));
        Quaternion q1q2 = q1.times(q2);
        Quaternion q2q1 = q2.times(q1);
        System.out.format("q1 \u00d7 q2 = %s%n", q1q2);
        System.out.format("q2 \u00d7 q1 = %s%n", q2q1);
        System.out.format("q1 \u00d7 q2 %s q2 \u00d7 q1%n", (q1q2.equals(q2q1) ? "=" : "\u2260"));
    }
}


Quine

A quine is a self-referential program that can,
without any external access, output its own source.

A   '''quine'''   (named after Willard Van Orman Quine)   is also known as:
::*   ''self-reproducing automata''        (1972)
::*   ''self-replicating program''                             or   ''self-replicating computer program''
::*   ''self-reproducing program''                                  or   ''self-reproducing computer program''
::*   ''self-copying program''                       or   ''self-copying computer program''

It is named after the philosopher and logician
who studied self-reference and quoting in natural language,
as for example in the paradox "'Yields falsehood when preceded by its quotation' yields falsehood when preceded by its quotation."

"Source" has one of two meanings. It can refer to the text-based program source.
For languages in which program source is represented as a data structure, "source" may refer to the data structure: quines in these languages fall into two categories: programs which print a textual representation of themselves, or expressions which evaluate to a data structure which is equivalent to that expression.

The usual way to code a quine works similarly to this paradox: The program consists of two identical parts, once as plain code and once ''quoted'' in some way (for example, as a character string, or a literal data structure). The plain code then accesses the quoted code and prints it out twice, once unquoted and once with the proper quotation marks added. Often, the plain code and the quoted code have to be nested.

;Task:
Write a program that outputs its own source code in this way. If the language allows it, you may add a variant that accesses the code directly. You are not allowed to read any external files with the source code. The program should also contain some sort of self-reference, so constant expressions which return their own value which some top-level interpreter will print out.  Empty programs producing no output are not allowed.

There are several difficulties that one runs into when writing a quine, mostly dealing with quoting:
* Part of the code usually needs to be stored as a string or structural literal in the language, which needs to be quoted somehow. However, including quotation marks in the string literal itself would be troublesome because it requires them to be escaped, which then necessitates the escaping character (e.g. a backslash) in the string, which itself usually needs to be escaped, and so on.
** Some languages have a function for getting the "source code representation" of a string (i.e. adds quotation marks, etc.); in these languages, this can be used to circumvent the quoting problem.
** Another solution is to construct the quote character from its [[character code]], without having to write the quote character itself. Then the character is inserted into the string at the appropriate places. The ASCII code for double-quote is 34, and for single-quote is 39.
* Newlines in the program may have to be reproduced as newlines in the string, which usually requires some kind of escape sequence (e.g. "\n"). This causes the same problem as above, where the escaping character needs to itself be escaped, etc.
** If the language has a way of getting the "source code representation", it usually handles the escaping of characters, so this is not a problem.
** Some languages allow you to have a string literal that spans multiple lines, which embeds the newlines into the string without escaping.
** Write the entire program on one line, for free-form languages (as you can see for some of the solutions here, they run off the edge of the screen), thus removing the need for newlines. However, this may be unacceptable as some languages require a newline at the end of the file; and otherwise it is still generally good style to have a newline at the end of a file. (The task is not clear on whether a newline is required at the end of the file.) Some languages have a print statement that appends a newline; which solves the newline-at-the-end issue; but others do not.

'''Next to the Quines presented here, many other versions can be found on the Quine page.'''

;Related task:
:*   print itself.

Solution: class S{public static void main(String[]a){String s="class S{public static void main(String[]a){String s=;char c=34;System.out.println(s.substring(0,52)+c+s+c+s.substring(52));}}";char c=34;System.out.println(s.substring(0,52)+c+s+c+s.substring(52));}}


Quine

Solution: class S{public static void main(String[]a){String p="class S{public static void main(String[]a){String p=%c%s%1$c;System.out.printf(p,34,p);}}";System.out.printf(p,34,p);}}


RPG attributes generator

'''RPG'''   =   Role Playing Game.

You're running a tabletop RPG, and your players are creating characters.

Each character has six core attributes: strength, dexterity, constitution, intelligence, wisdom, and charisma.

One way of generating values for these attributes is to roll four, 6-sided dice (d6) and sum the three highest rolls, discarding the lowest roll.

Some players like to assign values to their attributes in the order they're rolled.

To ensure generated characters don't put players at a disadvantage, the following requirements must be satisfied:

* The total of all character attributes must be at least 75.
* At least two of the attributes must be at least 15.

However, this can require a lot of manual dice rolling. A programatic solution would be much faster.

;Task:
Write a program that:
# Generates 4 random, whole values between 1 and 6.
# Saves the sum of the 3 largest values.
# Generates a total of 6 values this way.
# Displays the total, and all 6 values once finished.

* The order in which each value was generated must be preserved.
* The total of all 6 values must be at least 75.
* At least 2 of the values must be 15 or more.

Solution:
import java.util.List;
import java.util.Random;
import java.util.stream.Stream;

import static java.util.stream.Collectors.toList;

public class Rpg {

    private static final Random random = new Random();

    public static int genAttribute() {
        return random.ints(1, 6 + 1) // Throw dices between 1 and 6
            .limit(4) // Do 5 throws
            .sorted() // Sort them
            .limit(3) // Take the top 3
            .sum();   // Sum them
    }

    public static void main(String[] args) {
        while (true) {
            List<Integer> stats =
                Stream.generate(Rpg::genAttribute) // Generate some stats
                    .limit(6) // Take 6
                    .collect(toList()); // Save them in an array
            int sum = stats.stream().mapToInt(Integer::intValue).sum();
            long count = stats.stream().filter(v -> v >= 15).count();
            if (count >= 2 && sum >= 75) {
                System.out.printf("The 6 random numbers generated are: %s\n", stats);
                System.out.printf("Their sum is %s and %s of them are >= 15\n", sum, count);
                return;
            }
        }
    }
}


Ramanujan's constant

Calculate Ramanujan's constant (as described on the OEIS site) with at least
32 digits of precision, by the method of your choice.  Optionally, if using the e**(p*''x'') approach,
show that when evaluated with the last four Heegner numbers
the result is ''almost'' an integer.

Solution:
import java.math.BigDecimal;
import java.math.MathContext;
import java.util.Arrays;
import java.util.List;

public class RamanujanConstant {

    public static void main(String[] args) {
        System.out.printf("Ramanujan's Constant to 100 digits = %s%n%n", ramanujanConstant(163, 100));
        System.out.printf("Heegner numbers yielding 'almost' integers:%n");
        List<Integer> heegnerNumbers = Arrays.asList(19, 43, 67, 163);
        List<Integer> heegnerVals = Arrays.asList(96, 960, 5280, 640320);
        for ( int i = 0 ; i < heegnerNumbers.size() ; i++ ) {
            int heegnerNumber = heegnerNumbers.get(i);
            int heegnerVal = heegnerVals.get(i);
            BigDecimal integer = BigDecimal.valueOf(heegnerVal).pow(3).add(BigDecimal.valueOf(744));
            BigDecimal compute = ramanujanConstant(heegnerNumber, 50);
            System.out.printf("%3d : %50s ~ %18s (diff ~ %s)%n", heegnerNumber, compute, integer, integer.subtract(compute, new MathContext(30)).toPlainString());
        }
    }

    public static BigDecimal ramanujanConstant(int sqrt, int digits) {
        //  For accuracy on lat digit, computations with a few extra digits
        MathContext mc = new MathContext(digits + 5);
        return bigE(bigPi(mc).multiply(bigSquareRoot(BigDecimal.valueOf(sqrt), mc), mc), mc).round(new MathContext(digits));
    }

    //  e = 1 + x/1! + x^2/2! + x^3/3! + ...
    public static BigDecimal bigE(BigDecimal exponent, MathContext mc) {
        BigDecimal e = BigDecimal.ONE;
        BigDecimal ak = e;
        int k = 0;
        BigDecimal min = BigDecimal.ONE.divide(BigDecimal.TEN.pow(mc.getPrecision()));
        while ( true ) {
            k++;
            ak = ak.multiply(exponent).divide(BigDecimal.valueOf(k), mc);
            e = e.add(ak, mc);
            if ( ak.compareTo(min) < 0 ) {
                break;
            }
        }
        return e;

    }

    //  See : https://www.craig-wood.com/nick/articles/pi-chudnovsky/
    public static BigDecimal bigPi(MathContext mc) {
        int k = 0;
        BigDecimal ak = BigDecimal.ONE;
        BigDecimal a = ak;
        BigDecimal b = BigDecimal.ZERO;
        BigDecimal c = BigDecimal.valueOf(640320);
        BigDecimal c3 = c.pow(3);
        double digitePerTerm = Math.log10(c.pow(3).divide(BigDecimal.valueOf(24), mc).doubleValue()) - Math.log10(72);
        double digits = 0;
        while ( digits < mc.getPrecision() ) {
            k++;
            digits += digitePerTerm;
            BigDecimal top = BigDecimal.valueOf(-24).multiply(BigDecimal.valueOf(6*k-5)).multiply(BigDecimal.valueOf(2*k-1)).multiply(BigDecimal.valueOf(6*k-1));
            BigDecimal term = top.divide(BigDecimal.valueOf(k*k*k).multiply(c3), mc);
            ak = ak.multiply(term, mc);
            a = a.add(ak, mc);
            b = b.add(BigDecimal.valueOf(k).multiply(ak, mc), mc);
        }
        BigDecimal total = BigDecimal.valueOf(13591409).multiply(a, mc).add(BigDecimal.valueOf(545140134).multiply(b, mc), mc);
        return BigDecimal.valueOf(426880).multiply(bigSquareRoot(BigDecimal.valueOf(10005), mc), mc).divide(total, mc);
    }

    //  See : https://en.wikipedia.org/wiki/Newton's_method#Square_root_of_a_number
    public static BigDecimal bigSquareRoot(BigDecimal squareDecimal, MathContext mc) {
        //  Estimate
        double sqrt = Math.sqrt(squareDecimal.doubleValue());
        BigDecimal x0 = new BigDecimal(sqrt, mc);
        BigDecimal two = BigDecimal.valueOf(2);
        while ( true ) {
            BigDecimal x1 = x0.subtract(x0.multiply(x0, mc).subtract(squareDecimal).divide(two.multiply(x0, mc), mc), mc);
            String x1String = x1.toPlainString();
            String x0String = x0.toPlainString();
            if ( x1String.substring(0, x1String.length()-1).compareTo(x0String.substring(0, x0String.length()-1)) == 0 ) {
                break;
            }
            x0 = x1;
        }
        return x0;
    }

}


Ramer-Douglas-Peucker line simplification

The   '''Ramer-Douglas-Peucker'''   algorithm is a line simplification algorithm for reducing the number of points used to define its shape.

;Task:
Using the   '''Ramer-Douglas-Peucker'''   algorithm, simplify the   2D   line defined by the points:
    (0,0)  (1,0.1)  (2,-0.1)  (3,5)  (4,6)  (5,7)  (6,8.1)  (7,9)  (8,9)  (9,9)

The error threshold to be used is:   '''1.0'''.

Display the remaining points here.

;Reference:
:*   the Wikipedia article:   Ramer-Douglas-Peucker algorithm.

Solution:
import javafx.util.Pair;

import java.util.ArrayList;
import java.util.List;

public class LineSimplification {
    private static class Point extends Pair<Double, Double> {
        Point(Double key, Double value) {
            super(key, value);
        }

        @Override
        public String toString() {
            return String.format("(%f, %f)", getKey(), getValue());
        }
    }

    private static double perpendicularDistance(Point pt, Point lineStart, Point lineEnd) {
        double dx = lineEnd.getKey() - lineStart.getKey();
        double dy = lineEnd.getValue() - lineStart.getValue();

        // Normalize
        double mag = Math.hypot(dx, dy);
        if (mag > 0.0) {
            dx /= mag;
            dy /= mag;
        }
        double pvx = pt.getKey() - lineStart.getKey();
        double pvy = pt.getValue() - lineStart.getValue();

        // Get dot product (project pv onto normalized direction)
        double pvdot = dx * pvx + dy * pvy;

        // Scale line direction vector and subtract it from pv
        double ax = pvx - pvdot * dx;
        double ay = pvy - pvdot * dy;

        return Math.hypot(ax, ay);
    }

    private static void ramerDouglasPeucker(List<Point> pointList, double epsilon, List<Point> out) {
        if (pointList.size() < 2) throw new IllegalArgumentException("Not enough points to simplify");

        // Find the point with the maximum distance from line between the start and end
        double dmax = 0.0;
        int index = 0;
        int end = pointList.size() - 1;
        for (int i = 1; i < end; ++i) {
            double d = perpendicularDistance(pointList.get(i), pointList.get(0), pointList.get(end));
            if (d > dmax) {
                index = i;
                dmax = d;
            }
        }

        // If max distance is greater than epsilon, recursively simplify
        if (dmax > epsilon) {
            List<Point> recResults1 = new ArrayList<>();
            List<Point> recResults2 = new ArrayList<>();
            List<Point> firstLine = pointList.subList(0, index + 1);
            List<Point> lastLine = pointList.subList(index, pointList.size());
            ramerDouglasPeucker(firstLine, epsilon, recResults1);
            ramerDouglasPeucker(lastLine, epsilon, recResults2);

            // build the result list
            out.addAll(recResults1.subList(0, recResults1.size() - 1));
            out.addAll(recResults2);
            if (out.size() < 2) throw new RuntimeException("Problem assembling output");
        } else {
            // Just return start and end points
            out.clear();
            out.add(pointList.get(0));
            out.add(pointList.get(pointList.size() - 1));
        }
    }

    public static void main(String[] args) {
        List<Point> pointList = List.of(
                new Point(0.0, 0.0),
                new Point(1.0, 0.1),
                new Point(2.0, -0.1),
                new Point(3.0, 5.0),
                new Point(4.0, 6.0),
                new Point(5.0, 7.0),
                new Point(6.0, 8.1),
                new Point(7.0, 9.0),
                new Point(8.0, 9.0),
                new Point(9.0, 9.0)
        );
        List<Point> pointListOut = new ArrayList<>();
        ramerDouglasPeucker(pointList, 1.0, pointListOut);
        System.out.println("Points remaining after simplification:");
        pointListOut.forEach(System.out::println);
    }
}


Random Latin squares

A Latin square of size n is an arrangement of n symbols  in an n-by-n square in such a way that each row and column has each symbol appearing exactly once.
For the purposes of this task, a random Latin square of size n is a Latin square constructed or generated by a probabilistic procedure such that the probability of any particular Latin square of size n being produced is non-zero.

;Example n=4 randomised Latin square:
0 2 3 1
2 1 0 3
3 0 1 2
1 3 2 0

;Task:
# Create a function/routine/procedure/method/... that given n generates a randomised Latin square of size n.
# Use the function to generate ''and show here'', two randomly generated squares of size 5.

;Note:
Strict ''uniformity'' in the random generation is a hard problem and '''not''' a requirement of the task.

;Related tasks:
* [[Latin Squares in reduced form/Randomizing using Jacobson and Matthews' Technique]]
* [[Latin Squares in reduced form]]

;Reference:
* Wikipedia: Latin square
* OEIS: A002860

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

public class RandomLatinSquares {
    private static void printSquare(List<List<Integer>> latin) {
        for (List<Integer> row : latin) {
            Iterator<Integer> it = row.iterator();

            System.out.print("[");
            if (it.hasNext()) {
                Integer col = it.next();
                System.out.print(col);
            }
            while (it.hasNext()) {
                Integer col = it.next();
                System.out.print(", ");
                System.out.print(col);
            }
            System.out.println("]");
        }
        System.out.println();
    }

    private static void latinSquare(int n) {
        if (n <= 0) {
            System.out.println("[]");
            return;
        }

        List<List<Integer>> latin = new ArrayList<>(n);
        for (int i = 0; i < n; ++i) {
            List<Integer> inner = new ArrayList<>(n);
            for (int j = 0; j < n; ++j) {
                inner.add(j);
            }
            latin.add(inner);
        }
        // first row
        Collections.shuffle(latin.get(0));

        // middle row(s)
        for (int i = 1; i < n - 1; ++i) {
            boolean shuffled = false;
            shuffling:
            while (!shuffled) {
                Collections.shuffle(latin.get(i));
                for (int k = 0; k < i; ++k) {
                    for (int j = 0; j < n; ++j) {
                        if (Objects.equals(latin.get(k).get(j), latin.get(i).get(j))) {
                            continue shuffling;
                        }
                    }
                }
                shuffled = true;
            }
        }

        // last row
        for (int j = 0; j < n; ++j) {
            List<Boolean> used = new ArrayList<>(n);
            for (int i = 0; i < n; ++i) {
                used.add(false);
            }
            for (int i = 0; i < n - 1; ++i) {
                used.set(latin.get(i).get(j), true);
            }
            for (int k = 0; k < n; ++k) {
                if (!used.get(k)) {
                    latin.get(n - 1).set(j, k);
                    break;
                }
            }
        }

        printSquare(latin);
    }

    public static void main(String[] args) {
        latinSquare(5);
        latinSquare(5);
        latinSquare(10);
    }
}


Random number generator (device)

If your system has a means to generate random numbers involving not only a software algorithm   (like the /dev/urandom devices in Unix),   then:

show how to obtain a random 32-bit number from that mechanism.

;Related task
* [[Random_number_generator_(included)]]

Solution:
import java.security.SecureRandom;

public class RandomExample {
  public static void main(String[] args) {
    SecureRandom rng = new SecureRandom();

    /* Prints a random signed 32-bit integer. */
    System.out.println(rng.nextInt());
  }
}


Random number generator (included)

The task is to:
: State the type of random number generator algorithm used in a language's built-in random number generator. If the language or its immediate libraries don't provide a random number generator, skip this task.
: If possible, give a link to a wider explanation of the algorithm used.

Note: the task is ''not'' to create an RNG, but to report on the languages in-built RNG that would be the most likely RNG used.

The main types of pseudo-random number generator (Mersenne twister generator is a subclass). The last main type is where the output of one of the previous ones (typically a Mersenne twister) is fed through a [[cryptographic hash function]] to maximize unpredictability of individual bits.

Note that neither LCGs nor GFSRs should be used for the most demanding applications (cryptography) without additional steps.

Solution: Java's Random class uses a [[wp:Linear congruential generator|Linear congruential formula]], as described in [http://java.sun.com/javase/6/docs/api/java/util/Random.html its documentation]. The commonly used Math.random() uses a Random object under the hood.