Rosencrantz ve Guildenstern Koddur


10

Absürd oyunda Rosencrantz ve Guildenstern Ölü vardır , iki ana karakter Rosencrantz ve Guildenstern (ya onlar?) Her zaman kendi vücut parçalarının hangi bazen kim-ya da bunların hangi yukarı karıştırma hangi-çünkü bir algılanan eksikliği bireysel kimlik. İsimlerini karıştırsalar bile saçma olmaz mıydı?

Göreviniz, eşit uzunlukta bir dizeyi (ve tasarımla, 7 karakterden daha büyük bir dizeyi) alan bir işlevi yazmak , bölmek ve karıştırmaktır.

Bölme aşağıdaki gibi olacaktır : dize, "abscd"bir ayırıcı karakter olarak işlev görecek şekilde formatta olacaktır . İlk bölüm ve ayırıcı, absdizenin ilk yarısı, ikinci bölüm isecd

Uzunluğu aolacak(string length / 4) - 1

Uzunluğu bolacak(string length / 4)

Uzunluğu solacak1

Uzunluğu colacak(string length / 4) + 1

Uzunluğu dolacak(string length / 4) - 1

Bu gerçekten kafa karıştırıcı olabilir, bu yüzden size bazı örnekler göstereyim

("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

En sonunda:

Daha sonra parçaları karıştırıp, adscb

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

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

Rulez:

  1. Standart Loopholes yasaktır
  2. Kabul edilebilir cevaplar: bir girdi dizesi üzerinden girdi alan ve bir çıktı dizesi döndüren bir işlev
  3. Giriş dizesi yukarıda belirtilen gereksinimlere uymuyorsa, kodunuz hata vermelidir ZORUNLU (ne tür Exceptionveya ne olduğu önemli değil Error)
  4. Bu, code-golfen kısa (geçerli) cevap (her dilde) kazanır!
  5. Bir astar için bonus puan :-) (Gerçekten tho değil, sadece harika puanlar)

6
Gangsta rulezinizle ilgili olarak: Genel olarak tanımlanması zor olduğu için genellikle "işlevleri" tercih etmekten vazgeçirilir . Ayrıca, genellikle rahatsız edici kazan plakası koduna bağlandığı için geçersiz girdinin işlenmesinden de çoğunlukla kaçınılır.
Jonathan Frech

@JonathanFrech Bence giriş doğrulamasının zorluğu ilginç bir sorundur, çünkü dizi geçişinden dallanma mantığına, RegEx testine kadar çeşitli yollarla ele alınabilir, bu yüzden bunların optimizasyonu ekstra bir zorluk ekleyebilir ¯_ (ツ) _ / ¯ Yine de başka bir kod golf meydan okuma için deneyeceğim :-)
Michael

2
tfw herkes en sevdiği golf lang kodu yapmak için daha esnek io yöntemleri almaya çalışıyor. ve tfw hemen hemen tüm sorularda oluyor
Windmill Cookies


1
@NathanMerrill Spesifikasyonda, girdinin 7 karakterden uzun olması ve uzunluğunun dörtle bölünmesi gerektiği belirtiliyor, Jo King, hata yapması gereken böyle bir "abcd" uzunluğundaki 4 test örneğini
önerdi

Yanıtlar:


11

K (oK) , 35 34 33 bayt

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

Çevrimiçi deneyin!

Giriş doğrulama olmadan (ngn'in ödülü için), 25 24 23 bayt

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

Çevrimiçi deneyin!

Hızla biraz K öğrendim ve fiiller listesine baktığımda alternatif bir yaklaşım düşündüm ( değil burada işe yarayabilir kesim kullanılarak). Ve mükemmel çalıştı.

Nasıl çalışır

{<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

@ngn Gözlerime ne oldu Oo
Bubbler

3

Perl 6 , 60 58 bayt

Jo King sayesinde -2 bayt

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

Çevrimiçi deneyin!

Hata durumunda "Alt liste uzunluğunun rotorize edilmesi aralık dışında" atar.

açıklama

{               # 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

3

J , 36 35 bayt

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

Çevrimiçi deneyin!

-1 byte by {.+ negatif uzunluklar & ;.2bunun yerine "biten" işaretler olarak kesen.

Orijinal cevap, 36 bayt

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

Çevrimiçi deneyin!

ngn, önceki bir K cevabına yapılan bir yorumda "kes" den bahsetti ve bana aynı "kes" e sahip J'yi denememi sağladı (K'nın nasıl çalıştığı hakkında hiçbir fikrim yok).

Nasıl çalışır

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

Bu işlevin geçersiz girdileri otomatik olarak işlediğini unutmayın:

  • Girdi uzunluğu dördün katı değilse , uzunluk bağımsız değişkeni tamsayı olması gerektiğinden {.atar domain error.
  • Giriş uzunluğu 4 ise, kesim sadece iki segment üretir ve 5 A.atar index error.
  • Giriş uzunluğu 0 ise, kesilecek iki argüman aynı uzunlukta değildir, bu length errornedenle atılır.

3

Piton 3 , 103 102 101 97 88 86 84 bayt

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]

Çevrimiçi deneyin!

Gerçekten tek ;satırlık değil, satır başına satır sonu ve girintiden daha az bayttır.

Atar ZeroDivisionErrorgiriş dizi uzunluğu en az 8 ya da 4 olan bir tamsayı olması durumunda.

Ayrıca Python 2'de çalışır.

Jo King sayesinde -4 bayt

Ovs sayesinde -9 bayt

Jonathan Frech sayesinde -2 bayt

Bubbler sayesinde -2 bayt


@JoKing ipuçları için teşekkürler, çok takdir :)
Axim


@ovs bitişik endekslerde güzel yakalamak, parens gelince, ben en azından 20 dakika için bazılarını kurtulmak olmadığını denemek için çalıştı, o zaman tamamen //=en dış çift değişikliği ile gereksiz hale geldi özledim . Çok teşekkürler!
Axim

2
-l+1<-> 1-l?
Jonathan Frech

1
84 bayta ulaşmak için iki eşitsizliği birleştirin .
Bubbler

2

Perl 6 , 78 bayt

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

Çevrimiçi deneyin!

Dizeyi alan ve değiştirilmiş dizeyi geçerliyse döndüren anonim kod bloğu, aksi takdirde sıfır hata ile bölünme döndürür. Ben doğrudan bir dizi değiştirebilir biliyorum, bu yüzden dizenin iki bölümünü takas olabilir, ama ben oldukça anlayamıyorum.


2

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

{$[(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]}

Umarım daha fazla golf yapılabilir, dize uzunluğunun dörtle bölünebilir olup olmadığını test etmek için ekstra bir işlev dahil edilmiştir, giriş geçersizse bildirilmemiş değişkene referansla hata verir

EDIT: Uzunluğu 7'den büyük olan kaçırılmış durum, dahil

DÜZENLEME: Tek bir işlevde birleştirilmiş, gereksiz değişken bildirimleri kaldırıldı

Çevrimiçi deneyin!


1
bu çok daha kısa olabilir. "cut" ( indices_string) hakkında ne düşünüyorsunuz ? açıklamam gerekirse meyve bahçesinde bana ping
ngn

1
34
baytta

Kesmeyi biliyorum, ama kullanmayı düşünmedim ... 34 bytes ?! Eve döndüğümde bunu bir kez daha vereceğim ve
yaklaşıp yaklaşmadığımı göreceğim

söylemeliyim: benim çözüm geçersiz girişler (uzunluk <= 7) bir hataya neden olduğundan emin değil
ngn

1

Retina 0.8.2 , 58 veya 73 veya 83 veya 93 bayt

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

Çevrimiçi deneyin! Açıklama:

((((.)))*?)

Yakalama aiçinde $1ve mümkün olduğunca kısa yapmak *?. $#2, $#3Ve $#4uzunluğu olarak sonuna kadar a.

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

Yakalama biçinde $4. (?<-2>.)+Uzunluğuna kadar yakalar a, diğeri ise .gerektiği gibi, uzunluğu 1 ekler.

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

Yakalama sve ciçinde $6. Birleştirilmiş uzunlukları, uzunluklarından üç daha fazladır a.

((?<-4>.)+)

Yakalama diçinde $7. Uzunluğu, uzunluğundan daha fazla değildir a.

$

aMümkün olduğunca kısa yaptık , ancak yine de girdinin sonuna ulaşmak istiyoruz.

$1$7$6$5

Değişim bved .

Yukarıdaki aşama girdisini doğrulamaz. Retina'da çalışma zamanı hatası olmadığından, giriş doğrulaması için bir dizi seçenek vardır:

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

Uzunluk 8'den azsa veya 4'ün katı değilse hiçbir şey çıktılamaz. (+15 bayt)

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

çıktılar Error uzunluğu 4. (+ 25 bayt) 8 daha az ya da birden fazla ise,

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

Uzunluk 8'den küçükse veya 4'ün katları değilse asılır. (+35 bayt)


Bu geçersiz girdilere hata vermiyor (bu kadar sinir bozucu)
Jo King

1

C (GCC) ile -Dx=memcpyve -DL=(l-1), 154 158 160 bayt

Giriş dizesi uzunluğu 4 ile bölünemezse veya 8 karakterden kısa değilse NULL döndürür.

Öneriler için Rogem ve Jonathan Frech'e teşekkürler.

DÜZENLEME: Taşınan önişlemci komut satırını tanımlar ve bulmacaya tam olarak uyması için dizeyi dinamik olarak ayırır.

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)

Çevrimiçi deneyin!


Neden t[80]? Giriş uzunluğu ile ilgili bir üst sınır görünmemektedir.
Jonathan Frech

@JonathanFrech Bayt kurtarmak için yaptım ama haklısın. Bunun malloc()yerine kullanılacak çözümü değiştirdim .
ErikF

Değişiklikle döndürür, döndürme değeri NULLgeçersiz çıktı içindir, memcpy()türleri döndürmek için döndürme değerlerini , türleri atlamak için işlev benzeri bir makroyu ve atlamak için C99 değişken uzunlukta dizileri kullanır malloc().

Neden 160 bayt, //ya da -w?
l4m2

@ l4m2 -wsadece uyarıları bastırmak için bir kolaylıktır (bu nedenle hataların bulunması daha kolaydır). Genellikle //TIO'nun baytlarını benim için sayması için bir komut satırı argümanı eklerim ve sonra bunu yapmak için gereken bir ekstra karakteri hesaba katmak için toplamdan 1 düşerim.

1

Jöle , 28 bayt

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

(Tam bir programa izin verilirse, izi kaldırabiliriz F)
Uzunluk 8'den küçükse veya dört a ValueErrorile bölünemezse , inf(bir şamandıra) tamsayı bölünmesi sırasında 4- bölüm verimleri NaN(ayrıca bir şamandıra) oyuncu olmak int.

Çevrimiçi deneyin!

Nasıl?

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)





0

Java 8, 135 bayt

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);}

ArithmeticExceptionGiriş dizesi gereksinimlere uymuyorsa atar (sıfıra bölünür). Burada çevrimiçi deneyin .

Ungolfed:

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
}

Öner l/=l>7&l%4<1?4:0;yerinel=l>7&l%4<1?l/4:l/0;
ceilingcat

0

C (gcc) , 129 bayt

Değişiklikle döner. Şununla derleyin:

-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

Kaynak dosyası:

l;

Çevrimiçi deneyin!

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.
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.