Ordenar una cadena de opción

8

Antecedentes

En C, hay una función de ayuda de análisis sintáctico argumentos de línea de comandos: getopt.

Getopt toma el recuento de argumentos ( argc), la lista de argumentos ( argv) y una cadena que representa las opciones que el programa debe tomar ( optstring).

La cadena de opción ( optstring) es una serie de caracteres de opción seguidos de dos puntos (para una opción que requiere un argumento), dos puntos (para una opción con un argumento opcional) o cero puntos (para una opción sin argumento).

Por ejemplo: uno podría usar la siguiente cadena de opciones para el nuevo widget de su compañía.

"v::x:hy:S:G::dns:f::"

¡Pero eso se ve horrible! ¡Las opciones se mezclan todas juntas! Esta cadena de opciones se vería mucho mejor si se ordenara:

"f::G::v::S:s:x:y:dhn"

Especificaciones

  • La entrada será una cadena que coincida con la expresión regular ([A-Za-z]:{0,2})+

  • Debe tomar la entrada como una cadena o lista de caracteres.

  • Debe generar la cadena ordenada por el método detallado a continuación.

  • No necesita manejar entradas vacías.

  • No necesita manejar la entrada con opciones repetidas del mismo tipo ( "aa"no es válido, pero "aa:a::"es válido).

Método de clasificación

En la cadena de opción ordenada:

  • Los caracteres seguidos por dos puntos son los primeros, ordenados alfabéticamente, con letras mayúsculas antes de sus respectivas letras minúsculas (es decir, "aBb", no "Bab").

  • Luego están los caracteres con dos puntos, ordenados alfabéticamente, con letras mayúsculas antes de sus respectivas letras minúsculas.

  • Los últimos son los caracteres sin dos puntos, ordenados alfabéticamente, con letras mayúsculas antes de sus respectivas letras minúsculas.

Reglas

Puntuación

Este es el , por lo que gana la respuesta más corta en bytes en cada idioma.

Ejemplos

# "input" => "output"
"v::x:hy:S:G::dns:f::" => "f::G::v::S:s:x:y:dhn"
"aa:a::" => "a::a:a"
"B:" => "B:"
"Confusio:n::" => "n::o:Cfinosu"
"Confusio:n:" => "n:o:Cfinosu"
"m:qW:X:xc:vViI" => "c:m:W:X:IiqVvx"
"V:omo:V" => "o:V:moV"
"agg:ra:va::ting::" => "a::g::a:g:aginrtv"
"input" => "inptu"

Caso de prueba largo (312 caracteres)

Entradas no válidas (no tiene que manejar):

"gg" (duplicated option)
"" (empty string)
":w:" (first colon isn't after a character)
"x:y:0:fhn" ('0' is not alphabetic)
"A:::" (3 colons is invalid)
pizzapants184
fuente
agg:ra:va::ting::rompió la mía je ... Irónico.
Urna de pulpo mágico

Respuestas:

9

Casco , 11 bytes

ΣÖom_↔Oġλ¬√

Pruébalo en línea!

Explicación

ΣÖom_↔Oġλ¬√  Implicit input, say "kH::r:R:Hk:"
       ġ     Split between characters for which this gives a falsy result:
        λ      Take two arguments, ignore the first.
          √    Is the second argument a letter?
         ¬     Negate.
             Now we have the options: ["k","H::","r:","R:","H","k:"]
      O      Sort: ["H","H::","R:","k","k:","r:"]
 Ö           Sort by
     ↔       reversing and
  om_        converting everything to lowercase: ["H::","k:","R:","r:","H","k"]
Σ            Concatenate: H::k:R:r:Hk
Zgarb
fuente
Aquí hay un par de ideas muy inteligentes, debe agregar una explicación para que la gente pueda apreciarlas: D
Leo
1
@Leo Agregó un desglose del código.
Zgarb
3

Retina , 47 bytes

.
$&$&
T01`L`l`..
O^`\w.:*
.(.)
$1
O$^`\w:*
$.&

Pruébalo en línea!

La parte más complicada fue en realidad ordenar las letras, porque la función "ordenar por" de Retina no tiene una clasificación que no distinga entre mayúsculas y minúsculas (por lo que ordena las letras mayúsculas por delante de todas las letras minúsculas). Para evitar esto, tuve que insertar una copia en minúscula de cada personaje para ordenar y luego deshacerme de él nuevamente.

Martin Ender
fuente
¿Se ha agregado un tipo que no distingue entre mayúsculas y minúsculas en algún momento del año pasado? Y si no, ¿hay alguna manera de clasificar entre mayúsculas y minúsculas, pero conservando el orden original? Es decir, tEsTiNgcon el método de clasificación anterior, ordena los pares de letras en eEggiinNsstTtt → EgiNsTtlugar de eEggiinNsstttT → EgiNstT (las letras mayúsculas siempre se colocan antes de las letras minúsculas).
Kevin Cruijssen
1
@KevinCruijssen Puede hacerlo con ordenar ahora, porque puede transformar fácilmente el carácter en minúsculas en la cadena de sustitución. tio.run/##K0otycxLNPyvquGe8N9fJUGPSyVHRe3//xLX4pBMv3QA
Martin Ender
Oh bien. Yo nunca hubiera pensado en eso. Muchas gracias. He podido arreglar mi respuesta ahora. :)
Kevin Cruijssen
2

Japt , 17 16 bytes

f".:*" ñ_iZw vÃq

¡Pruébelo en línea!

Cómo funciona

Digamos que la cadena de entrada es v:vg::G:G::o:. La primera parte del código, f".:*"encuentra todas las coincidencias de la expresión regular /.:*/g, que coincide con un carácter seguido de cualquier número de dos puntos. Esto divide la entrada en[v:, v, g::, G:, G::, o:].

El ñmétodo en una matriz ordena cada matriz como si se aplicaran ciertos cambios, sin aplicarlos realmente (como sorted(array, key=<whatever>)en Python). Entonces necesitamos ordenar:

  • dos puntos dobles antes que todo lo demás;
  • dos puntos después de dos puntos, pero antes de no dos puntos;
  • letras en su orden alfabético; y finalmente
  • letras mayúsculas antes de minúsculas.

Z{ZiZéJ v} es la forma más corta que pude encontrar para hacer esto:

  Zw     Reverse Z.
     v   Convert to lowercase.
Zi       Insert this at the beginning of Z.

Esto es más fácil de entender con algunos ejemplos:

         v:   v  g::    G:   G::    o:
  Zw     :v   v  ::g    :G   ::G    :o
     v   :v   v  ::g    :g   ::g    :o
Zi       :vv: vv ::gg:: :gG: ::gG:: :oo:

Los valores originales se ordenan lexicográficamente por estas claves. El resultado es que::gG:: se ordena al frente, luego ::gg::, y así sucesivamente, dándonos [G::, g::, G:, o:, v:, v], que luego se une qy se genera.

ETHproducciones
fuente
1

JavaScript (ES6), 93 bytes

f=
s=>s.match(/\w:*/g).sort((a,b)=>b.length-a.length||parseInt(a,36)-parseInt(b,36)||a>b).join``
<input oninput=o.textContent=this.value&&f(this.value)><pre id=o>

Neil
fuente
1

Perl 5 , 69 + 1 ( -n) = 70 bytes

say sort{$b=~y///c<=>length$a||($"=lc$a)cmp lc$b||1-2*($"ne$a)}/.:*/g

Pruébalo en línea!

Xcali
fuente
Cada capital viene antes de sus minúsculas. Por ejemplo, 'AaBb'. Creo que cambiar =~/A-Z/a ==/A-Z/debería solucionar el problema.
pizzapants184
1

Haskell , 124 bytes

import Data.List
import Data.Char
s(c:x)|(l,r)<-span(==':')x=(-length l,toLower c,c:l):s r;s _=[]
t(_,_,x)=x
f=(t=<<).sort.s

Pruébalo en línea!

usuario28667
fuente
1

Golpetazo, 232 213 bytes

s(){ s=${1#?} c=${1%$s} o=${s%%[^:]*} s=${s#$o} o=$c$o;};
p()(s $1;l= g= p=$o d=$c;[[ $o ]]&&(while s $s;[[ $o ]];do
(((x=${#o}-${#p},y=36#$d-36#$c,x?x:y?y:62#$c-62#$d)>0))&&g+=$o||l+=$o;done;echo `p $g`$p`p $l`))

pruébalo en línea

Nahuel Fouilleul
fuente
1

C # (.NET Core) , 152 bytes

s=>{var o="";for(var d=":::";d!="";){d=d.Substring(1);for(var c='@';c!=90;o+=s.IndexOf(c+d)>=0?c+d:"",s=s.Replace(c+d,""),c^=' ')if(c<97)c++;}return o;}

Pruébalo en línea!

Sin golf:

s => { 
    var o = ""; 
    for (var d = ":::"; d != "";) { 
        d = d.Substring(1); 
        for (
            var c = '@'; 
            c != 90; 
            o += s.IndexOf(c + d) >= 0 ? c + d : "", s = s.Replace(c + d, ""), c ^= ' '
        ) if (c < 97) c++; 
    } 
    return o; 
}

La idea básica es iterar sobre las 156 opciones posibles y verificar su existencia. Si se encuentra, agregue a la salida y elimine de la entrada.

recursivo
fuente