I give you Nth permutation, you give me N

20

4

Input: a sequence of uppercase letters (ASCII [65;90]) which is the Nth* lexicographical permutation of the multiset of its characters

*permutations are numbered from 0 or 1 upwards

Output: base-10 integer N


Rulez

  • There might be duplicates (that's how this challenge differs from this one)
  • The characters are ordered by their ASCII value
  • In case of an input of length less than or equal to 1, the input is the first permutation and the result is 0 or 1 respectively
  • First permutation is that in which the leftmost character has the lowest value, the rightmost character has the highest value, and the sequence of characters between the first and the last character is the first permutation of the multiset of its characters (recursive definition!)
  • Shortest entry wins

Example

  • Input AAB produces output 0
  • Input ABA produces output 1
  • Input BAA produces output 2

  • Input ZZZ produces output 0
  • Input DCBA produces output 23

EDIT

Extra kudos to the one who can come up with a solution which doesn't produce all permutations and then search for the input. That's some challenge.

kyrill

Posted 2017-04-02T01:32:11.570

Reputation: 575

Hello and welcome to the site. This question is currently rather unclear. I am not really sure how the permutations are ordered. Are they lexicographically ordered? This should be defined in your question. – Post Rock Garf Hunter – 2017-04-02T01:35:10.003

1

We also have a sandbox so you can get this kind of feedback before posting to our main site. It is not mandatory to post there first, but a lot of times it is very helpful.

– Post Rock Garf Hunter – 2017-04-02T01:39:22.890

You said 'Uppercase', zzz and dcba is not uppercase. – Matthew Roh – 2017-04-02T02:07:14.290

@SIGSEGV corrected – kyrill – 2017-04-02T02:12:18.140

Can the output index be 1-based instead of 0-based? – Luis Mendo – 2017-04-02T02:51:20.940

Well... let's see what you have. – kyrill – 2017-04-02T02:55:23.673

Uhm, Is that a yes? – Luis Mendo – 2017-04-02T02:56:21.147

Yep. It's a yes. – kyrill – 2017-04-02T02:56:43.140

if you decide to account for the case when the input is empty, the output has to be 0 I think this should be removed. Answers can always claim they don't support empty input. Same for You can support other characters than ASCII uppercase letters – Luis Mendo – 2017-04-02T03:03:43.840

I agree in case of empty input, but other characters than uppercase letters would still have well-defined expected output. What I mean is that you don't have to support it, but you don't have to make an effort to treat such input as an error. If they claim they don't support it, then they just don't support it. Rules don't disallow that. – kyrill – 2017-04-02T03:10:26.410

But you say Input: a sequence of uppercase letters. So, considering what would happen for other characters is pointless – Luis Mendo – 2017-04-02T03:23:15.270

Right, I didn't realize that. Other letters than uppercase removed. – kyrill – 2017-04-02T03:28:05.120

Answers

0

Jelly, 5 bytes

Œ!QṢi

Try it online!

1-indexed output.

Erik the Outgolfer

Posted 2017-04-02T01:32:11.570

Reputation: 38 134

@downvoter This post is perfectly valid. – Erik the Outgolfer – 2017-04-13T13:16:17.337

5

Python 2, 69 bytes

Try it online

from itertools import*
lambda S:sorted(set(permutations(S))).index(S)

Dead Possum

Posted 2017-04-02T01:32:11.570

Reputation: 3 256

4

Python, 302 287 bytes

Dead Possum has already posted a short Pythonic solution, so I decided to go for the extra kudos. This solution does not generate all of the permutations. It can rapidly calculate the permutation index of a rather large string; it also handles an empty string correctly.

from math import factorial as f
from itertools import groupby as g
def p(t,b=''):
 if len(t)<2:return 0
 z,b=0,b or sorted(t)
 for i,c in enumerate(b):
  w=b[:i]+b[i+1:]
  if c==t[0]:return z+p(t[1:],w)
  if i<1 or c!=b[i-1]:
   n=f(len(w))
   for _,v in g(w):n//=f(len(list(v)))
   z+=n

Testing code:

def lexico_permute_string(s):
    ''' Generate all permutations of `s` in lexicographic order '''
    a = sorted(s)
    n = len(a) - 1
    while True:
        yield ''.join(a)
        for j in range(n-1, -1, -1):
            if a[j] < a[j + 1]:
                break
        else:
            return
        v = a[j]
        for k in range(n, j, -1):
            if v < a[k]:
                break
        a[j], a[k] = a[k], a[j]
        a[j+1:] = a[j+1:][::-1]

def test_all(base):
    for i, s in enumerate(lexico_permute_string(base)):
        rank = p(s)
        assert rank == i, (i, s, rank)
        print('{:2} {} {:2}'.format(i, s, rank))
    print(repr(base), 'ok\n')

for base in ('AAB', 'abbbbc'):
    test_all(base)

def test(s):
    print('{!r}\n{}\n'.format(s, p(s)))

for s in ('ZZZ', 'DCBA', 'a quick brown fox jumps over the lazy dog'):
    test(s)

output

 0 AAB  0
 1 ABA  1
 2 BAA  2
'AAB' ok

 0 abbbbc  0
 1 abbbcb  1
 2 abbcbb  2
 3 abcbbb  3
 4 acbbbb  4
 5 babbbc  5
 6 babbcb  6
 7 babcbb  7
 8 bacbbb  8
 9 bbabbc  9
10 bbabcb 10
11 bbacbb 11
12 bbbabc 12
13 bbbacb 13
14 bbbbac 14
15 bbbbca 15
16 bbbcab 16
17 bbbcba 17
18 bbcabb 18
19 bbcbab 19
20 bbcbba 20
21 bcabbb 21
22 bcbabb 22
23 bcbbab 23
24 bcbbba 24
25 cabbbb 25
26 cbabbb 26
27 cbbabb 27
28 cbbbab 28
29 cbbbba 29
'abbbbc' ok

'ZZZ'
0

'DCBA'
23

'a quick brown fox jumps over the lazy dog'
436629906477779191275460617121351796379337

Non-golfed version:

''' Determine the rank (lexicographic index) of a permutation 
    The permutation may contain repeated items

    Written by PM 2Ring 2017.04.03
'''

from math import factorial as fac
from itertools import groupby

def lexico_permute_string(s):
    ''' Generate all permutations of `s` in lexicographic order '''
    a = sorted(s)
    n = len(a) - 1
    while True:
        yield ''.join(a)
        for j in range(n-1, -1, -1):
            if a[j] < a[j + 1]:
                break
        else:
            return
        v = a[j]
        for k in range(n, j, -1):
            if v < a[k]:
                break
        a[j], a[k] = a[k], a[j]
        a[j+1:] = a[j+1:][::-1]

def perm_count(s):
    ''' Count the total number of permutations of sorted sequence `s` '''
    n = fac(len(s))
    for _, g in groupby(s):
        n //= fac(sum(1 for u in g))
    return n

def perm_rank(target, base):
    ''' Determine the permutation rank of string `target`
        given the rank zero permutation string `base`,
        i.e., the chars in `base` are in lexicographic order.
    '''
    if len(target) < 2:
        return 0
    total = 0
    head, newtarget = target[0], target[1:]
    for i, c in enumerate(base):
        newbase = base[:i] + base[i+1:]
        if c == head:
            return total + perm_rank(newtarget, newbase)
        elif i and c == base[i-1]:
            continue
        total += perm_count(newbase)

base = 'abcccdde'
print('total number', perm_count(base))

for i, s in enumerate(lexico_permute_string(base)):
    rank = perm_rank(s, base)
    assert rank == i, (i, s, rank)
    #print('{:2} {} {:2}'.format(i, s, rank))
print('ok')

About lexico_permute_string

This algorithm, due to Narayana Pandita, is from https://en.wikipedia.org/wiki/Permutation#Generation_in_lexicographic_order

To produce the next permutation in lexicographic order of sequence a

  1. Find the largest index j such that a[j] < a[j + 1]. If no such index exists, the permutation is the last permutation.
  2. Find the largest index k greater than j such that a[j] < a[k].
  3. Swap the value of a[j] with that of a[k].
  4. Reverse the sequence from a[j + 1] up to and including the final element a[n].

FWIW, you can see an annotated version of that function here.


FWIW, here's the inverse function.

def perm_unrank(rank, base, head=''):
    ''' Determine the permutation with given rank of the 
        rank zero permutation string `base`.
    '''
    if len(base) < 2:
        return head + ''.join(base)

    total = 0
    for i, c in enumerate(base):
        if i < 1 or c != base[i-1]:
            newbase = base[:i] + base[i+1:]
            newtotal = total + perm_count(newbase)
            if newtotal > rank:
                return perm_unrank(rank - total, newbase, head + c)
            total = newtotal
# Test

target = 'a quick brown fox jumps over the lazy dog'
base = ''.join(sorted(target))
rank = perm_rank(target, base)
print(target)
print(base)
print(rank)
print(perm_unrank(rank, base))

output

a quick brown fox jumps over the lazy dog
        aabcdeefghijklmnoooopqrrstuuvwxyz
436629906477779191275460617121351796379337
a quick brown fox jumps over the lazy dog

And here's a function that I wrote while developing perm_unrank which shows the breakdown of the subcounts.

def counts(base):
    for i, c in enumerate(base):
        newbase = base[:i] + base[i+1:]
        if newbase and (i < 1 or c != base[i-1]):
            yield c, perm_count(newbase)
            for h, k in counts(newbase):
                yield c + h, k 

def show_counts(base):
    TAB = ' ' * 4
    for s, t in counts(base):
        d = len(s) - 1
        print('{}{} {}'.format(TAB * d, s, t))

# Test
base = 'abccc'
print('total number', perm_count(base))
show_counts(base)

output

a 4
    ab 1
        abc 1
            abcc 1
    ac 3
        acb 1
            acbc 1
        acc 2
            accb 1
            accc 1
b 4
    ba 1
        bac 1
            bacc 1
    bc 3
        bca 1
            bcac 1
        bcc 2
            bcca 1
            bccc 1
c 12
    ca 3
        cab 1
            cabc 1
        cac 2
            cacb 1
            cacc 1
    cb 3
        cba 1
            cbac 1
        cbc 2
            cbca 1
            cbcc 1
    cc 6
        cca 2
            ccab 1
            ccac 1
        ccb 2
            ccba 1
            ccbc 1
        ccc 2
            ccca 1
            cccb 1

PM 2Ring

Posted 2017-04-02T01:32:11.570

Reputation: 469

Wow! Amazing solution! There are some bits of Python here I'm not familiar with that I'm going to have to go look up now to fully understand it. Well done! – David Conrad – 2017-04-03T18:40:11.470

You can change it to z=0 and substitute in t[0] and t[1:] where they're used (currently h and t) to save 8 bytes. – David Conrad – 2017-04-04T05:53:24.220

Congratulations, you get the extra kudos as well! Even though Jörg Hülsermann was first, but your version is recursive so it's not the same as his. – kyrill – 2017-04-04T10:46:57.960

Thanks, @kyrill Now I'm wondering how to do the reverse process efficiently: produce the permutation from its index. I guess it shouldn't be too hard to modify the usual factorial-base technique used for permutations without repeats...

– PM 2Ring – 2017-04-04T14:01:41.210

@DavidConrad Thanks! And thanks for the suggestion; why didn't I see that. :) I made a few more optimizations before I saw your 2nd comment, but I didn't have a chance to post them earlier. – PM 2Ring – 2017-04-04T14:02:13.517

@kyrill I've added code that produces the permutation from its rank. I suspect that this could be done a little more efficiently, but this code's fast enough for me. ;) – PM 2Ring – 2017-04-05T10:00:47.073

@DavidConrad You may be interested in my latest additions. – PM 2Ring – 2017-04-05T10:01:17.813

That's fantastic, I love it. Excellent work! – David Conrad – 2017-04-05T19:48:28.007

It should be shorter to define the factorial function yourself, instead of importing it :) – ArBo – 2019-01-19T11:58:14.710

@ArBo I guess it is, if I define it recursively, but I just couldn't bring myself to do that. ;) – PM 2Ring – 2019-01-19T12:14:58.497

1Here's the shortest I could come up with. It returns True for values of 1 or lower, but I think with your code that should be all right? f=lambda n:n<2or n*f(n-1) – ArBo – 2019-01-19T15:40:46.360

@ArBo Sure, that works. – PM 2Ring – 2019-01-19T15:53:07.697

3

MATL, 13 12 11 bytes

1 byte saved thanks to G B!

tY@Xu=!Af1)

Output is 1-based.

Try it online! Or verify all test cases.

Explanation

t      % Input string implicitly. Duplicate
Y@     % All permutations, sorted; each in a different row
Xu     % Unique rows
=      % Compare for equality, with broadcast
!      % Transpose
A      % All: true for columns that contain all entries true
f      % Find: indices of nonzero elements
1)     % Get first of those indices. Implicitly display

Luis Mendo

Posted 2017-04-02T01:32:11.570

Reputation: 87 464

Now you'll just remove the q right? – kyrill – 2017-04-02T02:57:14.760

@kyrill Exactly :-) – Luis Mendo – 2017-04-02T02:57:51.020

1And what about the S? Do you really need to sort it before the permutation? – G B – 2017-04-10T08:23:36.117

@GB Good point, it's not needed! I forgot that the "all permutations" function sorts based on values, not on indices. Thanks! – Luis Mendo – 2017-04-10T09:42:03.487

3

Julia, 121 125 bytes

Noncompeting, as it does not deal with duplicate letters correctly. I ported this from another language, from part of a solution to a Project Euler problem I did several years ago, and the first, 121-byte version had a bug because I had transposed the use of the permuted string and the sorted, canonical reference string.

f(p)=(n=0;z=length(p)-1;s=join(sort(collect(p)));for c in p z-=(n+=factorial(z)*(search(s, c)-1);p=replace(s,c,"",1);1)end;n)

For large inputs, this version uses bignums at the cost of 8 extra bytes:

f(p)=(n=0;z=BigInt(length(p)-1);s=join(sort(collect(p)));for c in p z-=(n+=factorial(z)*(search(s, c)-1);p=replace(s,c,"",1);1)end;n)

Ungolfed:

function f(perm)
    nth = 0
    size = length(perm) - 1
    sorted = join(sort(collect(p)))
    for ch in sorted
        index = search(perm, ch) - 1
        nth += factorial(size) * index
        perm = replace(perm, ch, "" , 1) # replace at most one copy
        size -= 1
    end
    return nth
end

Uses a factoriadic number system, q.v. Thus, it does not produce all the permutations and for large inputs will run enormously faster than those that do.

For example, the alphabet can be permuted into the rather contrived sentence "Quartz glyph job vex'd cwm finks." That sentence is the 259,985,607,122,410,643,097,474,123rd lexicographic permutation of the letters of the alphabet. (Approximately 260 septillionth permutation.) This program finds that in about 65 µs on my machine.

julia> @time f("quartzglyphjobvexdcwmfinks")
  0.000065 seconds (570 allocations: 19.234 KB)
259985607122410643097474122

Note that the number ends in ...122 rather than ...123 because OP requested that the permutations be numbered from 0 rather than from 1.

Julia, 375 bytes

I've left the indentation in for readability, but the byte count is without it.

p(t,b="")=begin
    l=length
    if l(t)<2 return 0 end
    f=factorial
    g(w)=(a=[];
        while w!=""
            s=""
            for c in w if c==w[1] s="$s$c" end end
            w=replace(w,s,"")
            push!(a,s)
        end;a)
    b=b>""?b:join(sort(collect(t)))
    z=0
    for(i,c) in enumerate(b)
        w=b[1:i-1]*b[i+1:end]
        if c==t[1] return z+p(t[2:end],w)
        elseif i>1&&c==b[i-1] continue end
        n=f(l(w))
        for v in g(w) n=div(n,f(l(v))) end
        z+=n
    end
    z
end

This one is just a straight Julia port of PM 2Ring's brilliant Python solution. I got hungry, so I decided I wanted the cookie after all. It's interesting to see the similarities and the differences between the two languages. I implemented itertools.groupby (in a limited form) as g(w).

But the logic isn't mine, so go and upvote PM 2Ring's answer.

Replace f=factorial with f(x)=factorial(BigInt(x)) if you want to be able to handle large inputs like p("QUARTZGLYPHJOBVEXDCWMFINKS").

David Conrad

Posted 2017-04-02T01:32:11.570

Reputation: 1 037

Excellent. You get the cookie! Just fix variable names in the ungolfed version. – kyrill – 2017-04-02T03:29:21.340

1Actually I want my cookie back. Your program returns wrong result for BAA ‒ expected 2, actual 3. – kyrill – 2017-04-02T03:36:12.730

@kyrill Ah, it seems I misunderstood the duplicates. In that case, I'm not sure I can see a way to do it that would avoid producing all permutations. – David Conrad – 2017-04-02T06:33:21.220

FWIW, my answer does a similar thing, but for input strings with repeated chars.

– PM 2Ring – 2017-04-03T11:35:33.563

3

05AB1E, 5 bytes

œêJ¹k

Uses the CP-1252 encoding. Try it online!

Adnan

Posted 2017-04-02T01:32:11.570

Reputation: 41 965

3

05AB1E, 5 bytes

œê¹Sk

Try it online!

Independently discovered from Adnan's answer.

Erik the Outgolfer

Posted 2017-04-02T01:32:11.570

Reputation: 38 134

He beat you by 42 seconds :D – kyrill – 2017-04-02T10:32:33.757

@kyrill Although you still accepted the wrong answer, I beat him with my Jelly answer by 5 minutes. – Erik the Outgolfer – 2017-04-02T10:34:22.507

But that Jelly produces 1-indexed output. Rules state the permutations are numbered from 0 upwards. I gave an exception to Luis Mendo who explicitly asked for it. – kyrill – 2017-04-02T10:37:01.353

@kyrill You have agreed that 1-indexed output is acceptable though.

– Erik the Outgolfer – 2017-04-02T10:37:45.133

All right, I will change the task description. – kyrill – 2017-04-02T10:38:39.140

6Yeah, giving exceptions to certain users is frowned upon. – Erik the Outgolfer – 2017-04-02T10:48:58.190

3

PHP, 124 Bytes

$a=str_split($argn);sort($a);for($i=$j=join($a);$i<=strrev($j);$i++)$i==$argn?print+$n:(($c=count_chars)($i)!=$c($j)?:$n++);

PHP, 136 Bytes

foreach($t=($c=count_chars)($argn)as$k=>$v)$i=$s.=str_repeat(chr($k),$v);for(;$i<=strrev($s);$i++)$i==$argn?print+$n:($c($i)!=$t?:$n++);

Online Version

Run with

echo '<string>' | php -nR '<code>'

Calculate with factorial

Expanded Version

function f($i){return array_product(range(1,$i));} #factorial
function p($s){
return f(strlen($s))/array_product(array_map("f",count_chars($s,1)));
} # factorial / divide through product of factorials for each char
$a=$argn;
$b="";
$r=[];
for($d=0;$a;$d++) # loop range before used chars in string 
{
    for($i=0;$i<strlen($a);$i++){ # loop for every char in the rest string 
        if($a[$i]<$a[0]) # if char is before first char order by ascii
        $r[$d.$a[$i]]=p(substr_replace($a,"",$i,1)); # add range before
    }
    $a=substr($a,1); # remove first char
}
echo array_sum($r); # Output the range before the used permutation

Output for the string PPCG

Array
(
    [0C] => 3    # in first run C is before P startposition = 3
    [0G] => 3    # in first run G is before P startposition = 3+3
    [1C] => 2    # in second run PC is before PP startposition = 3+3+2
    [1G] => 2    # in second run PG is before PP startposition = 3+3+2+2=8
)

Online Version

Jörg Hülsermann

Posted 2017-04-02T01:32:11.570

Reputation: 13 026

What kind of magic is this? You have bonus points for original approach, but you still produce all permutations and then search for input. – kyrill – 2017-04-02T11:04:02.123

@kyrill PHP can increment strings http://php.net/manual/en/language.operators.increment.php The logic does not search for input. It is more a comparision to the input

– Jörg Hülsermann – 2017-04-02T11:52:24.483

@kyrill for 5 byte more I could replace print+$n´ with ´die("$n")´ and the loop will stop after the permutation is found. And I must add$n=0` in the loop then the cast to integer works not in this change – Jörg Hülsermann – 2017-04-02T12:01:19.850

That's not really worth it, you would still iterate over many combinations like AAQ etc. – kyrill – 2017-04-02T12:17:40.077

@kyrill I have add a Version to calculate the sum of permutations before – Jörg Hülsermann – 2017-04-02T14:48:01.657

Congratulations! The added version indeed does not generate permutations. You win the special prize ;-) – kyrill – 2017-04-02T15:01:58.163

1I don't read PHP, but I think your expanded algorithm is fairly similar to mine. FWIW, I didn't notice that until after I'd written my answer. – PM 2Ring – 2017-04-03T11:44:13.553

1@PM2Ring It could been I could not read really your python version – Jörg Hülsermann – 2017-04-03T11:59:47.577

2

Mathematica, 33 31 bytes

Changing the problem spec allowed for a 2-byte savings.

Permutations@Sort@#~Position~#&

Pure function taking a list as input and returning a nonnegative integer N in the form {{N}}.

Greg Martin

Posted 2017-04-02T01:32:11.570

Reputation: 13 940

1You can drop the -1. – Martin Ender – 2017-04-02T12:54:03.550

@MartinEnder Originally there was a requirement that the permutations be indexed from 0. – kyrill – 2017-04-02T13:21:18.213

@kyrill Yes, but you removed it, so Greg can save those two bytes. – Martin Ender – 2017-04-02T13:23:56.053

2

JavaScript (ES6), 130 bytes

s=>(o=new Set,p=(s,q)=>s.map((t,i)=>p(t=[...s],q.concat(t.splice(i,1))))[0]||o.add(q.join``))([...s],[])&&[...o].sort().indexOf(s)

Less golfed

s=>{
  o = new Set; // use a set to avoid duplicates

  // recursive function to build all permutations (no cookie for me)
  p = (s, q) => 
  {
    y = s.map( (t,i) => // execute for each char at position i
          (
             t = [...s], // using t as local variable, store a copy of s
             x = t.splice(i,1), // remove char from t in position i, and store in array x
             p(t, q.concat(x)) // recursive call
          ));
    if (!y[0]) // if s was empty, I have a new permutation in q
      o.add( q.join('')) // convert to string and add to output set 
  }
  // call p to enumerate all permutations
  p( [...s], [] ) // convert string s to array, q starts empty

  o = [...o].sort() // get elements of o and sort lexicographically 
  return o.indexOf(s) // return the position of the input in o
}

Test

F=
s=>(o=new Set,p=(s,q)=>s.map((t,i)=>p(t=[...s],q.concat(t.splice(i,1))))[0]||o.add(q.join``))([...s],[])&&[...o].sort().indexOf(s)

function update() {
  O.textContent = F(I.value)
}

update()
<input id=I value='DCBA' oninput='update()'>
<pre id=O></pre>

edc65

Posted 2017-04-02T01:32:11.570

Reputation: 31 086

Well, you don't get a cookie, but you get extra credit for implementing your own function to generate permutations ;-) – kyrill – 2017-04-04T10:39:31.367

1

CJam, 7 bytes

q_e!\a#

Try it online!

Erik the Outgolfer

Posted 2017-04-02T01:32:11.570

Reputation: 38 134

1

Pyth, 5 bytes

xS{.p

Online interpreter

Takes quoted input.

Erik the Outgolfer

Posted 2017-04-02T01:32:11.570

Reputation: 38 134

@LeakyNun It doesn't work. – Erik the Outgolfer – 2017-04-30T10:50:31.790

@LeakyNun Input 'BAA' must return 2 since it's zero-indexed, but it returns 4 instead. – Erik the Outgolfer – 2017-04-30T10:52:21.627

1

Scala, 40 bytes

s=>s.permutations.toSeq.sorted indexOf s

To use it, assign this function to a variable:

val f:(String=>Int)=s=>s.permutations.toSeq.sorted indexOf s
println(f("BAA"))

Try it online at ideone

Unfortunately, permutations returns an iterator, which doesn't have a sorted method, so it has to be converted to a Seq

corvus_192

Posted 2017-04-02T01:32:11.570

Reputation: 1 889

1

C++, 96 bytes

We can make full use of the standard library here. The list of letters is passed as start/end iterators in standard C++ style.

#include<algorithm>
int f(char*a,char*z){int i=0;while(std::prev_permutation(a,z))++i;return i;}

We don't need to generate all permutations - since we have a transformation from one permutation to its predecessor, we simply count how many iterations it takes to reach the zeroth value.

Test program:

#include<cstring>
#include<iostream>
int main(int argc, char **argv)
{
    while (*++argv)
        std::cout << *argv << ": "
                  << f(*argv, *argv+std::strlen(*argv)) << std::endl;
}

Test results:

BAA: 0
BAA: 1
BAA: 2
ZZZ: 0
DCBA: 23
: 0

Toby Speight

Posted 2017-04-02T01:32:11.570

Reputation: 5 058

That's an original approach. Extra kudos to you too! – kyrill – 2017-04-10T09:10:48.747

1

Japt, 6 bytes

0-indexed

ñ á bU

Try it

Shaggy

Posted 2017-04-02T01:32:11.570

Reputation: 24 623

0

Ruby, 50 bytes

I expected this to be shorter. I wouldn't have added the sort if the docs didn't say "the implementation makes no guarantees about the order in which the permutations are yielded."

->x{x.chars.permutation.map{|v|v*""}.sort.index x}

snail_

Posted 2017-04-02T01:32:11.570

Reputation: 1 982