Mengurutkan karakter yang tidak berguna

21

Tantangan ini terinspirasi oleh ini jawaban yang sangat bagus oleh TidB.


Dalam jawaban TidB, setiap delapan karakter berada dalam urutan yang benar: gnilwoB edoC( Code Bowlingmundur). Namun senar lain yang berada di aneh, urutan acak.

Tantangan Anda adalah untuk memperbaikinya.

Ambil string (tidak kosong) dan bilangan bulat positif nsebagai input. String akan berisi karakter ASCII dalam rentang: 32-126 (spasi untuk tilde).

Anda harus mengurutkan string dalam urutan menaik (terlihat dari kiri, berdasarkan nilai kode ASCII), tetapi lewati setiap nkarakter ke-5, mulai dari akhir string. Sebagai contoh, mari kita ambil string abcdABC123sebagai input, dan n=4, maka kita akan mendapatkan:

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)

Contoh lain:

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)

String input dapat diambil pada format opsional (string, daftar karakter, daftar string karakter tunggal ...). Bilangan bulat input juga dapat diambil pada format opsional.

Kasus uji:

Formatnya akan n=__, diikuti oleh string input pada baris berikutnya. Outputnya adalah pada baris di bawah ini.

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
sumber

Jawaban:

7

MATL , 15 14 byte

ttfiX\qgP)S5M(

Input adalah string yang dilampirkan dalam tanda kutip tunggal dan angka. Simbol tanda kutip tunggal dalam string harus diloloskan dengan menduplikasi (seperti dalam MATLAB dan Oktaf).

Cobalah online! Atau verifikasi semua kasus uji .

Penjelasan

Pertimbangkan input 'abcdABC123'dan 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

Modulo 1-based artinya mod([1 2 3 4 5], 3)memberi [1 2 3 1 2]bukan yang biasa (berbasis 0) [1 2 0 1 2]. Ini diperlukan di sini untuk menangani kasus ini secara n=1memadai.

Luis Mendo
sumber
1
Saya berharap 05AB1E memiliki perintah terakhir ...
mbomb007
6

PHP, 101 byte

indeks string negatif (PHP 7.1) menghemat 21 byte - dan mungkin harinya:

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

Jalankan dengan php -nr '<code>' '<string>' <N>.

kerusakan

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
sumber
mengapa $i-=1dan tidak $i--?
Jörg Hülsermann
1
@ JörgHülsermann Karena $i--tidak berfungsi jika $iada NULL.
Titus
@ JörgHülsermann ... dan --$i, yang saya perlukan juga tidak. ;)
Titus
Saya belum pernah mencobanya sebelumnya. Terima kasih atas jawaban Anda
Jörg Hülsermann
6

Oktaf , 65 54 byte

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

Cobalah online!

Menggunakan pengindeksan logis untuk membuat array karakter 'tetap' dan 'diurutkan'. Penjelasan:

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

Cara yang saya buat lmensyaratkan bahwa sbukan nol, yang saya pikir merupakan persyaratan yang masuk akal, karena banyak bahasa digunakan \0sebagai pembatas akhir-string.

Sanchises
sumber
Anda dapat menyimpan beberapa byte jika Anda mem l- bypass dan menggunakan vektor nomor indeks secara langsung
Leo
@ Leo, bukankah saran Anda 8 byte lebih lama?
Stewie Griffin
@StewieGriffin ups, saya tidak melihat solusi yang diperbarui
Leo
5

Python 2, 191 byte

Ya, saya yakin ini solusi yang mengerikan.

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]

Cobalah online

Saya tidak akan repot menjelaskannya. Tidak apa-apa sampai saya menyadari bahwa itu perlu diindeks dari akhir. Sekarang monster. Pada titik ini, saya senang itu berfungsi.

mbomb007
sumber
1
Terpilih karena "penjelasan". : P
Stewie Griffin
4

JavaScript (ES6), 100 93 byte

Mengambil input dalam sintaks currying (s)(n) .

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

Diformat dan dikomentari

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

Uji kasus

Arnauld
sumber
2

Perl 5 , 94 byte

88 byte kode + -F -plbendera.

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

Cobalah online!

Ini terlalu lama menurut saya, tetapi sudah tidak terlalu jelek ... Saya masih mencoba untuk golf lebih jauh lagi.

Dada
sumber
2

Jelly , 14  13 byte

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

Program lengkap yang mencetak string ke STD out *.

Cobalah online!

Bagaimana?

Ṛ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

Saya tidak dapat membantu tetapi berpikir ada cara untuk menggunakan fakta yang mengubah inputnya

* untuk fungsi yang ingin diratakan keluarannya menjadi satu daftar F.
Misalnya input "abcdABC123", 4hasil:
[[['1'],['b']],[['2','A','C'],['B']],[['a','c',',d'],['3']]]
daripada:
['1','b','2','A','C','B','a','c',',d','3']

Jonathan Allan
sumber
1

Python + NumPy , 115 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

Mengambil daftar Python biasa sebagai input (tidak yakin apakah mengambil array akan dianggap halal); mengembalikan array NumPy yang berisi hasilnya.

Bekerja dengan menyembunyikan indeks yang relevan dan memilah sisanya.

Julian Wolf
sumber
1

Python 2, 119 113 byte

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]

Buat daftar semua karakter yang akan diurutkan, sortir dan gabungkan untuk dicetak, sambil menghindari beberapa pembalikan melalui pengindeksan negatif.

moooeeeep
sumber
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]menghemat 5 byte
TidB
@TidB Terima kasih, hampir menghilangkan scrollbar! (Tampaknya ada baris baru yang tertinggal dalam hitungan saya sebelumnya, oleh karena itu tampaknya menjadi 113 sekarang, bukan 114.)
moooeeeep
0

Ruby, 64 byte

Menggunakan regex untuk mengambil semua karakter yang tidak relevan, baik untuk penggantian maupun untuk penyortiran.

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

Cobalah online

Nilai Tinta
sumber