Trova il grado di una parola


23

Definizione

Il rango di una parola è definito come la posizione della parola quando tutte le possibili permutazioni (o disposizioni) delle sue lettere sono disposte in ordine alfabetico, come in un dizionario, indipendentemente dal fatto che le parole siano significative o meno.

Consideriamo queste due parole: "blu" e "visto". Per cominciare, scriveremmo tutte le possibili disposizioni delle lettere di queste parole in ordine alfabetico:

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

Ora guardiamo da sinistra e troviamo la posizione delle parole di cui abbiamo bisogno. Vediamo che la parola "blu" è in quarta posizione e "visto" è in decima posizione. Quindi il rango della parola "blu" è 4, e quello di "visto" è 10. Questo è il modo generale di calcolare il rango di una parola. Assicurati di iniziare a contare solo da 1.

Compito

Il tuo compito è scrivere un codice per prendere qualsiasi parola come input e visualizzarne il rango. Il rango dovrebbe essere l'output. Fai attenzione alle parole che contengono lettere ripetute.

Esempi

"prime" -> 94

"super" -> 93

"bless" -> 4

"speech" -> 354

"earth" -> 28

"a" -> 1

"abcd" -> 1

"baa" -> 3    

Puoi supporre che l'input sia completamente in minuscolo e che l'input conterrà solo caratteri alfabetici . Inoltre, se viene inserito uno spazio vuoto o una stringa non valida, è possibile restituire qualsiasi cosa.

punteggio

Questo è , quindi vince il codice più corto!



14
"Assicurati di iniziare a contare solo da 1". - Spetta a te avere questo requisito, ma tieni presente che è abbastanza comune consentire l'indicizzazione basata su 0 o 1 per tali sfide.
Jonathan Allan,

1
Sì, ikr, ma se inizi da 0, in realtà non stai visualizzando il rango originale, motivo per cui ho deciso di aggiungere questo requisito.
Manish Kundu,

Link utile . Riceverai AC se il tuo programma viene eseguito in tempo O(n log n)o meno. (scusa, no Python) Il mio invio (C ++) richiede 2,53 secondi per risolvere il test 14.
user202729

Posso fare una tupla o un elenco con quella parola, ad ['h', 'e', 'l', 'l', 'o']esempio al contrario 'hello'?
0WJYxL9FMN

Risposte:




6

05AB1E , 5 byte

ϐsk>

Provalo online! o come una suite di test

Spiegazione

œ       # get permutations of input
 ê      # sort and remove duplicates
  s     # swap input to top of stack
   k    # get index of input in the list
    >   # increment

4

Pyth , 6 byte

hxS{.p

Suite di test.

Spiegazione

hxS {.p || Programma completo.

    .p || Tutte le permutazioni dell'input.
   {|| Deduplicazione.
  S || Ordinare.
 x || Indice dell'input in questo elenco.
h || Incremento.

3

Gelatina , 5 byte

Œ!ṢQi

Provalo online! o vedi la suite di test

Come funziona

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

Non riesce a trovare parole che contengono lettere ripetute.
Manish Kundu,

@ManishKundu and Xcoder, fixed
caird coinheringaahing

Sfortunatamente Œ¿non funziona.
user202729

Funziona ṢŒ¿?
Esolanging Fruit

@EsolangingFruit No, che ha appena prodotto1
caird coinheringaahing




2

Japt , 8 10 byte

0-indicizzati. Poxy, inutile indicizzazione 1, aumentando il mio conteggio dei byte del 25%!

á â n bU Ä

Provalo


Spiegazione

áottiene tutte le permutazioni dell'ingresso, âelimina i doppioni, nli ordina e bottiene l'indice della prima occorrenza dell'ingresso, U.


Nota il requisito (insolito) "Assicurati di iniziare a contare solo da 1". Ho commentato nell'ambito del PO che sarebbe normale consentire anche lo 0-based.
Jonathan Allan il

1
Ah, dannazione; stoopid 1-indicizzazione. Si aggiornerà a breve ma aumenterà il mio conteggio dei byte del 25%.
Shaggy,

2

J , 28 23 byte

-5 byte grazie a FrownyFrog

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

Come funziona?

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

Provalo online!


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

@FrownyFrog - Buon uso di i. per trovare l'indice! Grazie!
Galen Ivanov,

Il link TIO è ancora la vecchia versione :)
Conor O'Brien il

@Conor O'Brien - risolto
Galen Ivanov il

Come al solito io non sono felice fino a ottenere una soluzione in K che è più corta della J uno. Detto questo, puoi usare lo stesso trucco qui? Generare permutazioni della stringa di input ordinata (eliminando quindi la necessità di ordinare l'elenco permutato)?
streetster

2

Tcl, 196 byte

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 non ha un metodo integrato per calcolare la successiva permutazione lessicografica, quindi dobbiamo farlo da soli. Ma aspetta ... è più breve farlo con una semplice funzione ricorsiva che calcola tutte le possibili permutazioni in qualsiasi ordine.

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]

Mi sono rasato alcuni byte: tio.run/…
sergiol

Più rasatura tio.run/…
sergiol

Grazie. Quando avrò di nuovo accesso a un vero computer, aggiornerò.
Dúthomhas,

2

K (oK) , 23 18 byte

Soluzione:

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

Provalo online!

Esempi:

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

Spiegazione:

Genera permutazioni degli indici della stringa di input ordinata, usale per indicizzare nuovamente la stringa di input, prendere le distinzioni, vedere dove corrispondeva la stringa originale e aggiungerne 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

2

Java 8, 211 byte

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

Spiegazione:

Provalo online.

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 byte

La prima risposta che viene eseguita in tempo polinomiale!

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)

Provalo online!

Richiede che l'input sia tutto maiuscolo, perché ... salva un byte.

Programma completo, accetta input da stdine output a stdout.


Nomi delle variabili: (tipo di codice ungolfed)

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

Sfortunatamente, from math import factorial as frichiede esattamente 1 byte in più.


(Nota non correlata: ho controllato il Combinatorica`pacchetto di Mathematica, niente di utile, incluso RankPermutation)


Quel codice è davvero carino.
Manish Kundu,

1

Buccia , 6 byte

S€(OuP

Provalo online! Sento che dovrebbe esserci un modo per lasciar perdere (.

Spiegazione:

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

Pulito , 113 111 byte

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

Provalo online!

+3 byte per gestire l'indicizzazione 1: /





1

JavaScript (ES6), 106 100 byte

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]

Casi test

Come?

P () è la nostra funzione di permutazione ricorsiva. Ma l'oggetto comprensivo di P viene anche usato per memorizzare i ranghi delle permutazioni.

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

Il codice di wrapping ora si legge come:

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 byte

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

Come da mia richiesta, il codice deve sicuramente essere eseguibile così com'è. La clausola solo funzione è sostanzialmente spazzatura. : - @

Grazie a coloro che hanno gentilmente risposto alla domanda su cosa si può ritagliare per me. Nell'interesse del codice valido , ho evitato il popolare GCC-ism di includere <bits / stdc ++. H>, che ho sempre considerato un brutto trucco di scappatoia.

Quello che segue è ciò che rimane del mio post originale:


Non sono sempre sicuro quando si usano C e C ++ ciò che conta per il totale dei byte. Secondo il programma, la funzione o lo snippet? la risposta è ancora vaga (purché non sia uno snippet, immagino). Quindi vado con la più breve delle due possibilità.

Qui è ungolfed con le intestazioni necessarie, ecc:

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

Che arriva fino a 230 byte, un terzo di quello standard richiesto da ogni programma C ++. (Quindi, non mi sento troppo male non contarlo, ma poiché non ho mai visto un reclamo fermo in entrambi i casi, OP dovrà dirmi quale preferisce soddisfare “scrivere un codice per prendere qualsiasi parola come input e mostra il suo grado. ")

Non sono inoltre sicuro che ciò soddisfi "il grado dovrebbe essere emesso".


1
Uh ... AFAIK le nostre regole contano necessarie ( using namespace std, le #include <algorithm> intestazioni utilizzate per definire la funzione in byte. E ... No, main(){}è un programma C ++ (g ++) valido a 8 byte.
user202729

Non sto cercando di essere un moccio ostinata, ma vedo candidature per C e C ++ (così come altre lingue) per tutto il tempo che sono solo una singola funzione. Voglio una risposta definitiva. In genere non gioco a golf nei linguaggi C proprio per questo motivo. (E sono felice di regolf.)
Dúthomhas,

1
Anche in Python, import mathè spesso necessario. Fammi trovare la meta pertinente ...
user202729

@ Dúthomhas Queste soluzioni non richiedono le intestazioni. L'aritmetica di base non richiede intestazione e alcune funzioni possono essere implicitamente dichiarate e completate dal collegamento dello stdlib (come putse printf). Il codice deve essere compilato ed eseguito correttamente così com'è per essere valido. Vedi: codegolf.meta.stackexchange.com/a/10085/45941
Mego

@Mego Senza dichiarazione di mainfunzioni non può essere eseguito così com'è.
user202729

0

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

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

Provalo online!




0

PowerShell , 275 byte

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

Provalo online!

Quindi, questo è un casino sanguinoso.

PowerShell non ha permutazioni incorporate, quindi questo codice utilizza l'algoritmo da qui (golfato pesantemente), che è disponibile sotto la Licenza pubblica limitata Microsoft ( Allegato B in questa pagina di licenza).

Il programma accetta l'input $scome stringa, quindi inizia il programma effettivo $b=New-Object .... Stiamo costruendo un nuovo oggetto StringBuilder , che è (essenzialmente) una stringa mutabile di caratteri. Questo ci consentirà di gestire le permutazioni più facilmente. Chiamiamo quindi la funzione n(impostando $jlungo la strada la lunghezza della stringa di input), sortcon il -unique contrassegna l'output, prendiamo il .indexOf()per trovare la stringa di input e aggiungiamo 1perché PowerShell è a zero.

La funzione è la parte principale del programma. Prende come input un numero e ciascuna iterazione conta alla rovescia fino a quando non raggiungiamo 1(cioè una singola lettera). Il resto della funzione essenzialmente chiama ricorsivamente la funzione, prende la lettera corrente e la scorre in ogni posizione.

C'è un singolo bit di logica aggiuntiva if($s.length-eq1){1;exit}per tenere conto delle stringhe di input di lunghezza 1dovute al funzionamento della funzione di permutazioni.


0

Pyt , 5 byte

ĐᒆỤ≥Ʃ

Spiegazione:

            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)

Provalo online!

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.