Trouvez le rang d'un mot


23

Définition

Le rang d'un mot est défini comme la position du mot lorsque toutes les permutations (ou dispositions) possibles de ses lettres sont organisées par ordre alphabétique, comme dans un dictionnaire, peu importe si les mots ont un sens ou non.

Examinons ces deux mots - «bleu» et «vu». Pour commencer, nous écririons tous les arrangements possibles des lettres de ces mots dans l'ordre alphabétique:

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

Regardons maintenant à gauche et trouvons la position des mots dont nous avons besoin. On voit que le mot "bleu" est en 4ème position et "vu" est en 10ème position. Ainsi, le rang du mot "bleu" est 4, et celui de "vu" est 10. C'est la façon générale de calculer le rang d'un mot. Assurez-vous de commencer à compter à partir de 1 seulement.

Tâche

Votre tâche consiste à écrire un code pour prendre n'importe quel mot en entrée et afficher son rang. Le rang doit être la sortie. Faites attention aux mots contenant des lettres répétées.

Exemples

"prime" -> 94

"super" -> 93

"bless" -> 4

"speech" -> 354

"earth" -> 28

"a" -> 1

"abcd" -> 1

"baa" -> 3    

Vous pouvez supposer que l'entrée est entièrement en minuscules et l'entrée ne contiendra que des caractères alphabétiques . De plus, si un espace vide ou une chaîne non valide est entré, vous pouvez renvoyer n'importe quoi.

Notation

C'est le , donc le code le plus court gagne!



14
"Assurez-vous de commencer à compter à partir de 1 seulement." - C'est entièrement à vous d'avoir cette exigence, mais notez qu'il est assez courant d'autoriser l'indexation basée sur 0 ou 1 pour de tels défis.
Jonathan Allan

1
Ouais ikr mais si vous partez de 0 alors vous n'affichez pas le rang d'origine, c'est pourquoi j'ai décidé d'ajouter cette exigence.
Manish Kundu

Lien utile . Vous obtiendrez AC si votre programme s'exécute dans le temps O(n log n)ou moins. (désolé, pas de Python) Ma soumission (C ++) prend 2,53 secondes pour résoudre le test 14.
user202729

Puis-je faire un tuple ou une liste avec ce mot, par exemple ['h', 'e', 'l', 'l', 'o']par opposition à 'hello'?
0WJYxW9FMN

Réponses:





4

Pyth , 6 octets

hxS{.p

Suite de tests.

Explication

hxS {.p || Programme complet.

    .p || Toutes les permutations de l'entrée.
   {|| Dédupliquer.
  S || Trier.
 x || Index de l'entrée dans cette liste.
h || Incrément.

3

Gelée , 5 octets

Œ!ṢQi

Essayez-le en ligne! ou voir la suite de tests

Comment ça marche

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

Échoue pour les mots contenant des lettres répétées.
Manish Kundu

@ManishKundu et Xcoder, fixe
caird coinheringaahing

Malheureusement, Œ¿cela ne fonctionne pas.
user202729

Est-ce que le ṢŒ¿travail?
Esolanging Fruit

@EsolangingFruit Non, cela ne fait que 1
sortir




2

Japt , 8 10 octets

0 indexé. Poxy, 1-indexation inutile, augmentant mon nombre d'octets de 25%!

á â n bU Ä

Essaye-le


Explication

áobtient toutes les permutations de l'entrée, âEnlève les doublons, nles trie et bobtient l'indice de la première occurrence de l'entrée, U.


Notez l'exigence (inhabituelle) "Assurez-vous de commencer à compter à partir de 1 seulement". J'ai commenté sous l'OP qu'il serait normal d'autoriser également basé sur 0.
Jonathan Allan

1
Ah, bon sang; stoopid 1-indexing. Mettra à jour sous peu, mais mon nombre d'octets augmentera de 25%.
Shaggy

2

J , 28 23 octets

-5 octets grâce à FrownyFrog

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

Comment ça marche?

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

Essayez-le en ligne!


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

@FrownyFrog - Bonne utilisation de i. pour trouver l'index! Merci!
Galen Ivanov

Le lien TIO est toujours l'ancienne version :)
Conor O'Brien

@Conor O'Brien - fixe
Galen Ivanov

Comme d' habitude , je ne suis pas heureux jusqu'à ce que je reçois une solution dans K qui est plus courte que la J un. Cela dit, pouvez-vous utiliser la même astuce ici? Générer des permutations de la chaîne d'entrée triée (supprimant ainsi la nécessité de trier la liste permutée)?
streetster

2

Tcl, 196 octets

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 n'a pas de méthode intégrée pour calculer la prochaine permutation lexicographique, nous devons donc le faire nous-mêmes. Mais attendez ... il est plus court de le faire avec une simple fonction récursive qui calcule toutes les permutations possibles dans n'importe quel ordre.

Non golfé:

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

J'ai rasé quelques octets: tio.run/…
sergiol

Plus rasage tio.run/...
sergiol

Merci. Quand j'aurai à nouveau accès à un vrai ordinateur, je mettrai à jour
Dúthomhas

2

K (oK) , 23 18 octets

Solution:

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

Essayez-le en ligne!

Exemples:

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

Explication:

Générez des permutations des index de la chaîne d'entrée triée, utilisez-les pour indexer de nouveau dans la chaîne d'entrée, prenez les éléments distincts, voyez où la chaîne d'origine correspondait et ajoutez-en une.

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 octets

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

Explication:

Essayez-le en ligne.

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 octets

La première réponse qui s'exécute en temps polynomial!

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)

Essayez-le en ligne!

Exiger que l'entrée soit entièrement en majuscules, car ... elle enregistre un octet.

Programme complet, prend l'entrée stdinet la sortie de stdout.


Noms de variables: (sorte de code non golfé)

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

Malheureusement, from math import factorial as f prend exactement 1 octet de plus.


(Remarque indépendante: j'ai vérifié le Combinatorica`package de Mathematica, rien d'utile, y compris RankPermutation)


Ce code est vraiment sympa.
Manish Kundu

1

Husk , 6 octets

S€(OuP

Essayez-le en ligne! Je pense qu'il devrait y avoir un moyen d'abandonner (.

Explication:

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

Nettoyer , 113 111 octets

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

Essayez-le en ligne!

+3 octets pour gérer l'indexation 1: /





1

JavaScript (ES6), 106 100 bytes

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]

Cas de test

Comment?

P () est notre fonction de permutation récursive. Mais l'objet englobant de P est également utilisé pour stocker les rangs des permutations.

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

Le code d'habillage se lit désormais comme suit:

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 octets

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

Selon ma demande, le code doit certainement être exécutable tel quel. La clause de fonction uniquement est essentiellement des ordures. : - @

Merci à ceux qui ont aimablement répondu à la question de savoir ce qui peut être découpé pour moi. Dans l'intérêt de la validité code , j'ai évité le GCC-isme populaire d'inclure <bits / stdc ++. H>, que j'ai toujours considéré comme une mauvaise triche.

Ce qui suit est ce qui reste de mon message d'origine:


Je ne suis toujours pas sûr lorsque j'utilise C et C ++ ce qui compte pour le total d'octets. Selon le programme, la fonction ou l'extrait?la réponse est encore vague (tant qu'il ne s'agit pas d'un extrait, je suppose). Je vais donc avec le plus court des deux possibilités.

Ici, il n'est pas golfé avec les en-têtes nécessaires, etc.:

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

Ce golf jusqu'à 230 octets, un tiers de ce passe- partout standard requis par chaque programme C ++. (Donc, je ne me sens pas trop mal sans le compter, mais comme je n'ai jamais vu de plainte ferme de toute façon, OP devra me dire ce qu'il préfère satisfaire "écrire un code pour prendre n'importe quel mot comme entrée" et afficher son rang. ")

Je ne suis pas sûr non plus que cela satisfasse «le rang devrait être affiché».


1
Euh ... AFAIK nos règles comptent nécessaires ( using namespace std, en- #include <algorithm> têtes utilisés pour définir la fonction en octets. Et ... Non, main(){}est un programme C ++ (g ++) valide à 8 octets.
user202729

Je ne veux pas être une morve obstinée, mais je vois les soumissions pour C et C ++ (ainsi que d' autres langues) tout le temps qui sont une seule fonction. Je veux une réponse définitive. Je ne joue généralement pas au golf en C pour cette raison. (Et je suis heureux de regolf.)
Dúthomhas

1
Même en Python, import mathc'est souvent nécessaire. Permettez-moi de trouver la méta pertinente ...
user202729

@ Dúthomhas Ces solutions ne nécessitent pas d'inclusion d'en-tête. L'arithmétique de base ne nécessite aucun en-tête, et certaines fonctions peuvent être implicitement déclarées et remplies par la liaison de stdlib (comme putset printf). Votre code doit être compilé et exécuté avec succès tel quel pour être valide. Voir: codegolf.meta.stackexchange.com/a/10085/45941
Mego

@Mego Sans déclaration de mainfonctions ne peut pas être exécuté tel quel .
user202729




0

PowerShell , 275 octets

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

Essayez-le en ligne!

Donc, c'est un bordel sanglant.

PowerShell n'a pas de permutations intégrées, donc ce code utilise l'algorithme d' ici (beaucoup joué), qui est disponible sous la licence publique limitée de Microsoft ( pièce B sur cette page de licence).

Le programme prend l'entrée $ssous forme de chaîne, puis le programme réel commence par $b=New-Object .... Nous construisons un nouvel objet StringBuilder , qui est (essentiellement) une chaîne de caractères modifiable. Cela nous permettra de gérer plus facilement les permutations. Nous appelons ensuite la fonction n(définissant en $jcours de route la longueur de la chaîne d'entrée), sortavec le -udrapeau nique la sortie, prenons le .indexOf()pour trouver la chaîne d'entrée et ajoutons1 car PowerShell est indexé zéro.

La fonction est la partie principale du programme. Il prend en entrée un nombre et chaque itération compte à rebours jusqu'à ce que nous atteignions 1(c'est-à-dire une seule lettre). Le reste de la fonction appelle essentiellement la fonction de manière récursive, prend la lettre actuelle et l'itère dans toutes les positions.

Il existe un seul bit de logique supplémentaire if($s.length-eq1){1;exit}pour prendre en compte les chaînes d'entrée de longueur en 1raison du fonctionnement de la fonction de permutations.


0

Pyt , 5 octets

ĐᒆỤ≥Ʃ

Explication:

            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)

Essayez-le en ligne!

En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.