文字列を分割する


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

得点

これはであるため、各言語の最短の回答が優先されます。

ソリューションで実際に言語の除算演算子を使用するためのボーナスポイント(実際にはnotではありません)。


1
ボーナスポイント?ああ男は、私がこれを行う奨め
マシュー盧


関連するが、どちらの部分もこの課題とまったく同じではない。
musicman523

それが明確にテストケースを追加してくださいようにするにはPPCG7余りがあるのでPPCG
イェルクHülsermann

@JörgHülsermannその入力は許可されていません。そのタイプの入力に関する詳細を追加し、より明確にするために再フォーマットしました。
musicman523

回答:




5

ピップ、21バイト

20バイトのコード、-nフラグの場合は+1 。

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

コマンドライン引数として入力を受け取ります。文字列と残りを改行で区切って出力します。オンラインでお試しください!

説明

正規表現操作をお楽しみください!

abcdefg文字列と3番号として取りましょう。regexを作成します(.{2})(.{2})(.{2})。これは、2つの文字の3つの実行に一致し、3つのキャプチャグループに保存します。次に、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

Haskell、62バイト

#オペレータは取っているStringInt、とのリストを返す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がの先頭からpingされs、次に初期サブストリングがtake結果からnになります。
    • 部分文字列の長さはd、残りの部分を除き、である必要があります。
      • 実際の余りは、より短くする必要がありますn。そうしないと、通常のピースが代わりに長くなります。
      • take指定された長さが長すぎる場合は文字列全体を返す>=n-1ため、残りの部分には任意の数を使用できます。
      • d+n*0^(n-i)dif i<nおよびd+nifを提供しi==nます。それ0^x1when x==0ですが、0ifを使用しx>0ます。

リスト内包表記を使用できる場所に注意する必要があります。
-qfwfq

4

Pythonの268の67 65バイト

  • @ musicman123は2バイトを保存しました: []
  • @Chas Brownに1バイトをありがとう: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😛まあ他のPythonの回答をoutgolfingやりました!
musicman523

ハハ..それはまったく意図されていなかった....:p
officialaimm

1
この答えは、今されていますoutgolfed
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




3

Rust、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ソースの正しいスライスにインデックスを付けstrcollectaに入力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^$`.

オンラインでお試しください!説明:最初のステージでは、パーツの数を単項に変換し、文字列の長さも取得します。次に、第2段階では、長さを部品数で除算し、残りを残します。第3段階では、結果に再び部品数を掛けます。これにより、正しい長さの正しい数の文字列が得られますが、コンテンツはまだありません。パーツの数は、第4段階で削除できるようになりました。5番目の段階では、すべてのキャラクターが反転します。これは、プレースホルダー文字列で元のコンテンツを切り替える効果がありますが、現在は正しい場所にありますが、逆の順序になっています。プレースホルダーは目的を果たしており、6番目のステージまでに削除されます。最後に、第7段階では、キャラクターを元の順序に戻します。


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

分割された文字列部分と残りの部分の2つの要素の配列を返します。

テストスニペット

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:]

まあ、これはボーナスポイントの資格があるように見えます。代わりにCookieを受け取ってください。 ああ、彼らは本物ではないのですか?くそ...

オンラインでお試しください!


1
あなたはクッキーを好むでしょうか、それともファクタリングして6バイトを節約しlen(h)ますか?:)
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

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に入力(例12345678B1が含まれ、除数が含まれます。これには、Excelの除算演算子もボーナスとして使用されます。

数式を配列数式として入力した後、数式バーで数式を強調表示し、次のように評価してF9結果を返します。

Excel formula evaluation showing split groups

-12バイト:それぞれINDIRECT("1:"&B1+1)を置換して、OFFSET(A1,,,B1+1)1回の出現につき2バイトを節約し、さらに余分な括弧を削除します。

-8バイト:冗長INDEX機能を削除します。

-4バイト:「残り」の処理をやり直します

-12バイト: -1によってINT(LEN(A1)/B1)生成さROW(OFFSET(A1,,,B1+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バイト(ØrjanJohansenに感謝!)

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... inwhereif then else。(3)多くの場合、パターンマッチングは同等性テストよりも優れています。(OK、letパターンガードはそれほど基本的ではないので、最近ここで他の人から学びました。)codegolf.stackexchange.com/questions/19255/…をチェックしてください
Ørjanヨハンセン

1
また、いくつかの便利なトリックについては、Haskellでのゴルフのヒントをご覧ください。
スディー

@ØrjanJohansenありがとう!セミコロンが有効でありlet、警備員のそれがかなり不正であることを忘れていました。しかし、短いコードの方が読みやすいでしょう?
qfwfq

1

オーム、3バイト(競合しない?)

lvσ

ビルトインはまだTIOに実装されておらず、レポジトリの最新のプルで動作するかどうかをテストするのに便利なPCがないため、競合しません。

組み込み¯\\ _(ツ)_ /¯。私は間違ったビルトインを使用しました...しかし、ちょっと他の人がまだ周りに横たわっています。今、私は間違ったビルトインを2回使用しました(または、1つのビルトインが残りで間違って動作します)。

v(フロア)分割であるため、ボーナスポイントを獲得できますか?


1
これは必要な方法で分割されません。たとえば、Hello, world! 5テストケースが間違っています。オンラインでお試しください!
Ørjanヨハンセン

さて、私は探しに行くよ別のビルトイン....
ローマグラーフ

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

R79 63バイト

インデックス作成を修正するGiuseppeの-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、私はインデックスの加算と乗算のすべてのバリエーションを試したに違いありませんが、その1つを逃しました。良いキャッチ。
CriminallyVulgar

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)]);
ヨルグヒュルサーマン

PHPコードが機能しない理由をサンプルコードで説明していただけますか?
キップ

1
オンラインでお試しください!それはA最初の実行ですべてを置き換える
ヨルグヒュルサーマン

1
角かっこを使用している
ヨルクヒュルサーマン

素敵なヒント!私は完全に忘れていた
キップ

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ヨハンセン

どういうことかいつものように、I / Oは柔軟です。?とにかく感謝、私は私の答えを編集します
...-キップ

1
PPCGの標準的な方法非常に柔軟です。そんなに多くない。
Ørjanヨハンセン

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ヨハンセン

ああ、あなたは正しい。昨夜質問を読み違えました:)機会があれば、更新されたソリューションを投稿します。
GAT
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.