ฉันให้การเรียงสับเปลี่ยน Nth กับคุณ


20

อินพุต:ลำดับของตัวอักษรตัวพิมพ์ใหญ่ (ASCII [65; 90]) ซึ่งเป็นลำดับที่N * การเรียงคำย่อเกี่ยวกับพจนานุกรมของมัลติเซ็ตของอักขระ

* การเรียงสับเปลี่ยนจะมีหมายเลขตั้งแต่ 0 หรือ 1 ขึ้นไป

เอาท์พุท:ฐาน -10 จำนวนเต็มN


Rulez

  • อาจมีการทำซ้ำ (นั่นคือความท้าทายนี้แตกต่างจาก สิ่งนี้ )
  • อักขระถูกจัดเรียงตามค่า ASCII
  • ในกรณีของการป้อนข้อมูลของความยาวน้อยกว่าหรือเท่ากับ 1 การป้อนข้อมูลคือการเปลี่ยนแปลงครั้งแรกและผลที่ได้คือ0หรือ1ตามลำดับ
  • การเปลี่ยนแปลงครั้งแรกคือสิ่งที่อักขระซ้ายสุดมีค่าต่ำสุดอักขระขวาสุดมีค่าสูงสุดและลำดับของอักขระระหว่างอักขระตัวแรกและอักขระสุดท้ายคือการเรียงสับเปลี่ยนครั้งแรกของชุดอักขระหลายชุด(นิยามแบบเรียกซ้ำ!)
  • รายการที่สั้นที่สุดชนะ

ตัวอย่าง

  • อินพุตAABสร้างเอาต์พุต0
  • อินพุตABAสร้างเอาต์พุต1
  • อินพุตBAAสร้างเอาต์พุต2

  • อินพุตZZZสร้างเอาต์พุต0
  • อินพุตDCBAสร้างเอาต์พุต23

แก้ไข

ความรุ่งโรจน์พิเศษสำหรับผู้ที่สามารถหาวิธีแก้ปัญหาที่ไม่ได้สร้างการเรียงสับเปลี่ยนทั้งหมดแล้วจึงค้นหาอินพุท นั่นคือความท้าทาย


สวัสดีและยินดีต้อนรับสู่เว็บไซต์ คำถามนี้ค่อนข้างชัดเจน ฉันไม่แน่ใจว่าจะเรียงลำดับพีชคณิตอย่างไร พวกเขามีคำสั่งทำพจนานุกรม? สิ่งนี้ควรถูกกำหนดไว้ในคำถามของคุณ
ข้าวสาลีตัวช่วยสร้าง

1
เรายังมีกล่องทรายเพื่อให้คุณได้รับข้อเสนอแนะประเภทนี้ก่อนโพสต์ในเว็บไซต์หลักของเรา ไม่จำเป็นต้องโพสต์ที่นั่นก่อน แต่หลายครั้งมีประโยชน์มาก
ข้าวสาลีตัวช่วยสร้าง

คุณพูดว่า 'ตัวพิมพ์ใหญ่' zzzและdcbaไม่ใช่ตัวพิมพ์ใหญ่
Matthew Roh

@SIGSEGV แก้ไขแล้ว
kyrill

ดัชนีการส่งออกสามารถเป็น 1-based แทน 0-based?
Luis Mendo

คำตอบ:




4

Python, 302 287 ไบต์

Dead Possum ได้โพสต์คำตอบสั้น ๆ ของ Pythonic ไว้แล้วดังนั้นฉันจึงตัดสินใจไปสู่ความรุ่งโรจน์เพิ่มเติม วิธีนี้ไม่ได้สร้างวิธีเรียงสับเปลี่ยนทั้งหมด มันสามารถคำนวณดัชนีการเปลี่ยนแปลงอย่างรวดเร็วของสตริงที่ค่อนข้างใหญ่ มันจัดการกับสตริงว่างได้อย่างถูกต้อง

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

รหัสการทดสอบ:

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)

เอาท์พุต

 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

รุ่นที่ไม่ใช่กอล์ฟ:

''' 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')

เกี่ยวกับ lexico_permute_string

อัลกอริทึมนี้เนื่องจาก Narayana Pandita มาจาก https://en.wikipedia.org/wiki/Permutation#Generation_in_lexicographic_order

เพื่อผลิตการเรียงสับเปลี่ยนลำดับถัดไปตามลำดับของคำศัพท์ a

  1. ค้นหาดัชนีที่ใหญ่ที่สุด j เช่น [j] <a [j + 1] หากไม่มีดัชนีดังกล่าวการเปลี่ยนแปลงคือการเปลี่ยนแปลงครั้งสุดท้าย
  2. ค้นหาดัชนีที่ใหญ่ที่สุด k มากกว่า j เช่นที่ [j] <a [k]
  3. สลับค่าของ [j] กับค่าของ [k]
  4. กลับลำดับจาก [j + 1] ถึงและรวมองค์ประกอบสุดท้าย a [n]

FWIW คุณสามารถดูรุ่นข้อเขียนของฟังก์ชั่นที่นี่


FWIW นี่คือฟังก์ชันผกผัน

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))

เอาท์พุต

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

และนี่คือฟังก์ชั่นที่ฉันเขียนในขณะที่กำลังพัฒนาperm_unrankซึ่งแสดงการแยกย่อยย่อย

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)

เอาท์พุต

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

ว้าว! ทางออกที่น่าทึ่ง! มีบางส่วนของ Python อยู่ที่นี่ฉันไม่คุ้นเคยกับการที่ฉันจะต้องไปค้นหาตอนนี้เพื่อเข้าใจมัน ทำได้ดี!
David Conrad

คุณสามารถเปลี่ยนเป็นz=0และแทนที่ในt[0]และt[1:]ที่พวกเขาใช้ (ปัจจุบันhและt) เพื่อบันทึก 8 ไบต์
David Conrad

ขอแสดงความยินดีคุณได้รับความชื่นชมเช่นกัน! แม้ว่าJörgHülsermannจะเป็นคนแรก แต่เวอร์ชันของคุณกลับมาซ้ำดังนั้นมันจึงไม่เหมือนกับของเขา
kyrill

ขอบคุณ @kyrill ตอนนี้ฉันสงสัยว่าจะทำกระบวนการย้อนกลับได้อย่างมีประสิทธิภาพ: สร้างการเปลี่ยนแปลงจากดัชนีของมัน ฉันเดาว่าไม่น่าจะยากเกินไปที่จะปรับเปลี่ยนเทคนิคพื้นฐานแบบแฟกทอเรียลที่ใช้สำหรับการเรียงสับเปลี่ยนโดยไม่ต้องทำซ้ำ ...
PM 2Ring

1
นี่คือระยะทางสั้นที่สุดที่ฉันสามารถทำได้ มันส่งกลับTrueค่า 1 หรือต่ำกว่า แต่ฉันคิดว่าด้วยรหัสของคุณที่ควรจะใช่ไหม f=lambda n:n<2or n*f(n-1)
ArBo


3

05AB1E , 5 ไบต์

œê¹Sk

ลองออนไลน์!

ค้นพบได้อย่างอิสระจากคำตอบของ Adnan


เขาเอาชนะคุณภายใน 42 วินาที: D
kyrill

@kyrill แม้ว่าคุณจะยังยอมรับคำตอบที่ผิด แต่ฉันก็เอาชนะเขาด้วยคำตอบ Jelly ของฉันภายใน 5 นาที
Erik the Outgolfer

แต่เยลลี่นั้นจะสร้างผลลัพธ์ที่มีดัชนี 1 ดัชนี กฎระบุว่าพีชคณิตมีจำนวนตั้งแต่ 0 ขึ้นไป ฉันให้ข้อยกเว้นกับ Luis Mendo ที่ขออย่างชัดเจน
kyrill


6
ใช่การให้ข้อยกเว้นแก่ผู้ใช้บางคนถูกทำให้ขมวดคิ้ว
Erik the Outgolfer

3

PHP, 124 ไบต์

$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 ไบต์

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++);

เวอร์ชั่นออนไลน์

ทำงานด้วย

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

คำนวณด้วยแฟคทอเรียล

เวอร์ชันขยาย

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

เอาต์พุตสำหรับสตริง 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
)

เวอร์ชั่นออนไลน์


เวทมนตร์แบบนี้คืออะไร? คุณมีคะแนนโบนัสสำหรับวิธีการดั้งเดิม แต่คุณยังคงผลิตพีชคณิตทั้งหมดแล้วค้นหาอินพุต
kyrill

@kyrill PHP สามารถเพิ่มสตริงได้php.net/manual/en/language.operators.increment.phpตรรกะไม่ค้นหาอินพุต เป็นการเปรียบเทียบกับอินพุตมากขึ้น
JörgHülsermann

@kyrill สำหรับ 5 ไบต์ขึ้นไปฉันสามารถแทนที่print+$n´ with ´die("$n")´ and the loop will stop after the permutation is found. And I must add $ n = 0` ในลูปแล้วการส่งไปยังเลขจำนวนเต็มไม่ได้อยู่ในการเปลี่ยนแปลงนี้
JörgHülsermann

1
ฉันไม่ได้อ่าน PHP แต่ฉันคิดว่าอัลกอริทึมแบบขยายของคุณนั้นค่อนข้างคล้ายกับของฉัน FWIW ฉันไม่ได้สังเกตว่าจนกว่าฉันจะเขียนคำตอบ
PM 2Ring

1
@ PM2Ring เป็นไปไม่ได้ที่ฉันจะไม่ได้อ่านเวอร์ชันไพ ธ อนของคุณจริงๆ
JörgHülsermann

3

จูเลีย121 121ไบต์

ไม่ใช่การแข่งขันเพราะมันไม่ได้จัดการกับตัวอักษรที่ซ้ำกันอย่างถูกต้อง ฉันบอกสิ่งนี้จากภาษาอื่นจากส่วนหนึ่งของการแก้ปัญหาไปยังปัญหา Project Euler ที่ฉันทำเมื่อหลายปีก่อนและรุ่นแรกขนาด 121 ไบต์มีข้อผิดพลาดเนื่องจากฉันได้เปลี่ยนการใช้สตริงที่เรียงสับเปลี่ยนและการอ้างอิงแบบบัญญัติ เชือก

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)

สำหรับอินพุตขนาดใหญ่รุ่นนี้ใช้ bignums ที่ราคา 8 ไบต์พิเศษ:

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

ใช้ระบบจำนวน factoriadic , qv ดังนั้นมันไม่ได้สร้างการเรียงสับเปลี่ยนทั้งหมดและสำหรับอินพุตขนาดใหญ่จะทำงานได้เร็วกว่ามหาศาลที่ทำ

ตัวอย่างเช่นสามารถใช้ตัวอักษรเป็นประโยคที่ประดิษฐ์ขึ้นมาได้ "Quartz glyph job vex'd cwm finks" ประโยคนั้นคือ 259,985,607,122,410,643,097,097,474,123rd การเรียงสับเปลี่ยนพจนานุกรมของอักษรตัวอักษร (การเปลี่ยนแปลงประมาณ 260 ล้านครั้ง) โปรแกรมนี้พบว่าประมาณ 65 mys บนเครื่องของฉัน

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

โปรดทราบว่าหมายเลขลงท้ายด้วย ... 122 แทนที่จะเป็น ... 123 เนื่องจาก OP ขอให้การเรียงสับเปลี่ยนเป็นตัวเลขจาก 0 แทนที่จะเป็น 1

Julia, 375 bytes

ฉันได้เว้นย่อหน้าไว้เพื่อให้สามารถอ่านได้ แต่จำนวนไบต์นั้นไม่มี

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

อันนี้เป็นเพียงพอร์ตจูเลียที่ตรงกับโซลูชั่น Python ที่ยอดเยี่ยมของ PM 2Ring ฉันหิวดังนั้นฉันตัดสินใจว่าฉันต้องการคุกกี้หลังจากทั้งหมด มันน่าสนใจที่ได้เห็นความเหมือนและความแตกต่างระหว่างสองภาษา ผมดำเนินการitertools.groupby(ในรูปแบบที่ จำกัด ) g(w)ในฐานะ

แต่ตรรกะไม่ใช่ของเราเพื่อไปและ upvote คำตอบ PM 2Ring ของ

แทนที่f=factorialด้วยf(x)=factorial(BigInt(x))หากคุณต้องการจัดการอินพุตขนาดใหญ่เช่น p ("QUARTZGLYPHJOBVEXDCWMFINKS")


ยอดเยี่ยม คุณได้รับคุกกี้! เพียงแก้ไขชื่อตัวแปรในเวอร์ชันที่ไม่ดี
kyrill

1
ที่จริงฉันต้องการคุกกี้ของฉันกลับมา โปรแกรมของคุณผลตอบแทนผิดBAA- คาดว่าจะเกิดขึ้นจริง2 3
kyrill

@kyrill อาดูเหมือนว่าฉันเข้าใจผิดซ้ำซ้อน ในกรณีนั้นฉันไม่แน่ใจว่าฉันสามารถเห็นวิธีการที่จะหลีกเลี่ยงการเปลี่ยนลำดับทั้งหมด
David Conrad

FWIW คำตอบของฉันทำสิ่งที่คล้ายกัน แต่สำหรับสตริงอินพุตที่มีตัวอักษรซ้ำ
PM 2Ring

3

MATL , 13 12 11 ไบต์

บันทึก 1 ไบต์ต้องขอบคุณGB !

tY@Xu=!Af1)

เอาท์พุทเป็นแบบ 1

ลองออนไลน์! หรือตรวจสอบกรณีทดสอบทั้งหมด

คำอธิบาย

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

ตอนนี้คุณจะลบqใช่ไหม
kyrill

@kyrill ตรง :-)
Luis Mendo

1
แล้ว S ล่ะ คุณต้องการเรียงลำดับก่อนการเปลี่ยนแปลงหรือไม่?
GB

@GB จุดดีไม่จำเป็น! ฉันลืมว่าฟังก์ชั่น "พีชคณิตทั้งหมด" เรียงตามค่าไม่ใช่ดัชนี ขอบคุณ!
Luis Mendo

2

Mathematica, 33 31 ไบต์

อนุญาตให้เปลี่ยนข้อมูลจำเพาะของปัญหาเพื่อการประหยัดแบบ 2 ไบต์

Permutations@Sort@#~Position~#&

ฟังก์ชั่นการถ่ายเพียวรายการเป็น input และกลับมาติดลบในรูปแบบN{{N}}


1
-1คุณสามารถวาง
Martin Ender

@MartinEnder เดิมมีข้อกำหนดว่าจะมีการเรียงสับเปลี่ยนดัชนีจาก 0
kyrill

@kyrill ใช่ แต่คุณลบออกดังนั้น Greg สามารถบันทึกสองไบต์เหล่านั้นได้
Martin Ender

2

JavaScript (ES6), 130 ไบต์

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)

น้อย 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
}

ทดสอบ

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>


ดีคุณไม่ได้รับคุกกี้ แต่คุณจะได้รับเครดิตพิเศษสำหรับการใช้งานฟังก์ชั่นของคุณเองในการสร้างการเรียงสับเปลี่ยน ;-)
kyrill



1

สกาลา, 40 ไบต์

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

หากต้องการใช้ให้กำหนดฟังก์ชันนี้ให้กับตัวแปร:

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

ลองออนไลน์ได้ที่ ideone

น่าเสียดายที่permutationsส่งคืนตัววนซ้ำซึ่งไม่มีsortedวิธีดังนั้นจึงต้องแปลงเป็นSeq


1

C ++, 96 ไบต์

เราสามารถใช้ห้องสมุดมาตรฐานได้อย่างเต็มที่ที่นี่ รายการตัวอักษรจะถูกส่งผ่านเป็นตัววนซ้ำเริ่มต้น / สิ้นสุดในสไตล์ C ++ มาตรฐาน

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

เราไม่จำเป็นต้องสร้างการเรียงสับเปลี่ยนทั้งหมด - เนื่องจากเรามีการแปลงจากการเปลี่ยนรูปแบบครั้งเดียวเป็นรุ่นก่อน

โปรแกรมทดสอบ:

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

ผลการทดสอบ:

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

นั่นเป็นวิธีการดั้งเดิม ขอชื่นชมคุณเช่นกัน!
kyrill


0

Ruby, 50 ไบต์

ฉันคาดว่าสิ่งนี้จะสั้นกว่านี้ ฉันจะไม่เพิ่มsortถ้าเอกสารไม่ได้พูดว่า "การดำเนินการไม่รับประกันเกี่ยวกับลำดับการเปลี่ยนลำดับที่จะได้รับ"

->x{x.chars.permutation.map{|v|v*""}.sort.index x}
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.