Знайдіть ранг слова


23

Визначення

Ранг слова визначається як положення слова, коли всі можливі перестановки (або розташування) його букв розташовані в алфавітному порядку, як у словнику, незалежно від того, чи мають значення слова чи ні.

Розглянемо ці два слова - «синій» і «побачений». Для початку ми б написали всі можливі розташування літер цих слів в алфавітному порядку:

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

Тепер подивимось зліва і знайдемо положення потрібних нам слів. Ми бачимо, що слово "синій" знаходиться на 4-й позиції, а "побачене" - на 10-й позиції. Отже, ранг слова "синій" дорівнює 4, а "бачив" - 10. Це загальний спосіб обчислення чину слова. Переконайтеся, що ви почнете рахувати лише з 1.

Завдання

Ваше завдання - написати код, щоб взяти будь-яке слово як вхідне та відобразити його ранг. Ранг повинен бути результатом. Будьте уважні до слів, що містять повторні букви.

Приклади

"prime" -> 94

"super" -> 93

"bless" -> 4

"speech" -> 354

"earth" -> 28

"a" -> 1

"abcd" -> 1

"baa" -> 3    

Ви можете припустити, що вхід повністю розміщений з малих літер, а вхід буде містити лише алфавітні символи . Також якщо введено порожній пробіл або недійсний рядок, ви можете повернути що завгодно.

Оцінка балів

Це , тому найкоротший код виграє!



14
"Переконайтеся, що ви почнете рахувати лише з 1." - Цією вимогою цілком залежить від вас, але зауважте, що для таких викликів досить часто допускати індексацію на основі 0 або 1.
Джонатан Аллан

1
Так, ikr, але якщо ви починаєте з 0, то ви фактично не відображаєте оригінальний ранг, тому я вирішив додати цю вимогу.
Маніш Кунду

Корисне посилання . Ви отримаєте змінного струму, якщо ваша програма запускається вчасно O(n log n)чи менше. (вибачте, ні Python) Для мого подання (C ++) для вирішення тестування потрібно 2,53 секунди
user202729

Чи можу я скласти кортеж чи список із цим словом, наприклад ['h', 'e', 'l', 'l', 'o'], на відміну від 'hello'?
0WJYxW9FMN

Відповіді:





4

Pyth , 6 байт

hxS{.p

Тестовий набір.

Пояснення

hxS {.p || Повна програма.

    .p || Усі перестановки вводу.
   {|| Дублікат.
  S || Сортувати.
 х || Індекс вхідних даних до цього списку.
h || Приріст.

3

Желе , 5 байт

Œ!ṢQi

Спробуйте в Інтернеті! або побачити тестовий набір

Як це працює

Œ!Ṣ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

Помилки для слів, що містять повторні букви.
Маніш Кунду

@ManishKundu та Xcoder, виправлено
caird coinheringaahing

На жаль Œ¿, не працює.
користувач202729

Чи ṢŒ¿працює?
Esolanging Fruit

@EsolangingFruit Ні, це тільки вихід1
caird coinheringaahing




2

Japt , 8 10 байт

0-індексований. Poxy, непотрібна 1-індексація, збільшуючи кількість байтів на 25%!

á â n bU Ä

Перевірте це


Пояснення

áотримує все перестановки вхідних, âвидаляє дублікати, nсортує їх і bотримує індекс першого входження входу, U.


Зверніть увагу на (незвичне) "Переконайтеся, що ви почнете рахувати лише з 1". Я під час ОП прокоментував, що було б нормально дозволити також базуватися на 0.
Джонатан Аллан

1
Ах, проклятий; стоопід 1-індексація. Незабаром оновиться, але кількість байтів збільшиться на 25%.
Кудлатий

2

J , 28 23 байти

-5 байт завдяки FrownyFrog

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

Як це працює?

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

Спробуйте в Інтернеті!


1
23:1+/:~@~.@(A.~i.@!@#)i.]
Хмурий жаба

@FrownyFrog - Добре використання i. для пошуку індексу! Спасибі!
Гален Іванов

Посилання TIO - це все ще стара версія :)
Conor O'Brien

@Conor O'Brien - виправлено
Гален Іванов

Як завжди , я не заспокоюся , поки не отримаю рішення в K , що коротше , ніж J один. Однак, чи можете ви використати ту саму хитрість? Створити перестановки відсортованого вхідного рядка (тому усуваючи необхідність сортування перестановленого списку)?
стрітер

2

Tcl, 196 байт

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 не має вбудованого методу для обчислення наступної лексикографічної перестановки, тому ми повинні це зробити самі. Але зачекайте ... коротше це зробити за допомогою простої рекурсивної функції, яка обчислює всі можливі перестановки в будь-якому порядку.

Безголівки:

# 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]

Я поголив кілька байтів: tio.run/…
sergiol

Більше гоління tio.run/…
сергіол

Дякую. Коли я знову отримаю доступ до справжнього комп’ютера, я оновлю.
Дютомхас

2

K (oK) , 23 18 байт

Рішення:

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

Спробуйте в Інтернеті!

Приклади:

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

Пояснення:

Створіть перестановки індексів відсортованого вхідного рядка, використовуйте їх для індексації у вхідний рядок, виберіть розрізнення, подивіться, де збігається початковий рядок, і додайте його.

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 байт

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

Пояснення:

Спробуйте в Інтернеті.

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 байт

Перша відповідь, що працює в поліномічний час!

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)

Спробуйте в Інтернеті!

Потрібно, щоб вхід був великим регістром, тому що ... він економить байт.

Повна програма, приймає вхід stdinі виводить на stdout.


Імена змінних: (різновид неперевершеного коду)

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

На жаль, from math import factorial as fзаймає рівно ще 1 байт.


(Непов’язана примітка: я перевірив Combinatorica`пакет Mathematica, нічого корисного, в тому числі RankPermutation)


Цей код справді приємний.
Маніш Кунду






1

JavaScript (ES6), 106 100 байт

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]

Тестові справи

Як?

P () - наша рекурсивна функція перестановки. Але охоплюючий об'єкт P також використовується для зберігання рядів перестановок.

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

Код упаковки тепер звучить як:

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 байт

#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]);}

Згідно з моїм запитом, код обов'язково повинен бути виконаним як є. Застереження, яке стосується лише функції, в основному є сміттям. : - @

Дякую тим, хто люб’язно відповів на питання, що можна вирізати для мене. В інтересах дійсного коду, я уникав популярного GCC-ism, включаючи <bits / stdc ++. H>, який я завжди вважав поганою обробкою лазівки.

Далі йде те, що залишилося від моєї оригінальної публікації:


Я завжди не впевнений, коли використовую C і C ++, що зараховується до загального байту. Відповідно до програми, функції чи знімка? відповідь все ще невизначена (якщо я думаю, що це не фрагмент, я думаю). Тож я йду з найкоротшим із двох можливостей.

Тут він не перебуває з необхідними заголовками тощо:

#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] );
}

Це гольфи до 230 байт, що становить третину від стандартної котлоагрегату, необхідної для кожної програми C ++. (Отже, я не відчуваю себе дуже погано, не рахуючи цього, але оскільки я жодного разу не бачив твердої скарги, ОП доведеться сказати мені, який він бажає задовольнити: "написати код, щоб взяти будь-яке слово як вхідне" і відобразити його ранг. ")

Я також не впевнений, чи задовольняє це “ранг має бути виведений”.


1
Е - е ... AFAIK розраховувати наші правила необхідно ( using namespace std, #include <algorithm> заголовки використовуються для визначення функції в байтах і ... Ні ,. main(){}Дійсний C ++ (г ++) Програма на 8 байт.
user202729

Я не намагаюся бути впертим соплі, але весь час бачу подання для C і C ++ (як і інших мов), які є лише однією функцією. Я хочу остаточну відповідь. Звичайно, я зазвичай не гольфую на мовах С. (І я радий регольфу.)
Дютомхас

1
Навіть у Python import mathце часто необхідно. Дозвольте мені знайти відповідну мета ...
user202729

@ Dúthomhas Ці рішення не потребують заголовка включає. Основна арифметика не вимагає заголовка, і деякі функції можна неявно оголошувати і заповнювати пов'язуванням stdlib (як putsі printf). Ваш код повинен скластись і запуститись успішно, оскільки він є дійсним. Див: codegolf.meta.stackexchange.com/a/10085/45941
Mego

@Mego Без оголошення mainфункції неможливо запустити як є.
користувач202729




0

PowerShell , 275 байт

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

Спробуйте в Інтернеті!

Отже, це кривавий безлад.

У PowerShell немає вбудованих перестановок, тому цей код використовує алгоритм звідси (сильно гольф), який доступний під обмеженою публічною ліцензією Microsoft ( Додаток В на цій сторінці ліцензування).

Програма приймає введення $sяк рядок, потім починається фактична програма $b=New-Object .... Ми будуємо новий об'єкт StringBuilder , який є (по суті) змінним рядком символів. Це дозволить нам легше обробляти перестановки. Потім ми викликаємо функцію n(встановлюючи $jпо довжині вхідну рядок), sortз -uпозначкою nique на виході, беремо .indexOf()знахідку для введення рядка і додаємо, 1оскільки PowerShell індексується нулем.

Функція є основною частиною програми. Він приймає як введення число, і кожна ітерація буде рахуватися, поки ми не досягнемо 1(тобто однієї літери). Решта функції по суті рекурсивно викликає функцію, а також приймає поточну букву і повторює її через кожну позицію.

Існує єдиний біт додаткової логіки if($s.length-eq1){1;exit}для обліку вхідних рядків довжини 1через те, як працює функція перестановок.


Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.