Encuentra el rango de una palabra

23

Definición

El rango de una palabra se define como la posición de la palabra cuando todas las permutaciones (o arreglos) posibles de sus letras se ordenan alfabéticamente, como en un diccionario, sin importar si las palabras son significativas o no.

Consideremos estas dos palabras: "azul" y "visto". Para comenzar, escribiríamos todos los arreglos posibles de las letras de estas palabras en orden alfabético:

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

Ahora miremos desde la izquierda y encontremos la posición de las palabras que necesitamos. Vemos que la palabra "azul" está en la cuarta posición y "visto" está en la décima posición. Entonces, el rango de la palabra "azul" es 4, y el de "visto" es 10. Esta es la forma general de calcular el rango de una palabra. Asegúrese de comenzar a contar solo desde 1.

Tarea

Su tarea es escribir un código para tomar cualquier palabra como entrada y mostrar su rango. El rango debe ser la salida. Tenga cuidado con las palabras que contienen letras repetidas.

Ejemplos

"prime" -> 94

"super" -> 93

"bless" -> 4

"speech" -> 354

"earth" -> 28

"a" -> 1

"abcd" -> 1

"baa" -> 3    

Puede suponer que la entrada está completamente en minúsculas y la entrada solo contendrá caracteres alfabéticos . Además, si se ingresa un espacio en blanco o una cadena no válida, puede devolver cualquier cosa.

Tanteo

Este es el , por lo que gana el código más corto.

Manish Kundu
fuente
Relacionado.
Martin Ender
14
"Asegúrese de comenzar a contar solo desde 1". - Es totalmente de usted tener este requisito, pero tenga en cuenta que es bastante común permitir la indexación basada en 0 o 1 para tales desafíos.
Jonathan Allan
1
Sí, ikr, pero si comienzas desde 0, en realidad no estás mostrando el rango original, por eso decidí agregar este requisito.
Manish Kundu
Enlace útil . Obtendrá AC si su programa se ejecuta a tiempo O(n log n)o menos. (lo siento, no Python) Mi envío (C ++) toma 2.53s para resolver la prueba 14.
user202729
¿Puedo hacer una tupla o una lista con esa palabra, por ejemplo, ['h', 'e', 'l', 'l', 'o']en lugar de 'hello'?
0WJYxW9FMN

Respuestas:

4

Pyth , 6 bytes

hxS{.p

Banco de pruebas.

Explicación

hxS {.p || Programa completo

    .p || Todas las permutaciones de la entrada.
   {|| Deduplicar
  S || Ordenar.
 x || Índice de la entrada en esta lista.
h || Incremento.
Sr. Xcoder
fuente
3

Jalea , 5 bytes

Œ!ṢQi

Pruébalo en línea! o ver el conjunto de pruebas

Cómo funciona

Œ!Ṣ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
caird coinheringaahing
fuente
Falla en palabras que contienen letras repetidas.
Manish Kundu
@ManishKundu y Xcoder, arreglado
caird coinheringaahing
Lamentablemente Œ¿no funciona.
user202729
Funciona ṢŒ¿?
Esolanging Fruit
@EsolangingFruit No, eso solo da como resultado1
caird coinheringaahing
3

CJam , 8 bytes

q_e!\a#)

Pruébalo en línea!

+1 byte debido a un requisito indexado 1.

Erik el Outgolfer
fuente
Acabo de recibir exactamente la misma respuesta :(
Esolanging Fruit
@EsolangingFruit Todavía puedes publicarlo si quieres :-)
Erik the Outgolfer
3

Haskell , 56 bytes

import Data.List
elemIndex<*>([]:).nub.sort.permutations

Pruébalo en línea!

+6 bytes debido al requisito de 1 indexación. :(

totalmente humano
fuente
2

Japt , 8 10 bytes

0 indexado. ¡Poxy, indexación 1 innecesaria, aumentando mi recuento de bytes en un 25%!

á â n bU Ä

Pruébalo


Explicación

á obtiene todas las permutaciones de la entrada, â Elimina los duplicados, nlos ordena y bobtiene el índice de la primera aparición de la entrada, U.

Lanudo
fuente
Tenga en cuenta el requisito (inusual) "Asegúrese de comenzar a contar desde 1 solamente". He comentado bajo el OP que sería normal permitir también basado en 0.
Jonathan Allan
1
Ah, maldita sea; stoopid 1-indexing. Se actualizará en breve, pero aumentará mi recuento de bytes en un 25%.
Shaggy
2

J , 28 23 bytes

-5 bytes gracias a FrownyFrog

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

¿Cómo funciona?

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

Pruébalo en línea!

Galen Ivanov
fuente
1
23:1+/:~@~.@(A.~i.@!@#)i.]
FrownyFrog
@FrownyFrog - Buen uso de i. para encontrar el índice! ¡Gracias!
Galen Ivanov
El enlace TIO sigue siendo la versión anterior :)
Conor O'Brien
@Conor O'Brien - arreglado
Galen Ivanov
Como de costumbre no estoy feliz hasta que consiga una solución de K que es más corto que el J uno. Dicho esto, ¿puedes usar el mismo truco aquí? ¿Generar permutaciones de la cadena de entrada ordenada (por lo tanto, elimina la necesidad de ordenar la lista permutada)?
Callejero
2

Tcl, 196 bytes

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 no tiene un método incorporado para calcular la próxima permutación lexicográfica, por lo que debemos hacerlo nosotros mismos. Pero espera ... es más corto hacerlo con una función recursiva simple que calcula todas las permutaciones posibles en cualquier orden.

Sin 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]
Dúthomhas
fuente
Afeité
sergiol
Más afeitado tio.run/…
sergiol
Gracias. Cuando vuelva a tener acceso a una computadora real, actualizaré.
Dúthomhas
2

K (oK) , 23 18 bytes

Solución:

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

Pruébalo en línea!

Ejemplos:

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

Explicación:

Genere permutaciones de los índices de la cadena de entrada ordenada, úselas para indexar nuevamente en la cadena de entrada, tome las distinciones, vea dónde coincide la cadena original y agregue una.

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
callejero
fuente
2

Java 8, 211 bytes

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

Explicación:

Pruébalo en línea.

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`
Kevin Cruijssen
fuente
2

Python 3 , 183 182 bytes

La primera respuesta que se ejecuta en tiempo polinomial!

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)

Pruébalo en línea!

Requiere que la entrada sea todo en mayúsculas, porque ... guarda un byte.

Programa completo, toma entrada stdiny salida a stdout.


Nombres de variables: (tipo de código no protegido)

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

Desafortunadamente, from math import factorial as ftoma exactamente 1 byte más.


(Nota no relacionada: revisé el Combinatorica`paquete de Mathematica, nada útil, incluido RankPermutation)

usuario202729
fuente
Ese código es realmente bueno.
Manish Kundu
1

Casco , 6 bytes

S€(OuP

Pruébalo en línea! Siento que debería haber una manera de caer (.

Explicación:

 €     -- 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
Laikoni
fuente
1

Limpio , 113 111 bytes

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

Pruébalo en línea!

+3 bytes para manejar la indexación 1: /

Οurous
fuente
1

Python 3 , 105 104 103 bytes

f=lambda s:s==s*2or f(s[1:])+sum(f(sorted(s[:s.index(c)]+s[s.index(c)+1:])[::-1])for c in{*s}if c<s[0])

Pruébalo en línea!

Dennis
fuente
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]

Casos de prueba

¿Cómo?

P () es nuestra función de permutación recursiva. Pero el objeto que abarca P también se usa para almacenar los rangos de las permutaciones.

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

El código de ajuste ahora se lee como:

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[]
Arnauld
fuente
1

C ++, 230 bytes

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

Según mi pedido, el código definitivamente debe ser ejecutable tal como está. La cláusula de solo función es básicamente basura. : - @

Gracias a quienes amablemente respondieron la pregunta de qué se puede cortar para mí. En interés de válido código , he evitado el popular GCC-ism de incluir <bits / stdc ++. H>, que siempre he considerado una trampa falsa.

Lo que sigue es lo que queda de mi publicación original:


Siempre estoy inseguro cuando uso C y C ++, lo que cuenta para el total de bytes. Según el programa, la función o el fragmento? la respuesta sigue siendo vaga (supongo que siempre que no sea un fragmento). Así que voy con la más corta de las dos posibilidades.

Aquí no tiene los encabezados necesarios, 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] );
}

Que los campos de golf se reducen a 230 bytes, un tercio de ese estándar requerido por cada programa C ++. (Por lo tanto, no me siento tan mal sin contarlo, pero como nunca he visto una queja firme de ninguna manera, OP tendrá que decirme qué prefiere satisfacer "escriba un código para tomar cualquier palabra como entrada" y mostrar su rango ".)

Tampoco estoy seguro de si esto satisface "el rango debería ser el resultado".

Dúthomhas
fuente
1
Uh ... AFAIK nuestras reglas cuentan necesarias ( using namespace std, #include <algorithm> encabezados utilizados para definir la función en bytes. Y ... No, main(){}es un programa válido de C ++ (g ++) a 8 bytes.
user202729
No estoy tratando de ser un moco obstinado, pero veo presentaciones para C y C ++ (así como otros lenguajes) todo el tiempo que son solo una función. Quiero una respuesta definitiva Por lo general, no juego golf en lenguajes C por esta misma razón. (Y estoy feliz de regolf.)
Dúthomhas
1
Incluso en Python, a import mathmenudo es necesario. Déjame encontrar el meta relevante ...
user202729
@ Dúthomhas Esas soluciones no requieren encabezado incluye. La aritmética básica no requiere encabezado, y algunas funciones pueden declararse y rellenarse implícitamente mediante la vinculación de stdlib (like putsy printf). Su código debe compilarse y ejecutarse correctamente tal cual para que sea válido. Ver: codegolf.meta.stackexchange.com/a/10085/45941
Mego
@Mego Sin declaración de mainfunciones no se puede ejecutar como está.
user202729
0

Perl 5 , 98 + 3 ( -pF) = 101 bytes

$"=',';@a=grep{++$k{$_}<=1&&"@F"eq join$",sort/./g}sort glob"{@F}"x(@F=sort@F);1while!/$a[$\++]/}{

Pruébalo en línea!

Xcali
fuente
0

PowerShell , 275 bytes

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

Pruébalo en línea!

Entonces, esto es un desastre sangriento.

PowerShell no tiene ninguna permutaciones incorporada, por lo que este código utiliza el algoritmo de aquí (mucho golf), que está disponible bajo la Licencia pública limitada de Microsoft ( Anexo B en esta página de licencias).

El programa toma la entrada $scomo una cadena, luego el programa real comienza con $b=New-Object .... Estamos construyendo un nuevo objeto StringBuilder , que es (esencialmente) una cadena mutable de caracteres. Esto nos permitirá manejar las permutaciones más fácilmente. Luego llamamos a la función n(configurada $jen el camino para que sea la longitud de la cadena de entrada), sortcon la -umarca nique como salida, tome.indexOf() para encontrar la cadena de entrada y agreguemos 1porque PowerShell está indexado a cero.

La función es la parte principal del programa. Toma como entrada un número, y cada iteración contará hasta que alcancemos1 (es decir, una sola letra). El resto de la función esencialmente llama recursivamente a la función, así como toma la letra actual y la itera en cada posición.

Hay un solo bit de lógica adicional if($s.length-eq1){1;exit}para tener en cuenta las cadenas de entrada de longitud 1debido a cómo funciona la función de permutaciones.

AdmBorkBork
fuente
0

Pyt , 5 bytes

ĐᒆỤ≥Ʃ

Explicación:

            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)

Pruébalo en línea!

mudkip201
fuente