Rosencrantz i Guildenstern są Code

10

W absurdalnej sztuce Rosencrantz i Guildenstern nie żyją , dwaj główni bohaterowie Rosencrantz i Guildenstern (czy są?) Zawsze mieszają, która z nich jest kim - a czasem która z ich części ciała jest - z powodu postrzeganego braku indywidualna tożsamość. Czy nie byłoby absurdalne, gdyby nawet tasowali się wokół swoich nazwisk?

Twoim zadaniem jest napisanie funkcji, która przyjmuje ciąg o parzystej długości (i z założenia wielokrotność 4), która jest większa niż 7 znaków, podziel ją i potasuj.

Podział będzie następujący : ciąg znaków będzie miał format "abscd", przy czym s będzie działało jak znak separatora. Pierwsza sekcja i separator absbędą pierwszą połową łańcucha, podczas gdy druga połowa będziecd

Długość abędzie(string length / 4) - 1

Długość bbędzie(string length / 4)

Długość sbędzie1

Długość cbędzie(string length / 4) + 1

Długość dbędzie(string length / 4) - 1

To może być bardzo mylące, dlatego pokażę kilka przykładów

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

Wreszcie:

Następnie tasujesz części, generując adscb

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

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

Rulez:

  1. Standardowe luki są zabronione
  2. Dopuszczalne odpowiedzi: funkcja, która pobiera dane wejściowe przez jeden ciąg wejściowy i zwraca jeden ciąg wyjściowy
  3. Jeśli ciąg wejściowy nie spełnia powyższych wymagań, kod MUSI się nie powieść (nie ma znaczenia, jaki Exceptionlub Error)
  4. To jest code-golftak, że wygrywa najkrótsza (ważna) odpowiedź (w każdym języku)!
  5. Punkty bonusowe za linijkę :-) (Niezupełnie, tylko fajne punkty)
Michał
źródło
6
Jeśli chodzi o twoją gangstę: zazwyczaj nie zaleca się faworyzowania „funkcji” , ponieważ ogólnie trudno je zdefiniować. Co więcej, unika się również obsługi nieprawidłowych danych wejściowych, ponieważ zwykle sprowadza się to do irytującego kodu płyty kotłowej.
Jonathan Frech
@JathanathanFrech Myślę, że wyzwanie sprawdzania poprawności danych wejściowych jest interesującym problemem, ponieważ można sobie z nim poradzić na wiele sposobów, od przejścia przez tablicę, przez logikę rozgałęzień, po testy RegEx, więc ich optymalizacja może stanowić dodatkowe wyzwanie ¯_ (ツ) _ / ¯ Spróbuję tego na innym golfowym
Michael
2
tfw wszyscy starają się uzyskać bardziej elastyczne metody io, aby kod był w ich ulubionym języku golfowym. i tfw dzieje się to prawie na wszystkie pytania
Windmill Cookies
1
@NathanMerrill W specyfikacji podano, że dane wejściowe muszą być dłuższe niż 7 znaków, a ich długość musi być podzielna przez cztery, Jo King sugerował wpisanie przypadku testowego o długości 4, takiego jak „abcd”, który powinien zostać błędny
Thaufeki

Odpowiedzi:

11

K (oK) , 35 34 33 bajtów

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

Wypróbuj online!

Bez sprawdzania poprawności danych wejściowych (dla nagrody NNG), 25 24 23 bajtów

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

Wypróbuj online!

Szybko nauczyłem się trochę K i patrząc na listę czasowników pomyślałem, że może tu działać alternatywne podejście ( bez użycia cięcia). I działało idealnie.

Jak to działa

{<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
źródło
@ngn Co się stało z moimi oczami Oo
Bubbler
3

Perl 6 , 60 58 bajtów

-2 bajty dzięki Jo King

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

Wypróbuj online!

Zgłasza „Długość obrotowej podlisty jest poza zakresem” w przypadku błędu.

Wyjaśnienie

{               # 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
źródło
3

J , 36 35 bajtów

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

Wypróbuj online!

-1 bajt przez {.+ długości ujemne i ;.2który zamiast tego odcina je jako znaczniki „kończące”.

Oryginalna odpowiedź, 36 bajtów

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

Wypróbuj online!

ngn wspomniał o „cut” w komentarzu do wcześniejszej odpowiedzi K i sprawiło, że wypróbowałem J, który ma to samo „cut” (nie mam pojęcia, jak działa K).

Jak to działa

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

Pamiętaj, że ta funkcja automatycznie obsługuje nieprawidłowe dane wejściowe:

  • Jeśli długość wejściowa nie jest wielokrotnością czterech, {.wyrzuca, domain errorponieważ argumentem długości muszą być liczby całkowite.
  • Jeśli długość wejściowa wynosi 4, cięcie wytwarza tylko dwa segmenty i 5 A.rzuca index error.
  • Jeśli wejściowa długość wynosi 0, dwa argumenty do przecięcia nie mają tej samej długości, więc length errorjest wyrzucane.
Bubbler
źródło
3

Python 3 , 103 102 101 97 88 86 84 bajtów

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]

Wypróbuj online!

W rzeczywistości nie jest to jedna linijka, ale ;jest o jeden bajt mniej na linię niż podział linii i wcięcie.

Zgłasza, ZeroDivisionErrorjeśli długość ciągu wejściowego jest mniejsza niż 8 lub nie jest całkowitą wielokrotnością liczby 4.

Działa również w Python 2.

-4 bajty dzięki Jo King

-9 bajtów dzięki ovs

-2 bajty dzięki Jonathanowi Frechowi

-2 bajty dzięki Bubblerowi

Axim
źródło
@JoKing dzięki za wskazówki, mile widziane :)
Axim
1
88 bajtów
ovs
@ovs niezły haczyk na sąsiednie indeksy, jeśli chodzi o pareny, próbowałem przez co najmniej 20 minut, aby sprawdzić, czy mogę się ich pozbyć, a potem całkowicie przegapiłem to, że zmiana //=na skrajną parę stała się zbędna. Wielkie dzięki!
Axim,
2
-l+1<-> 1-l?
Jonathan Frech,
1
Połącz dwie nierówności, aby uzyskać 84 bajty .
Bubbler,
2

Perl 6 , 78 bajtów

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

Wypróbuj online!

Anonimowy blok kodu, który pobiera ciąg i zwraca zmodyfikowany ciąg, jeśli jest prawidłowy, w przeciwnym razie zwraca podział przez błąd zero. Wiem, że mogę modyfikować tablicę bezpośrednio, więc mogłem zamienić dwie sekcje łańcucha, ale nie jestem w stanie tego rozgryźć.

Jo King
źródło
2

K (ngn / k) , 120 113 103 99 95 bajtów

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

Miejmy nadzieję, że można go bardziej pograć w golfa, zawiera dodatkową funkcję do testowania, czy długość łańcucha jest podzielna przez cztery, wyprowadza błąd w odniesieniu do niezadeklarowanej zmiennej, jeśli dane wejściowe są nieprawidłowe

EDYCJA: Utracony stan na długości większej niż 7, w tym

EDYCJA: W połączeniu z jedną funkcją usunięto zbędne deklaracje zmiennych

Wypróbuj online!

Thaufeki
źródło
1
to może być znacznie krótsze. wiesz o „cut” ( indices_string)?
pinguj
1
mogę to zrobić w 34 bajtach :)
ngn
Wiem o cięciu, ale nie myślałem o jego użyciu ... 34 bajty ?! Będę musiał
powtórzyć,
powinienem wspomnieć: moje rozwiązanie nie upewnia się, że nieprawidłowe dane wejściowe (długość <= 7) powodują błąd
ngn
1

Siatkówka 0.8.2 , 58 lub 73 lub 83 lub 93 bajty

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

Wypróbuj online! Wyjaśnienie:

((((.)))*?)

Przechwytywanie aw $1, i uczynić go możliwie jak najkrótszy *?. $#2, $#3A $#4skończyć jako długość a.

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

Capture bin $4. Te (?<-2>.)+zrzuty aż do długości a, podczas gdy drugi .dodaje 1 do jego długości, w miarę potrzeb.

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

Przechwytywanie si cw $6. Ich łączna długość jest o 3 większa niż długość a.

((?<-4>.)+)

Capture din $7. Jego długość jest nie większa niż długość a.

$

Zrobiliśmy atak krótko, jak to możliwe, ale nadal chcemy osiągnąć koniec danych wejściowych.

$1$7$6$5

Wymiana bid .

Powyższy etap nie weryfikuje danych wejściowych. Ponieważ Retina nie ma błędów w czasie wykonywania, istnieje wiele opcji sprawdzania poprawności danych wejściowych:

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

Nie wyświetla nic, jeśli długość jest mniejsza niż 8 lub nie jest wielokrotnością 4. (+15 bajtów)

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

Wyprowadzane, Errorjeśli długość jest mniejsza niż 8 lub nie jest wielokrotnością 4. (+25 bajtów)

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

Zawiesza się, jeśli długość jest mniejsza niż 8 lub nie jest wielokrotnością 4. (+35 bajtów)

Neil
źródło
Nie rzuca to błędu na nieprawidłowe dane wejściowe (choć jest to irytujące)
Jo King
1

C (GCC) z -Dx=memcpyi -DL=(l-1), 154 158 160 bajtów

Zwraca NULL, jeśli długości ciągu wejściowego nie można podzielić przez 4 lub mniej niż 8 znaków.

Dziękujemy Rogemowi i Jonathanowi Frechowi za sugestie.

EDYCJA: Przeniesiony preprocesor definiuje do linii poleceń i dynamicznie przydziela ciąg, aby ściśle odpowiadał układance.

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)

Wypróbuj online!

ErikF
źródło
Dlaczego t[80]? Wydaje się, że nie ma górnej granicy dotyczącej długości wejściowej.
Jonathan Frech,
@JathanathanFrech Zrobiłem to, aby zapisać bajty, ale masz rację. malloc()Zamiast tego zmieniłem rozwiązanie .
ErikF,
Zwraca przez modyfikację, zwracana wartość jest NULLdla niepoprawnych danych wyjściowych, używa wartości zwracanych z memcpy(), makra podobnego do funkcji do pomijania typów i tablic o zmiennej długości C99 do pomijania malloc().
Dlaczego 160 bajtów, czy liczyć //albo -w?
l4m2
@ l4m2 -wto tylko wygoda do tłumienia ostrzeżeń (więc łatwiej jest znaleźć błędy). Zazwyczaj dodam argumenty wiersza poleceń po tym, //aby TIO policzyło dla mnie bajty, a następnie odejmuję 1 od sumy, aby uwzględnić jeden dodatkowy znak potrzebny do tego.
1

Galaretka , 28 bajtów

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

(Jeśli dozwolony jest pełny program, możemy usunąć końcowe F).
Jeśli długość jest mniejsza niż 8 lub nie jest podzielna przez cztery, a ValueErrorpodczas dzielenia liczb całkowitych inf( liczby zmiennoprzecinkowe) jest zwiększane o 4- podział daje NaN(także liczbę zmiennoprzecinkową), która wtedy nie może zostać obsadzonym int.

Wypróbuj online!

W jaki sposób?

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
źródło
1

Galaretka , 25 bajtów

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

Wypróbuj online!

Można usunąć, aby ten w pełnym programie.

Erik the Outgolfer
źródło
1

JavaScript (ES6), 97 89 bajtów

Zaoszczędzono 8 bajtów dzięki @ l4m2

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

Wypróbuj online!

Arnauld
źródło
1
89B
l4m2
0

Java 8, 135 bajtów

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

Zgłasza ArithmeticException(dzieli przez zero), jeśli ciąg wejściowy nie spełnia wymagań. Wypróbuj online tutaj .

Nie golfowany:

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
}
OOBalance
źródło
Zaproponuj l/=l>7&l%4<1?4:0;zamiastl=l>7&l%4<1?l/4:l/0;
ceilingcat
0

C (gcc) , 129 bajtów

Zwraca przez modyfikację. Połącz z:

-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

Plik źródłowy:

l;

Wypróbuj 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.

źródło