Bir dize böl


23

Meydan okuma

Bir dize ve bir sayı verildiğinde, dize, eşit sayıda parçaya bölün . Örneğin, sayı 3 ise, dizenin uzunluğu ne olursa olsun dizeyi 3 parçaya bölmeniz gerekir.

İpin uzunluğu verilen sayıya eşit şekilde bölünmezse, her bir parçanın boyunu yuvarlamanız ve bir "kalan" ipi döndürmeniz gerekir. Örneğin, giriş dizesinin uzunluğu 13 ve sayı 4 ise, her biri 3 boyutunda dört dize ve ayrıca 1 boyutunda kalan bir dize döndürmelisiniz.

Kalan hiçbir şey yoksa, bir tanesini geri döndüremez veya boş dizgiyi geri döndüremezsiniz.

Verilen sayının ipin uzunluğuna eşit veya daha az olması garanti edilir. Örneğin, giriş "PPCG", 7gerçekleşmeyecektir çünkü "PPCG"7 karaktere bölünemez. (Uygun sonucun olacağını varsayalım (["", "", "", "", "", "", ""], "PPCG"). Bunu girdi olarak kaldırmaktan daha kolay.)

Her zamanki gibi, G / Ç esnektir. Sonunda bir çift dizge ve kalan dizeyi veya geri kalan diziyi içeren bir dizi dizeyi döndürebilirsiniz.

Test durumları

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

puanlama

Bu , yani her dilde en kısa cevap kazanır.

Çözümünüzü gerçekten de dilinizin işlem operatörünü kullanması için bonus puanları (gerçekten 😛 değil).


1
Bonus puanlar? Oh adamım bunu yapmalıyım
Matthew Roh


İlgili , ancak hiçbiri bu zorluklarla aynı değil.
musicman523

Daha açık Testcase ekleyin yapmak için PPCG, 7kalan yaniPPCG
Jörg Hülsermann

@ JörgHülsermann Bu girişe izin verilmedi. Bu tür girdilerle ilgili daha fazla ayrıntı ekledim ve daha net olması için yeniden biçimlendirdim.
musicman523

Yanıtlar:




5

Pip , 21 bayt

20 baytlık kod, -nbayrak için +1 .

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

Girdileri komut satırı argümanı olarak alır; dizeleri çıkarır ve yeni satır ayrılmış. Çevrimiçi deneyin!

açıklama

Regex işlemleri ile eğlenceli!

abcdefgDize ve 3sayımız olarak kabul edelim . (.{2})(.{2})(.{2})İki karakterden oluşan üç sırayla eşleşen ve bunları üç yakalama grubunda depolayan regex'i oluştururuz. Ardından, Pip'in regex eşleşme değişkenlerini kullanarak 1) yakalama gruplarının listesini ["ab";"cd";"ef"]ve 2) eşleşmeyen dizenin kalanını yazdırabiliriz "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 bayt

#Bir operatör, bir alıyor Stringve Intve bir listesini dönenString s.

Olarak kullanın "Hello, world!"#4.

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

Çevrimiçi deneyin!

Nasıl çalışır

  • sgiriş dizesidir ve nkalan olmayan parçaların sayısıdır.
  • dHer "normal" parçanın uzunluğu. divtamsayı bölümüdür.
  • Liste anlayışı n+1, kalan kısımları olmak üzere parçalar oluşturur.
    • idahil olmak 0üzere n, arasında yineleme yapar .
    • Her parça için, ilk önce i*dbaşlangıç ​​karakterlerinin doğru miktarı ( ) başlangıçtan dropitibaren s, sonra ilk alt dizgi takesonuçtan n'dir.
    • Kalan altlık uzunluğu d, kalan parça hariç olmalıdır .
      • Asıl kalan n, normal parçaların yerine uzatılacağı için olduğundan daha kısa olmalıdır .
      • takeverilen uzunluk çok büyükse tüm dizeyi döndürür, böylece >=n-1kalan parça için herhangi bir sayıyı kullanabiliriz .
      • İfadesi if ve if d+n*0^(n-i)verir . O kullanır olduğu zaman , ama eğer .di<nd+ni==n0^x1x==00x>0

Liste anlama alanlarını nerede kullanabileceğimi izlemem gerekecek.
qfwfq


4

C ++ 14, 209 180 bayt

Bu biraz uzun, ancak bölme operatörünü kullanıyor:

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

Kullanımı:

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

Çevrimiçi sürüm: http://ideone.com/hbBW9u


4

Pyth, 9 bayt

cz*L/lzQS

Çevrimiçi deneyin

Nasıl çalışır

İlk önce otomatik Qolarak başlatılır eval(input())ve otomatik zolarak başlatılır 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

Pas , 107 bayt

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

Çevrimiçi deneyin!

biçimlendirilmiş:

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

Bu basitçe mapkaynağın doğru dilimlerine endekslenir str( collectbirVec ) ve kalanı keser.

Ne yazık ki, bunu bir kapatma işlemi yapamam (74 bayt):

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

derleyici ile başarısız olarak

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

ve eğer türünü sağlarsam s:&str, yaşamlar yanlıştır:

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 bayt

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

O^$`.

¶1+$

O^$`.

Çevrimiçi deneyin! Açıklama: İlk aşama, parça sayısını tek parçaya dönüştürür ve aynı zamanda ipin uzunluğunu alır. İkinci aşama daha sonra uzunluğu, parçaların sayısına bölüp kalanları bırakır. Üçüncü aşama, sonucu tekrar parça sayısıyla çarpar. Bu bize doğru uzunluktaki doğru dizi sayısını veriyor, ancak henüz içeriğe sahip değiller. Parça sayısı şimdi dördüncü aşamada silinebilir. Beşinci aşama, tüm karakterleri tersine çevirir. Bu, orijinal içeriği yer tutucu dizgileriyle değiştirme etkisine sahiptir, ancak şimdi doğru yerde olmasına rağmen, ters sırada. Yer sahipleri amaçlarına hizmet etmiş ve altıncı aşamada silinmiştir. Sonunda yedinci aşama, karakterleri orijinal sıralarına geri döndürür.


3

Perl 6 , 36 bayt

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

Çevrimiçi deneyin!

Son elemanın geri kalanı (eğer varsa) olduğu dizelerin listelerini döndürür.

Açıklama:

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

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

İki elementin bir dizisini döndürür: bölünmüş dize parçaları ve kalan kısım.

Test Parçacığı

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 bayt

¯W=Ul fV)òW/V pUsW

Çevrimiçi test edin! ( -Qçıktıyı görselleştirmek için bayrak kullanır )

açıklama

¯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 Bayt

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

Çevrimiçi deneyin!


PPCG'ye Hoşgeldiniz! Yayınınıza "Çevrimiçi deneyin" bağlantısını ekledim. Sanırım çözümünüzü işlev yerine tam bir program haline getirerek biraz kısaltabilirsiniz. Çevrimiçi deneyin!
musicman523

2

05AB1E , 12 bayt

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

Çevrimiçi deneyin!

açıklama

²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
Giriş sırasını tersine çevirerek 9 bayt .
Kevin Cruijssen

2

Brachylog , 16 bayt

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

Çevrimiçi deneyin!

Giriş olarak bir liste olarak alır [string, number]ve liste olarak çıkar[remainder, parts] . (Dize parçaları tırnak işaretleri ile basılmadığından, açıklık için “Merhaba dünya!” Testlerinde virgüllerin yerine noktalı virgül konuldu.)

                    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.

(Ayrıca, tutarlı bir çıktı biçimi için koddaki virgülün yerini noktalı virgülle değiştirdim). Virgül ile koymuştum. aslında neden bu şekilde çalıştığını biliyorum ...)

Bu, 16 baytlık bir sayı olarak ortaya çıktıktan sonra, +₁ᵗ⟨ġl⟩işe dayanarak bir şeyler yapmaya çalıştım , ama düzeltmeler uzadıkça uzamaya devam ettim.



2

Excel Formülü, 185 173 165 161 149 bayt

Bir dizi formülü ( Ctrl+ Shift+ Enter) olarak aşağıdakiler girilmelidir :

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

Girişinizi nerede A1(örneğin 12345678) veB1 içeren ve böleni içeren yerde. Bu ayrıca bonus için Excel'in bölme operatörünü de kullanır.

Formülü bir dizi formülü olarak girdikten sonra, formül çubuğunda vurgulayın F9ve sonucu döndürmek için kullanarak değerlendirin , örneğin:

Excel formula evaluation showing split groups

-12 bayt: her yerine INDIRECT("1:"&B1+1)sahip OFFSET(A1,,,B1+1)bayt başına oluşumu 2 kaydet ve bir miktar gereksiz parantezleri kaldırıldıktan toplama.

-8 bayt: gereksiz INDEXişlevi kaldırır .

-4 bayt: "kalan" işlemlerini yeniden işleme.

-12 bayt: Yedekli INT(LEN(A1)/B1)diziyi ROW(OFFSET(A1,,,B1+1))-1 ile oluşturulan diziyi uzaklaştırarak kaldır .




1

Mathematica, 58 bayt

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

Bir karakter listesi ve giriş olarak pozitif bir tamsayı alarak salt işlev. Örneğin, son sınama durumu tarafından

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

ve iadeler:

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

1

Haskell, 120 88 bayt (Ørjan Johansen sayesinde!)

divBölme operatörü olarak sayılır mı ?

Bunu nasıl azaltabileceğimi merak ediyorum, henüz tüm hileleri öğrenmedim.

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
En temel püf noktaları ile hızlı bir yeniden yazma: 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). Dolayısıyla, (1) Tekrar tekrar kullanılan bir tanımlayıcı, özellikle uzunsa kısaltılabilir. (2) Muhafızları ve desen koruyucuları her zaman neredeyse daha kısadır let... in, whereve if then else. (3) Desen eşleştirmesi genellikle eşitlik testinden daha iyidir. (Tamam, letbir örüntü bekçideki o kadar temel değil, yakın zamanda başka birinden öğrenmiştim.) Ve codegolf.stackexchange.com/questions/19255/… adresine bakın .
Ørjan Johansen

1
Ayrıca, bazı yararlı püf noktaları için Haskell'de golf için İpuçları bölümüne bakın.
sudee

@ ØrjanJohansen Teşekkürler! Noktalı virgüllerin geçerli olduğunu letve gardiyanın oldukça aldatıcı olduğunu unuttum . Fakat kısa kod daha doğru okunur değil mi?
qfwfq

1

Ohm, 3 bayt (rekabet etmeyen?)

lvσ

Rekabetçi değil çünkü yerleşik henüz TIO'da uygulanmadı ve en son depoda çalışıp çalışmadığını test etmek için kullanışlı bir bilgisayarım yok.

Dahili ¯ \\ _ (ツ) _ / ¯. Ben yanlış yerleşik kullandım ... Ama hey hala etrafta yatan başka biri var. Şimdi yanlış yerleşik iki kez kullandım (veya geriye kalanlarda yanlış olan bir dahili eser).

v(Kat) bölümü olduğundan bonus puan kazanıyor muyum ?


1
Bu, gerektiği şekilde bölünmez. örneğin Hello, world! 5test çantası yanlıştır. Çevrimiçi deneyin!
Ørjan Johansen

Pekala, başka bir dahili arayacağım ....
Roman Gräf

1

CJam , 16 bayt

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

Yığın üzerindeki argümanları bekleyen anonim blok ve sonucu yığında bırakır.

Çevrimiçi deneyin!

açıklama

Argümanları olarak bekler 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 bayt

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

Orta alanlar ve ara basamakların dışında, bu hiç golf oynamamıştır. Bir şekilde uzun bir yol kat ettiğimi umuyorum, parantezlerim ve argüman referanslarım ( [ve]).

See Jupyter notebook for test cases, such as the following:

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

Thanks. Read too fast. Comment removed
Jonah

1

R, 79 63 bytes

-16 from Giuseppe fixing the indexing

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

Try it online!

Built around giving vector inputs to substring()


63 bytes -- simplified the indexing a bit.
Giuseppe

@Giuseppe Haha, I must have tried every variant of adding and multiplying on the index, but missed that one. Good catch.
CriminallyVulgar

0

PHP, 152 bytes

Thanks @JörgHülsermann (brackets tip!)

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

Try it online!


1
Your PHP Way doesn't work cause it replaces not only at the beginning. preg_replace is an alternative or you can use [,$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

Can you explain me with a example code why doesn't work my PHP code ?
kip

1
Try it online! It replaces all A in the first run
Jörg Hülsermann

1
You can drop the array_walk construct if you use brackets Try it online!
Jörg Hülsermann

Nice tip ! I totally forgot
kip


0

PowerShell v3+, 72, 80 bytes

Assumes $s contains the input string; $n contains the number of characters per "piece". This also assumes that "StrictMode" is off. Otherwise, an error would be returned because of indexing further into an array than actually exists (i.e. if array has 4 elements and i call the non-existent 5th element). With StrictMode off, PS doesn't care and it'll ignore the error.

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

Using notation ($s|% ToCharA*) i was able to save 1 character compared to $s.ToCharArray() : )

Update:

Updated code to actually satisfy challenges requirements. Again assumes $s contains the input string; however, this time $n contains the number of "pieces". The remainder is printed out last. And i used PowerShell's division operator

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

Try it online!


I believe you've misunderstood the question, the input is the number of pieces (excluding remainder).
Ørjan Johansen

Oh, you're right. I mis-read the question last night : ) I'll post my updated solution when i have a chance.
GAT
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.