Розенкранц и Гильденстерн являются Кодексом

10

В абсурдной пьесе Розенкранц и Гильденстерн мертвы , два главных героя Розенкранц и Гильденстерн (или они?) Всегда путают, кто из них есть кто, а иногда и какой из их собственных частей тела из-за ощущаемого отсутствия индивидуальная идентичность. Разве не было бы абсурдом, если бы они даже перемешали свои имена?

Ваша задача состоит в том, чтобы написать функцию, которая принимает строку четной длины (и, по замыслу, кратную 4), которая превышает 7 символов, разделяет ее и перемешивает ее.

Разделение должно быть следующим : строка будет иметь формат "abscd", где s будет символом-разделителем . Первый раздел и разделитель absбудут первой половиной строки, тогда как вторая половина будетcd

Длина aбудет(string length / 4) - 1

Длина bбудет(string length / 4)

Длина sбудет1

Длина cбудет(string length / 4) + 1

Длина dбудет(string length / 4) - 1

Это может быть очень запутанным, поэтому позвольте мне показать вам несколько примеров

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

В заключение:

Затем вы перемешаете части вокруг, выводя adscb

ех. "rosencrantz&guildenstern" --> "rosenstern&guildencrantz"

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

Rulez:

  1. Стандартные лазейки запрещены
  2. Приемлемые ответы: функция, которая принимает входные данные через одну входную строку и возвращает одну выходную строку
  3. Если входная строка не соответствует требованиям, указанным выше, ваш код ДОЛЖЕН выдавать ошибку (не имеет значения, какого типа Exceptionили Error)
  4. Так code-golfчто самый короткий (действительный) ответ (на каждом языке) выигрывает!
  5. Бонусные баллы за однострочник :-) (Не совсем так, просто классные баллы)
Майкл
источник
6
Относительно вашего гангста рула: Обычно не рекомендуется отдавать предпочтение «функциям» , поскольку их трудно определить в целом. Кроме того, обработка неправильного ввода также в основном избегается, так как обычно сводится к надоедливому коду котельной плиты.
Джонатан Фрех
@JonathanFrech Я думаю, что проблема проверки входных данных представляет собой интересную проблему, поскольку она может быть решена различными способами, от обхода массива до логики ветвления и тестирования RegEx, поэтому их оптимизация может добавить дополнительную проблему ¯_ (ツ) _ / ¯ Я попробую это для еще одной игры в гольф кода :-)
Майкл
2
Все пытаются получить более гибкие методы, чтобы код создавался в их любимом поле для гольфа. и это происходит почти на все вопросы
Windmill Cookies
1
@NathanMerrill В спецификации упоминается, что длина ввода должна быть больше 7 символов, а его длина должна делиться на четыре, Джо Кинг предлагал ввести в тестовом примере длину 4, такую ​​"abcd", которая должна выдавать ошибку
Thaufeki

Ответы:

11

K (ок) , 35 34 33 байта

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

Попробуйте онлайн!

Без проверки ввода (для вознаграждения ngn), 25 24 23 байта

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

Попробуйте онлайн!

Быстро изучив немного K, и, глядя на список глаголов, я подумал, что здесь может работать альтернативный подход ( без использования cut). И это сработало отлично.

Как это работает

{<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 Что случилось с моими глазами Oo
Bubbler
3

Perl 6 , 60 58 байт

-2 байта благодаря Джо Кингу

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

Попробуйте онлайн!

Выдает «Rotorizing длина подсписка вне диапазона» в случае ошибки.

объяснение

{               # 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
источник
3

J , 36 35 байт

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

Попробуйте онлайн!

-1 байт {.+ отрицательные длины и ;.2вместо них используются маркеры «окончания».

Оригинальный ответ, 36 байт

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

Попробуйте онлайн!

ngn упомянул «вырезать» в комментарии к более раннему ответу K , и это заставило меня попробовать J, который имеет такой же «вырез» (я понятия не имею, как работает K).

Как это работает

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

Обратите внимание, что эта функция автоматически обрабатывает неверные данные:

  • Если входная длина не кратна четырем, {.throws, domain errorпоскольку его аргумент length должен быть целым числом.
  • Если длина ввода равна 4, разрез производит только два сегмента и 5 A.выбрасывает index error.
  • Если длина ввода равна 0, два аргумента для обрезки не имеют одинаковую длину, поэтому length errorвыбрасывается.
фонтанчик для питья
источник
3

Python 3 , 103 102 101 97 88 86 84 байта

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]

Попробуйте онлайн!

На самом деле не одна ;строка , но на один байт на строку меньше, чем разрыв строки и отступ.

Выдает, ZeroDivisionErrorесли длина входной строки меньше 8 или не кратна 4.

Также работает в Python 2.

-4 байта благодаря Джо Кингу

-9 байт благодаря овсу

-2 байта благодаря Джонатану Фреху

-2 байта благодаря Bubbler

Axim
источник
@JoKing спасибо за советы, очень ценю :)
Axim
1
88 байт
ов
Хороший улов @ov для соседних индексов, что касается паренов, я пробовал по крайней мере 20 минут, чтобы посмотреть, смогу ли я избавиться от некоторых из них, затем я полностью упустил, что с изменением //=самой внешней пары стало излишним. Огромное спасибо!
Аксим
2
-l+1<-> 1-l?
Джонатан Фрех
1
Объедините два неравенства, чтобы получить 84 байта .
Bubbler
2

Perl 6 , 78 байт

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

Попробуйте онлайн!

Блок анонимного кода, который принимает строку и возвращает измененную строку, если она действительна, иначе возвращает ошибку деления на ноль. Я знаю, что могу изменить массив напрямую, чтобы я мог поменять местами два раздела строки, но я не могу понять это.

Джо Кинг
источник
2

K (нгн / к) , 120 113 103 99 95 байт

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

Будем надеяться, что их можно увеличить, добавив дополнительную функцию для проверки, если длина строки делится на четыре, выводит ошибку со ссылкой на необъявленную переменную, если ввод неверен

РЕДАКТИРОВАТЬ: Пропущенное условие на длине больше 7, включая

РЕДАКТИРОВАТЬ: объединены в одну функцию, удалены избыточные объявления переменных

Попробуйте онлайн!

Thaufeki
источник
1
это может быть намного короче. ты знаешь про "вырезать" ( indices_string)? пинг меня в саду, если я должен объяснить это
нг
1
я могу сделать это в 34 байта :)
NNN
Я знаю о сокращении, но я не думал об использовании этого ... 34 байта ?! Я собираюсь дать этому еще один
шанс,
я должен упомянуть: мое решение не гарантирует, что неправильные входы (длина <= 7) вызывают ошибку
ngn
1

Сетчатка 0.8.2 , 58 или 73 или 83 или 93 байта

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

Попробуйте онлайн! Объяснение:

((((.)))*?)

Захват aв $1, и сделать его как можно более коротким *?. $#2, $#3И в $#4конечном итоге , как длина a.

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

Захват bв $4. В (?<-2>.)+захватывает до длины a, в то время как другой .добавляет 1 к его длине по мере необходимости.

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

Захват sи cв $6. Их общая длина на три больше, чем длина a.

((?<-4>.)+)

Захват dв $7. Его длина не больше, чем длина a.

$

Мы сделали aкак можно короче, но мы все еще хотим достичь конца ввода.

$1$7$6$5

Обмен bи d.

Вышеуказанный этап не проверяет его ввод. Поскольку Retina не имеет ошибок во время выполнения, существует несколько вариантов проверки ввода:

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

Ничего не выводится, если длина меньше 8 или не кратна 4. (+15 байт)

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

Выводится, Errorесли длина меньше 8 или не кратна 4. (+25 байт)

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

Зависает, если длина меньше 8 или не кратна 4. (+35 байт)

Нил
источник
Это не выдает ошибку на недопустимых входах (как это ни раздражает)
Джо Кинг
1

C (gcc) с -Dx=memcpyа -DL=(l-1), 154 158 160 байт

Возвращает NULL, если длина входной строки не делится на 4 или короче 8 символов.

Спасибо Rogem и Jonathan Frech за предложения.

РЕДАКТИРОВАТЬ: Перемещенный препроцессор определяет в командной строке и делает строку динамически распределенной, чтобы строго соответствовать загадке.

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)

Попробуйте онлайн!

ErikF
источник
Почему t[80]? Кажется, нет верхней границы относительно длины ввода.
Джонатан Фрех
@JonathanFrech Я сделал это, чтобы сохранить байты, но вы правы. Я изменил решение, чтобы использовать malloc()вместо этого.
ErikF
Возвращает модификацией, возвращаемое значение NULLдля неверного вывода, использует возвращаемые значения из memcpy(), подобного функции макроса для пропуска типов и массивов переменной длины C99 для пропуска malloc().
Почему 160 байтов, вы считаете //или -w?
l4m2
@ l4m2 -w- просто удобство для подавления предупреждений (поэтому ошибки легче найти). Я обычно добавляю аргументы командной строки после a, //чтобы TIO подсчитывал мне их байты, а затем вычитал 1 из общего количества, чтобы учесть один дополнительный символ, необходимый для этого.
1

Желе , 28 байт

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

(Если разрешена полная программа, мы можем удалить завершающий символ F).
Если длина меньше 8 или не делится на четыре, a ValueErrorувеличивается во время целочисленного деления inf(float) на 4- деление дает NaN(также float), которое затем не может быть брошенным на int.

Попробуйте онлайн!

Как?

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)
Джонатан Аллан
источник
1

JavaScript (Node.js) , 80 байт

s=>(g=s.substr.bind(s))(0,l=s.length/4-1)+g(-l)+g(l-~l,l+3)+g(l,l+1,l<1==l%1||Z)

Попробуйте онлайн!

JavaScript (Node.js) , 84 байта

s=>(g=(a,b)=>s.substr(a,b))(0,l=s.length/4-1)+g(-l)+g(l-~l,l+3)+g(l,l+1,l<1==l%1||Z)

Попробуйте онлайн!

JavaScript (Node.js) , 87 байт

s=>(l=s.length/4)<2||l%1?Z:(g=(a,b)=>s.substr(a,b))(0,l-1)+g(1-l)+g(l+l-1,l+2)+g(l-1,l)

Попробуйте онлайн!

Короче чем RegExp

l4m2
источник
0

Java 8, 135 байт

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

Выдает ArithmeticException(делит на ноль), если входная строка не соответствует требованиям. Попробуйте это онлайн здесь .

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
}
OOBalance
источник
Предлагаю l/=l>7&l%4<1?4:0;вместоl=l>7&l%4<1?l/4:l/0;
floorcat
0

C (gcc) , 129 байт

Возвращает по модификации. Компилировать с:

-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

Исходный файл:

l;

Попробуйте онлайн!

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.

источник