Project Euler Problem 24 Solved

| Comments

Lexicographic permutations

A permutation is an ordered arrangement of objects. For example, 3124 is one possible permutation of the digits 1, 2, 3 and 4. If all of the permutations are listed numerically or alphabetically, we call it lexicographic order. The lexicographic permutations of 0, 1 and 2 are:

012 021 102 120 201 210

What is the millionth lexicographic permutation of the digits 0, 1, 2, 3, 4, 5, 6, 7, 8 and 9?

Solution

p24.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
#!/usr/bin/python2
# -*- coding: utf-8 -*-

from math import factorial


def get_perm(digits, number):
    if len(digits) == 0:
        return ''
    (perm, counter) = ('', factorial(len(digits) - 1))
    for digit in digits:
        if counter >= number:
            digits.remove(digit)
            perm += str(digit) + get_perm(digits, number)
            break
        number -= counter
    return perm


if __name__ == '__main__':
    import time
    startTime = time.time()
    perm = get_perm([d for d in range(10)], 1000000)
    print perm, '%sms' % ((time.time() - startTime) * 1000)
p24.php
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
<?php
function factorial($n) {
    $result = 1;
    for ($i = 2;$i <= $n;$i++) $result*= $i;
    return $result;
}

function get_perm($digits, $number) {
    $perm = "";
    $length = count($digits);
    $counter = factorial($length - 1);
    for ($i = 0;$i < $length;$i++) {
        if ($counter >= $number) {
            $segment = array_splice($digits, $i, 1);
            $perm = $segment[0] . get_perm($digits, $number);
            break;
        }
        $number-= $counter;
    }
    return $perm;
}

$startTime = microtime(true);
$digits = array(0, 1, 2, 3, 4, 5, 6, 7, 8, 9);
$perm = get_perm($digits, 1000000);
$costs = (microtime(true) - $startTime) * 1000;
echo "$perm ${costs}ms\n";
?>
p24.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
package main

import (
  "fmt"
  "strconv"
  "time"
)

func factorial(n int) int {
  result := 1
  for i := 2; i <= n; i++ {
      result *= i
  }
  return result
}

func get_perm(digits []int, number int) string {
  perm, length := "", len(digits)
  counter := factorial(length - 1)
  for i := 0; i < length; i++ {
      if counter >= number {
          digit := digits[i]
          digits = append(digits[:i], digits[i+1:]...)
          perm += strconv.Itoa(digit) + get_perm(digits, number)
          break
      }
      number -= counter
  }
  return perm
}

func main() {
  startTime := time.Now()
  digits := []int{0, 1, 2, 3, 4, 5, 6, 7, 8, 9}
  perm := get_perm(digits, 1000000)
  fmt.Println(perm, time.Now().Sub(startTime))
}

I’m the 57181st person to have solved this problem.

I’ve just advanced to Level 1. 61264 members (15.9%) have made it this far.

I have earned 1 new award:

The Journey Begins: Progress to Level 1 by solving twenty-five problems

Comments