Divide una cuerda


23

Reto

Dada una cadena y un número, divida la cadena en tantas partes del mismo tamaño. Por ejemplo, si el número es 3, debe dividir la cadena en 3 partes, independientemente de su longitud.

Si la longitud de la cadena no se divide de manera uniforme en el número proporcionado, debe redondear el tamaño de cada pieza y devolver una cadena "restante". Por ejemplo, si la longitud de la cadena de entrada es 13 y el número es 4, debe devolver cuatro cadenas cada una de tamaño 3, más una cadena restante de tamaño 1.

Si no hay resto, simplemente no puede devolver uno o devolver la cadena vacía.

Se garantiza que el número proporcionado será menor o igual que la longitud de la cadena. Por ejemplo, la entrada "PPCG", 7no ocurrirá porque "PPCG"no se puede dividir en 7 cadenas. (Supongo que el resultado correcto sería (["", "", "", "", "", "", ""], "PPCG"). Es más fácil simplemente no permitir esto como entrada).

Como de costumbre, la E / S es flexible. Puede devolver un par de cadenas y la cadena restante, o una lista de cadenas con el resto al final.

Casos de prueba

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

Tanteo

Este es el , por lo que gana la respuesta más corta en cada idioma.

Los puntos de bonificación (no realmente 😛) para hacer que su solución realmente use el operador de división de su idioma.


1
¿Puntos extra? Oh hombre, tengo que hacer esto
Matthew Roh


Relacionado , pero ninguna de las partes es exactamente igual a este desafío.
musicman523

Para aclararlo PPCG, agregue un caso de prueba , 7por lo que el resto esPPCG
Jörg Hülsermann

@ JörgHülsermann Esa entrada no está permitida. He agregado más detalles relacionados con ese tipo de entrada y reformateado las cosas para que quede más claro.
musicman523

Respuestas:




5

Pipa , 21 bytes

20 bytes de código, +1 para -nbandera.

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

Toma entradas como argumentos de línea de comandos; produce cadenas y el resto separados por nueva línea. Pruébalo en línea!

Explicación

Diversión con operaciones de expresiones regulares!

Tomemos abcdefgcomo nuestra cadena y 3como nuestro número. Construimos la expresión regular (.{2})(.{2})(.{2}), que coincide con tres corridas de dos caracteres y los almacena en tres grupos de captura. Luego, utilizando las variables de coincidencia de expresiones regulares de Pip, podemos imprimir 1) la lista de grupos de captura ["ab";"cd";"ef"]y 2) el resto de la cadena que no coincidió "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 bytes

#es un operador que toma un Stringy un Int, y devuelve una lista de Strings.

Usar como "Hello, world!"#4.

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

Pruébalo en línea!

Cómo funciona

  • ses la cadena de entrada y nes el número de piezas no restantes.
  • d es la longitud de cada pieza "normal". dives la división entera.
  • La comprensión de la lista construye n+1piezas, siendo la última el resto.
    • iitera de 0an , inclusive.
    • Para cada pieza, primero la cantidad correcta ( i*d) de caracteres iniciales se droppedirá desde el principio de s, luego una subcadena inicial estake n del resultado.
    • La longitud de la subcadena tomada debe ser d , a excepción de la pieza restante.
      • El resto real debe ser más corto que n, de lo contrario, las piezas normales se alargarían en su lugar.
      • takedevuelve la cadena completa si la longitud dada es demasiado grande, por lo que podemos usar cualquier número >=n-1para la pieza restante.
      • La expresión d+n*0^(n-i)da dsi i<ny d+nsi i==n. Utiliza que 0^xes 1cuando x==0, pero 0si x>0.

Tendré que observar dónde puedo usar las comprensiones de listas.
qfwfq

4

Python 2 , 68 67 65 bytes

  • @ musicman123 guardó 2 bytes: salida sin encerrar con []
  • Gracias a @Chas Brown por 1 Byte: x[p*i:p+p*i]comox[p*i][:p]
def f(x,n):p=len(x)/n;print[x[p*i:][:p]for i in range(n)],x[p*n:]

Pruébalo en línea!


1
Ahorre 1 byte reemplazando x[p*i:p+p*i]conx[p*i:][:p]
Chas Brown

1
+1 para :p😛 ¡Bien hecho superando a las otras respuestas de Python!
musicman523

Jaja ... eso no fue pensado en absoluto ...: p
officialaimm

1
Esta respuesta ahora ha sido superada
musicman523 01 de

4

C ++ 14, 209 180 bytes

Eso es demasiado largo, pero usa el operador de división:

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

Uso:

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

Versión en línea: http://ideone.com/hbBW9u


4

Pyth, 9 bytes

cz*L/lzQS

Pruébalo en línea

Cómo funciona

Primero Qse autoinicializa eval(input())y zse autoinicializa 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

Óxido , 107 bytes

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

Pruébalo en línea!

Formateado:

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

Esto simplemente mapenvía índices a las porciones correctas de la fuente str( collecting en a Vec) y corta el resto.

Desafortunadamente, no puedo hacer esto un cierre (74 bytes):

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

ya que el compilador falla con

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

y si proporciono el tipo de s:&str, las vidas son incorrectas:

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 bytes

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

O^$`.

¶1+$

O^$`.

Pruébalo en línea! Explicación: La primera etapa convierte el número de partes a unario y también toma la longitud de la cadena. La segunda etapa luego divide la longitud por el número de partes, dejando el resto. La tercera etapa multiplica el resultado por el número de partes nuevamente. Esto nos da el número correcto de cadenas de la longitud correcta, pero aún no tienen el contenido. El número de partes ahora se puede eliminar en la cuarta etapa. La quinta etapa invierte todos los personajes. Esto tiene el efecto de cambiar el contenido original con las cadenas de marcador de posición, pero aunque ahora está en el lugar correcto, está en orden inverso. Los marcadores de posición han cumplido su propósito y se eliminan en la sexta etapa. Finalmente, la séptima etapa invierte a los personajes a su orden original.


3

Perl 6 , 36 bytes

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

Pruébalo en línea!

Devuelve una lista de listas de cadenas, donde el último elemento es el resto (si hay uno).

Explicación:

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

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

Devuelve una matriz de dos elementos: las partes de cadena divididas y la parte restante.

Fragmento de prueba

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 bytes

¯W=Ul fV)òW/V pUsW

¡Pruébelo en línea! (usos-Q bandera para visualizar la salida)

Explicación

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

Pruébalo en línea!


Bienvenido a PPCG! Agregué un enlace "Pruébelo en línea" a su publicación. Creo que puede acortar ligeramente su solución convirtiéndola en un programa completo en lugar de una función. Pruébalo en línea!
musicman523

2

05AB1E , 12 bytes

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

Pruébalo en línea!

Explicación

²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 bytes invirtiendo el orden de entrada.
Kevin Cruijssen

2

Brachylog , 16 bytes

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

Pruébalo en línea!

Toma la entrada como una lista [string, number]y las salidas como una lista [remainder, parts]. (Las comas se reemplazaron con punto y coma en los casos de prueba "¡Hola, mundo!" Para mayor claridad, ya que los fragmentos de cadena no se imprimen con comillas).

                    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.

(También reemplacé una coma en el código con un punto y coma para un formato de salida consistente. Con la coma , los casos sin resto solo mostrarían las partes sin un resto vacío, y por muy bueno que sea para algunos propósitos, no realmente sé por qué funciona de esa manera ...)

Después de que esto resultó ser un total de 16 bytes, traté de hacer algo basado en el +₁ᵗ⟨ġl⟩trabajo, pero a medida que las correcciones se hicieron más y más largas, decidí que me quedaría con mi solución original por ahora.



2

Fórmula de Excel, 185 173 165 161 149 bytes

Lo siguiente debe ingresarse como una fórmula de matriz ( 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))))

Donde A1contiene su entrada (por ejemplo 12345678) y B1contiene el divisor. Esto también utiliza el operador de división de Excel para obtener una bonificación.

Después de ingresar la fórmula como una fórmula de matriz, resáltela en la barra de fórmulas y evalúela usando F9para devolver el resultado, por ejemplo:

Evaluación de fórmula de Excel que muestra grupos divididos

-12 bytes: sustituirse unos INDIRECT("1:"&B1+1)con OFFSET(A1,,,B1+1)al ahorro 2 bytes por ocurrencia, más un poco de poner en orden la eliminación de soportes redundantes.

-8 bytes: eliminar la INDEXfunción redundante .

-4 bytes: retrabajar el manejo del "resto".

-12 bytes: eliminar redundantes INT(LEN(A1)/B1)compensando la matriz generada ROW(OFFSET(A1,,,B1+1))por -1.




1

Mathematica, 58 bytes

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

Función pura que toma una lista de caracteres y un entero positivo como entrada. Por ejemplo, el último caso de prueba es llamado por

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

y vuelve:

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

1

Haskell 120 88 bytes (¡gracias a Ørjan Johansen!)

¿ divCuenta como el operador de división?

Tengo curiosidad por saber cómo podría reducir esto, todavía no he aprendido todos los trucos.

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
Una reescritura rápido con la mayoría de los trucos básicos: 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). Entonces, (1) Un identificador usado repetidamente puede abreviarse, especialmente si es largo. (2) Los guardias y los guardias de patrones son casi siempre más cortos que let... in, wherey if then else. (3) La coincidencia de patrones suele ser mejor que la prueba de igualdad. (OK, leten un patrón de protección no es tan básico, recientemente lo aprendí de otra persona aquí). Y echa un vistazo a codegolf.stackexchange.com/questions/19255/… .
Ørjan Johansen

1
Además, eche un vistazo a Consejos para jugar al golf en Haskell para obtener algunos trucos útiles.
sudee

@ ØrjanJohansen ¡Gracias! Olvidé que los puntos y comas eran válidos, y que leten la guardia es bastante tortuoso. Pero el código más corto es más legible, ¿verdad?
qfwfq

1

Ohm, 3 bytes (¿no compite?)

lvσ

No compite porque el incorporado aún no está implementado en TIO y no tengo una PC a mano para probar si funciona en el último tirón en el repositorio.

¯ \\ _ (ツ) _ / ¯ incorporado. Utilicé el incorporado incorrecto ... Pero bueno, todavía hay otro por ahí.Ahora usé el incorporado incorrecto dos veces (o uno incorporado funciona mal con los restos).

¿Obtengo puntos de bonificación porque ves la división (piso)?


1
Esto no se divide en la forma requerida. Por ejemplo, el caso de Hello, world! 5prueba está mal. Pruébalo en línea!
Ørjan Johansen

Bueno, voy a buscar otro incorporado ...
Roman Gräf

1

CJam , 16 bytes

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

Bloque anónimo que espera los argumentos en la pila y deja el resultado en la pila después.

Pruébalo en línea!

Explicación

Espera argumentos como 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 bytes

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

Aparte de la eliminación de espacios y pasos intermedios, esto no ha sido golfizado. Espero haber tomado el camino largo de alguna manera, con mis paréntesis y referencias de argumentos ([ y ]).

Consulte el cuaderno Jupyter para ver casos de prueba, como los siguientes:

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

Gracias. Lee muy rápido. Comentario eliminado
Jonás

1

R , 79 63 bytes

-16 de Giuseppe arreglando la indexación

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

Pruébalo en línea!

Construido alrededor de dar entradas de vectores a substring()


63 bytes : simplificó un poco la indexación.
Giuseppe

@Giuseppe Jaja, debo haber probado todas las variantes de sumar y multiplicar en el índice, pero me perdí esa. Buena atrapada.
CriminallyVulgar

0

PHP , 152 bytes

Gracias @ JörgHülsermann (¡punta de paréntesis!)

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

Pruébalo en línea!


1
Su PHP Way no funciona porque reemplaza no solo al principio. preg_replacees una alternativa o se puede usar[,$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

¿Me puede explicar con un código de ejemplo por qué no funciona mi código PHP?
kip

1
Pruébalo en línea! Reemplaza todo Aen la primera carrera
Jörg Hülsermann

1
Puede soltar la construcción array_walk si usa paréntesis ¡ Pruébelo en línea!
Jörg Hülsermann

Buen consejo! Lo olvidé por completo
kip


0

PowerShell v3 + , 72 , 80 bytes

Asume $scontiene la cadena de entrada; $ncontiene el número de caracteres por "pieza". Esto también supone que "StrictMode" está desactivado. De lo contrario, se devolvería un error debido a la indexación en una matriz más de lo que realmente existe (es decir, si la matriz tiene 4 elementos y yo llamo el 5to elemento inexistente). Con StrictMode desactivado, a PS no le importa e ignorará el error.

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

Usando la notación ($s|% ToCharA*)pude guardar 1 carácter en comparación con$s.ToCharArray() :)

Actualizar:

Código actualizado para satisfacer los requisitos de desafíos. De nuevo se supone que $scontiene la cadena de entrada; sin embargo, esta vez $ncontiene el número de "piezas". El resto se imprime al final. Y usé el operador de división de PowerShell

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

Pruébalo en línea!


Creo que ha entendido mal la pregunta, la entrada es el número de piezas (excluyendo el resto).
Ørjan Johansen

Oh tienes razon Anoche leí mal la pregunta:) Publicaré mi solución actualizada cuando tenga la oportunidad.
GAT
Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.