Mapa discreto de Baker

15

Introducción

El mapa de Baker es un sistema dinámico importante que exhibe un comportamiento caótico. Es una función desde el cuadrado de la unidad a sí misma definida intuitivamente de la siguiente manera.

  • Corta el cuadrado verticalmente por la mitad, dando como resultado dos rectángulos de tamaño 0.5×1.
  • Apila la mitad derecha sobre la izquierda, dando como resultado un rectángulo de tamaño 0.5×2
  • Comprime el rectángulo en un 1×1cuadrado.

En este desafío, implementará una versión discreta de esta transformación.

Entrada y salida

Su entrada es una matriz 2D de caracteres ASCII imprimibles y espacios en blanco de tamaño 2m×2npara algunos m, n > 0. Su salida es una matriz similar obtenida de la siguiente manera, utilizando la 6×4matriz

ABCDEF
GHIJKL
MNOPQR
STUVWX

como ejemplo. Primero, apile la mitad derecha de la matriz sobre la mitad izquierda:

DEF
JKL
PQR
VWX
ABC
GHI
MNO
STU

Luego, divida las columnas en pares de caracteres y gire independientemente cada par 90 grados en el sentido de las agujas del reloj, "comprimiendo" el rectángulo alto de nuevo a la forma original:

JDKELF
VPWQXR
GAHBIC
SMTNUO

Esta es la salida correcta para la matriz anterior.

Reglas

Los formatos de entrada y salida son flexibles. Puede usar cadenas delimitadas por nueva línea, listas de cadenas o matrices 2D de caracteres. Sin embargo, la entrada y la salida deben tener exactamente el mismo formato: debe poder iterar su envío un número arbitrario de veces en cualquier entrada válida.

Puede escribir un programa completo o una función. El conteo de bytes más bajo gana, y las lagunas estándar no se permiten.

Casos de prueba

Input:
12
34

Output:
42
31

Input:
Hell
!  o
d  -
lroW

Output:
 lol
o W-
!H e
ldr 

Input:
ABCDEF
GHIJKL
MNOPQR
STUVWX

Output:
JDKELF
VPWQXR
GAHBIC
SMTNUO

Input:
*___  ___  o
o|__) |__) *
*|    |    o
o __   __  *
*|    | _  o
o|__  |__| *

Output:
|_____)   *o
 |_ _     *o
||_ __|   *o
o*|_____)   
o* |_ _     
o*||_ _     
Zgarb
fuente

Respuestas:

11

Pyth, 25 19 18 bytes

msC_dcs_Cmck/lk2Q2

Demostración en línea . Utiliza una matriz 2D de caracteres.

La matriz de cadenas tiene un carácter más largo (19 bytes). Demostración en línea

Explicación:

         m      Q    map each string k in input:
            /lk2        calculate half the line-length: len(k)/2
          ck/lk2        chop k into pieces of length len(k)/2
                        results in two pieces
        C            zip the resulting list
                     results in a tuple ([first half of strings], [second half of strings])
       _             invert the order ([second half of strings], [first half of strings])
      s              sum (combine the two lists to a big one
     c           2   chop them into tuples
m                          for each tuple of strings: 
 sC_d                        invert, zip, and sum

La última parte es un poco confusa al principio. Supongamos que tenemos la tupla ['DEF', 'JKL'](uso el ejemplo del OP).

    d  (('D', 'E', 'F'), ('J', 'K', 'L'))   just the pair of strings
   _d  (('J', 'K', 'L'), ('D', 'E', 'F'))   invert the order
  C_d  [('J', 'D'), ('K', 'E'), ('L', 'F')] zipped
 sC_d  ('J', 'D', 'K', 'E', 'L', 'F')       sum (combine tuples)
Jakube
fuente
44
No te estoy tomando el pelo, acabo de forma independiente escribí la exacta misma solución como lo hizo. Revisé todas las respuestas para tener una idea, pero nada detallado.
orlp
@orlp Sí, es bastante frecuente que el enfoque directo en Pyth sea el más corto. Así que muchas personas lo encuentran fácilmente.
Jakube
@orlp Btw, acaba de hacer una solicitud de extracción al repositorio de Pyth (aún no se acepta). En el futuro, simplemente puede hacer en c2klugar de ck/lk2. c2kdivide la cadena en dos partes iguales.
Jakube
9

Julia, 136 bytes

Una implementación muy sencilla. No es una entrada particularmente competitiva, ¡pero fue divertido!

A->(s=size(A);w=s[2];u=2;C=vcat(A[:,u+1:w],A[:,1:u]);D=cell(s);j=1;for i=1:2:size(C,1) D[j,:]=vec(flipdim(C[i:i+1,:],1));j+=1end;D)

Esto crea una función lambda que acepta una matriz bidimensional como entrada y devuelve una matriz bidimensional transformada.

Ungolfed + explicación:

function f(A)

    # Determine bounds
    s = size(A)          # Store the array dimensions
    w = s[2]             # Get the number of columns
    u = w ÷ 2            # Integer division, equivalent to div(w, 2)

    # Stack the right half of A atop the left
    C = vcat(A[:, u+1:w], A[:, 1:u])

    # Initialize the output array with the appropriate dimensions
    D = cell(s)

    # Initialize a row counter for D
    j = 1

    # Loop through all pairs of rows in C
    for i = 1:2:size(C, 1)

        # Flip the rows so that each column is a flipped pair
        # Collapse columns into a vector and store in D
        D[j, :] = vec(flipdim(C[i:i+1, :], 1))

        j += 1
    end

    return D
end

Para llamarlo, asigne un nombre a la función, por ejemplo f=A->(...).

Salida de ejemplo:

julia> A = ["A" "B" "C" "D" "E" "F";
            "G" "H" "I" "J" "K" "L";
            "M" "N" "O" "P" "Q" "R";
            "S" "T" "U" "V" "W" "X"]
julia> f(A)

4x6 Array{Any,2}:
 "J"  "D"  "K"  "E"  "L"  "F"
 "V"  "P"  "W"  "Q"  "X"  "R"
 "G"  "A"  "H"  "B"  "I"  "C"
 "S"  "M"  "T"  "N"  "U"  "O"

julia> B = ["H" "e" "l" "l";
            "!" " " " " "o";
            "d" " " " " "-";
            "l" "r" "o" "W"]
julia> f(B)

4x4 Array{Any,2}:
 " "  "l"  "o"  "l"
 "o"  " "  "W"  "-"
 "!"  "H"  " "  "e"
 "l"  "d"  "r"  " "

Y prueba de que se puede encadenar arbitrariamente:

julia> f(f(B))

4x4 Array{Any,2}:
 "W"  "o"  "-"  "l"
 "r"  " "  " "  "e"
 "o"  " "  " "  "l"
 "l"  "!"  "d"  "H"

Las sugerencias son bienvenidas como siempre, y me complacerá brindarle más explicaciones.

Alex A.
fuente
8

CJam, 25 24 bytes

qN/_0=,2/f/z~\+2/Wf%:zN*

Implementación de especificaciones directas. Explicación:

qN/                       "Split input by rows";
   _0=,2/                 "Get half of length of each row";
         f/               "Divide each row into two parts";
           z              "Convert array of row parts to array of half columns parts";
            ~\+           "Put the second half of columns before the first half and join";
               2/         "Group adjacent rows";
                 Wf%      "Flip the row pairs to help in CW rotation";
                    :z    "Rotate pairwise column elements CW";
                      N*  "Join by new line";

Pruébalo en línea aquí

Optimizador
fuente
7

JavaScript (ES6), 104141

Editar Revisando la especificación, descubrí que el número de filas debe ser par (me perdí esto antes). Por lo tanto, no es demasiado complicado encontrar la posición de fuente correcta para cada carácter en la salida en un solo paso.

F=a=>a.map((r,i)=>
  [...r].map((c,k)=>
     a[l=i+i]?a[(j=l+1)-k%2][(k+r.length)>>1]:a[l-j-k%2][k>>1]
  ).join('')
)

Prueba en la consola Firefox / FireBug

;[["ABCDEF","GHIJKL","MNOPQR","STUVWX"]
 ,["12","34"], ["Hell","!  o","d  -","lroW"]
 ,["*___  ___  o","o|__) |__) *","*|    |    o","o __   __  *","*|    | _  o","o|__  |__| *"]
].forEach(v=>console.log(v.join('\n')+'\n\n'+F(v).join('\n')))

Salida

ABCDEF
GHIJKL
MNOPQR
STUVWX

JDKELF
VPWQXR
GAHBIC
SMTNUO

12
34

42
31

Hell
!  o
d  -
lroW

 lol
o W-
!H e
ldr 

*___  ___  o
o|__) |__) *
*|    |    o
o __   __  *
*|    | _  o
o|__  |__| *

|_____)   *o
 |_ _     *o
||_ __|   *o
o*|_____)   
o* |_ _     
o*||_ _     
edc65
fuente
5

J, 45 39 bytes

   $$[:,@;@|.@|:([:,:~2,2%~1{$)<@|:@|.;.3]

J tiene una función de teselación (corte ;.) que ayuda mucho.

   ]input=.4 6$97}.a.
abcdef
ghijkl
mnopqr
stuvwx

   ($$[:,@;@|.@|:([:,:~2,2%~1{$)<@|:@|.;.3]) input
jdkelf
vpwqxr
gahbic
smtnuo
randomra
fuente
Vea mi respuesta para otra forma de resolver el desafío en J.
FUZxxl
4

Haskell, 128 127 bytes

import Control.Monad
f=g.ap((++).map snd)(map fst).map(splitAt=<<(`div`2).length)
g(a:b:c)=(h=<<zip b a):g c
g x=x
h(a,b)=[a,b]

Uso: f ["12", "34"]->["42","31"]

Cómo funciona:

                                 input list:
                                   ["abcdef", "ghijkl", "mnopqr", "stuvwx"]
==========================================================================

map(splitAt=<<(`div`2).length)   split every line into pairs of halves:
                                   -> [("abc","def"),("ghi","jkl"),("mno","pqr"),("stu","vwx")]
ap((++).map snd)(map fst)        take all 2nd elements of the pairs and
                                 put it in front of the 1st elements:
                                   -> ["def","jkl","pqr","vwx","abc","ghi","mno","stu"]
(    zip b a) : g c              via g: take 2 elements from the list and
                                 zip it into pairs (reverse order), 
                                 recur until the end of the list:
                                   -> [[('j','d'),('k','e'),('l','f')],[('v','p'),('w','q'),('x','r')],[('g','a'),('h','b'),('i','c')],[('s','m'),('t','n'),('u','o')]]
h=<<                             convert all pairs into a two element list
                                 and concatenate:
                                   -> ["jdkelf","vpwqxr","gahbic","smtnuo"]  

Editar: @Zgarb encontró un byte para guardar.

nimi
fuente
¡Agradable! Puede guardar 1 byte haciendo g x=xpara el caso de la lista vacía.
Zgarb
3

GNU sed -r, 179 bytes

La puntuación incluye +1 para el -rargumento de sed.

Me tomó un tiempo descubrir cómo hacer esto sed, pero creo que lo tengo ahora:

# Insert : markers at start and end of each row
s/  /:  :/g
s/(^|$)/:/g
# Loop to find middle of each row
:a
# Move row start and end markers in, one char at a time
s/:([^  :])([^  :]*)([^ :]):/\1:\2:\3/g
ta
# Loop to move left half of each row to end of pattern buffer
:b
s/([^   :]+)::(.*)/\2   \1/
tb
# remove end marker
s/$/:/
# double loop to merge odd and even rows
:c
# move 1st char of rows 2 and 1 to end of pattern buffer
s/^([^  :])([^  ]*) ([^ ])(.*)/\2   \4\3\1/
tc
# end of row; remove leading tab and add trailing tab 
s/^ +(.*)/\1    /
tc
# remove markers and trailing tab
s/(:|   $)//g

Tenga en cuenta que todos los espacios en blanco anteriores deben ser tabcaracteres individuales . Los comentarios no están incluidos en el puntaje de golf.

Tenga en cuenta también que esto hace un uso extensivo de los :caracteres marcadores. Si la secuencia de entrada contiene :, se producirá un comportamiento indefinido. Esto puede mitigarse reemplazando todo :con algún carácter que no se imprima (por ejemplo, BEL) sin costo alguno para la puntuación de golf.

Entrada y salida es una lista de cadenas separadas por tabulaciones:

$ echo 'Hell
!  o
d  -
lroW' | paste -s - | sed -rf baker.sed | tr '\t' '\n'
 lol
o W-
!H e
ldr 
$ 
Trauma digital
fuente
3

J, 33 32 caracteres

Un verbo monádico.

0 2,.@|:_2|.\"1-:@#@{.(}.,.{.)|:

Explicación

Comencemos definiendo Ycomo nuestra entrada de muestra.

   ] Y =. a. {~ 65 + i. 4 6          NB. sample input
ABCDEF
GHIJKL
MNOPQR
STUVWX

La primera parte ( -:@#@{. (}. ,. {.) |:) se divide Ypor la mitad y se agrega y luego termina:

   # {. Y                            NB. number of columns in Y
6
   -: # {. Y                         NB. half of that
3
   |: Y                              NB. Y transposed
AGMS
BHNT
CIOU
DJPV
EKQW
FLRX
   3 {. |: Y                         NB. take three rows
AGMS
BHNT
CIOU
   3 }. |: Y                         NB. drop three rows
DJPV
EKQW
FLRX
   3 (}. ,. {.) |: Y                 NB. stitch take to drop
DJPVAGMS
EKQWBHNT
FLRXCIOU

En la segunda parte ( _2 |.\"1) dividimos esto en pares de dos y los invertimos:

   R =. (-:@#@{. (}. ,. {.) |:) Y    NB. previous result
   _2 <\"1 R                         NB. pairs put into boxes
┌──┬──┬──┬──┐
│DJ│PV│AG│MS│
├──┼──┼──┼──┤
│EK│QW│BH│NT│
├──┼──┼──┼──┤
│FL│RX│CI│OU│
└──┴──┴──┴──┘
   _2 <@|.\"1 R                      NB. reversed pairs
┌──┬──┬──┬──┐
│JD│VP│GA│SM│
├──┼──┼──┼──┤
│KE│WQ│HB│TN│
├──┼──┼──┼──┤
│LF│XR│IC│UO│
└──┴──┴──┴──┘

Finalmente (0 2 ,.@|: ), transponemos la matriz según sea necesario y descartamos el eje final:

   ] RR =. _2 |.\"1 R                NB. previous result
JD
VP
GA
SM

KE
WQ
HB
TN

LF
XR
IC
UO
   0 2 |: RR                         NB. transpose axes
JD
KE
LF

VP
WQ
XR

GA
HB
IC

SM
TN
UO
   ($ RR) ; ($ 0 2 |: RR)            NB. comparison of shapes
┌─────┬─────┐
│3 4 2│4 3 2│
└─────┴─────┘
   ,. 0 2 |: RR                      NB. discard trailing axis
JDKELF
VPWQXR
GAHBIC
SMTNUO

Toda la expresión con espacios en blanco insertados:

0 2 ,.@|: _2 |.\"1 -:@#@{. (}. ,. {.) |:

Y como verbo explícito:

3 : ',. 0 2 |: _2 |.\"1 (-: # {. y) (}. ,. {.) |: y'
FUZxxl
fuente