Разделить строку


23

Вызов

Учитывая строку и число, разделите строку на столько частей одинакового размера. Например, если число равно 3, вы должны разделить строку на 3 части независимо от длины строки.

Если длина строки не делится поровну на предоставленное число, вы должны округлить размер каждой части и вернуть строку «остаток». Например, если длина входной строки равна 13, а число равно 4, вы должны вернуть четыре строки размером 3, а также строку остатка размера 1.

Если остатка нет, вы можете просто не вернуть его или вернуть пустую строку.

Указанное число гарантированно будет меньше или равно длине строки. Например, ввод "PPCG", 7не произойдет, потому что "PPCG"не может быть разделен на 7 строк. (Я полагаю, что правильный результат будет (["", "", "", "", "", "", ""], "PPCG"). Это проще просто запретить в качестве ввода.)

Как обычно, I / O является гибким. Вы можете вернуть пару строк и оставшуюся строку или один список строк с остатком в конце.

Контрольные примеры

"Hello, world!", 4 -> (["Hel", "lo,", " wo", "rld"], "!") ("!" is the remainder)
"Hello, world!", 5 -> (["He", "ll", "o,", " w", "or"], "ld!")
"ABCDEFGH", 2 -> (["ABCD", "EFGH"], "") (no remainder; optional "")
"123456789", 5 -> (["1", "2", "3", "4", "5"], "6789")
"ALABAMA", 3 -> (["AL", "AB", "AM"], "A")
"1234567", 4 -> (["1", "2", "3", "4"], "567")

счет

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

Бонусные баллы (на самом деле не 😛) за то, что ваше решение фактически использует оператор деления вашего языка.


1
Бонусные очки? О, мужик, я должен это сделать
Мэтью Ро


Связанные , но ни одна из частей не такая же, как эта задача.
musicman523

Чтобы было понятнее, добавьте PPCG7PPCG
контрольный

@ JörgHülsermann Этот вход запрещен. Я добавил больше деталей, относящихся к этому типу ввода и переформатировал вещи, чтобы быть более понятным.
musicman523

Ответы:




5

Пип , 21 байт

20 байт кода, +1 за -nфлаг.

a~C(#a//b*XX)XbP$$$'

Принимает входные данные в качестве аргументов командной строки; выводит строки и остаток, разделенный символом новой строки. Попробуйте онлайн!

объяснение

Веселье с помощью регулярных выражений!

Давайте возьмем abcdefgнашу строку и 3наш номер. Мы создаем регулярное выражение (.{2})(.{2})(.{2}), которое соответствует трем сериям двух символов и сохраняет их в трех группах захвата. Затем, используя переменные соответствия регулярного выражения Пипа, мы можем вывести 1) список групп захвата ["ab";"cd";"ef"]и 2) остаток строки, которая не была сопоставлена "g".

                      a,b are cmdline args; XX is the regex `.` (match any one character)
    #a//b             Len(a) int-divided by b: the length of each chunk
         *XX          Apply regex repetition by that number to `.`, resulting in something
                        that looks like `.{n}`
  C(        )         Wrap that regex in a capturing group
             Xb       Repeat the whole thing b times
a~                    Match the regex against a
               P$$    Print $$, the list of all capture groups (newline separated via -n)
                  $'  Print $', the portion of the string after the match

5

Haskell , 62 байта

#оператор, принимающий a Stringи an Intи возвращающий список Strings.

Использовать как "Hello, world!"#4.

s#n|d<-length s`div`n=[take(d+n*0^(n-i))$drop(i*d)s|i<-[0..n]]

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

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

  • sявляется входной строкой и nявляется количеством не-остатков.
  • dдлина каждого «нормального» куска. divцелочисленное деление.
  • Понимание списка строит n+1куски, причем последним является остаток.
    • iповторяется от 0до n, включительно.
    • Для каждого фрагмента сначала правильное количество ( i*d) начальных символов dropначинается с начала s, а затем исходная подстрока - taken из результата.
    • Длина взятой подстроки должна быть d, за исключением оставшейся части.
      • Фактический остаток должен быть короче n, так как в противном случае нормальные части будут удлинены.
      • takeвозвращает всю строку, если указанная длина слишком велика, поэтому мы можем использовать любое число >=n-1для оставшейся части.
      • Выражение d+n*0^(n-i)дает, dесли i<nи d+nесли i==n. Она использует , что 0^xэто 1когда x==0, но 0если x>0.

Мне нужно будет посмотреть, где я могу использовать списки.
qfwfq

4

Python 2 , 68 67 65 байт

  • @ musicman123 сохранил 2 байта: вывод без включения []
  • Спасибо @Chas Brown за 1 байт: x[p*i:p+p*i]какx[p*i][:p]
def f(x,n):p=len(x)/n;print[x[p*i:][:p]for i in range(n)],x[p*n:]

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


1
Сохраните 1 байт, заменив x[p*i:p+p*i]наx[p*i:][:p]
Час Браун

1
+1 за :p😛 Молодец, превзошел все остальные ответы Python!
musicman523

Хаха .. это не было предназначено вообще ....: p
officialaimm

1
Этот ответ был переигран
musicman523

4

C ++ 14, 209 180 байт

Это слишком долго, но использует оператор деления:

#include<bits/stdc++.h>
using q=std::string;using z=std::vector<q>;z operator/(q s,int d){int p=s.length()/d,i=0;z a;for(;i<d+1;){a.push_back(s.substr(i++*p,i^d?p:-1));}return a;}

Использование:

vector<string> result = string("abc")/3;

Онлайн версия: http://ideone.com/hbBW9u


4

Pyth, 9 байт

cz*L/lzQS

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

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

Сначала Qпроисходит автоинициализация eval(input())и zвыполняется автоинициализация input().

cz*L/lzQSQ
     lz      length of z
    /  Q     integer division by Q
  *L         times every element of
        SQ       [1, 2, …, Q]
cz           chop z at those locations


3

Ржавчина , 107 байт

fn f(s:&str,n:usize)->(Vec<&str>,&str){let c=s.len()/n;((0..n).map(|i|&s[i*c..i*c+c]).collect(),&s[c*n..])}

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

отформатирован:

fn q129259(s: &str, n: usize) -> (Vec<&str>, &str) {
    let c = s.len() / n;
    ((0..n).map(|i| &s[i * c..i * c + c]).collect(), &s[c * n..])
}

Это просто mapуказатели на правильные срезы источникаstr ( collectвходящие в a Vec) и удаляет остаток.

К сожалению, я не могу сделать это закрытием (74 байта):

|s,n|{let c=s.len()/n;((0..n).map(|i|&s[i*c..i*c+c]).collect(),&s[c*n..])}

так как компилятор не работает с

error: the type of this value must be known in this context
 --> src\q129259.rs:5:18
  |
5 |          let c = s.len() / n;
  |                  ^^^^^^^

и если я предоставлю тип s:&str, время жизни неправильное:

error[E0495]: cannot infer an appropriate lifetime for lifetime parameter in function call due to conflicting requirements
 --> src\q129259.rs:6:27
  |
6 |          ((0..n).map(|i| &s[i * c..i * c + c]).collect(), &s[c * n..])
  |                           ^^^^^^^^^^^^^^^^^^^
  |
note: first, the lifetime cannot outlive the anonymous lifetime #1 defined on the body at 4:18...
 --> src\q129259.rs:4:19
  |
4 |       (|s: &str, n| {
  |  ___________________^
5 | |          let c = s.len() / n;
6 | |          ((0..n).map(|i| &s[i * c..i * c + c]).collect(), &s[c * n..])
7 | |      })(s, n)
  | |______^
note: ...so that reference does not outlive borrowed content
 --> src\q129259.rs:6:27
  |
6 |          ((0..n).map(|i| &s[i * c..i * c + c]).collect(), &s[c * n..])
  |                           ^
note: but, the lifetime must be valid for the lifetime 'a as defined on the body at 3:58...
 --> src\q129259.rs:3:59
  |
3 |   fn q129259<'a>(s: &'a str, n: usize) -> (Vec<&str>, &str) {
  |  ___________________________________________________________^
4 | |     (|s: &str, n| {
5 | |          let c = s.len() / n;
6 | |          ((0..n).map(|i| &s[i * c..i * c + c]).collect(), &s[c * n..])
7 | |      })(s, n)
8 | | }
  | |_^
note: ...so that expression is assignable (expected (std::vec::Vec<&'a str>, &'a str), found (std::vec::Vec<&str>, &str))
 --> src\q129259.rs:4:5
  |
4 | /     (|s: &str, n| {
5 | |          let c = s.len() / n;
6 | |          ((0..n).map(|i| &s[i * c..i * c + c]).collect(), &s[c * n..])
7 | |      })(s, n)
  | |_____________^

3

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

(.+)¶(.+)
$2$*1¶$.1$*1¶$1
(1+)¶(\1)+
$1¶$#2$*1¶
\G1(?=1*¶(1+))
$1¶
¶¶1+

O^$`.

¶1+$

O^$`.

Попробуйте онлайн! Объяснение: Первый этап преобразует количество частей в одинарный, а также принимает длину строки. Затем второй этап делит длину на количество частей, оставляя остаток. Третий этап снова умножает результат на количество частей. Это дает нам правильное количество строк правильной длины, но они еще не имеют содержимого. Количество частей теперь может быть удалено четвертым этапом. Пятая стадия меняет всех персонажей. Это приводит к переключению исходного содержимого со строками-заполнителями, но хотя теперь оно находится в нужном месте, оно в обратном порядке. Заполнители выполнили свою задачу и удалены шестым этапом. Наконец, седьмой этап возвращает персонажей обратно в их первоначальный порядок.


3

Perl 6 , 36 байт

{$^a.comb.rotor($a.comb/$^b xx$b,*)}

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

Возвращает список списков строк, где последний элемент является остатком (если он есть).

Объяснение:

{                                  }  # Anonymous code block
 $^a.comb                             # Split the string into a list of chars
         .rotor(                  )   # And split into
                            xx$b      # N lists
                $a.comb/$^b           # With string length/n size
                                ,*    # And whatever is left over  

2

JavaScript (ES6), 77 байт

(s,d,n=s.length)=>[s.match(eval(`/.{${n/d|0}}/g`)).slice(0,d),s.slice(n-n%d)]

Возвращает массив из двух элементов: разделенных строковых частей и оставшейся части.

Тестовый фрагмент

f=
(s,d,n=s.length)=>[s.match(eval(`/.{${n/d|0}}/g`)).slice(0,d),s.slice(n-n%d)]
<div oninput="O.innerHTML=I.value&&J.value?JSON.stringify(f(I.value,+J.value)):''">String: <input id=I> Number: <input id=J size=3></div>
<pre id=O>


2

Japt , 18 байт

¯W=Ul fV)òW/V pUsW

Проверьте это онлайн! (использование-Q флаг для визуализации вывода)

объяснение

¯W=Ul fV)òW/V pUsW  : Implicit: U = input string, V = input integer
   Ul fV            : Floor U.length to a multiple of V.
 W=                 : Assign this value to variable W.
¯       )           : Take the first W characters of U (everything but the remainder).
         òW/V       : Partition this into runs of length W / V, giving V runs.
              pUsW  : Push the part of U past index W (the remainder) to the resulting array.
                    : Implicit: output result of last expression

2

Python, 82 76 74 байта

def G(h,n):l=len(h);r=l/n;print[h[i:i+r]for i in range(0,n*r,r)],h[l-l%n:]

Ну, похоже, это соответствует бонусным баллам. Могу ли я получить печенье вместо этого? Ой, подождите, они не настоящие? Штопать...

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



2

Python, 95, 87, 76 73 байта

def f(s,n):
 a=[];i=len(s)/n
 while n:a+=s[:i],;s=s[i:];n-=1
 print a+[s]

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


Добро пожаловать в PPCG! Я добавил ссылку "Попробуйте онлайн" в ваш пост. Я думаю, что вы можете немного сократить свое решение, сделав его полной программой, а не функцией. Попробуйте онлайн!
musicman523

2

05AB1E , 12 байтов

²g¹‰`s¹.D)R£

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

объяснение

²g¹‰`s¹.D)R£
²g           # Push length of string
  ¹          # Push amount of pieces
   ‰         # divmod of the two
    `s       # Flatten the resulting array and flip it around
      ¹.D    # Repeat the resulting length of the pieces amount of pieces times(wow that sounds weird)
         )   # Wrap stack to array
          R  # Reverse (so the remainder is at the end)
           £ # Split the input string into pieces defined by the array

1
9 байтов путем изменения порядка ввода.
Кевин Круйссен

2

Брахилог , 16 байт

kʰ↙Xḍ₎Ylᵛ&ht↙X;Y

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

Принимает ввод как список [string, number]и выводит как список [remainder, parts]. (Для ясности запятые были заменены точкой с запятой в контрольных примерах «Hello, world!», Поскольку фрагменты строки не печатались в кавычках.)

                    The input
 ʰ                  with its first element
k ↙X                having the last X elements removed
    ḍ               and being cut into a number of pieces
     ₎              where that number is the last element of the input
      Y             is Y
       lᵛ           the elements of which all have the same length,
         &          and the input
          h         's first element
           t↙X      's last X elements
              ;     paired with
               Y    Y
                    are the output.

(Я также заменил запятую в коде точкой с запятой для согласованного формата вывода. С запятой , случаи без остатка будут просто выводить части без пустого остатка, и как бы хорошо это ни было для некоторых целей, я не на самом деле знаю, почему это так работает ...)

После получения целых 16 байтов я попытался сделать что-то на основе +₁ᵗ⟨ġl⟩работы, но, поскольку исправления становились все длиннее и дольше, я решил, что пока просто буду придерживаться своего первоначального решения.



2

Формула Excel, 185 173 165 161 149 байт

Следующее должно быть введено как формула массива ( Ctrl+ Shift+ Enter):

=MID(A1,(ROW(OFFSET(A1,,,B1+1))-1)*INT(LEN(A1)/B1)+1,INT(LEN(A1)/B1)*ROW(OFFSET(A1,,,B1+1))/IF(ROW(OFFSET(A1,,,B1+1))=B1+1,1,ROW(OFFSET(A1,,,B1+1))))

Где A1содержится ваш вклад (например 12345678) иB1 содержит делитель. Это также использует оператор деления Excel в качестве бонуса.

После ввода формулы в виде формулы массива выделите ее в строке формул и оцените, используя, F9чтобы вернуть результат, например:

Оценка формулы Excel, показывающая разделенные группы

-12 байт: замените каждый INDIRECT("1:"&B1+1)на, OFFSET(A1,,,B1+1)чтобы сэкономить 2 байта за один раз, а также уберите лишние скобки.

-8 байт: удалить избыточную INDEXфункцию.

-4 байта: переделать обработку «остатка».

-12 байт: удалить избыточность INT(LEN(A1)/B1)путем смещения массива, сгенерированного ROW(OFFSET(A1,,,B1+1))на -1.




1

Mathematica, 58 байт

{#~Partition~a,#2}&@@TakeDrop[#,(a=Floor[Length@#/#2])#2]&

Чистая функция, принимающая список символов и положительное целое число в качестве входных данных. Например, последний контрольный пример вызывается

{#~Partition~a,#2}&@@TakeDrop[#,(a=Floor[Length@#/#2])#2]&[{"1","2","3","4","5","6","7"},4]

и возвращает:

{{{"1"}, {"2"}, {"3"}, {"4"}}, {"5", "6", "7"}}

1

Haskell, 120 88 байтов (спасибо Эрджану Йохансену!)

Имеет ли div оператором деления?

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

q=splitAt;x!s|n<-div(length s)x,let g""=[];g s|(f,r)<-q n s=f:g r,(a,b)<-q(n*x)s=(g a,b)

2
Быстрый переписан с большинством основных трюков: t=splitAt;x!s|n<-div(length s)x,let g""=[];g s|(f,r)<-t n s=f:g r,(a,b)<-t(n*x)s=(g a,b). Итак, (1) многократно используемый идентификатор может быть сокращен, особенно если он длинный. (2) Охранники и паттерны почти всегда короче let... in, whereи if then else. (3) Сравнение с образцом часто лучше, чем проверка на равенство. (Хорошо, что letв паттерне шаблонов это не так просто, я недавно узнал об этом от кого-то еще здесь.) И посмотрите codegolf.stackexchange.com/questions/19255/… .
Орджан Йохансен

1
Кроме того, взгляните на советы по игре в гольф на Хаскелле, чтобы узнать некоторые полезные советы .
Sudee

@ ØrjanJohansen Спасибо! Я забыл, что точки с запятой действительны, а что letв охране довольно коварны. Но более короткий код более читабелен, верно?
qfwfq

1

Ом, 3 байта (не конкурирующие?)

lvσ

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

Встроенный ¯ \\ _ (ツ) _ / ¯. Я использовал неправильный встроенный ... Но эй, есть еще один, лежащий вокруг.Теперь я использовал неверный встроенный два раза (или один встроенный неправильно работает с остатками).

Получу ли я бонусные баллы, потому что vэто (этаж) деление?


1
Это не разбито так, как требуется. например, Hello, world! 5контрольный пример неправильный. Попробуйте онлайн!
Орджан Йохансен,

Ну, я собираюсь искать другой встроенный ....
Роман Gräf

1

CJam , 16 байтов

{_,2$//_2$<@@>s}

Анонимный блок ожидает аргументы в стеке и оставляет результат в стеке после.

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

объяснение

Ожидает аргументов как number "string".

_,              e# Copy the string and get its length.
  2$            e# Copy the number.
    /           e# Integer divide the length by the number.
     /          e# Split the string into slices of that size.
      _         e# Copy the resulting array.
       2$       e# Copy the number.
         <      e# Slice the array, keeping only the first <number> elements.
          @@    e# Bring the number and original array to the top.
            >   e# Slice away the first <number> elements,
             s  e# and join the remaining elements into a string.

1

J , 26 байт

(]$~[,(<.@%~#));]{.~0-(|#)

Помимо элиминирующих пространств и промежуточных ступеней, это не игра в гольф. Я ожидаю, что я как-то прошел долгий путь, что с моими скобками и ссылками на аргументы ( [и ]).

См. Блокнот Jupyter для тестовых случаев, таких как следующие:

   5 chunk test2
┌──┬───┐
│He│ld!│
│ll│   │
│o,│   │
│ w│   │
│or│   │
└──┴───┘

Спасибо. Читай слишком быстро. Комментарий удален
Иона

1

Р , 79 63 байта

-16 от Джузеппе, исправляющего индексацию

function(s,n,k=nchar(s),l=k%/%n)substring(s,0:n*l+1,c(1:n*l,k))

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

Построен вокруг предоставления векторных входов substring()


63 байта - немного упростила индексацию.
Джузеппе

@ Джузеппе Хаха, я, должно быть, пробовал каждый вариант добавления и умножения индекса, но пропустил этот вариант. Хороший улов.
Преступно-Вульгарно

0

PHP , 152 байта

Спасибо @ JörgHülsermann (скобки чаевые!)

$c=$s=explode('|',readline());
while($s[1]--)$s[0]=preg_replace('/^'.($l[]=substr($s[0],0,strlen($c[0])/$c[1])).'/','',$s[0]);
$l[r]=$s[0];
print_r($l);

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


1
Ваш путь PHP не работает, потому что он заменяет не только в начале. preg_replaceявляется альтернативой или вы можете использовать[,$s,$d]=$argv;print_r(array_slice(str_split($s,$l=strlen($s)/$d^0),0,$d)+[$d=>substr($s,$l*$d)]);
Йорг Хюльсерманн

Можете ли вы объяснить мне пример кода, почему не работает мой код PHP?
тыс.фунтов

1
Попробуйте онлайн! Он заменяет все Aв первом заезде
Йорг Хюльсерманн

1
Вы можете отказаться от конструкции array_walk, если используете скобки. Попробуйте онлайн!
Йорг Хюльсерманн

Хороший совет! Я полностью забыл
кип

0

Python 3 , 94 байт

i=input().split('|')
s,n=i[0],int(i[1])
c=len(s)//n
while n:print(s[:c]);s=s[c:];n-=1
print(s)

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


Предполагая, что ввод в переменной не является допустимым методом ввода .
Орджан Йохансен,

Что это означает? Как обычно, I / O является гибким. ? В любом случае, спасибо, я редактирую свой ответ ...
kip

1
Стандартные методы PPCG в являются довольно гибкими. Просто не так много.
Орджан Йохансен,

0

PowerShell v3 + , 72 , 80 байт

Предполагает $s содержит входную строку; $nсодержит количество символов на «кусок». Это также предполагает, что «StrictMode» выключен. В противном случае будет возвращена ошибка из-за индексации дальше в массив, чем фактически существует (то есть, если массив имеет 4 элемента, и я вызываю несуществующий 5-й элемент). С выключенным StrictMode PS не волнует, и он проигнорирует ошибку.

for($i = 0;$i -le $s.Length;$i+=$n+1){-join($s|% ToCharA*)[$i..($i+$n)]}

Используя нотацию, ($s|% ToCharA*)я смог сохранить 1 символ по сравнению с $s.ToCharArray():)

Обновить:

Обновленный код для удовлетворения требований Снова предполагает, $sсодержит входную строку; однако это время $nсодержит количество «штук». Остальная часть печатается последней. И я использовал оператор деления PowerShell

0..($n-1)|%{$p=[math]::Floor($s.length/$n)}{$s|% Su*($_*$p) $p}{$s|% Su*($n*$p)}

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


Я полагаю, вы не поняли вопрос, вход количество частей (без остатка).
Орджан Йохансен

О, ты прав. Вчера вечером я неправильно прочитал вопрос :) Я опубликую свое обновленное решение, когда у меня будет шанс.
GAT
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.