Bagilah sebuah string


23

Tantangan

Diberikan string dan angka, bagi string menjadi banyak bagian yang berukuran sama. Misalnya, jika angkanya 3, Anda harus membagi string menjadi 3 bagian tidak peduli berapa lama string itu.

Jika panjang tali tidak terbagi rata menjadi angka yang disediakan, Anda harus membulatkan ukuran masing-masing bagian dan mengembalikan string "sisa". Misalnya, jika panjang string input adalah 13, dan angkanya adalah 4, Anda harus mengembalikan empat string masing-masing ukuran 3, ditambah string sisa ukuran 1.

Jika tidak ada yang tersisa, Anda mungkin tidak mengembalikan satu, atau mengembalikan string kosong.

Jumlah yang disediakan dijamin kurang dari atau sama dengan panjang tali. Misalnya, input "PPCG", 7tidak akan terjadi karena "PPCG"tidak dapat dibagi menjadi 7 string. (Saya kira hasil yang tepat adalah (["", "", "", "", "", "", ""], "PPCG"). Lebih mudah untuk tidak mengizinkan ini sebagai masukan.)

Seperti biasa, I / O itu fleksibel. Anda dapat mengembalikan pasangan string dan string sisa, atau satu daftar string dengan sisanya di akhir.

Uji kasus

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

Mencetak gol

Ini adalah , jadi jawaban tersingkat di setiap bahasa menang.

Poin bonus (tidak benar-benar 😛) untuk membuat solusi Anda benar-benar menggunakan operator divisi bahasa Anda.


1
Poin bonus? Ya ampun, aku harus melakukan ini
Matius Roh


Terkait , tetapi tidak ada bagian yang sama dengan tantangan ini.
musicman523

Untuk membuatnya lebih jelas, silakan tambahkan testcase PPCG, 7jadi sisanya adalahPPCG
Jörg Hülsermann

@ JörgHülsermann Input itu tidak diizinkan. Saya telah menambahkan lebih banyak detail yang berkaitan dengan jenis input dan memformat ulang hal-hal untuk lebih jelas.
musicman523

Jawaban:


6

Python 2 , 63 byte

s,n=input()
b=len(s)/n
while n:print s[:b];s=s[b:];n-=1
print s

Cobalah online!


Sudah selesai dilakukan dengan baik! Saya benar-benar tidak berpikir ini bisa bermain golf lebih jauh.
musicman523

5

PHP> = 7.1, 75 byte

[,$s,$d]=$argv;print_r(preg_split('/.{'.(strlen($s)/$d^0).'}\K/',$s,$d+1));

Testcases

PHP> = 7.1, 52 byte

hanya cetak sisanya

[,$s,$d]=$argv;echo substr($s,(strlen($s)/$d^0)*$d);

Uji Kasus


5

Pip , 21 byte

20 byte kode, +1 untuk -nbendera.

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

Mengambil input sebagai argumen baris perintah; string keluaran dan sisanya dipisahkan baris baru. Cobalah online!

Penjelasan

Bersenang-senang dengan operasi regex!

Mari kita ambil abcdefgstring dan 3nomor kita. Kami membangun regex (.{2})(.{2})(.{2}), yang mencocokkan tiga run dari dua karakter dan menyimpannya dalam tiga grup tangkap. Kemudian, menggunakan variabel pencocokan regex Pip, kita dapat mencetak 1) daftar grup tangkap ["ab";"cd";"ef"], dan 2) sisa string yang tidak cocok "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 byte

#adalah operator yang mengambil Stringdan Int, dan mengembalikan daftar String.

Gunakan sebagai "Hello, world!"#4.

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

Cobalah online!

Bagaimana itu bekerja

  • sadalah string input dan njumlah potongan yang tidak tersisa.
  • dadalah panjang masing-masing bagian "normal". divadalah pembagian integer.
  • Pemahaman daftar membangun n+1potongan-potongan, dengan yang terakhir sisanya.
    • iberalih dari 0ke n, inklusif.
    • Untuk setiap bagian, pertama jumlah yang tepat ( i*d) dari karakter awal adalah dropped sejak awal s, kemudian substring awal adalah taken dari hasilnya.
    • Panjang substring yang diambil harus d, kecuali untuk bagian sisanya.
      • Sisanya yang sebenarnya harus lebih pendek dari n, karena jika tidak, potongan normal akan diperpanjang sebagai gantinya.
      • takemengembalikan seluruh string jika panjang yang diberikan terlalu besar, sehingga kita dapat menggunakan angka apa pun >=n-1untuk bagian sisanya.
      • Ekspresi d+n*0^(n-i)memberi djika i<ndan d+njika i==n. Menggunakannya 0^xadalah 1kapan x==0, tetapi 0jika x>0.

Saya harus memperhatikan di mana saya dapat menggunakan daftar pemahaman.
qfwfq

4

Python 2 , 68 67 65 byte

  • @ musicman123 menyimpan 2 byte: keluaran tanpa disertai []
  • Terima kasih kepada @Chas Brown untuk 1 Byte: 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:]

Cobalah online!


1
Hemat 1 byte dengan menggantinya x[p*i:p+p*i]denganx[p*i:][:p]
Chas Brown

1
+1 untuk :p😛 Cukup bagus untuk mengalahkan jawaban Python lainnya!
musicman523

Haha .. itu sama sekali tidak dimaksudkan ....: p
officialaimm

1
Jawaban ini sekarang dikalahkan
musicman523

4

C ++ 14, 209 180 byte

Itu agak terlalu lama, tetapi menggunakan operator divisi:

#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;}

Pemakaian:

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

Versi online: http://ideone.com/hbBW9u


4

Pyth, 9 byte

cz*L/lzQS

Cobalah online

Bagaimana itu bekerja

Pertama Qadalah autoinitialized ke eval(input())dan zautoinitialized ke 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

Karat , 107 byte

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

Cobalah online!

Diformat:

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

Ini hanya mapindeks ke irisan yang benar dari sumber str( collecting ke a Vec) dan mengiris sisanya.

Sayangnya, saya tidak bisa membuat ini menjadi penutupan (74 byte):

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

sebagai kompiler gagal dengan

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

dan jika saya memberikan jenis s:&str, masa hidupnya salah:

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

Retina , 92 byte

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

O^$`.

¶1+$

O^$`.

Cobalah online! Penjelasan: Tahap pertama mengubah jumlah bagian menjadi unary dan juga mengambil panjang string. Tahap kedua kemudian membagi panjang dengan jumlah bagian, menyisakan sisanya. Tahap ketiga mengalikan hasil dengan jumlah bagian lagi. Ini memberi kami jumlah string yang benar dengan panjang yang benar, tetapi mereka belum memiliki konten. Jumlah bagian sekarang dapat dihapus oleh tahap keempat. Tahap kelima membalikkan semua karakter. Ini memiliki efek beralih konten asli dengan string placeholder, tetapi meskipun sekarang di tempat yang tepat, itu dalam urutan terbalik. Placeholder telah memenuhi tujuan mereka dan dihapus pada tahap keenam. Akhirnya tahap ketujuh membalikkan karakter kembali ke urutan aslinya.


3

Perl 6 , 36 byte

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

Cobalah online!

Mengembalikan daftar daftar string, di mana elemen terakhir adalah sisanya (jika ada).

Penjelasan:

{                                  }  # 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 byte

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

Mengembalikan array dari dua elemen: bagian string yang dibagi dan bagian sisanya.

Cuplikan Tes

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 byte

¯W=Ul fV)òW/V pUsW

Uji secara online! (menggunakan -Qbendera untuk memvisualisasikan output)

Penjelasan

¯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, 95, 87, 76 73 Bytes

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

Cobalah online!


Selamat datang di PPCG! Saya menambahkan tautan "Coba online" ke pos Anda. Saya pikir Anda dapat sedikit mempersingkat solusi Anda dengan menjadikannya program yang lengkap dan bukan fungsi. Cobalah online!
musicman523

2

05AB1E , 12 byte

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

Cobalah online!

Penjelasan

²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 byte dengan membalik urutan input.
Kevin Cruijssen

2

Brachylog , 16 byte

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

Cobalah online!

Mengambil input sebagai daftar [string, number]dan menghasilkan sebagai daftar [remainder, parts]. (Tanda koma diganti dengan titik koma dalam kasus uji "Halo, dunia!" Untuk kejelasan, karena fragmen string tidak dapat dicetak dengan tanda kutip.)

                    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.

(Saya juga mengganti koma dalam kode dengan titik koma untuk format output yang konsisten. Dengan koma , case tanpa sisa hanya akan menampilkan bagian-bagian tanpa sisa yang kosong, dan sebaik itu untuk beberapa tujuan, saya tidak sebenarnya tahu mengapa ia bekerja seperti itu ...)

Setelah ini menjadi +₁ᵗ⟨ġl⟩total 16 byte, saya mencoba untuk membuat sesuatu berdasarkan pekerjaan, tetapi karena perbaikannya semakin lama saya memutuskan bahwa saya hanya akan tetap dengan solusi asli saya untuk saat ini.



2

Formula Excel, 185 173 165 161 149 byte

Berikut ini harus dimasukkan sebagai rumus array ( 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))))

Di mana A1berisi input Anda (mis12345678 ) DanB1 berisi pembagi. Ini juga menggunakan operator divisi Excel untuk mendapat bonus.

Setelah memasukkan rumus sebagai rumus larik, sorot di bilah rumus dan evaluasi menggunakan F9 untuk mengembalikan hasilnya, misalnya:

Evaluasi rumus Excel menunjukkan grup terpisah

-12 byte: ganti masing INDIRECT("1:"&B1+1)- masing denganOFFSET(A1,,,B1+1) untuk menyimpan 2 byte per kejadian, ditambah beberapa merapikan menghapus tanda kurung redundan.

-8 byte: hapus redundanINDEX fungsi yang .

-4 byte: pengerjaan ulang "sisa".

-12 byte: menghapus redundan INT(LEN(A1)/B1)dengan mengimbangi array yang dihasilkan ROW(OFFSET(A1,,,B1+1))oleh -1.




1

Mathematica, 58 byte

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

Fungsi murni mengambil daftar karakter dan bilangan bulat positif sebagai input. Misalnya, test case terakhir dipanggil oleh

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

dan mengembalikan:

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

1

Haskell, 120 88 bytes (terima kasih kepada Ørjan Johansen!)

Apakah div dihitung sebagai operator divisi?

Saya ingin tahu bagaimana saya bisa mengurangi ini, saya belum mempelajari semua triknya.

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
Sebuah menulis ulang cepat dengan paling trik dasar: 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). Jadi, (1) Identifier yang digunakan berulang kali dapat disingkat, terutama jika panjang. (2) Pelindung dan pelindung pola hampir selalu lebih pendek dari let... in, wheredan if then else. (3) Pencocokan pola seringkali lebih baik daripada pengujian kesetaraan. (Oke, bahwa letdalam pola pengawal tidak terlalu mendasar, saya baru-baru ini mempelajarinya dari orang lain di sini.) Dan lihat codegolf.stackexchange.com/questions/19255/… .
Ørjan Johansen

1
Juga, lihat Tip untuk bermain golf di Haskell untuk beberapa trik berguna.
sudee

@ ØrjanJohansen Terima kasih! Saya lupa bahwa titik koma itu valid, dan bahwa letdi penjaga itu cukup licik. Tetapi kode yang lebih pendek lebih mudah dibaca, bukan?
qfwfq

1

Ohm, 3 byte (tidak bersaing?)

lvσ

Non-bersaing karena built-in belum diimplementasikan di TIO dan saya tidak punya PC berguna untuk menguji apakah itu bekerja di tarikan terbaru dalam repo.

Built-in ¯ \\ _ (ツ) _ / ¯. Saya menggunakan built-in yang salah ... Tapi hei masih ada yang lain berbaring. Sekarang saya menggunakan built-in yang salah dua kali (atau satu built-in yang salah dengan sisanya).

Apakah saya mendapatkan poin bonus karena vdivisi (lantai)?


1
Ini tidak terpecah seperti yang dibutuhkan. mis. Hello, world! 5testcase salah. Cobalah online!
Ørjan Johansen

Yah saya akan mencari built-in lain ....
Roman Gräf

1

CJam , 16 byte

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

Blok anonim mengharapkan argumen pada stack dan membiarkan hasilnya pada stack setelahnya.

Cobalah online!

Penjelasan

Mengharapkan argumen sebagai 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 byte

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

Selain menghilangkan ruang dan langkah menengah, ini belum golf. Saya berharap bahwa saya telah mengambil jalan panjang entah bagaimana, apa dengan tanda kurung dan referensi argumen ( [dan] ).

Lihat buku catatan Jupyter untuk kasus-kasus pengujian, seperti yang berikut:

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

Terima kasih. Baca terlalu cepat. Komentar dihapus
Jonah

1

R , 79 63 byte

-16 dari Giuseppe memperbaiki pengindeksan

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

Cobalah online!

Dibangun sekitar memberikan input vektor substring()


63 byte - menyederhanakan pengindeksan sedikit.
Giuseppe

@ Giuseppe Haha, saya pasti telah mencoba setiap varian menambahkan dan mengalikan indeks, tetapi melewatkan yang satu itu. Tangkapan yang bagus.
Penjahat Penjara

0

PHP , 152 byte

Terima kasih @ JörgHülsermann (ujung kurung!)

$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);

Cobalah online!


1
Cara PHP Anda tidak berfungsi karena ia menggantikan tidak hanya di awal. preg_replaceadalah alternatif atau Anda dapat menggunakan[,$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

Bisakah Anda menjelaskan kepada saya dengan kode contoh mengapa tidak bekerja kode PHP saya?
kip

1
Cobalah online! Ini menggantikan semua Adalam menjalankan pertama
Jörg Hülsermann

1
Anda dapat menghentikan konstruksi array_walk jika Anda menggunakan tanda kurung Coba online!
Jörg Hülsermann

Tip yang bagus! Saya benar-benar lupa
kip


0

PowerShell v3 + , 72 , 80 byte

Diasumsikan $s berisi string input; $nberisi jumlah karakter per "bagian". Ini juga mengasumsikan bahwa "StrictMode" tidak aktif. Kalau tidak, kesalahan akan dikembalikan karena pengindeksan lebih jauh ke dalam array daripada yang sebenarnya ada (yaitu jika array memiliki 4 elemen dan saya sebut elemen 5 tidak ada). Dengan menonaktifkan StrictMode, PS tidak peduli dan itu akan mengabaikan kesalahan.

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

Menggunakan notasi ($s|% ToCharA*) saya bisa menyimpan 1 karakter dibandingkan dengan $s.ToCharArray():)

Memperbarui:

Kode yang diperbarui untuk benar-benar memenuhi persyaratan tantangan. Sekali lagi anggap $sberisi string input; Namun, kali ini $nberisi jumlah "potongan". Sisanya dicetak terakhir. Dan saya menggunakan operator divisi PowerShell

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

Cobalah online!


Saya percaya Anda telah salah paham pertanyaannya, inputnya adalah jumlah bagian (tidak termasuk sisanya).
Ørjan Johansen

Oh kamu benar Saya salah membaca pertanyaan tadi malam:) Saya akan memposting solusi saya yang diperbarui ketika saya memiliki kesempatan.
GAT
Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.