Розенкранц і Гільденстерн - Кодекс


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
tfw всі намагаються отримати більш гнучкі методи іо, щоб зробити код у своєму улюбленому гольф-гольфі. і tfw це трапляється майже з усіх питань
Cookie Windmill


1
@NathanMerrill У специфікації згадується, що довжина вводу повинна бути більше 7 символів, а її довжина повинна бути розділена на чотири, Джо Кінг пропонував ввести в тестовий випадок довжину 4 такого "abcd", яка повинна
помилитися

Відповіді:


11

K (oK) , 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

Спробуйте в Інтернеті!

У разі помилки виводиться "Роторизація довжини підспісу" за межами "

Пояснення

{               # 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 байт

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

Спробуйте в Інтернеті!

-1 байт на {.+ від’ємну довжину, ;.2а замість них скорочується як «кінцеві» маркери.

Оригінальна відповідь, 36 байт

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

Спробуйте в Інтернеті!

ngn згадав "вирізати" в коментарі до попередньої відповіді К , і це змусило мене спробувати 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

Зауважте, що ця функція автоматично обробляє недійсні входи:

  • Якщо довжина вводу не кратна чотирьом, {.кидаєdomain error оскільки аргумент його довжини повинен бути цілим числом.
  • Якщо довжина вводу дорівнює 4, розріз виробляє лише два сегменти і 5 A.кидки index error.
  • Якщо вхідна довжина дорівнює 0, два аргументи для вирізання не мають однакової довжини, тому length errorвикидається.

3

Пітон 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


@JoKing спасибі за підказки, дуже вдячний :)
Axim


@ovs приємний вилов на сусідніх індексах, що стосується паронів, я намагався обійти принаймні 20 хвилин, щоб побачити, чи можу я позбутися деяких з них, то я зовсім пропустив, що зі зміною на //=саму зовнішню пару став зайвим. Дякую купу!
Аксим

2
-l+1<-> 1-l?
Джонатан Фрех

1
Об’єднайте дві нерівності, щоб дістатися до 84 байт .
Бубон

2

Perl 6 , 78 байт

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

Спробуйте в Інтернеті!

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


2

К (нг / к) , 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]}

Сподіваємось, можна збільшити більше, включити додаткову функцію для тестування, якщо довжина рядка ділиться на чотири, виводить помилку з посиланням на незадекларовану змінну, якщо введення недійсне

EDIT: Пропущений стан довжиною більше 7, включено

EDIT: У поєднанні в одну функцію видалено зайві декларації змінної

Спробуйте в Інтернеті!


1
це може бути набагато коротше. ти знаєш про "cut" ( indices_string)? пінг мене в саду, якщо я мушу це пояснити
пн.

1
я можу це зробити у 34 байтах :)
ngn

Я знаю про вирізання, але не думав про його використання ... 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 байт)


Це не призводить до помилок на недійсних введеннях (як це дратує)
Jo King

1

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

Повертає NULL, якщо довжина вхідного рядка не ділиться на 4 або менше 8 символів.

Дякую Роґему та Джонатану Фреху за пропозиції.

EDIT: Переміщений препроцесор визначає командний рядок і робить рядок динамічно виділеним, щоб суворо відповідати головоломці.

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)

Спробуйте в Інтернеті!


Чому t[80]? Здається, немає верхньої межі щодо вхідної довжини.
Джонатан Фрех

@JonathanFrech Я зробив це для збереження байтів, але ви правильні. Я змінив рішення для використання malloc()замість цього.
ErikF

Повертається за допомогою модифікації, повертає значення NULLдля недійсного виводу, використовує значення повернення з memcpy(), макрос, подібний до функції, для пропускання типів та масивів змінної довжини C99 для пропуску malloc().

Чому 160 байт, ви вважаєте, //чи -w?
l4м2

@ l4m2 -w- це лише зручність придушення попереджень (тому помилки легше знайти). Я, як правило, додаю аргументи командного рядка після того, //щоб TIO порахував їхні байти, а потім відніс 1 від загальної суми для обліку одного додаткового символу, необхідного для цього.

1

Желе , 28 байт

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

(Якщо дозволена повна програма, ми можемо видалити трейлінг F)
Якщо довжина менше 8 або не ділиться на чотири а ValueErrorпіднімається під час цілого поділу inf(поплавця) на 4- поділ дає вихід NaN(також поплавок), який потім не може бути відлитим до 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


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(ділиться на нуль), якщо рядок введення не відповідає вимогам. Спробуйте його онлайн тут .

Безголівки:

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
}

Запропонувати l/=l>7&l%4<1?4:0;замістьl=l>7&l%4<1?l/4:l/0;
roofcat

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;

Спробуйте в Інтернеті!

Дегольф

-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.
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.