Ordenar personajes inútiles

21

Este desafío está inspirado en esta muy buena respuesta de TidB.


En la respuesta de TidB, cada ocho caracteres está en el orden correcto: gnilwoB edoC( Code Bowlinghacia atrás). Sin embargo, las otras cadenas están en un orden extraño y aleatorio.

Tu desafío es arreglar esto.

Tome una cadena (no vacía) y un entero positivo ncomo entrada. La cadena contendrá caracteres ASCII en el rango: 32-126 (espacio para tilde).

Debe ordenar la cadena en orden ascendente (vista desde la izquierda, en función del valor del código ASCII), pero omita todos nlos caracteres, comenzando desde el final de la cadena. Como ejemplo, tomemos la cadena abcdABC123como entrada y n=4luego obtendremos:

abcdABC123   <- Input string. (n=4)
_b___B___3   <- These will not be sorted (every 4th starting from the end)
1_2AC_acd_   <- The remaining characters, sorted
1b2ACBacd3   <- The final string (the output)

Otro ejemplo:

9876543210   <- Input string (n=2)
_8_6_4_2_0   <- These will not be sorted
1_3_5_7_9_   <- The remaining characters, sorted
1836547290   <- The final string (the output)

La cadena de entrada se puede tomar en un formato opcional (cadena, lista de caracteres, lista de cadenas de caracteres individuales ...). El entero de entrada también se puede tomar en un formato opcional.

Casos de prueba:

El formato será n=__, seguido de la cadena de entrada en la siguiente línea. La salida está en la línea de abajo.

n=1   (All elements will stay in place)
nafgaksa1252#"%#
nafgaksa1252#"%#    

n=214  (The last character will stay in place. All other are sorted. 
&/lpfAVD
&/AVflpD  

n=8
g7L9T E^n I{><#ki XSj!uhl y= N+|wA}Y~Gm&o?'cZPD2Ba,RFJs% V5U.W;1e  0_zM/d$bH`@vKoQ 43Oq*C
g       n !#$%&'i*+,./01l234579;w<=>?@ADoEFGHIJKBLMNOPQR STUVWXYeZ^_`abcdhjkmqsuovyz{|}~C
Stewie Griffin
fuente

Respuestas:

7

MATL , 15 14 bytes

ttfiX\qgP)S5M(

Las entradas son una cadena entre comillas simples y un número. Los símbolos de comillas simples en la cadena se deben escapar mediante la duplicación (como en MATLAB y Octave).

Pruébalo en línea! O verificar todos los casos de prueba .

Explicación

Considere las entradas 'abcdABC123'y 4.

tt     % Implicitly input string. Duplicate twice
       % STACK: 'abcdABC123', 'abcdABC123', 'abcdABC123'
f      % Find: indices of nonzero elements: gives [1 2 ... n] where n is input length
       % STACK: 'abcdABC123', 'abcdABC123', [1 2 3 4 5 6 7 8 9 10]
i      % Input n
       % STACK: 'abcdABC123', 'abcdABC123', [1 2 3 4 5 6 7 8 9 10], 4
X\     % 1-based modulo
       % STACK: 'abcdABC123', 'abcdABC123', [1 2 3 4 1 2 3 4 1 2 3 4]
qg     % Subtract 1, convert to logical: gives true (1) for 1, false (0) otherwise
       % STACK: 'abcdABC123', 'abcdABC123', [0 1 1 1 0 1 1 1 0 1]
P      % Flip
       % STACK: 'abcdABC123', 'abcdABC123', [1 0 1 1 1 0 1 1 1 0]
)      % Use as logical index into the string
       % STACK: 'abcdABC123', 'acdAC12'
S      % Sort
       % STACK: 'abcdABC123', '12ACacd'
5M     % Push logical index again
       % STACK: 'abcdABC123', '12ACacd', [1 0 1 1 1 0 1 1 1 0]
(      % Write into original string as specified by the index. Implicitly display
       % STACK: 1b2ACBacd3

El módulo basado en 1 significa que mod([1 2 3 4 5], 3)da en [1 2 3 1 2]lugar de lo habitual (basado en 0) [1 2 0 1 2]. Esto es necesario aquí para manejar el caso n=1adecuadamente.

Luis Mendo
fuente
1
Ojalá 05AB1E tuviera ese último comando ...
mbomb007
6

PHP, 101 bytes

los índices de cadena negativos (PHP 7.1) ahorran 21 bytes, y posiblemente el día:

for([,$s,$n]=$argv;a&$c=$s[$i-=1];)$i%$n+1?$a[]=$c:0;for(sort($a);++$i;)echo$i%$n+1?$a[+$k++]:$s[$i];

Corre con php -nr '<code>' '<string>' <N>.

Descompostura

for([,$s,$n]=$argv;     # import command line arguments to $s and $n
    a&$c=$s[$i-=1];)    # loop backward through string
    $i%$n+1?$a[]=$c:0;      # if index is not n-th, copy character to array
for(sort($a);           # sort array
    ++$i;)              # loop forward through string:
    echo$i%$n+1             # if index is not n-th
        ?$a[+$k++]              # print character from array
        :$s[$i]                 # else print character from string
    ;
Tito
fuente
¿Por qué $i-=1no $i--?
Jörg Hülsermann
1
@ JörgHülsermann Porque $i--no funciona si $ies así NULL.
Titus
@ JörgHülsermann ... y --$i, lo que necesitaría tampoco lo hace. ;)
Tito
Nunca lo he probado antes. Gracias por su respuesta
Jörg Hülsermann
6

Octava , 65 54 bytes

function s=f(s,n)
l=~~s;l(end:-n:1)=0;s(l)=sort(s(l));

Pruébalo en línea!

Utiliza la indexación lógica para crear una matriz de caracteres "fijos" y "ordenados". Explicación:

function s=f(s,n) % Create a function, taking a string `s` and the number `n`; the output is also named `s`.
l=~~s;             % Create logical array with the same size of the input string 
                  %    [equivalent to much more verbose true(size(s))].
l(end:-n:1)=0;    % Set the 'fixed' character positions. MATLAB/Octave automatically produces
                  %    the correct result even if n is larger than the string length.
s(l)=sort(s(l)) % Select the elements from `s` where `l` is true. Sort, and store in the corresponding positions in `s`.

La forma en que creé lrequiere que sno sea cero, lo que creo que es un requisito razonable, ya que muchos idiomas usan \0como delimitador de fin de cadena.

Sanchises
fuente
Puede guardar algunos bytes si omite ly usa un vector de números de índice directamente
Leo
@Leo, ¿no es tu sugerencia de 8 bytes más?
Stewie Griffin
@StewieGriffin whoops, no vi la solución actualizada
Leo
5

Python 2, 191 bytes

Sí, estoy seguro de que esta es una solución terrible.

n,s=input()
s=s[::-1]
R=range(len(s)/n+1)
J=''.join
k=s[::n]
t=J(sorted(J(s[i*n+1:i*n+n]for i in R)))
n-=1
print J(j[::-1]for i in zip(k,[t[::-1][i*n:i*n+n][::-1]for i in R])for j in i)[::-1]

Pruébalo en línea

No me voy a molestar en explicarlo. Estuvo bien hasta que me di cuenta de que necesita ser indexado desde el final. Ahora es un monstruo. En este punto, me alegro de que funcione.

mbomb007
fuente
1
Votado a favor debido a la "explicación". : P
Stewie Griffin
4

JavaScript (ES6), 100 93 bytes

Toma entrada en la sintaxis de curry (s)(n).

s=>n=>s.replace(/./g,(c,i)=>(F=_=>(s.length-++i)%n)()?[...s].filter(F,i=0).sort()[j++]:c,j=0)

Formateado y comentado

s => n => s.replace(        // given a string s and an integer n
  /./g,                     // for each character c of s
  (c, i) => (               // at position i:
    F = _ =>                //   F = function that tests whether the
      (s.length - ++i) % n  //       character at position i is non-static
  )()                       //   call F() on the current position
  ?                         //   if the current character is non-static:
    [...s].filter(F, i = 0) //     get the list of non-static characters
      F, i = 0              //     by filtering all characters in s with F()
    )                       //
    .sort()[j++]            //     sort them and pick the next occurrence
  :                         //   else:
    c,                      //     let c unchanged
  j = 0                     //   initialize j = non-static character pointer
)                           //

Casos de prueba

Arnauld
fuente
2

Perl 5 , 94 bytes

88 bytes de código + -F -plbanderas.

$_=join"",(map{(--$i%$n?"":$F[$#F-$i--]),$_}sort grep$i++%$n,reverse@F),chop if($n=<>)>1

Pruébalo en línea!

En mi opinión, es demasiado largo, pero ya no es tan feo ... De todos modos, todavía estoy tratando de jugarlo más.

Dada
fuente
2

Jalea , 14  13 bytes

FṢṁ
ṚsṚµḢ€ż@Ç

Programa completo que imprime la cadena a STD *.

Pruébalo en línea!

¿Cómo?

ṚsṚµḢ€ż@Ç - Main link: string s, non-negative number n
Ṛ         - reverse s
 s        - split into chunks of size n
  Ṛ       - reverse the resulting list
   µ      - monadic chain separation (call that list x)
    Ḣ€    - head €ach - yield a list of the first entries of each of x and modify x
        Ç - call the last link (1) as a monad - get the sorted and re-split list
      ż@  - zip together (with reversed @rguments)

FṢṁ - link 1, sort and reshape like self: list of lists
F   - flatten into a single list
 Ṣ  - sort
  ṁ - mould the result like the input

No puedo evitar pensar que hay una manera de usar el hecho de que modifica su entrada

* para una función, uno querría aplanar la salida en una sola lista con F.
Por ejemplo, una entrada de "abcdABC123", 4produce: en
[[['1'],['b']],[['2','A','C'],['B']],[['a','c',',d'],['3']]]
lugar de:
['1','b','2','A','C','B','a','c',',d','3']

Jonathan Allan
fuente
1

Python + NumPy , 115 114 bytes

from numpy import *
def f(x,n):l=len(x);x=array(x);m=[1<2]*l;m[-1::-n]=[1>2]*len(m[0::n]);x[m]=sort(x[m]);return x

Toma una lista de Python regular como entrada (no estaba seguro de si tomar una matriz se consideraría kosher); devuelve una matriz NumPy que contiene el resultado.

Funciona enmascarando los índices relevantes y ordenando el resto.

Julian Wolf
fuente
1

Python 2, 119113 bytes

n,l=input()
i=range(len(l))
print"".join(sorted(l[~a]for a in i if a%n)[-a+a/n]if a%n else l[~a]for a in i)[::-1]

Crea una lista de todos los caracteres que se ordenarán, los ordena y los fusiona para imprimirlos, evitando algunos cambios a través de la indexación negativa.

moooeeeep
fuente
1
print"".join(sorted(l[~a]for a in i if a%n)[-a+a/n]if a%n else l[~a]for a in i)[::-1]ahorra 5 bytes
TidB
@TidB Gracias, ¡casi eliminé la barra de desplazamiento! (Aparentemente hubo un salto de línea final involucrado en mi recuento anterior, por lo tanto, parece ser que ahora en lugar de 113 114.)
moooeeeep
0

Ruby, 64 bytes

Utiliza expresiones regulares para capturar todos los caracteres irrelevantes, tanto para reemplazar como para ordenar.

->i,s,j=-1{s.gsub(r=/.(?!(?=.{#{i}})*$)/){s.scan(r).sort[j+=1]}}

Pruébalo en línea

Tinta de valor
fuente