Перевернуть строку кусками


34

Ваша задача - написать программу, которая, учитывая число и строку, разбивает строку на куски такого размера и переворачивает их.

правила

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

Тестовые случаи

n   s           Output

2   abcdefgh    ghefcdab
3   foobarbaz   bazbarfoo
3   abcdefgh    ghdefabc
2   a           a
1   abcdefgh    hgfedcba
2   aaaaaa      aaaaaa
2   baaaab      abaaba
50  abcdefgh    abcdefgh
6   abcdefghi   ghiabcdef

Это , поэтому вы должны стремиться к как можно меньшему количеству байтов.


Ответы:


29

Желе , 2 байта

sṚ

Полная программа, которая печатает результат.

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

Как?

sṚ - Main link: string, number                                   e.g. 'abcdefg', 3
s  - split string into chunks of length number (keeping any overflow) ["abc","def","g"]
 Ṛ - reverse the resulting list                                       ["g","def","abc"]
   - implicit print                                                   gdefabc

28
Мне нравится, как два байта генерируют 4 строки объяснения.
Павел



8

JavaScript (ES6), 37 байт

n=>F=s=>s&&F(s.slice(n))+s.slice(0,n)

Принимает ввод с помощью карри: сначала число, затем строка, как f(2)("abcdefgh").


7

Perl 6 ,  28  20 байтов

{$^b.comb($^a).reverse.join}

Попытайся

{[R~] $^b.comb($^a)}

Попытайся

Expanded:

{  # bare block lambda with placeholder parameters 「$a」 and 「$b」
  [R[~]] # reduce the following using the reverse meta operator `R`
         # combined with the string concatenation operator

    # `comb` with a number splits the invocant into chunks of that size
    $^b.comb($^a)
}




4

Рёда , 36 байт

f n{[[_]..[try head n-1]]|reverse|_}

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

Это функция, которая принимает один аргумент. Символы строки должны быть в потоке.

tryиспользуется для сброса ошибок в случае, если headфункция не может прочитать n-1значения.

Объяснение:

f n{[[_]..[try head n-1]]|reverse|_}
f n{                               } /* Function declaration */
                                     /* In a loop: */
      _                              /*   Pull one value */
           try head n-1              /*   Pull n-1 values (or less) */
     [ ]..[            ]             /*   Make an array */
    [                   ]            /*   Push it to the stream */
                         |reverse    /* Reverse all values in the stream */
                                 |_  /* Flat all arrays in the stream */
                                     /* Characters in the stream are printed */

Не так запутанно, как обычно. Я думаю, что это довольно красиво. :)


5
Вам удалось сделать программу менее читаемой, чем желе.
Павел

Почему не [[try head n]]работает вместо [[_]..[try head n-1]]?
Kritixi Lithos

@KritixiLithos Потому что _цикл выражения. [[try head n]]будет принимать n значений один раз , но [[_]..[try head n-1]]принимает n значений до тех пор, пока остаются значения.
fergusq

4

CJam , 5 байтов

q~/W%

Входные данные - это число и строка, заключенные в двойные кавычки, разделенные пробелом.

Попробуйте онлайн! Или проверьте все тестовые случаи .

объяснение

q~   e# Read all input and evaluate: pushes a number and a string
/    e# Split string into chunks of that size. Last chunk may be
     e# smaller. Gives an array of strings
W%   e# Reverse the array. Implicitly display

4

Пакетная, 74 байта

@if %2=="" (echo %~3)else set s=%~2&call %0 %1 "%%s:~%1%%" "%%s:~,%1%%%~3"

Скорее досадно, что в итоге получается рекурсивным, а не хвостовым.


4

V , 13 10 байт

òÀ|lDÏpòÍî

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

ò      ò    ' Recursively
 À|         ' Go to the "nth" column
   l        ' Move one character right (breaks loop when no more chunks)
    D       ' Delete from here to the end of the line
     Ï      ' Add a line above the current line (now contains one chunk)
      p     ' Paste the remainder of the line that was deleted
        Íî  ' Remove all newlines

В бою:

abcdefghijkl

превращается в

efghijkl
abcd

который становится

ijkl
efgh
abcd

прежде чем все новые строки будут удалены


4

брейкфак , 78 байт

,<<<+[[>]>+>[[>],<[<]>+>-]<-[->>[>]>>+<<<[<]<]>>]<<<<[[<]>[-[+.[-]]+>]<[<]<<<]

Первый байт ввода - это размер порции, заданный значением байта. Остальные байты считаются строкой.

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

Расширено и прокомментировано

Read the chunk size byte
This cell will become a counter cell
,

Move left a few cells an increment; 
this is to make the starting position 
line up with the relative positioning
needed to fit in with the loop
<<<+

While the current cell is nonzero:
[

 Move right to the first zero cell
 [>]

 Move right once and increment and then move right to the counter cell
 The increment is required because of "move to zero cell" loops
 >+>

 This loop will store one chunk of the input in consecutive memory cells
 [
  [>]   Move right until a zero cell is hit
  ,     Store 1 byte of input there
  <[<]  Move back left until a zero cell (other than the current one) is hit
  >+>-  Increment the temporary cell by 1 and decrement the counter
 ] (end loop once the counter hits zero)

 Decrement the temp cell (because we needed to have 1 there initially to make the cell location work)
 <-

 Move the temp cell to three cells after the end of the chunk
 This is the new counter cell for the next chunk
 [->>[>]>>+<<<[<]<]

 Move two cells right from where the temp cell was
 This is the first cell of the chunk; if it's 0
 then the input is finished and the loop should end
 >>
]

Due to the way the counter is kept track of the tape head
will always be four cells to the right of the last input cell
when the loops breaks
<<<<

Now the chunks are printed one by one
At the start of an iteration the tape head is at the end of a chunk
[
 Locate the start of the last chunk
 [<]>

 Print the chunk:
 [
  Print the byte held in the current cell if it isn't 1
  This is necessary because we left a stray 1 in a cell at
  the start which shouldn't be printed
  -[+.[-]]+

  Move to the next cell
  >
 ]

 Move to just left of the chunk
 <[<]

 Move three cells over to the end of the next chunk
 <<<
]

4

PowerShell, 56 49 байт

-7 байт благодаря маззи

param($n,$s)$s-split"(.{$n})"-ne''|%{$r=$_+$r};$r

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


1) 49 байт. 2) Пожалуйста, выложите полную программу, а не codenippet. Как проверить? Извлеките свой код в отдельный файл с расширением .ps1и попробуйте вызвать этот скрипт вместо вашего кода. Если это работает, то тест прошел успешно.
Маззи

3

Mathematica, 46 байтов

""<>Reverse@Partition[Characters@#2,#,#,1,{}]&

Анонимная функция. Принимает число и строку в качестве ввода и возвращает строку в качестве вывода. Не так много, чтобы увидеть здесь.


3

Javascript - 54 47 46 байт

Переделал:

(s,n)=>s.match(eval(`/.{1,${n}}/g`)).reverse()

Используется как

f=(s,n)=>s.match(eval(`/.{1,${n}}/g`)).reverse()
alert(f("abcdefgh",2));

Спасибо @ETHproductions за некоторое ускорение RegEx. Спасибо @Shaggy за дополнительный байт в eval!

Оригинал:

(s,n)=>s.match(new RegExp('.{1,'+n+'}','g')).reverse()

1
Хороший ответ! Я полагаю, что вы можете сэкономить пару байтов, создав регулярное выражение сeval('/.{1,'+n+'}/g')
ETHproductions

@ETHproductions Ах да. Это то, что я пытался сделать. Я не был достаточно знаком с регулярным выражением, чтобы сделать это все же!
Blue Okiris

Я думаю, что вы можете сохранить байт с карри,s=>n=> ...
Павел

Сохраните байт eval("/.{1,${n}}/g"), используя кавычки вместо кавычек.
Лохматый


3

Сетчатка , 38 байт

1 байт сохранен благодаря @LeakyNun

^

+`(.* (1)+¶)((?<-2>.)+)
$3$1
 1+¶

(Обратите внимание на пробел во второй строке и завершающий пробел)

Эта программа воспринимает ввод как одинарный в первой строке, а строку - во второй.

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

Тестирование! (слегка модифицированный)

объяснение

Первый шаг - добавить пробел (это станет важным позже).

^
 

Теперь мы изменим. Это использует балансирующие группы .NET. Важно отметить, что группы здесь действуют как стеки, поэтому каждое совпадение по существу помещается в стек. Здесь мы записываем каждую цифру унарного числа в группу 2. Теперь каждый раз, когда символ в строке обнаруживается, совпадение выбирается из группы 2. Это гарантирует, что количество символов не превышает число унарного числа.

+`(.* (1)+¶)                       Capture the unary number in group 2
             ((?<-2>.)+)           Balancing group for substrings
$3$1                               Reverse

И, наконец, удалите одинарный номер и перевод строки.

 1+¶


Я думаю, что это приемлемо принять число в одинарном.
Утренняя монахиня

В любом случае, вы можете заменить \dна, .чтобы сохранить байт.
Утренняя монахиня

Второе ^также избыточно.
Утренняя монахиня

@LeakyNun Программа теперь принимает входные данные в унарном формате, поэтому мне это больше не нужно \d. И спасибо за
Kritixi Lithos

33 байта с помощью ленивого (не жадного) совпадения.
Утренняя монахиня

3

Ява, 147 138 байт

String r(String s,int n){String r="";int l=s.length();for(int i=l/n*n;i>=0;i-=n)if(!(i>=l))r+=(i+n)>=l?s.substring(i):s.substring(i,i+n);return r;}

Сохранено 9 байт благодаря Кевину Круйссену!

String r(String s,int n){String r="";int l=s.length(),i=l/n*n;for(;i>=0;i-=n)if(i<l)r+=i+n>=l?s.substring(i):s.substring(i,i+n);return r;}

В развернутом виде:

String r(String s,int n){
    String r="";
    int l=s.length(),i=l/n*n;
    for(;i>=0;i-=n)
        if(i<l)
            r+=i+n>=l?s.substring(i):s.substring(i,i+n);
    return r;
}

На самом деле, это моя первая попытка поиграть в кодегольф, поэтому любые отзывы приветствуются


Добро пожаловать в PPCG!
Павел

1
Привет, добро пожаловать в PPCG! Это уже довольно хорошо, но есть еще кое-что для игры в гольф: int l=s.length();for(int i=l/n*n;может быть, у int l=s.length(),i=l/n*n;for(;вас есть только int один раз. А if(!(i>=l))может быть if(l<i). А r+=(i+n)>=l?можно без скобок r+=i+n>=l?. Кроме того, если вы еще не видели его, я могу порекомендовать просмотреть « Советы по игре в гольф на Java», чтобы найти несколько полезных советов по игре в гольф. :) Еще раз добро пожаловать.
Кевин Круйссен

3

Perl 5 , 25 байт

Использует -lnM5.010флаги.

say reverse<>=~/.{1,$_}/g

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

Привет Гринну за то, что он рассказал мне о =~ m/.{1,$n}/g

-M5.010 позволяет использовать say функцию, которая для наших целей является печать с более коротким именем.

-nпомещает первую строку ввода в $_и-l отключает завершающий перевод строки.

Затем мы получаем вторую строку ввода с помощью <>и применяем ее к регулярному выражению .{1,$_}: любой символ, от 1 до $ _ (первый ввод) раз. Так как по умолчанию он жадный, он всегда пытается найти символы $ _. 1,Необходимо для возможного остаточного куска в конце.

/gМодификатор дает нам каждый матч , что регулярное выражение в строке ввода в виде списка, который затем обращенно и напечатанной. В Perl передача списка для sayприсоединения к нему без разделителя по умолчанию.





2

QBIC , 24 байта

:;[1,_lA|,a|Z=_sA,b,a|+Z

Это прекрасно использует новую подстроку-функцию, которую я недавно добавил в QBIC:

:;          Read in the cmd line params a (number) and A$ (text)
[1,_lA|,a|  Set up a FOR loop: FOR b = 1; b <= A$.length; b += a
Z=          Modify Z$; Z$ is autoprinted at the end of QBIC code
_sA,b,a|    SUBSTRING: _s is the function followed by the string 
               to take from, the starting pos and the # of chars
+Z          Take chunks from further into A$, put them before Z$



2

C 69 байтов

i;f(s,n)char*s;{i=strlen(s);for(i-=i%n;printf("%.*s",n,s+i),i;i-=n);}

Результат распечатывается на стандартный вывод.


2

Scala, 57 55 байт

(n:Int,s:String)=>(""/:s.grouped(n).toSeq.reverse)(_+_)

Спасибо Джейкоб! Попробуй здесь .

Примечание: используя символьную форму foldLeft ("/:"), я смог снять еще пару байтов.


сделайте это анонимной функцией и используйте mkStringвместо reduceLeft(n:Int,s:String)=>s.grouped(n).toSeq.reverse.mkString("")
Джейкоб


2

R , 69 60 байт

function(s,n)cat(substring(s,(x=nchar(s):0*n)+1,x+n),sep="")

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

Спасибо Кириллу Л. за предложение удалить seq.



@KirillL. мы можем перейти к 60 байтам, если поменяем порядок аргументов на :и некоторые манипуляции позволят нам избавиться от конечного результата -1.
Джузеппе

Умная, очень милая!
Кирилл Л.
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.