문자열 나누기


23

도전

문자열과 숫자가 주어지면 문자열을 동일한 크기의 여러 부분 으로 나눕니다 . 예를 들어 숫자가 3이면 문자열 길이에 관계없이 문자열을 3 개로 나눕니다.

문자열의 길이가 제공된 숫자로 균등하게 분할되지 않으면 각 조각의 크기를 반올림하고 "나머지"문자열을 반환해야합니다. 예를 들어 입력 문자열의 길이가 13이고 숫자가 4 인 경우 각각 크기가 3 인 4 개의 문자열과 나머지 크기가 1 인 문자열을 반환해야합니다.

나머지가 없으면 단순히 반환하지 않거나 빈 문자열을 반환 할 수 있습니다.

제공된 숫자는 문자열 길이보다 작거나 같아야합니다. 예를 들어, 7 개의 문자열로 나눌 수 없으므로 입력 "PPCG", 7이 발생 "PPCG"하지 않습니다. (적절한 결과는 다음과 같습니다 (["", "", "", "", "", "", ""], "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
보너스 포인트? 오 이런 내가해야 해
Matthew Roh


Related 그러나, 어느 부분도이 도전과 완전히 동일하지 않습니다.
musicman523

이 명확 테스트 케이스를 추가하십시오 만들려면 PPCG, 7나머지는 그래서PPCG
요 르그 Hülsermann

@ JörgHülsermann 해당 입력이 허용되지 않습니다. 이러한 유형의 입력과 관련된 세부 정보를 추가하고보다 명확하게 재구성했습니다.
musicman523

답변:




5

, 21 바이트

20 바이트 코드, -n플래그는 +1

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와 a를 가져 와서 s Int목록을 반환 하는 연산자 String입니다.

로 사용하십시오 "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다음 take결과에서 초기 하위 문자열이 n입니다.
    • d나머지 부분을 제외한 부분 문자열 길이는이어야합니다 .
      • 실제 나머지는 n대신 짧아야합니다. 그렇지 않으면 일반 조각이 대신 길어집니다.
      • take주어진 길이가 너무 길면 전체 문자열을 반환하므로 >=n-1나머지 부분에 숫자 를 사용할 수 있습니다 .
      • 이 표현식 d+n*0^(n-i)dif i<nd+nif를 제공 합니다 i==n. 이 것을 사용하는 0^x것입니다 1x==0,하지만 0경우 x>0.

리스트 이해력을 사용할 수있는 곳을 감시해야합니다.
qfwfq

4

파이썬 2 , 68 67 65 바이트

  • @ musicman123은 2 바이트를 절약했습니다. []
  • 1 바이트에 대한 @Chas Brown 덕분에 : x[p*i:p+p*i]asx[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
다음으로 교체 x[p*i:p+p*i]하여 1 바이트를 절약하십시오x[p*i:][:p]
Chas Brown

1
+1 :p😛 다른 파이썬 답변을 능가합니다!
musicman523

하하 .. 전혀 의도되지 않았다 .... : p
officialaimm

1
이 답변은 현재되었습니다 outgolfed
musicman523

4

C ++ 14, 209180 바이트

너무 길지만 나누기 연산자를 사용합니다.

#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




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로 보내고 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^$`.

온라인으로 사용해보십시오! 설명 : 첫 번째 단계는 부품 수를 단항으로 변환하고 문자열의 길이도 사용합니다. 그런 다음 두 번째 단계는 길이를 부품 수로 나누고 나머지는 남겨 둡니다. 세 번째 단계는 결과에 부품 수를 다시 곱합니다. 이것은 우리에게 정확한 길이의 정확한 수의 문자열을 제공하지만, 아직 내용이 없습니다. 이제 4 단계에서 부품 수를 삭제할 수 있습니다. 다섯 번째 단계는 모든 문자를 뒤집습니다. 이는 자리 표시 자 문자열을 사용하여 원본 내용을 전환하는 효과가 있지만 지금은 올바른 위치에 있지만 반대 순서입니다. 자리 표시자는 목적을 달성했으며 6 단계에서 삭제됩니다. 마지막으로 일곱 번째 단계는 문자를 원래 순서로 되돌립니다.


3

펄 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

자바 스크립트 (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

apt , 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

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 바이트 .
Kevin Cruijssen

2

Brachylog , 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 바이트 : "remainder"처리 재 작업.

-12 바이트 : -1 INT(LEN(A1)/B1)ROW(OFFSET(A1,,,B1+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

Haskell, 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) 패턴 일치는 종종 평등 테스트보다 낫습니다. (OK, let패턴 가드가 그렇게 기본적이지 않다는 것을 최근에 여기 다른 사람에게서 배웠습니다.) 그리고 codegolf.stackexchange.com/questions/19255/…을 확인하십시오 .
Ørjan Johansen

1
또한 Haskell의 골프 팁을 살펴보고 유용한 트릭을 찾으십시오 .
sudee

@ ØrjanJohansen 감사합니다! 나는 세미콜론이 유효하다는 것을 잊어 버렸고 let경비원은 상당히 악의적이었습니다. 그러나 더 짧은 코드는 더 읽기 쉽습니다.
qfwfq

1

옴, 3 바이트 (비경쟁?)

lvσ

빌트인은 아직 TIO에서 구현되지 않았기 때문에 경쟁이 아닙니다. 레포의 최신 풀에서 작동하는지 테스트 할 수있는 PC가 없습니다.

내장 ¯ \\ _ (ツ) _ / ¯. 나는 잘못된 내장을 사용했다. 그러나 아직도 다른 하나가 놓여있다. 이제 잘못된 내장을 두 번 사용했습니다 (또는 하나의 내장이 나머지와 잘못 작동합니다).

v(바닥) 분할 이기 때문에 보너스 포인트를 받습니까?


1
필요한 방식으로 분할되지 않습니다. 예를 들어 Hello, world! 5테스트 케이스가 잘못되었습니다. 온라인으로 사용해보십시오!
Ørjan Johansen

글쎄, 나는 또 다른 내장을 찾을거야 ....
로마 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│   │
└──┴───┘

감사. 너무 빨리 읽으십시오. 댓글 제거
요나


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 Way가 작동하지 않아 처음부터 교체 할 수 없습니다. 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첫 번째 실행에
요 르그 Hülsermann에게

1
대괄호를 사용하면 array_walk 구문을 삭제할 수 있습니다. 온라인으로 사용해보십시오!
Jörg Hülsermann

좋은 팁! 나는 완전히 잊었다
kip


0

PowerShell v3 + , 72 , 80 바이트

$s입력 문자열을 포함 한다고 가정 합니다. $n"조각"당 문자 수를 포함합니다. 또한 "StrictMode"가 꺼져 있다고 가정합니다. 그렇지 않으면 실제로 존재하는 것보다 더 배열로 인덱싱하여 오류가 반환됩니다 (즉, 배열에 4 개의 요소가 있고 존재하지 않는 5 번째 요소를 호출하는 경우). 엄격 모드를 끄면 PS는 신경 쓰지 않으며 오류를 무시합니다.

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

표기법을 사용 ($s|% ToCharA*)하여 $s.ToCharArray()다음에 비해 1 문자를 저장할 수있었습니다 .)

최신 정보:

실제로 도전 과제 요구 사항을 충족하도록 코드가 업데이트되었습니다. 다시 $s입력 문자열이 있다고 가정 합니다. 그러나 이번에 $n는 "조각"의 수를 포함합니다. 나머지는 마지막에 인쇄됩니다. 그리고 PowerShell의 부서 연산자를 사용했습니다.

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

온라인으로 사용해보십시오!


나는 당신이 질문을 오해했다고 생각합니다. 입력은 조각 의 입니다 (나머지는 제외).
Ørjan Johansen

아, 맞아 어젯밤에 질문을 잘못 읽었습니다 :) 기회가있을 때 업데이트 된 솔루션을 게시 할 것입니다.
GAT
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.