[RUBY] Program to search all permutations (for competitive programming)

I wrote a program in each language that enumerates all permutations. Assuming that there are four elements, 10, 20, 30, and 40, the output is as follows. If there are $ n $ elements, it will output $ n! $ Lines. If you write some processing in the place to output, you can search all permutations.

 10 20 30 40
 10 20 40 30
 10 30 20 40
 10 30 40 20
 10 40 20 30
 10 40 30 20
 20 10 30 40
 20 10 40 30
...

Language written:

--Library use: C ++, Scala, Ruby, Python --Original implementation: C language, Java, JavaScript, Elixir

Background:

AtCoder's ABC183 C --Travel required permutation enumeration. I didn't know the algorithm for permutation enumeration, so I forcibly wrote it during the competition and got AC, but when I read the explanation, there was a smarter algorithm. Moreover, in some languages, a library for enumerating permutations was also standard equipment.

I was disappointed, so I wrote a program to list all permutations in each language.

reference:

-AtCoder official commentary

C++

C ++ has a function called next_permutation.

#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;

int main() {
  int len = 4;
  vector<int> vec(len);
  for (int i = 0; i < len; i++) vec[i] = 10 * (i+1);
  do {
    for (int i = 0; i < len; i++) cout << " " << vec[i];
    cout << endl;
  } while (next_permutation(vec.begin(), vec.end()));
}

Scala

Scala has a method called permutations.

object Main extends App {
  val len = 4;
  val seq = (1 to len).map(10 * _);
  seq.permutations.foreach { seq =>
    println(" " + seq.mkString(" "));
  }
}

Ruby

Ruby has a method called permutation.

len = 4
arr = (1 .. len).map do |i|
  10 * i
end
arr.permutation do |arr|
  puts(" " + arr.join(" "))
end

Python

Python has a function called itertools.permutations.

import itertools

len = 4
lst = [10 * (i+1) for i in range(len)]
for lst2 in itertools.permutations(lst):
    print(" " + " ".join(map(str, lst2)))

C language

I'm implementing the C ++ next_permutation myself. (Almost the explanation of AtCoder is the same)

#include <stdio.h>

int next_permutation(int *arr, int len) {
  int left = len - 2;
  while (left >= 0 && arr[left] >= arr[left+1]) left--;
  if (left < 0) return 0;
  int right = len - 1;
  while (arr[left] >= arr[right]) right--;
  { int t = arr[left]; arr[left] = arr[right]; arr[right] = t; }
  left++;
  right = len - 1;
  while (left < right) {
    { int t = arr[left]; arr[left] = arr[right]; arr[right] = t; }
    left++;
    right--;
  }
  return 1;
}

int main() {
  int len = 4;
  int arr[len];
  for (int i = 0; i < len; i++) arr[i] = 10 * (i+1);
  do {
    for (int i = 0; i < len; i++) printf(" %d", arr[i]);
    printf("\n");
  } while (next_permutation(arr, len));
}

Java

It is the same implementation as next_permutation implemented in C language.

class Main {
  public static boolean nextPermutation(int[] arr) {
    int len = arr.length;
    int left = len - 2;
    while (left >= 0 && arr[left] >= arr[left+1]) left--;
    if (left < 0) return false;
    int right = len - 1;
    while (arr[left] >= arr[right]) right--;
    { int t = arr[left]; arr[left] = arr[right];  arr[right] = t; }
    left++;
    right = len - 1;
    while (left < right) {
      { int t = arr[left]; arr[left] = arr[right]; arr[right] = t; }
      left++;
      right--;
    }
    return true;
  }

  public static void main(String[] args) {
    int len = 4;
    var arr = new int[len];
    for (int i = 0; i < len; i++) {
      arr[i] = 10 * (i+1);
    }
    do {
      var sb = new StringBuilder();
      for (int i = 0; i < len; i++) {
        sb.append(String.format(" %d", arr[i]));
      }
      System.out.println(sb);
    } while (nextPermutation(arr));
  }
}

JavaScript

It is the same implementation as next_permutation implemented in C language and Java.

function next_permutation(arr) {
    const len = arr.length;
    let left = len - 2;
    while (left >= 0 && arr[left] >= arr[left+1]) left--;
    if (left < 0) return false;
    let right = len - 1;
    while (arr[left] >= arr[right]) right--;
    { const t = arr[left]; arr[left] = arr[right]; arr[right] = t; }
    left++;
    right = len - 1;
    while (left < right) {
        { const t = arr[left]; arr[left] = arr[right]; arr[right] = t; }
        left++;
        right--;
    }
    return true;
}

const len = 4;
const arr = [];
for (let i = 0; i < len; i++) arr.push(10 * (i+1));
do {
    let str = "";
    for (let i = 0; i < len; i++) str += " " + arr[i];
    console.log(str);
} while (next_permutation(arr));

Elixir

It is an algorithm different from the implementation in C language and Java. Unlike next_permutation, all permutation patterns are created first.

defmodule Main do
  def permutations([]), do: [[]]
  def permutations(list) do
    for elem <- list, p <- permutations(list -- [elem]), do: [elem | p]
  end

  def main do
    len = 4
    list = (1 .. len) |> Enum.map(fn x -> 10 * x end)
    permutations(list) |> Enum.each(fn l ->
      IO.puts(" " <> Enum.join(l, " "))
    end)
  end
end

Recommended Posts

Program to search all permutations (for competitive programming)
Terminology for all programming languages
Python3 standard input for competitive programming
[Competitive programming] [Python3] Required knowledge, for myself
An introduction to object-oriented programming for beginners by beginners
Introduction to Programming (Python) TA Tendency for beginners
[For beginners] How to study programming Private memo
Script to search all selected object hierarchies in Blender
Preparing to start "Python machine learning programming" (for macOS)
I thought about how to learn programming for free.
Private memos used for list operations and competitive programming
[For beginners of competitive pros] Three input methods to remember when starting competitive programming in Python