Розділіть рядок


23

Виклик

Давши рядок і число, розділіть рядок на стільки частин однакового розміру. Наприклад, якщо число дорівнює 3, слід розділити рядок на 3 частини, незалежно від того, яка довжина струни.

Якщо довжина струни не ділиться рівномірно на вказане число, слід округлити розмір кожного шматка і повернути рядок "залишок". Наприклад, якщо довжина вхідного рядка дорівнює 13, а число - 4, вам слід повернути чотири рядки розміром 3, плюс залишок ряду розміром 1.

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

Забезпечене число гарантується меншим або рівним довжині рядка. Наприклад, введення "PPCG", 7не відбудеться, оскільки "PPCG"його неможливо розділити на 7 рядків. (Я вважаю, що це був би правильний результат (["", "", "", "", "", "", ""], "PPCG"). Простіше просто заборонити це як введення даних.)

Як завжди, введення / виведення є гнучким. Ви можете повернути пару рядків і рядок, що залишився, або один список рядків із залишком в кінці.

Тестові справи

"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}), який відповідає трьом запускам двох символів і зберігає їх у трьох групах захоплення. Тоді, використовуючи регекс-відповідні змінні Pip, ми можемо надрукувати 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

Хаскелл , 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 Браун за 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

Ха - ха .. це не призначалися взагалі ....: р
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

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

Пітон, 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]. (Коми були замінені крапками з комою в тестах "Привіт, світ!" Для наочності, оскільки фрагменти рядків не друкуються цитатами.)

                    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

Математика, 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

Хаскелл, 120 88 байт (спасибі Ørjan Johansen!)

Чи 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/… .
Ørjan Johansen

1
Також подивіться поради щодо гольфу в Хаскеллі для деяких корисних прийомів.
sudee

@ ØrjanJohansen Дякую! Я забув, що крапки з комою є дійсними, і що letв охороні досить хитро. Але коротший код легше читати, правда?
qfwfq

1

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

lvσ

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

Вбудований ¯ \\ _ (ツ) _ / ¯. Я використовував неправильну вбудовану ... Але все-таки є ще одна, що лежить навколо. Тепер я використав неправильний вбудований два рази (або одна вбудована працює неправильно з залишками).

Чи отримую я бонусні бали через vподіл (підлога)?


1
Це не розбивається так, як потрібно. наприклад, Hello, world! 5тестова шафа неправильна. Спробуйте в Інтернеті!
Ørjan Johansen

Ну я буду шукати інший вбудований ....
Роман Гряф

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-(|#)

Окрім усунення простору та проміжних кроків, це не було полем для гри. Я очікую, що я якось пройшов довгий шлях, що з дужками та аргументами аргументів ( [і] ).

Див. Зошит Юпітера щодо тестових випадків, таких як:

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

Спасибі. Читати занадто швидко. Коментар видалено
Jonah

1

R , 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 байти - трохи спростили індексацію.
Джузеппе

@Giuseppe Haha, я, мабуть, спробував кожен варіант додавання та множення на індекс, але пропустив цей. Хороший улов.
Кримінально-

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)]);
Jörg Hülsermann

Чи можете ви пояснити мені на прикладі коду, чому не працює мій PHP-код?
kip

1
Спробуйте в Інтернеті! Він замінює всіхA у першому циклі
Йорг Гюльсерманн

1
Ви можете скинути конструкцію array_walk, якщо використовуєте дужки. Спробуйте це в Інтернеті!
Йорг Гюльсерманн

Приємна порада! Я зовсім забув
kip

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)

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


Якщо припустити, що вхід є змінною, це не допустимий метод введення .
Ørjan Johansen

Що це означає? Як завжди, введення / виведення є гнучким. ? У будь-якому випадку дякую, я редагую свою відповідь ...
kip

1
Стандартні методи PPCG в є досить гнучкими. Тільки не дуже.
Ørjan Johansen

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

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


Я вважаю, що ви неправильно зрозуміли питання, вхід - це кількість штук (крім решти).
Ørjan Johansen

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