Convertir n cadenas de m longitud en m cadenas de n longitud

16

Escriba un programa que, dado cualquier número 'n' de cadenas de longitud 'm', devuelva el número 'm' de cadenas 'n' de longitud, con esta condición:

Cada nueva cadena debe contener las letras en el mismo índice de las otras cadenas

Por ejemplo, la primera cadena de salida debe contener la primera letra de todas las cadenas de entrada, la segunda cadena de salida debe contener la segunda letra de todas las cadenas de entrada, y así sucesivamente.

Ejemplos (los números debajo de las letras son los índices de las cadenas):

input: "car", "dog", "man", "yay"
        012    012    012    012
output: "cdmy", "aoaa", "rgny"
         0000    1111    2222

input: "money", "taken", "trust"
        01234    01234    01234
output: "mtt", "oar", "nku", "ees", "ynt"
         000    111    222    333    444

Suponga que la entrada es correcta cada vez

¡El código de bytes más corto gana!

Editar:

Dado que hay muchos lenguajes de programación, y podría haber muchas soluciones posibles para cada uno de ellos, publicaré la solución más corta para cada lenguaje de programación y el usuario que la proporcionó. ¡Sigue codificando!

Reeditar:

Gracias al usuario Dennis , inserté un fragmento para las tablas de clasificación.

Ingrese el nombre aquí
fuente
2
Tenemos un fragmento de tabla de clasificación que puede agregar a su cuerpo de preguntas. No es necesario hacer eso a mano.
Dennis
Lo siento, no sabía que se llamaba "transposición"
Ingrese el nombre aquí
66
No creo que estos desafíos sean duplicados, debido a las diferencias que implican una transposición irregular y un extraño manejo de espacios en blanco en la otra pregunta. Si bien en algunos idiomas las respuestas pueden ser muy similares, creo que en la mayoría serán lo suficientemente diferentes como para que esto no sea un duplicado.
FryAmTheEggman

Respuestas:

21

Pyth, 1 byte

C

Pruébalo aquí

Otra transposición incorporada

Azul
fuente
55
¡¿Como es esto posible?!
DavidC
¡Seguramente estás bromeando!
Vincent
Pyth es el nuevo Mathematica!
Loovjo
9

Python, 36 29 bytes

zip(*s) devuelve una lista de tuplas de cada personaje, transpuesta.

lambda s:map(''.join,zip(*s))

Pruébalo en línea

mbomb007
fuente
La salida dice "cdmy", "aoaa", "rgny", que es una lista ["cdmy", "aoaa", "rgny"]o una tupla("cdmy", "aoaa", "rgny")
mbomb007
map(''.join,zip(*s))también funciona para la conversión de cadenas (solo Python 2), y para Python 3, [*map(''.join,zip(*s))]funciona afaik
Value Ink el
@ KevinLau-notKenny también map(''.join,zip(*s))es válido para Python 3: de forma predeterminada, permitimos iteradores / generadores en lugar de listas.
Mego
7

PowerShell v2 +, 66 54 bytes

param($n)for($x=0;$n[0][$x];$x++){-join($n|%{$_[$x]})}

Yo ... no map, no zip, no transpose, etc., así que podemos rodar los nuestros. Grandes accesorios para @DarthTwon para el golf de 12 bytes.

Toma entrada $n, establece un forbucle. La inicialización se establece $xen 0, la prueba es si todavía tenemos letras en nuestra palabra $n[0][$x], y si incrementamos$x++ cada iteración.

Dentro del bucle, tomamos nuestro conjunto de cadenas, lo canalizamos a un bucle interno que escupe el carácter apropiado de cada palabra. Eso se encapsula en a -joinpara formar una cadena, y esa cadena se deja en la tubería. Al final de la ejecución, las cadenas en la tubería se imprimen implícitamente.

PS C:\Tools\Scripts\golfing> .\convert-n-strings.ps1 "Darth","-Twon","Rocks"
D-R
aTo
rwc
tok
hns
AdmBorkBork
fuente
1
Bueno, ese es el tipo de respuestas que quería ver;) Es demasiado simple escribir en ,lugar de pensar en la respuesta
ingrese el nombre aquí
El uso de un bucle while puede pare además que abajo: param($n)$x=0;while($n[0][$x]){-join($n|%{$_[$x]});$x++}. Y no hay errores aquí: D
ThePoShWolf
@DarthTwon Excelente. O use un forbucle para otros dos. ;-)
AdmBorkBork
Hmm ... Lo intenté, pero no después de realmente reducir mi whileciclo. Buen trabajo señor!
ThePoShWolf
¿Se puede usar Linq en Powershell?
aloisdg se muda a codidact.com el
7

Vim, 37 36 pulsaciones de teclas

Todas las otras respuestas son aburridas y utilizan aburridas incorporaciones de un solo byte. Aquí hay una respuesta hacky que hace todo de forma manual, en algo que ni siquiera es un lenguaje de programación:

Gmaqqgg:s/./&<cr>d<C-v>`aGo<esc>pvGgJ@qq@q`adgg

Explicación:

G                                   "move to the end of this line
     ma                             "And leave mark 'a' here
       qq                           "Start recording in register 'q'
         gg                         "Move to the beginning
           :s/./&<cr>               "Assert that there is atleast one character on this line
                      d             "Delete
                       <C-v>        "Blockwise
                            `a      "Until mark 'a'

    G                               "Move to the end of the buffer
     o<esc>                         "Open a newline below us
           p                        "And paste what we deleted
            vG                      "Visually select everything until the end
              gJ                    "And join these without spaces
                @q                  "Call macro 'q'. The first time, this will do nothing,
                                    "The second time, it will cause recursion.
                  q                 "Stop recording
                   @q               "Call macro 'q' to start it all

Ahora, todo está bien, pero al búfer le queda algo de texto adicional. Entonces debemos:

`a                              "Move to mark 'a'
  dgg                           "And delete everything until the first line
DJMcMayhem
fuente
5

CJam, 6 5 bytes

Guardado 1 byte gracias a Luis Mendo.

qS%zp

Pruébalo en línea!

q      e# Get all input
 S%    e# Split it on spaces
   z   e# Take the transpose
    p  e# Print it as an array
Gato de negocios
fuente
4

Pyke, 1 byte

,

Pruébalo aquí!

Transponer.

Azul
fuente
1
Oh ... No pensé que hubiera sido tan simple: /
Ingrese el nombre aquí
1
Sí, parece que no puedo encontrar un duplicado buscando 60 segundos sin embargo
Azul
4

Retina , 45 43 bytes

El recuento de bytes asume la codificación ISO 8859-1.

O$#`.(?<=(.+))|¶
$.1
!`(?<=(¶)+.*)(?<-1>.)+

El avance de línea principal es significativo. La entrada y la salida son listas terminadas en salto de línea de cadenas ASCII imprimibles (tenga en cuenta que ambas tienen un solo salto de línea final).

Pruébalo en línea!

Sabía por un tiempo que transponer bloques rectangulares sería un dolor en Retina (mientras que transponer cuadrados no es tan malo), pero en realidad nunca lo intenté. La primera solución fue de hecho la friolera de 110 bytes, pero después de varios cambios sustanciales en el enfoque, los 45 bytes resultantes no son tan malos como sospechaba (pero aún así ...). La explicación seguirá mañana.

Explicación

Etapa 1: ordenar

O$#`.(?<=(.+))|¶
$.1

Esto hace el trabajo principal de reordenar los caracteres en la entrada, pero termina desordenando la separación en líneas. Curiosamente, si eliminamos el , obtenemos el código requerido para transponer una entrada cuadrada.

Las etapas de clasificación (denotadas por O) funcionan de la siguiente manera: encuentran todas las coincidencias de la expresión regular dada (la que está después de la `), y luego clasifican esas coincidencias y las vuelven a insertar en los lugares donde se encontraron las coincidencias. Como sucede, esta expresión regular coincide con todos los caracteres: sin saltos de línea a través de la .(?<=(.*))alternativa y saltos de línea a través de . Por lo tanto, ordena todos los caracteres en la entrada. La parte más interesante es lo que están ordenados por .

La $opción activa un modo de "ordenar por", donde cada coincidencia se reemplaza con el patrón de sustitución en la segunda línea, que luego se utiliza para comparar las coincidencias. Además, #le dice a Retina que convierta el resultado de la sustitución en un entero y compare esos enteros (en lugar de tratarlos como cadenas).

Entonces, finalmente, tenemos que mirar la expresión regular y la sustitución. Si la primera alternativa coincide (es decir, hemos emparejado cualquier carácter dentro de una de las líneas), entonces (?<=(.*))captura todo hasta ese personaje en esa línea en grupo 1. El $.1patrón en la sustitución reemplaza esto con la longitud del grupo 1. Por lo tanto, el primer carácter en cada cadena se convierte 1, el segundo se convierte 2, el tercero se convierte 3y así sucesivamente. Ahora debería quedar claro cómo esto transpone una entrada cuadrada: todos los primeros caracteres de las líneas aparecen primero y todos terminan en la línea superior, luego todos los segundos caracteres terminan en la segunda línea y así sucesivamente. Pero para estas entradas rectangulares, también estamos haciendo coincidir los avances de línea. Desde grupo1no se utiliza en este caso, la sustitución está vacía, pero a los efectos de la #opción, esto se considera 0. Eso significa que todos los avances de línea están ordenados al frente.

Así que ahora tenemos los caracteres en el primer orden (primer carácter de cada cadena, segundo carácter de cada cadena, etc.) y todos los avances de línea al principio.

Etapa 2: partido

!`(?<=(¶)+.*)(?<-1>.)+

Ahora necesitamos dividir los caracteres en líneas de la longitud correcta. Esta longitud corresponde al número de líneas en la entrada original, que corresponde al número de avances de línea que tenemos al comienzo de la cadena.

La división se realiza aquí con la ayuda de una etapa de coincidencia, que simplemente encuentra todas las coincidencias de la expresión regular dada y usa la !opción para imprimir esas coincidencias (lo predeterminado sería contarlas en su lugar). Entonces, el objetivo de la expresión regular es hacer coincidir una línea a la vez.

Comenzamos "contando" el número con el lookbehind (?<=(¶)*.*). Genera una captura en grupo 1por cada salto de línea en el frente.

Luego, para cada una de esas capturas, hacemos coincidir un solo personaje con (?<-1>.)+.

Martin Ender
fuente
4

código de máquina x86, 19 bytes

En hexadecimal:

fc89d35651a401dee2fb91aa595e464a75f1c3

Entrada:: ECX# de cadenas (n) EDX,: longitud de cadena individual (m) ESI,: matriz de cadenas de entrada,: EDIbúfer de salida que recibe la matriz de cadenas. Se presume que la matriz se define como char src[n][m+1]entrada y char dst[m][n+1]salida, y todas las cadenas tienen terminación NULL.

0:  fc                  cld
1:  89 d3               mov ebx,edx   ;EDX is the counter for the outer loop
_outer:
3:  56                  push esi
4:  51                  push ecx
_inner:
5:  a4                  movsb         ;[EDI++]=[ESI++]
6:  01 de               add esi,ebx   ;Same char, next string
8:  e2 fb               loop _inner   ;--ECX==0 => break
a:  91                  xchg eax,ecx  ;EAX=0
b:  aa                  stosb         ;NULL-terminate just completed string
c:  59                  pop ecx
d:  5e                  pop esi       ;First string,
e:  46                  inc esi       ;...next char
f:  4a                  dec edx
10: 75 f1               jnz _outer
12: c3                  ret
meden
fuente
3

Brachylog , 5 bytes

z:ca.

Espera una lista de cadenas como entrada, p. Ej. run_from_atom('z:ca.',["money":"taken":"trust"],Output).

Explicación

z       Zip the strings in the Input list
 :ca.   output is the application of concatenation to each element of the zip
Fatalizar
fuente
3

05AB1E, 3 bytes

ø€J

Explicado

     # implicit input, eg: ['car', 'dog', 'man', 'yay']
ø    # zip, producing [['c', 'd', 'm', 'y'], ['a', 'o', 'a', 'a'], ['r', 'g', 'n', 'y']]
 €J  # map join, resulting in ['cdmy', 'aoaa', 'rgny']

Pruébalo en línea

Emigna
fuente
2

CJam , 3 bytes

{z}

Este es un bloque de código (equivalente a una función; permitido por defecto ) que espera la entrada en la pila y deja la salida en la pila.

Pruébalo en línea!

Luis Mendo
fuente
1
@Drgreeneggsandironman Bueno, la respuesta con más votos dice que el valor predeterminado debería ser "programas o funciones"
Luis Mendo
2

JavaScript ES6, 48 46 bytes

a=>[...a[0]].map((n,x)=>a.map(a=>a[x]).join``)

Me siento excluido, no tenemos una función zip integrada. Gracias nicael por señalar mi error de tipo.

Uso

(a=>[...a[0]].map((n,x)=>a.map(a=>a[x])))(["asd","dsa"]); //or whatever is above, might change due to edits

devoluciones

["ad","ss","da"]
hierba carbonizada
fuente
Excepción: TypeError: a [0] .map no es una función
edc65
1
Necesitas [...a[0]].map, ya a[0]que no es una matriz.
nicael
@nicael gracias. estropeó los tipos. Esto demuestra por qué no debería jugar golf tan temprano en la mañana.
charredgrass
@nicael Los edité .joinpara solucionar ese problema.
charredgrass
1
join`` en lugar de join('')guardar 2 bytes. Voto negativo retirado
edc65
2

Bash + BSD utilidades, 27

sed s/./\&:/g|rs -c: -g0 -T

E / S a través de cadenas separadas por nueva línea STDIN / STDOUT.

Es posible que necesite instalar rscon sudo apt install rso similar. Funciona de fábrica en OS X.

La -Topción de rshacer el trabajo pesado de la transposición. El resto es solo formatear:

  • El sedcomando simplemente se inserta :después de cada personaje
  • -c:especifica que las columnas de entrada están :separadas
  • -g0 especifica que las columnas de salida tienen separación de ancho cero

Si mi lectura de la página de rsmanual es correcta, entonces lo siguiente debería funcionar para un puntaje de 12, pero desafortunadamente no funciona - vea la nota a continuación:

rs -E -g0 -T

Salida de ejemplo:

$ printf "%s\n" car dog man yay |sed s/./\&:/g|rs -c: -g0 -T
cdmy
aoaa
rgny
$

Si se espera que la entrada sea ASCII imprimible, se :puede reemplazar con algún carácter no imprimible, por ejemplo, 0x7BEL .


Nota

Quería entender por qué no podía tener la -Eopción de trabajar y deshacerme del sedpreprocesamiento. Encontré el rscódigo fuente aquí . Como puede ver, dar esta opción establece elONEPERCHAR bandera. Sin embargo, no hay nada en el código que realmente verifique el estado de este indicador. Así que creo que podemos decir que a pesar de que esta opción está documentada, no está implementada.

De hecho, esta opción está documentada en la página de rsmanual de Linux :

-E Considere cada carácter de entrada como una entrada de matriz.

pero no la versión OS X.

Trauma digital
fuente
2

PHP, 82 bytes

function f($a){foreach($a as$s)foreach(str_split($s)as$i=>$c)$y[$i].=$c;return$y;}

toma y devuelve una serie de cadenas

Descompostura

function f($a)
{
    foreach($a as$s)                    // loop through array $a
        foreach(str_split($s)as$i=>$c)  // split string to array, loop through characters
            $y[$i].=$c;                 // append character to $i-th result string
    return$y;
}

ejemplos

$samples=[
    ["asd","dsa"], ["ad","ss","da"],
    ["car", "dog", "man", "yay"], ["cdmy", "aoaa", "rgny"],
    ["money", "taken", "trust"], ["mtt", "oar", "nku", "ees", "ynt"]
];
echo '<pre>';
while ($samples)
{
    echo '<b>in:</b> ';         print_r($x=array_shift($samples));
    echo '<b>out:</b> ';        print_r(f($x));
    echo '<b>expected:</b> ';   print_r(array_shift($samples));
    echo '<hr>';
}
Titus
fuente
2

APL, 3 bytes

↓⍉↑

toma las cadenas de entrada y las convierte en una matriz de caracteres. transpone la matriz. divide las filas de la matriz resultante en cadenas.

lstefano
fuente
1

Mathematica, 26 bytes

""<>#&/@(Characters@#)&

Función anónima. Toma una lista de cadenas como entrada y devuelve una lista de cadenas como salida. El carácter Unicode es U + F3C7, que representa \[Transpose]. Funciona convirtiendo a una matriz de caracteres, transponiendo y volviendo a convertir en una lista de cadenas. Si el formato de entrada / salida se extendiera, entonces una simple transposición de 5 bytes funcionaría:

#&
LegionMammal978
fuente
+1 me golpeaste hasta el golpe! (Pero no pude usar el símbolo Transponer). Por cierto, ¿por qué no aparece la T en la pantalla? (Está allí cuando copio su código a Mathematica).
DavidC
@DavidC El carácter Unicode está en el Área de uso privado, que está marcado como una sección para caracteres propietarios y, por lo tanto, no se le asigna oficialmente un glifo ni se representa en absoluto en la mayoría de las fuentes. La fuente de Mathematica simplemente representa este carácter como un superíndice T y lo interpreta como a \[Transpose].
LegionMammal978
@DavidC ¿Por qué no usan ?
Adám
@ Adám IDK, tendrías que preguntarle a Wolfram Research sobre eso, no a mí
LegionMammal978
@ LegionMammal978 No, estoy feliz siempre que tenga APL obvio .
Adám
1

MATLAB / Octave, 4 bytes

@(x)x'

Esto define una función anónima. El formato de entrada es ['car'; 'dog'; 'man'; 'yay'].

Pruébalo aquí .

Luis Mendo
fuente
¿Qué formato es la entrada para esta solución? No creo que funcione con la forma en que Matlab maneja las cadenas si intenta ingresarlas de manera Matlabby, por ejemplo f = @(x)x', f([{'abcd'},{'abcd'},{'abcd'}])salidas ans = 'abcd' 'abcd' 'abcd'
sintax
@sintax El formato de entrada debe ser una matriz de caracteres 2D, como en el ejemplo vinculado en la respuesta. Está utilizando una matriz de celdas de cadenas (obtenida mediante la concatenación de matrices de celdas simples). Debe ser: f(['abcd';'abcd';'abcd']). He editado la respuesta para especificar el formato de entrada
Luis Mendo
1

Haskell, 41 bytes

f l=zipWith($)[map(!!n)|n<-[0..]]$l<$l!!0

O con un poco más de aire:

f l = zipWith ($) [map (!! n) | n <- [0..]] $
                  l <$ (l !! 0)

La segunda lista es la lista de palabras repetidas "el tiempo de una palabra". En cada lista de palabras, seleccionamos la enésima letra de cada palabra, dando el resultado.

villou24
fuente
1
No hay necesidad de un programa completo, porque "programa" significa "programa o función" , por lo que una función es suficiente. Puede pasar y devolver una lista de cadenas y, por lo tanto, omitir wordsy unwords. Además, map(\_->l)(l!!0)es l<*l!!0, por lo que se reduce a \l->zipWith($)[map(!!n)|n<-[0..]]$l<$l!!0.
nimi
Oh, bien, gracias :) Estoy actualizando.
villou24
Oops, error tipográfico: es l<$l!!0(primera vez mal, segunda vez bien), pero de todos modos lo entendiste bien.
nimi
1

Lisp común, 62 bytes

(lambda(s)(apply'map'list(lambda(&rest x)(coerce x'string))s))

La mapfunción toma un tipo de resultado (aquí list), una función f para aplicar y una o más secuencias s1 , ..., sn . Todas las secuencias se repiten en paralelo. Para cada tupla de elementos (e1, ..., en) tomados de esas secuencias, llamamos (f e1 ... en) y el resultado se acumula en una secuencia del tipo deseado.

Tomamos una lista de cadenas, digamos ("car" "dog" "man" "yay"), y usamos applypara llamar map. Tenemos que hacer esto para que la lista de entrada se use como más argumentos para map. Más precisamente, esto:

(apply #'map 'list fn '("car" "dog" "man" "yay"))

... es equivalente a:

(map 'list f "car" "dog" "man" "yay")

Y dado que las cadenas son secuencias, iteramos en paralelo sobre todos los primeros caracteres, luego todos los segundos caracteres, etc. Por ejemplo, la primera iteración llama f de la siguiente manera:

(f #\c #\d #\m #\y)

La lambda anónima toma la lista de argumentos que se le dan y la obliga a volver a una cadena.

volcado de memoria
fuente
1

Perl, 91 bytes

Tan largo ...

$l=<>;$p=index($l," ")+1;@i=split//,$l;for$a(0..$p-1){print$i[$a+$_*$p]for(0..$p);print" "}

Pruébalo aquí!

Swadhikar C
fuente
0

Ruby, 46 bytes

Probablemente la primera vez que "Las cadenas de Ruby no son Enumerables" en realidad me está mordiendo duro ya que tuve que mapear las cadenas en matrices antes del procesamiento. (Normalmente tener que usar String#charsno es suficiente pérdida de bytes para importar, pero como necesito mapearlos, duele mucho más)

->s{s.map!(&:chars).shift.zip(*s).map &:join}
Value Ink
fuente
0

Clojure, 68 bytes

#(map(fn[g](reduce(fn[a b](str a(nth b g)))""%))(range(count(% 0))))

Mapea una función que es solo reduce (va sobre los elementos de la lista uno por uno y une el enésimo carácter de la cadena) en el rango de 0 a la longitud de la primera cadena.

Véalo en línea: https://ideone.com/pwhZ8e

acantilado
fuente
0

C #, 53 bytes

t=>t[0].Select((_,i)=>t.Aggregate("",(a,b)=>a+b[i]));

C # lambda ( Func) donde está la salida IList<string>y la salida es IEnumerable<string>. No sé cómo funciona zipen otro idioma, pero no puedo encontrar una manera de usar el C # aquí.AggregateSe ajusta bien a la necesidad. No hay transposición en C #, hay una en Excel pero no la usaré.

Pruébalo en línea!

aloisdg se muda a codidact.com
fuente