Rosencrantz dan Guildenstern adalah Kode

10

Dalam drama absurd Rosencrantz dan Guildenstern are Dead , dua karakter utama Rosencrantz dan Guildenstern (atau mereka?) Selalu mencampuradukkan siapa di antara mereka yang — atau kadang-kadang bagian tubuh mereka yang mana — karena dianggap kurang memiliki identitas individu. Bukankah tidak masuk akal jika mereka bahkan mengacak-acak nama mereka?

Tugas Anda adalah menulis fungsi yang mengambil string dengan panjang genap (dan dengan desain, kelipatan 4) yang lebih besar dari 7 karakter, membaginya, dan mengocoknya.

Pemisahan harus sebagai berikut : string akan berformat "abscd", dengan akting sebagai karakter pemisah. Bagian pertama dan pemisah, absakan menjadi bagian pertama dari string, sedangkan bagian kedua akan menjadicd

Panjangnya aakan(string length / 4) - 1

Panjangnya bakan(string length / 4)

Panjangnya sakan1

Panjangnya cakan(string length / 4) + 1

Panjangnya dakan(string length / 4) - 1

Ini mungkin benar-benar membingungkan, jadi izinkan saya menunjukkan kepada Anda dengan beberapa contoh

("a" + "bb" + "s" + "ccc" + "d").length //8
  1     2      1      3      1
|-------4--------|  |----4-----| <--- (4 is half of 8)

("rosen" + "crantz" + "&" + "guilden" + "stern").length  //24
    5         6        1        7          5

("foo" + "barr" + "?" + "barry" + "foo").length
   3       4       1      5         3

Akhirnya:

Anda kemudian mengocok bagian di sekitar, mengeluarkan adscb

ex. "rosencrantz&guildenstern" --> "rosenstern&guildencrantz"

"foobarr?barryfoo" --> "foofoo?barrybarr"

Aturan:

  1. Celah Standar dilarang
  2. Jawaban yang dapat diterima: fungsi yang mengambil input melalui satu string input dan mengembalikan satu string output
  3. Jika string input tidak sesuai dengan persyaratan yang diberikan di atas, kode Anda HARUS error (tidak peduli apa Exceptionatau Error)
  4. Ini code-golf, jadi jawaban terpendek (valid) (dalam setiap bahasa) menang!
  5. Poin bonus untuk satu liner :-) (Tidak juga, hanya poin keren)
Michael
sumber
6
Mengenai gangsta rulez Anda: Biasanya tidak disarankan untuk memilih "fungsi" , karena sulit didefinisikan secara umum. Selain itu, penanganan input yang tidak valid juga sebagian besar dihindari, karena biasanya bermuara pada kode plat-boiler yang mengganggu.
Jonathan Frech
@JonathanFrech Saya pikir tantangan validasi input adalah masalah yang menarik, karena dapat ditangani berbagai cara, mulai dari array traversal, ke branching logic, hingga pengujian RegEx, sehingga optimalisasi ini dapat menambah tantangan ekstra ¯ _ (ツ) _ / ¯ Saya akan mencobanya untuk tantangan kode golf lain :-)
Michael
2
Jika semua orang berusaha mendapatkan metode io yang lebih fleksibel untuk membuat kode dalam bahasa golf favorit mereka. dan tfw itu terjadi pada hampir semua pertanyaan
Windmill Cookies
1
@NathanMerrill Disebutkan dalam spesifikasi bahwa panjang input harus lebih dari 7 karakter dan panjangnya harus dapat dibagi empat, Jo King menyarankan entri test case dengan panjang 4 "abcd" seperti itu yang seharusnya error
Thaufeki

Jawaban:

11

K (oK) , 35 34 33 byte

{$[8>#x;.;<x!4!-&4#-1 0 2+-4!#x]}

Cobalah online!

Tanpa validasi input (untuk karunia ngn), 25 24 23 byte

{<x!4!-&4#-1 0 2+-4!#x}

Cobalah online!

Cepat belajar sedikit K dan, melihat daftar kata kerja, saya pikir pendekatan alternatif ( tidak menggunakan cut) bisa bekerja di sini. Dan itu bekerja dengan sempurna.

Bagaimana itu bekerja

{<x!4!-&4#-1 0 2+-4!#x}
                 -4!#x    Length divided by four (floor division)
        4#-1 0 2+         Generate lengths (x/4-1, x/4, x/4+2, x/4-1)
       &                  Generate that many 0, 1, 2, 3's
    4!-                   Negate and modulo 4; effectively swap 1 and 3
 <x!                      Sort the original string by above

{$[8>#x;.; <code> ]}  Input validation
 $[8>#x           ]   If the length is less than 8
        .             Dynamically generate an error
           <code>     Otherwise, run the main code
Bubbler
sumber
@ ngn Apa yang terjadi dengan mata saya Oo
Bubbler
3

Perl 6 , 60 58 byte

-2 byte terima kasih kepada Jo King

{[~] .rotor($_/4 X-1,0,+^-$_+>2,-1,1)[0,4,2,3,1;*]}o*.comb

Cobalah online!

Lempar "Panjang daftar rotorisasi di luar jangkauan" jika terjadi kesalahan.

Penjelasan

{               # Anonymous block
 [~]            # Join
   .rotor(      # Split into sublists of specific length
     $_/4 X-    # Subtract from len/4
     1,
     0,
     +^-$_+>2,  # (len-1)>>2
                #   subtraction yields 1 if len is multiple of 4
                #   otherwise a value less than 1 causing an error
     -1,       
     1)
   [0,4,2,3,1;*]  # Rearrange sublists and take inner elements
}o*.comb          # Split into characters and feed into block
nwellnhof
sumber
3

J , 36 35 byte

5;@A.](<;.2~;)1<@{."+~1 0 _2 1-4%~#

Cobalah online!

-1 byte oleh {.+ panjang negatif & ;.2yang memotong yang sebagai penanda "berakhir" sebagai gantinya.

Jawaban asli, 36 byte

5;@A.](<;.1~;)1<@{."+~_1 0 2 _1+4%~#

Cobalah online!

ngn menyebut "cut" pada komentar ke jawaban K sebelumnya , dan itu membuat saya mencoba J yang memiliki "cut" yang sama (saya tidak tahu bagaimana K bekerja).

Bagaimana itu bekerja

5;@A.](<;.1~;)1<@{."+~_1 0 2 _1+4%~#  Monadic train.
                                4%~#  Length divided by four
                      _1 0 2 _1+      Generate the four segment lengths
              1<@{."+~  Generate [1 0 0...] boxed arrays of those lengths
      (     ;)          Raze; unbox and concatenate
     ] <;.1~            Cut the input string on ones as starting marker, then box each
5  A.  Rearrange the boxes in the order 0 3 2 1
 ;@    Raze again

Perhatikan bahwa fungsi ini secara otomatis menangani input yang tidak valid:

  • Jika panjang input bukan kelipatan empat, {.melempar domain errorkarena argumen panjangnya harus bilangan bulat.
  • Jika panjang input adalah 4, potongan hanya menghasilkan dua segmen, dan 5 A.melempar index error.
  • Jika panjang input adalah 0, dua argumen untuk memotong tidak memiliki panjang yang sama, jadi length errordilemparkan.
Bubbler
sumber
3

Python 3 , 103 102 101 97 88 86 84 byte

def f(s):l=len(s);l//=4*(l%4<1<l/4);return s[:l-1]+s[1-l:]+s[2*l-1:1-l]+s[l-1:2*l-1]

Cobalah online!

Bukan benar-benar satu-liner, tetapi ;satu byte lebih sedikit per baris dari linebreak dan indent.

Melempar ZeroDivisionErrorjika panjang string input kurang dari 8 atau bukan kelipatan bilangan bulat dari 4.

Juga berfungsi di Python 2.

-4 byte terima kasih kepada Jo King

-9 byte berkat ovs

-2 byte terima kasih kepada Jonathan Frech

-2 byte terima kasih kepada Bubbler

Axim
sumber
@JoKing, terima kasih atas tipsnya, sangat dihargai :)
Axim
1
88 bytes
ovs
@ovs tangkapan yang bagus pada indeks yang berdekatan, seperti untuk parens, saya mencoba sekitar setidaknya 20 menit untuk melihat apakah saya bisa menyingkirkan beberapa dari mereka, maka saya benar-benar merindukan bahwa dengan perubahan //=pada pasangan terluar menjadi mubazir. Terima kasih banyak!
Axim
2
-l+1<-> 1-l?
Jonathan Frech
1
Gabungkan kedua ketidaksetaraan untuk mencapai 84 byte .
Bubbler
2

Perl 6 , 78 byte

*.comb[0..*/4-2,3* */4+1..*,*/2-1/(*>7)..3* */4,*/4-1/(*%%4)..*/2-2].flat.join

Cobalah online!

Blok kode anonim yang mengambil string dan mengembalikan string yang dimodifikasi jika valid, yang lain mengembalikan pembagian dengan kesalahan nol. Saya tahu saya bisa memodifikasi array secara langsung, jadi saya bisa menukar dua bagian dari string, tetapi saya tidak bisa mengetahuinya.

Jo King
sumber
2

K (ngn / k) , 120 113 103 99 95 byte

{$[(r>7)&0=4!r:#:x;{g:(s:*|(y*2)#x)\x;((y-1)#*g),((-y-1)#*|g),s,((y+1)#*|g),(-y)#*g}[x;r%4];l]}

Semoga dapat diturunkan lebih banyak, termasuk fungsi tambahan untuk pengujian jika panjang string dapat dibagi empat, kesalahan output dengan referensi ke variabel yang tidak dideklarasikan jika input tidak valid

SUNTING: Kondisi terlewat yang panjangnya lebih dari 7, termasuk

EDIT: Digabungkan menjadi satu fungsi, menghapus deklarasi variabel redundan

Cobalah online!

Thaufeki
sumber
1
ini bisa menjadi jauh lebih pendek. Anda tahu tentang "cut" ( indices_string)? ping saya di kebun jika saya harus menjelaskannya
ngn
1
saya bisa melakukannya dalam 34 byte :)
ngn
Saya tahu tentang cut, tapi saya tidak berpikir untuk menggunakannya ... 34 byte ?! Aku harus mencoba ini lagi ketika aku pulang dan melihat apakah aku sudah dekat itu
Thaufeki
saya harus menyebutkan: solusi saya tidak memastikan bahwa input yang tidak valid (panjang <= 7) menyebabkan kesalahan
ngn
1

Retina 0.8.2 , 58 atau 73 atau 83 atau 93 byte

((((.)))*?)(.(?<-2>.)+)(...(?<-3>.)+)((?<-4>.)+)$
$1$7$6$5

Cobalah online! Penjelasan:

((((.)))*?)

Capture adi $1, dan membuatnya sesingkat mungkin *?. $#2, $#3dan $#4berakhir sebagai panjang a.

(.(?<-2>.)+)

Menangkap bdi $4. Yang (?<-2>.)+menangkap hingga panjang a, sedangkan yang lain .menambahkan 1 panjangnya seperti yang diperlukan.

(...(?<-3>.)+)

Tangkap sdan cmasuk $6. Panjang gabungan mereka adalah tiga lebih dari panjang a.

((?<-4>.)+)

Menangkap ddi $7. Panjangnya tidak lebih dari panjang a.

$

Kami membuat asesingkat mungkin, tetapi kami masih ingin mencapai akhir input.

$1$7$6$5

Pertukaran bdan d.

Tahap di atas tidak memvalidasi inputnya. Karena Retina tidak memiliki kesalahan run-time, ada sejumlah opsi untuk validasi input:

G`^(....){2,}$

Tidak menghasilkan apa-apa jika panjangnya kurang dari 8 atau tidak kelipatan 4. (+15 byte)

^(?!(....){2,}$).*
Error

Keluaran Error jika panjangnya kurang dari 8 atau tidak kelipatan 4. (+25 byte)

+`^(....)*..?.?$|^(....)?$
.....$1

Hang jika panjangnya kurang dari 8 atau tidak kelipatan 4. (+35 byte)

Neil
sumber
Ini tidak menimbulkan kesalahan pada input yang tidak valid (sama menjengkelkannya)
Jo King
1

C (gcc) dengan -Dx=memcpydan -DL=(l-1), 154 158 160 byte

Mengembalikan NULL jika panjang string input tidak habis dibagi 4 atau lebih pendek dari 8 karakter.

Terima kasih kepada Rogem dan Jonathan Frech untuk sarannya.

EDIT: Preprocessor yang dipindahkan mendefinisikan ke baris perintah dan membuat string yang dialokasikan secara dinamis untuk benar-benar sesuai dengan puzzle.

f(s,t,l)char*s,*t;{l=strlen(s);l%4|l<8?t=0:(t=malloc(l+1),l/=4,x(t,s,L),x(t+L,s+3*l+1,L),x(t+2*L,s+L+l,l+2),x(t+3*l,s+L,l),t[4*l]=0);l=t;}//-Dx=memcpy -DL=(l-1)

Cobalah online!

ErikF
sumber
Mengapa t[80]? Tampaknya tidak ada batas atas tentang panjang input.
Jonathan Frech
@ JonathanFrech Saya melakukannya untuk menghemat byte tetapi Anda benar. Saya telah mengubah solusi untuk digunakan malloc()sebagai gantinya.
ErikF
Pengembalian dengan modifikasi, nilai kembali NULLuntuk output yang tidak valid, menggunakan nilai kembali dari memcpy(), makro seperti fungsi untuk melewati tipe dan array panjang variabel C99 untuk dilewati malloc().
Mengapa 160 byte, apakah Anda menghitung //atau -w?
l4m2
@ l4m2 -whanyalah kemudahan untuk menekan peringatan (sehingga kesalahan lebih mudah ditemukan). Saya biasanya menambahkan argumen baris perintah setelah //TIO menghitung byte mereka untuk saya, dan kemudian mengurangi 1 dari total ke akun untuk satu karakter tambahan yang diperlukan untuk melakukan itu.
1

Jelly , 28 byte

L7»4ḍİ×L:4;;ĖÄƲFÄœṖ⁸⁽%[D¤ị$F

(Jika program lengkap diizinkan, kami dapat menghapus trailing F)
Jika panjangnya kurang dari 8 atau tidak habis dibagi empat a ValueErrordinaikkan selama pembagian bilangan bulat dari inf(float) oleh 4- divisi menghasilkan NaN(juga float) yang kemudian tidak dapat dilemparkan ke sebuah int.

Cobalah online!

Bagaimana?

L7»4ḍİ×L:4;;ĖÄƲFÄœṖ⁸⁽%[D¤ị$F - Link: list of characters
L                            - length
 7                           - literal seven
  »                          - maximum (of length & 7)
   4ḍ                        - divisible by four? (yields 1 for good inputs; 0 otherwise)
     İ                       - inverse (1 yields 1; 0 yields inf)
      ×L                     - multiply by length (length or inf)
        :4                   - integer divide by 4 (errors given inf)
              Ʋ              - last four links as a monad (f(x)):
          ;                  -   concatenate -> [x,x]
            Ė                -   enumerate -> [1,x]
           ;                 -   concatenate -> [x,x,[1,x]]
             Ä               -   cumulative sum (vectorises at depth 1) -> [x,x,[1,1+x]]
               F             - flatten -> [x,x,1,1+x]
                Ä            - cumulative sum -> [x,2x,2x+1,3x+2]
                   ⁸         - chain's left argument (the input)
                 œṖ          - partition at indices (chops up as per requirements)
                          $  - last two links as a monad (f(z)):
                        ¤    -   nilad followed by link(s) as a nilad:
                    ⁽%[      -     10342
                       D     -     decimal digits -> [1,0,3,4,2]
                         ị   -   index into z (rearranges the pieces as per requirements)
                           F - flatten (back to a list of characters)
Jonathan Allan
sumber
1

Jelly , 25 byte

L:4’+“¡¢¢£¡‘Ṡ3¦ÄṬk⁸Ṛ2,5¦Ẏ

Cobalah online!

The dapat dihapus untuk membuat ini menjadi program penuh.

Erik the Outgolfer
sumber
1

JavaScript (ES6), 97 89 byte

Disimpan 8 byte berkat @ l4m2

s=>(l=s.length/4)<2||l%1?Z:s.replace(eval(`/(.{${l}})(.{${l+2}})(.{${l-1}})$/`),'$3$2$1')

Cobalah online!

Arnauld
sumber
1
89B
14m2
0

Java 8, 135 byte

s->{int l=s.length();l=l>7&l%4<1?l/4:l/0;return s.substring(0,l-1)+s.substring(3*l+1)+s.substring(2*l-1,3*l+1)+s.substring(l-1,2*l-1);}

Melempar ArithmeticException(membaginya dengan nol) jika string input tidak cocok dengan persyaratan. Cobalah online di sini .

Tidak Disatukan:

s -> { // lambda function taking a String argument and returning a String
    int l = s.length(); // take the length of the input ...
    l = l > 7 &         // ... if it's  greater than 7 and ...
        l % 4 < 1       // ... a multiple of 4 ...
      ? l / 4           // ... divide by 4; otherwise ...
      : l / 0;          // ... error out (division by zero throws ArithmeticException)
    return // concatenate and return:
           s.substring(0, l - 1)             // a
         + s.substring(3 * l + 1)            // d
         + s.substring(2 * l - 1, 3 * l + 1) // sc
         + s.substring(l - 1, 2 * l - 1);    // b
}
Ketidakseimbangan
sumber
Sarankan l/=l>7&l%4<1?4:0;alih-alihl=l>7&l%4<1?l/4:l/0;
ceilingcat
0

C (gcc) , 129 byte

Kembali dengan modifikasi. Kompilasi dengan:

-Df(s)=({char t[l=strlen(s)];l%4|l<8?0:(l/=4,x(t,s+l*2-1,l-~l),x(x(x(s+l*3,s+l-1,l)-l-2,t,l+2)-l+1,t+l+2,l-1),s);}) -Dx=memcpy

Sumber data:

l;

Cobalah online!

Degolf

-Df(s)=({ // Function-like macro f. Takes a char* as a parameter.
          // Return value is a pointer to s if successful, and to NULL if string was invalid.
     char t[l=strlen(s)]; // Allocate a local temp string.
     l%4|l<8?0: // Detect invalid strings. Return 0 (NULL) on invalid string.
         (l/=4, // We're only really concerned with floor(len/4), and this will yield that.
             memcpy(t,s+l*2-1,l-~l), // Copy the second half of chars to the temp storage.
             memcpy( // Because memcpy returns the address of the destination, we can chain
                     // the calls to save quite a few bytes, even after x->memcpy substitution.
                 memcpy(memcpy(s+l*3,s+l-1,l) // Next, copy the second quarter to the end.
                     -l-2,t,l+2) // After that, we copy back the third quarter to its place.
                          -l+1,t+l+2,l-1) // Finally, copy the fourth quarter to where the second
                                          // quarter was.
                      ,s);}) // And return the pointer.

sumber