Bir Kelimenin Sıralamasını Bul


23

Tanım

Bir kelimenin sırası, harflerinin tüm olası permütasyonları (veya düzenlemeleri), bir sözlükteki gibi, kelimeler anlamlı olup olmadığına bakılmaksızın, alfabetik olarak düzenlendiğinde kelimenin konumu olarak tanımlanır.

Bu iki kelimeyi ele alalım - "mavi" ve "görülmüş". Öncelikle, bu kelimelerin harflerinin tüm olası düzenlemelerini alfabetik sıraya göre yazarız:

"blue": "belu","beul","bleu","blue","buel","bule","eblu","ebul","elub","elbu","eubl",
        "eulb","lbeu","lbue","lebu","leub","lube","lueb","ubel","uble","uebl","uelb",
        "ulbe","uleb"
"seen": "eens","eesn","enes","ense","esen","esne","nees","nese","nsee","seen",
        "sene","snee"

Şimdi soldan bakalım ve ihtiyacımız olan kelimelerin konumunu bulalım. "Mavi" kelimesinin dördüncü sırada ve "görüldü" ifadesinin 10. konumda olduğunu görüyoruz. Yani "mavi" kelimesinin sırası 4 ve "görülen" sayısı 10'dur. Bu, bir kelimenin sıralamasını hesaplamanın genel yoludur. Yalnızca 1'den saymaya başladığınızdan emin olun.

Görev

Göreviniz herhangi bir kelimeyi girdi olarak almak ve sıralamasını görüntülemek için bir kod yazmaktır. Rütbe çıkışı olmalıdır. Tekrarlanan harfleri içeren kelimelere dikkat edin.

Örnekler

"prime" -> 94

"super" -> 93

"bless" -> 4

"speech" -> 354

"earth" -> 28

"a" -> 1

"abcd" -> 1

"baa" -> 3    

Girişin tamamen küçük harf olduğunu varsayalım ve giriş sadece alfabetik karakterler içerecektir . Ayrıca, boşluk veya geçersiz bir dize girilirse, herhangi bir şey döndürebilirsiniz.

puanlama

Bu , yani en kısa kod kazanır!



14
"Yalnızca 1'den saymaya başladığınızdan emin olun." - Bu gereksinime sahip olmak tamamen size bağlıdır, ancak bu tür zorluklar için 0 veya 1 tabanlı endekslemeye izin vermenin oldukça yaygın olduğunu unutmayın.
Jonathan Allan,

1
Evet ikr ama 0'dan başlarsanız aslında orijinal sıralamayı göstermiyorsunuzdur, bu yüzden bu şartı eklemeye karar verdim.
Manish Kundu

Faydalı bağlantı . Programınız zaman içinde O(n log n)veya daha az sürede çalışırsa AC alırsınız . (üzgünüm, Python yok) Gönderim (C ++) 14 testini çözmek için 2.53 saniye sürüyor.
user202729 2

Örneğin, ['h', 'e', 'l', 'l', 'o']bunun yerine bir kelime listesi veya bir kelime yapabilir miyim 'hello'?
0WJYxW9FMN

Yanıtlar:





4

Pyth , 6 bayt

hxS{.p

Test odası.

açıklama

hxS {.p || Tam program

    .p || Girişin tüm permütasyonları.
   {|| Deduplicate.
  S || Çeşit.
 x || Bu listeye girişin dizini.
h || Artış.

3

Jöle , 5 bayt

Œ!ṢQi

Çevrimiçi deneyin! veya test odasına bakın

Nasıl çalışır

Œ!ṢQi - Main link. Argument: s (string)      e.g. 'baa'
Œ!    - All permutations                          ['baa', 'baa', 'aba', 'aab', 'aba', 'aab']
  Ṣ   - Sort                                      ['aab', 'aab', 'aba', 'aba', 'baa', 'baa']
   Q  - Deduplicate                               ['aab', 'aba', 'baa']
    i - 1-based index of s                        3

Tekrarlanan harfleri içeren kelimeler için başarısız.
Manish Kundu

@ManishKundu ve Xcoder, sabit
18'de caird coinheringaahing

Maalesef Œ¿çalışmıyor.
user202729

Çalışıyor ṢŒ¿mu
Esolanging Fruit

@EsolangingFruit Hayır, sadece çıktılar1
19:18




2

Japt , 8 10 bayt

0 endeksli. Poxy, gereksiz 1-endeksleme, bayt sayımı% 25 arttırıyor!

á â n bU Ä

Dene


açıklama

ágirişin tüm izinlerini alır, âkopyaları kaldırır, nsıralar ve bgirişin ilk oluşum endeksini alır U,.


(Olağandışı) "Sadece 1'den saymaya başladığınızdan emin olun" şartına dikkat edin. OP kapsamında, 0 tabanına izin vermenin normal olacağı yorumunda bulundum.
Jonathan Allan,

1
Ah, kahretsin; stoopid 1 indeksleme. Kısa süre içinde güncellenecek, ancak bayt sayımı% 25 artıracak.
Shaggy

2

J , 28 23 bayt

FrownyFrog sayesinde -5 bayt

1+/:~@~.@(A.~i.@!@#)i.]

Nasıl çalışır?

                      ] - the argument
         (A.~      )    - permutations in the 
             i.@!@#     - range 0 to factorial of the arg. length
  /:~@~.@               - remove duplicates and sort
                    i.  - index of arg. in the sorted list
1+                      - add 1 (for 1-based indexing)

Çevrimiçi deneyin!


1
23:1+/:~@~.@(A.~i.@!@#)i.]
FrownyFrog

@ FrownyFrog - i'nin iyi kullanımı. endeksi bulmak için! Teşekkürler!
Galen Ivanov

TIO bağlantısı hala eski versiyondur :)
Conor O'Brien,

@Conor O'Brien - sabit
Galen Ivanov

Her zaman olduğu gibi , K'den J olandan daha kısa bir çözüm bulana kadar mutlu değilim . Dedi ki, burada aynı numarayı kullanabilir misiniz? Sıralanan giriş dizesinin permütasyonlarını oluştur (bu nedenle izin verilen listeyi sıralama gereksinimini ortadan kaldırır)?
streetster

2

Tcl, 196 bayt

proc p {a p} {if {$a eq {}} {lappend ::p $p} {while {[incr n]<=[llength $a]} {p [lreplace $a $n-1 $n-1] $p[lindex $a $n-1]}}}
p [split $argv ""] ""
puts [expr [lsearch [lsort -unique $p] $argv]+1]

Tcl'nin bir sonraki sözlükbilimsel permütasyonu hesaplamak için yerleşik bir yöntemi yoktur, bu yüzden kendimiz yapmak zorundayız. Fakat bekleyin ... tüm olası izinleri herhangi bir sıra ile hesaplayan basit bir özyinelemeli işlevle yapmak daha kısa sürer .

Ungolfed:

# Compute all possible permutations of the argument list
# Puts the result in ::all_permutations
proc generate_all_permutations {xs {prefixes ""}} {
  if {$xs eq {}} {
    lappend ::all_permutations $prefixes
  } else {
    while {[incr n] <= [llength $xs]} {
      generate_all_permutations [lreplace $xs $n-1 $n-1] $prefixes[lindex $xs $n-1]
    } 
  }
}

# Get our input as command-line argument, turn it into a list of letters
generate_all_permutations [split $argv ""]

# Sort, remove duplicates, find the original argument, and print its 1-based index
puts [expr [lsearch [lsort -unique $all_permutations] $argv]+1]

Bazı baytları traş ettim: tio.run/…
sergiol

Daha fazla tıraş tio.run/…
sergiol

Teşekkür ederim. Gerçek bir bilgisayara tekrar girdiğimde güncelleme yapacağım.
Dúthomhas

2

K (OK) , 23 18 bayt

Çözüm:

1+*&x~/:?x@prm@<x:

Çevrimiçi deneyin!

Örnekler:

1+*&x~/:?x@prm@<x:"seen"
10
1+*&x~/:?x@prm@<x:"blue"
4

Açıklama:

Sıralanan giriş dizgisinin indekslerinin permütasyonlarını oluşturun, bunları tekrar giriş dizgisine indekslemek için kullanın, farklılıkları alın, orijinal dizginin nerede eşleştiğini görün ve bir tane ekleyin.

1+*&x~/:?x@prm@<x: / the solution
                x: / save input string as x
               <   / return indices when sorting x ascending
           prm@    / apply (@) function prm
         x@        / index into x with these permutations
        ?          / distinct (remove duplicates)
    x~/:           / apply match (~) between x and each-right (/:)
   &               / return indexes where true (ie the match)
  *                / take the first one
1+                 / add 1 due to 1-indexing requirement

2

Java 8, 211 bayt

import java.util.*;TreeSet q=new TreeSet();s->{p("",s);return-~q.headSet(s).size();}void p(String p,String s){int l=s.length(),i=0;if(l<1)q.add(p);for(;i<l;p(p+s.charAt(i),s.substring(0,i)+s.substring(++i,l)));}

Açıklama:

Çevrimiçi deneyin.

import java.util.*;        // Required import for TreeSet

TreeSet q=new TreeSet();   // Sorted Set on class-level

s->{                       // Method with String parameter and integer return-type
  p("",s);                 //  Save all unique permutations of the String in the sorted set
  return-~q.headSet(s).size();}
                           //  Return the 0-indexed index of the input in the set + 1

void p(String p,String s){ // Separated method with 2 String parameters and no return-type
  int l=s.length(),        //  The length of the String `s`
      i=0;                 //  Index integer, starting at 0
  if(l<1)                  //  If String `s` is empty
    q.add(p);              //   Add `p` to the set
  for(;i<l;                //  Loop from 0 to `l` (exclusive)
    p(                     //   Do a recursive call with:
      p+s.charAt(i),       //    `p` + the character at the current index of `s` as new `p`
      s.substring(0,i)+s.substring(++i,l)));}
                           //    And `s` minus this character as new `s`

2

Python 3 , 183 182 bayt

Polinom zaman içinde koşan ilk cevap!

a=[*map(ord,input())]
f=lambda x:x and x*f(x-1)or 1
c=[0]*98
for C in a:c[C]+=1
l=len(a)
F=f(l)
for i in c:F//=f(i)
r=1
for x in a:F//=l;l-=1;r+=sum(c[:x])*F;F*=c[x];c[x]-=1
print(r)

Çevrimiçi deneyin!

Girdilerin tümü büyük harf olmalıdır, çünkü ... bir bayt kazandırır.

Tam program, giriş stdinve çıkış alır stdout.


Değişken isimleri: (yersiz kod tür)

a : permu
f : factorial
c : count_num
C : char
l : n_num_left
F : factor
r : result

Maalesef, from math import factorial as ftam olarak 1 bayt daha var.


(İlişkili not: Combinatorica`Mathematica paketini kontrol ettim , dahil olmak üzere yararlı bir şey değil RankPermutation)


Bu kod gerçekten çok hoş.
Manish Kundu,

1

Kabuğu , 6 bayt

S€(OuP

Çevrimiçi deneyin! Düşmenin bir yolu olması gerektiğini düşünüyorum (.

Açıklama:

 €     -- return index of the input 
S (    -- in the list generated by applying the following functions to the input:
     P -- permutations
    u  -- remove duplicates
   O   -- sort

1

Temiz , 113 111 bayt

import StdEnv,StdLib
?s=elemIndex s[[]:removeDup(foldr(\a b=sort[insertAt i a x\\x<-b,i<-[0..length x]])[[]]s)]

Çevrimiçi deneyin!

1 indekslemeyi işlemek için +3 bayt: /





1

JavaScript (ES6), 106 100 bayt

w=>(P=(a,s)=>a[0]?a.map((_,i)=>P(b=[...a],s+b.splice(i,1))):P[s]=P[s]||++k)[P([...w].sort(),k=''),w]

Test durumları

Nasıl?

P () özyinelemeli permütasyon fonksiyonumuzdur. Ancak P'yi kapsayan nesne , permütasyonların saflarını depolamak için de kullanılır.

P = (a, s) =>               // given an array of letters a[] and a string s
  a[0] ?                    // if a[] is not empty:
    a.map((_, i) =>         //   for each entry at position i in a[]:
      P(                    //     do a recursive call to P() with:
        b = [...a],         //       a copy b[] of a[], with a[i] removed
        s + b.splice(i, 1)  //       the extracted letter appended to s
      )                     //     end of recursive call
    )                       //   end of map()
  :                         // else:
    P[s] = P[s] || ++k      //   if P[s] is not already defined, set it to ++k

Kaydırma kodu şimdi şöyle yazıyor:

w =>                        // given the input word w
  P[                        // return the permutation rank for w
    P(                      //   initial call to P() with:
      [...w].sort(),        //     the lexicographically sorted letters of w
      k = ''                //     s = k = '' (k is then coerced to a number)
    ),                      //   end of call
    w                       //   actual index used to read P[]
  ]                         // end of access to P[]

1

C ++, 230 bayt

#include<algorithm>
#include<iostream>
#include<string>
using namespace std;void R(string s){int n=1;auto p=s;sort(begin(p),end(p));do if(p==s)cout<<n;while(++n,next_permutation(begin(p),end(p)));}int main(int n,char**a){R(a[1]);}

Benim sorduğum gibi, kod kesinlikle olduğu gibi çalıştırılabilir olması gerekir. Yalnızca işlev cümlesi temelde çöptür. : - '

Benim için neyin kestirilebileceği sorusuna kibarca cevap verenlere teşekkür ederim. Sağlama açısından geçerli kod, ben her zaman kötü mazgal hile kabul var <bit / stdc ++. H> dahil popüler GCC-izm kaçınılmalıdır.

Aşağıdakiler asıl gönderimden kalanlar:


C ve C ++ kullanırken bayt toplamı ne sayar, her zaman emin değilim. Program, İşlev veya Metin Parçacığına Göre ? Cevap hala belirsiz (snippet olmadığı sürece sanırım). Bu yüzden iki olasılıktan en kısa olanıyla gidiyorum.

Burada gerekli başlıklar vb. İle asılmıştır :

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

void R( string s )
{
  int n = 1;
  auto p = s;
  sort( begin(p), end(p) );
  do if (p == s) cout << n;
  while (++n, next_permutation( begin(p), end(p) ));
}

int main( int n, char** a )
{
  R( a[1] );
}

Her C ++ programının gerektirdiği standart kazanın üçte biri kadar, 230 bayta kadar golf . (Bu yüzden, saymadığım için kendimi kötü hissetmiyorum, ama hiçbir şekilde kesin bir şikayet göremediğim için, OP bana hangisini tatmin etmeyi tercih ettiğini “bir girdi olarak herhangi bir kelimeyi almak için bir kod yazmayı” söylemeli ve rütbesini göster. ”)

Ayrıca “rütbe verilmelidir” diye de tatmin edip etmediğinden emin değilim.


1
Ah ... AFAIK bizim kurallar (gerekli saymak using namespace std, #include <algorithm> başlıklar bayt fonksiyonunu tanımlamak için kullanılan Ve ... Hayır. main(){}8 bayt ++ (g ++) programı geçerli C'dir.
user202729

Objektif bir sümük olmaya çalışmıyorum, ama C ve C ++ 'a (diğer dillerin yanı sıra) her zaman sadece tek bir işlev için yapılan gönderileri görüyorum . Kesin bir cevap istiyorum. Genelde bu sebeple C dillerinde golf oynamam. (Ve ben regolf olmaktan mutluyum.)
Dúthomhas

1
Python'da bile import math, genellikle gereklidir. İlgili
metayı bulmama

@ Dúthomhas Bu çözümler başlık içermesini gerektirmez. Temel aritmetik, başlık gerektirmez ve bazı işlevler stdlib'in bağlanmasıyla örtük olarak bildirilebilir ve doldurulabilir ( putsve benzeri printf). Kodunuz geçerli olması için olduğu gibi derlenmeli ve başarılı bir şekilde çalıştırılmalıdır. Bakınız: codegolf.meta.stackexchange.com/a/10085/45941
Mego

@Mego İşlevler bildirilmeden olduğu maingibi çalıştırılamaz.
user202729




0

PowerShell , 275 bayt

param($s)function n($a){if($a-eq1){return}0..($a-1)|%{n($a-1);if($a-eq2){$b.ToString()}$p=($j-$a);[char]$t=$b[$p];for($z=($p+1);$z-lt$j;$z++){$b[($z-1)]=$b[$z]}$b[($z-1)]=$t}}if($s.length-eq1){1;exit}$b=New-Object Text.StringBuilder $s;(n($j=$s.length)|sort -u).indexOf($s)+1

Çevrimiçi deneyin!

Yani, bu kanlı bir karmaşa.

Bu kod adlı algoritma kullanır böylece PowerShell, herhangi permütasyon yerleşik yok burada (Microsoft Sınırlı Kamu Lisansı altında mevcuttur (ağır golfed), Ek B bu lisanslama sayfasında).

Program $sbir dize olarak girdi alır , sonra gerçek program ile başlar $b=New-Object .... Yeni bir StringBuilder nesnesi oluşturuyoruz, (aslında) değişken karakter dizesidir. Bu, permütasyonları daha kolay ele almamızı sağlayacaktır. Sonra işlevi çağırmak n(ayarı $j, giriş dizesi uzunlukta olması yol boyunca) sortile -ualmak, nique bayrak çıkışı .indexOf()giriş dizesini bulmak ve eklenti1 PowerShell sıfır endeksli olduğu için.

Fonksiyon programın ana kısmıdır. Girdiyi bir sayı olarak alır ve her yineleme ulaşana kadar geri sayılır1 (örneğin, tek bir harf). Fonksiyonun geri kalanı esas olarak fonksiyonu tekrarlı olarak çağırır, mevcut harfi alır ve her pozisyonda tekrar eder.

Permütasyonların nasıl çalıştığına bağlı olarak if($s.length-eq1){1;exit}, giriş uzunluğunu 1girmek için tek bir bit ek mantık var .


0

Pyt , 5 bayt

ĐᒆỤ≥Ʃ

Açıklama:

            Implicit input
Đ           Duplicate input
 ᒆ         Get list of all permutations of input
  Ụ         Get unique permutations
   ≥        Does each permutation come before or is equal to the input?
    Ʃ       Sum of result of previous step (converts booleans to ints)

Çevrimiçi deneyin!

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.