Diskrete Bäckerkarte

15

Einführung

Die Karte des Bäckers ist ein wichtiges dynamisches System, das chaotisches Verhalten aufweist. Es ist eine Funktion vom Einheitsquadrat bis zu sich selbst, die intuitiv wie folgt definiert wird.

  • Schneiden Sie das Quadrat vertikal in zwei Hälften, um zwei Rechtecke zu erhalten 0.5×1.
  • Stapeln Sie die rechte Hälfte über die linke, so dass ein Rechteck entsteht 0.5×2
  • Komprimiere das Rechteck wieder zu einem 1×1Quadrat.

In dieser Herausforderung implementieren Sie eine diskrete Version dieser Umwandlung.

Ein- und Ausgang

Bei Ihrer Eingabe handelt es sich um ein 2D-Array druckbarer ASCII-Zeichen und 2m×2nbei einigen um Leerzeichen m, n > 0. Ihre Ausgabe ist ein ähnliches Array, das mithilfe des 6×4Arrays wie folgt erhalten wird

ABCDEF
GHIJKL
MNOPQR
STUVWX

als Beispiel. Stapeln Sie zuerst die rechte Hälfte des Arrays über die linke Hälfte:

DEF
JKL
PQR
VWX
ABC
GHI
MNO
STU

Teilen Sie dann die Spalten in Zeichenpaare auf und drehen Sie jedes Paar unabhängig voneinander um 90 Grad im Uhrzeigersinn, um das hohe Rechteck wieder in die ursprüngliche Form zu "komprimieren":

JDKELF
VPWQXR
GAHBIC
SMTNUO

Dies ist die korrekte Ausgabe für das obige Array.

Regeln

Die Eingabe- und Ausgabeformate sind flexibel. Sie können durch Zeilenumbrüche getrennte Zeichenfolgen, Listen von Zeichenfolgen oder 2D-Arrays von Zeichen verwenden. Die Eingabe und Ausgabe müssen jedoch genau dasselbe Format haben: Sie müssen in der Lage sein, Ihre Eingabe beliebig oft für eine gültige Eingabe zu wiederholen.

Sie können entweder ein vollständiges Programm oder eine Funktion schreiben. Die niedrigste Byteanzahl gewinnt, und Standardlücken sind nicht zulässig.

Testfälle

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
quelle

Antworten:

11

Pyth, 25 19 18 Bytes

msC_dcs_Cmck/lk2Q2

Online-Demonstration . Es wird ein 2D-Array von Zeichen verwendet.

Das Array von Zeichenfolgen ist ein Zeichen länger (19 Byte). Online-Demonstration

Erläuterung:

         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

Der letzte Teil ist zunächst etwas verwirrend. Nehmen wir an, wir haben das Tupel ['DEF', 'JKL'](ich verwende das Beispiel aus dem 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
quelle
4
Ich mache keine Witze, ich habe nur unabhängig die exakt gleiche Lösung wie Sie geschrieben. Ich habe alle Antworten beschönigt, um eine Vorstellung zu bekommen, aber nichts Detailliertes.
Orlp
@orlp Ja, es kommt ziemlich oft vor, dass der direkte Ansatz in Pyth der kürzeste ist. So finden es mehrere Menschen leicht.
Jakube
@orlp Übrigens, habe gerade eine Pull-Anfrage an das Pyth-Repo gesendet (noch nicht akzeptiert). In Zukunft können Sie einfach tun c2kstatt ck/lk2. c2kTeilt die Zeichenfolge in zwei gleiche Teile.
Jakube
9

Julia, 136 Bytes

Eine sehr einfache Implementierung. Kein besonders konkurrenzfähiger Beitrag, aber es hat Spaß gemacht!

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)

Dadurch wird eine Lambda-Funktion erstellt, die ein zweidimensionales Array als Eingabe akzeptiert und ein transformiertes zweidimensionales Array zurückgibt.

Ungolfed + Erklärung:

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

Um es aufzurufen, geben Sie der Funktion einen Namen, z f=A->(...).

Beispielausgabe:

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

Und der Beweis, dass es beliebig verkettet werden kann:

julia> f(f(B))

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

Vorschläge sind wie immer willkommen und ich gebe gerne weitere Erklärungen.

Alex A.
quelle
8

CJam, 25 24 Bytes

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

Einfache Implementierung der Spezifikation. Erläuterung:

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

Probieren Sie es hier online aus

Optimierer
quelle
7

JavaScript (ES6), 104 141

Bearbeiten Beim Überprüfen der Spezifikation stellte ich fest, dass die Anzahl der Zeilen gerade sein muss (das habe ich zuvor verpasst). So ist es nicht allzu kompliziert, in einem einzigen Schritt die richtige Quellenposition für jedes Zeichen in der Ausgabe zu finden.

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

Test In der Firefox / FireBug-Konsole

;[["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')))

Ausgabe

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
quelle
5

J 45 39 Bytes

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

J hat eine Tessellation-Funktion (Cut ;.), die sehr hilfreich ist.

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

   ($$[:,@;@|.@|:([:,:~2,2%~1{$)<@|:@|.;.3]) input
jdkelf
vpwqxr
gahbic
smtnuo
randomra
quelle
Siehe meine Antwort für einen anderen Weg, um die Herausforderung in 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]

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

Wie es funktioniert:

                                 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 hat ein zu speicherndes Byte gefunden.

nimi
quelle
Nett! Sie können 1 Byte speichern, indem Sie g x=xfür den leeren Listenfall tun .
Zgarb
3

GNU sed -r, 179 Bytes

Die Punktzahl enthält +1 für das zu -rsedierende Argument.

Es hat eine Weile gedauert, bis ich herausgefunden habe, wie das funktioniert sed, aber ich glaube, ich habe es jetzt:

# 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

Beachten Sie, dass alle oben genannten Leerzeichen aus einzelnen tabZeichen bestehen sollten. Kommentare sind in der Golfwertung nicht enthalten.

Beachten Sie auch, dass dies in großem Umfang :Markierungszeichen verwendet. Wenn der Eingabestream enthält :, tritt undefiniertes Verhalten auf. Dies kann abgemildert werden, indem alle :Zeichen durch nicht druckbare Zeichen (z. B. BEL) ersetzt werden. Dies ist für die Golfwertung kostenlos .

Eingabe und Ausgabe ist eine durch Tabulatoren getrennte Liste von Zeichenfolgen:

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

J, 33 32 Zeichen

Ein monadisches Verb.

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

Erläuterung

Beginnen wir mit der Definition Y, dass dies unser Beispiel ist.

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

Der erste Teil ( -:@#@{. (}. ,. {.) |:) wird Yin zwei Hälften geteilt und an das Ende angehängt:

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

Im zweiten Teil ( _2 |.\"1) teilen wir dies in Zweierpaare auf und kehren sie um:

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

Schließlich ( 0 2 ,.@|:) transponieren wir die Matrix nach Bedarf und verwerfen die nachlaufende Achse:

   ] 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

Der gesamte Ausdruck mit eingefügtem Leerzeichen:

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

Und als explizites Verb:

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