Carte de Baker discrète

15

introduction

La carte de Baker est un système dynamique important qui présente un comportement chaotique. C'est une fonction du carré unitaire à elle-même définie intuitivement comme suit.

  • Coupez le carré verticalement en deux, ce qui donne deux rectangles de taille 0.5×1.
  • Empilez la moitié droite en haut à gauche, ce qui donne un rectangle de taille 0.5×2
  • Compressez le rectangle en un 1×1carré.

Dans ce défi, vous allez implémenter une version discrète de cette transformation.

Entrée et sortie

Votre entrée est un tableau 2D de caractères ASCII imprimables et des espaces de taille 2m×2npour certains m, n > 0. Votre sortie est un tableau similaire obtenu comme suit, en utilisant le 6×4tableau

ABCDEF
GHIJKL
MNOPQR
STUVWX

par exemple. Tout d'abord, empilez la moitié droite du tableau en haut de la moitié gauche:

DEF
JKL
PQR
VWX
ABC
GHI
MNO
STU

Ensuite, divisez les colonnes en paires de caractères et tournez indépendamment chaque paire de 90 degrés dans le sens des aiguilles d'une montre, en "compressant" le grand rectangle à sa forme d'origine:

JDKELF
VPWQXR
GAHBIC
SMTNUO

Il s'agit de la sortie correcte pour le tableau ci-dessus.

Règles

Les formats d'entrée et de sortie sont flexibles. Vous pouvez utiliser des chaînes délimitées par des sauts de ligne, des listes de chaînes ou des tableaux 2D de caractères. Cependant, l'entrée et la sortie doivent avoir exactement le même format: vous devez pouvoir répéter votre soumission un nombre arbitraire de fois sur n'importe quelle entrée valide.

Vous pouvez écrire soit un programme complet soit une fonction. Le nombre d'octets le plus bas gagne et les failles standard sont interdites.

Cas de test

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
la source

Réponses:

11

Pyth, 25 19 18 octets

msC_dcs_Cmck/lk2Q2

Démonstration en ligne . Il utilise un tableau 2D de caractères.

Le tableau de chaînes est un caractère plus long (19 octets). Démonstration en ligne

Explication:

         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 dernière partie est un peu déroutante au début. Supposons que nous ayons le tuple ['DEF', 'JKL'](j'utilise l'exemple de l'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
la source
4
Je ne vous plaisantez, je viens écrit la indépendamment exacte même solution que vous avez fait. J'ai passé sous silence toutes les réponses pour avoir une idée, mais rien de détaillé.
orlp
@orlp Oui, c'est assez souvent que l'approche directe en Pyth est la plus courte. Ainsi, plusieurs personnes le trouvent facilement.
Jakube
@orlp Btw, vient de faire une pull request au repo Pyth (pas encore accepté). À l'avenir, vous pouvez simplement faire c2kau lieu de ck/lk2. c2kdivise la chaîne en deux parties égales.
Jakube
9

Julia, 136 octets

Une implémentation très simple. Pas une entrée particulièrement compétitive, mais c'était amusant!

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)

Cela crée une fonction lambda qui accepte un tableau à 2 dimensions en entrée et renvoie un tableau à 2 dimensions transformé.

Non golfé + explication:

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

Pour l'appeler, donnez un nom à la fonction, par exemple f=A->(...).

Exemple de sortie:

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

Et preuve qu'il peut être enchaîné arbitrairement:

julia> f(f(B))

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

Les suggestions sont les bienvenues comme toujours, et je me ferai un plaisir de vous fournir d'autres explications.

Alex A.
la source
8

CJam, 25 24 octets

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

Implémentation simple des spécifications. Explication:

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

Essayez-le en ligne ici

Optimiseur
la source
7

JavaScript (ES6), 104 141

Edit En examinant la spécification, j'ai trouvé que le nombre de lignes doit être pair (j'ai manqué cela auparavant). Il n'est donc pas trop compliqué de trouver la position source correcte pour chaque caractère en sortie en une seule étape.

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('')
)

Tester dans la console 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')))

Production

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
la source
5

J, 45 39 octets

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

J a une fonction de pavage (coupe ;.) qui aide beaucoup.

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

   ($$[:,@;@|.@|:([:,:~2,2%~1{$)<@|:@|.;.3]) input
jdkelf
vpwqxr
gahbic
smtnuo
randomra
la source
Voir ma réponse pour une autre façon de résoudre le défi dans J.
FUZxxl
4

Haskell, 128 127 octets

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]

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

Comment ça fonctionne:

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

Edit: @Zgarb a trouvé un octet à enregistrer.

nimi
la source
Agréable! Vous pouvez enregistrer 1 octet en faisant g x=xpour le cas de liste vide.
Zgarb
3

GNU sed -r, 179 octets

Le score inclut +1 pour l' -rarg à sed.

Il m'a fallu un certain temps pour comprendre comment procéder sed, mais je pense que je l'ai maintenant:

# 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

Notez que tous les espaces ci-dessus doivent être des tabcaractères simples . Les commentaires ne sont pas inclus dans le score de golf.

Notez également que cela utilise largement les :caractères marqueurs. Si le flux d'entrée contient :, un comportement indéfini s'ensuivra. Ceci peut être atténué en remplaçant tous :par un caractère non imprimable (par exemple BEL) sans frais pour le score de golf.

L'entrée et la sortie sont une liste de chaînes séparées par des tabulations:

$ echo 'Hell
!  o
d  -
lroW' | paste -s - | sed -rf baker.sed | tr '\t' '\n'
 lol
o W-
!H e
ldr 
$ 
Traumatisme numérique
la source
3

J, 33 32 caractères

Un verbe monadique.

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

Explication

Commençons par définir Ycomme étant notre exemple d'entrée.

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

La première partie ( -:@#@{. (}. ,. {.) |:) se divise Yen deux et ajoute puis se termine:

   # {. 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

Dans la deuxième partie ( _2 |.\"1), nous divisons cela en paires de deux et les inversons:

   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│
└──┴──┴──┴──┘

Enfin ( 0 2 ,.@|:), nous transposons la matrice au besoin et éliminons l'axe de fuite:

   ] 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

L'expression entière avec un espace inséré:

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

Et comme verbe explicite:

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