Sortieren Sie unbrauchbare Zeichen

21

Diese Herausforderung ist inspiriert von dieser sehr schönen Antwort von TidB.


In der Antwort von TidB sind alle acht Zeichen in der richtigen Reihenfolge: gnilwoB edoC( Code Bowlingrückwärts). Die anderen Saiten jedoch sind waren in einer fremden, zufälligen Reihenfolge.

Ihre Herausforderung besteht darin, dies zu beheben.

Nehmen Sie eine (nicht leere) Zeichenfolge und eine positive Ganzzahl nals Eingabe. Die Zeichenfolge enthält ASCII-Zeichen im Bereich von 32 bis 126 (Leerzeichen für Tilde).

Sie müssen die Zeichenfolge in aufsteigender Reihenfolge sortieren (von links gesehen, basierend auf dem ASCII-Code-Wert), aber jedes nZeichen ab dem Ende der Zeichenfolge überspringen . Nehmen wir als Beispiel den String abcdABC123als Eingabe und n=4dann erhalten wir:

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)

Ein anderes Beispiel:

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)

Die Eingabezeichenfolge kann in einem optionalen Format erfolgen (Zeichenfolge, Liste der Zeichen, Liste der einzelnen Zeichenfolgen ...). Die eingegebene Ganzzahl kann auch in einem optionalen Format angegeben werden.

Testfälle:

Das Format lautet n=__, gefolgt von der Eingabezeichenfolge in der nächsten Zeile. Die Ausgabe erfolgt in der Zeile darunter.

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
quelle

Antworten:

7

MATL , 15 bis 14 Bytes

ttfiX\qgP)S5M(

Eingaben sind eine Zeichenfolge in einfachen Anführungszeichen und eine Zahl. Einfache Anführungszeichen in der Zeichenfolge sollten durch Duplizieren maskiert werden (wie in MATLAB und Octave).

Probieren Sie es online! Oder überprüfen Sie alle Testfälle .

Erläuterung

Betrachten Sie Eingaben 'abcdABC123'und 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

1-basierte Modulo Mittel, mod([1 2 3 4 5], 3)gibt [1 2 3 1 2]statt der üblichen (0-basiert) [1 2 0 1 2]. Dies ist hier erforderlich, um den Fall n=1angemessen zu behandeln.

Luis Mendo
quelle
1
Ich wünschte, 05AB1E hätte diesen letzten Befehl ...
mbomb007
6

PHP, 101 Bytes

Negative String-Indizes (PHP 7.1) sparen 21 Bytes - und möglicherweise den Tag:

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

Laufen Sie mit php -nr '<code>' '<string>' <N>.

Nervenzusammenbruch

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
    ;
Titus
quelle
warum $i-=1nicht $i--?
Jörg Hülsermann
1
@ JörgHülsermann Weil es $i--nicht funktioniert wenn es $iist NULL.
Titus
@ JörgHülsermann ... und --$idas würde ich auch nicht brauchen. ;)
Titus
Ich habe es noch nie versucht. Vielen Dank für Ihre Antwort
Jörg Hülsermann
6

Oktave , 65 54 Bytes

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

Probieren Sie es online!

Verwendet die logische Indizierung, um ein Array von "festen" und "sortierten" Zeichen zu erstellen. Erläuterung:

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`.

Die Art und Weise, wie ich sie erstellt habe l, ssetzt voraus, dass sie ungleich Null ist, was meiner Meinung nach eine vernünftige Voraussetzung ist, da viele Sprachen \0als Begrenzer für das Ende der Zeichenfolge verwendet werden.

Sanchises
quelle
Sie können einige Bytes sparen, wenn Sie leinen Vektor von Indexnummern direkt umgehen und verwenden
Leo
@Leo, ist dein Vorschlag nicht 8 Bytes länger?
Stewie Griffin
@ StewieGriffin whoops, ich habe die aktualisierte Lösung nicht gesehen
Leo
5

Python 2, 191 Bytes

Ja, ich bin sicher, das ist eine schreckliche Lösung.

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]

Probieren Sie es online aus

Ich werde mich nicht darum kümmern, es zu erklären. Es war in Ordnung, bis mir klar wurde, dass es von Anfang an indexiert werden muss. Jetzt ist es ein Monster. An dieser Stelle bin ich nur froh, dass es funktioniert.

mbomb007
quelle
1
Aufgewertet wegen der "Erklärung". : P
Stewie Griffin
4

JavaScript (ES6), 100 93 Byte

Übernimmt Eingaben in der Currying-Syntax (s)(n) .

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

Formatiert und kommentiert

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

Testfälle

Arnauld
quelle
2

Perl 5 , 94 Bytes

88 Byte Code + -F -plFlags.

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

Probieren Sie es online!

Es ist meiner Meinung nach viel zu lang, aber schon gar nicht so hässlich ... Ich versuche es trotzdem weiter zu golfen.

Dada
quelle
2

Jelly , 14  13 Bytes

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

Vollständiges Programm, das den String nach STD ausgibt *.

Probieren Sie es online!

Wie?

Ṛ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

Ich kann nicht anders, als zu glauben, dass es einen Weg gibt, die Tatsache zu nutzen, die ihre Eingabe verändert

* für eine Funktion möchte man die Ausgabe mit zu einer einzigen Liste zusammenfassen F.
Zum Beispiel ein Eingang "abcdABC123", 4ergibt sich :
[[['1'],['b']],[['2','A','C'],['B']],[['a','c',',d'],['3']]]
statt:
['1','b','2','A','C','B','a','c',',d','3']

Jonathan Allan
quelle
1

Python + NumPy , 115 bis 114 Byte

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

Verwendet eine reguläre Python-Liste als Eingabe (war nicht sicher, ob das Aufnehmen eines Arrays als koscher angesehen wird); gibt ein NumPy-Array zurück, das das Ergebnis enthält.

Arbeitet, indem die relevanten Indizes ausgeblendet und der Rest sortiert wird.

Julian Wolf
quelle
1

Python 2, 119 113 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]

Erstellt eine Liste aller zu sortierenden Zeichen, sortiert sie und führt sie zum Drucken zusammen, wobei ein Teil der Umkehrung durch negative Indizierung vermieden wird.

moooeeeep
quelle
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]spart 5 Bytes
TidB
@TidB Danke, die Bildlaufleiste wurde fast entfernt! (Anscheinend gab es in meiner vorherigen Zählung einen nachgestellten Zeilenumbruch, daher scheint es jetzt 113 statt 114 zu sein.)
moooeeeep
0

Ruby, 64 Bytes

Verwendet Regex, um alle irrelevanten Zeichen zu erfassen, sowohl zum Ersetzen als auch zum Sortieren.

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

Probieren Sie es online aus

Wert Tinte
quelle