単語のランクを見つける


23

定義

単語のランクは、単語が意味のあるかどうかに関係なく、辞書のように、文字の可能なすべての順列(または配置)がアルファベット順に配置されるときの単語の位置として定義されます。

「青」と「見える」という2つの単語を考えてみましょう。そもそも、これらの単語の文字のすべての可能な配置をアルファベット順に記述します。

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

次に、左から見て、必要な単語の位置を見つけましょう。「blue」という単語が4番目の位置にあり、「seen」という単語が10番目の位置にあることがわかります。したがって、単語「blue」のランクは4、「seen」のランクは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から開始すると、実際には元のランクが表示されないため、この要件を追加することにしました。
マニッシュ

便利なリンク。プログラムが時間内に実行された場合、ACを取得しますO(n log n)。(申し訳ありませんが、Pythonの)私の提出(C ++)テスト14解決するために2.53sを取る
user202729

私は例えば、その単語とタプルやリストを行うことができます['h', 'e', 'l', 'l', 'o']とは対照的に、 'hello'
0WJYxW9FMN

回答:





4

Pyth、6バイト

hxS{.p

テストスイート。

説明

hxS {.p || 完全なプログラム。

    .p || 入力のすべての順列。
   {|| 重複排除。
  S || ソート。
 x || このリストへの入力のインデックス。
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、修正済み
ケアード・コマーンリング

残念ながらŒ¿機能しません。
user202729

DOESのṢŒ¿作品?
エソランジングフルーツ

@EsolangingFruitいいえ、それはただ出力されます1
ケアード・コミンヘリングアーイング




2

Japt8 10バイト

0インデックス。ポクシー、不要な1インデックス、バイトカウントが25%増加します!

á â n bU Ä

試して


説明

á入力のすべての順列は、取得しâ、重複を削除し、nそれらをソートしてb、入力が最初に出現する位置のインデックスを取得しますU


(異常な)「必ず1からカウントを開始してください」要件に注意してください。OPの下で、0ベースも許可するのが普通だとコメントしました。
ジョナサンアラン

1
ああ、ゴッドダムニット。愚かな1インデックス。間もなく更新されますが、バイトカウントが25%増加します。
シャギー

2

J28 23バイト

FrownyFrogのおかげで-5バイト

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

@FrownyFrog-iの適切な使用。インデックスを見つけるために!ありがとう!
ガレンイワノフ

TIOリンクはまだ古いバージョンです:)
コナーオブライエン

@コナー・オブライエン-修正済み
ガレン・イワノフ

いつものように、KJソリューションよりも短いソリューションを取得するまでは満足できません。とはいえ、ここで同じトリックを使用できますか?ソートされた入力文字列の順列を生成します(したがって、順列リストをソートする必要がなくなります)?
ストリートスター

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/...
sergiol

ありがとうございました。再び実際のコンピューターにアクセスできるようになったら、更新します。
ドゥトーマス

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

オンラインでお試しください!

入力をすべて大文字にする必要があります。1バイトを節約するためです。

完全なプログラム。入力をから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]);}

私の質問によると、コードは間違いなくそのまま実行可能である必要があります。関数のみの句は基本的にゴミです。:-@

私のために何を切り出すことができるかという質問に親切に答えてくれた人々に感謝します。有効な利益のためにコードために、私は<bits / stdc ++。h>をインクルードするという一般的なGCC主義を避けました。

以下は、元の投稿の残りの部分です。


CとC ++を使用する場合、バイト合計にカウントされるものが常に不明です。プログラム、機能、またはスニペットによると答えはまだあいまいです(スニペットでない限り)。したがって、2つの可能性のうち最短のものを使用します。

ここでは、必要なヘッダーなどが含まていません

#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 ++プログラムが必要とする標準的な定型の3分の1です。(だから、それを数えなくても悪くはないが、どちらの方法でもしっかりした苦情を見たことがないので、OPは彼がどちらを好むのかを教えなければならない。ランクを表示します。」)

これが「ランクを出力する必要がある」かどうかもわかりません。


1
ええと...私たちのルールは必要です(using namespace std#include <algorithm> ヘッダーをバイトで関数を定義するために使用されるヘッダー。そして...いいえ、main(){}8バイトで有効なC ++(g ++)プログラムです
。– user202729

私は頑固な鼻水になろうとはしていませんが、CとC ++(および他の言語)のサブミッションは常に 1つの機能であると考えています。決定的な答えが欲しい。この理由から、私は通常C言語でゴルフをしません。(そして、私はリゴルフに満足しています。)
ドゥソムス

1
Pythonでさえ、import mathしばしば必要です。関連するメタを見つけましょう
...-user202729

@Dúthomhasこれらのソリューションには、ヘッダーインクルードは必要ありません。基本的な算術演算にはヘッダーは不要です。また、一部の関数は、stdlibのリンクによって暗黙的に宣言および入力できます(putsandなどprintf)。コードを有効にするには、コードをそのままコンパイルして正常に実行する必要があります。参照:codegolf.meta.stackexchange.com/a/10085/45941
Mego

@Mego main関数の宣言なしでは、そのまま実行できません。
user202729




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 Limited Public License(このライセンスページの別紙B)で利用可能な、ここからのアルゴリズム(大量にゴルフ)を使用します。

プログラムは入力$sを文字列として受け取り、実際のプログラムはで始まり$b=New-Object ...ます。新しいStringBuilderオブジェクトを構築しています。これは(本質的に)可変文字列です。これにより、順列をより簡単に処理できるようになります。次に、niqueフラグを出力にn設定し$jて関数を呼び出し(入力文字列の長さになるように設定します)、入力文字列を見つけて追加し、PowerShellのインデックスがゼロであるため追加します。sort-u.indexOf()1

機能はプログラムの主要部分です。入力として数値を取り、各反復は到達するまでカウントダウンします1(つまり、1文字)。残りの関数は基本的に関数を再帰的に呼び出し、現在の文字を取得してすべての位置で繰り返します。

順列関数がどのように機能するかによりif($s.length-eq1){1;exit}、長さの入力文字列を考慮する追加のロジックが1ビットあります1


弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.