Na mojej Kostce Rubika jest mrówka


44

Standardowa, rozwiązana kostka Rubika 3 × 3 × 3 ma 6 różnokolorowych ścian, z których każda jest siatką kwadratów 3 × 3 w jednym kolorze. Biała twarz jest naprzeciwko żółtego, czerwona przeciwnie do pomarańczowego, niebieska przeciwnie do zielonego, a kiedy biały jest skierowany w górę, czerwony jest po lewej stronie niebieskiego:

Układ kostki Rubika

Wyobraź sobie, że mrówka siedzi na środkowym kwadracie białej twarzy, twarzą do czerwonej twarzy. Możesz mu dać 3 polecenia:

  • Forward ( ^) - zrób krok w kierunku do następnego kwadratu siatki, przekraczając w razie potrzeby krawędź sześcianu.
  • W prawo ( >) - obróć w prawo (zgodnie z ruchem wskazówek zegara) o 90 °, pozostając w tym samym kwadracie siatki.
  • Lewo ( <) - obróć w lewo (przeciwnie do ruchu wskazówek zegara) o 90 °, pozostając w tym samym kwadracie siatki.

Biorąc pod uwagę dowolną listę poleceń, znajdź kolory kwadratów odwiedzanych przez mrówkę (nie licząc białego kwadratu początkowego).

Na przykład sekwencja poleceń ^^>^^<^^^ma ścieżkę, która wygląda następująco:

przykładowa ścieżka

Kolory kwadratów siatki odwiedzanych w kolejności, nie licząc kwadratu początkowego, są white red red green green green yellowlub są po prostu wrrgggy.

Napisz program lub funkcję, która pobiera ciąg znaków polecenia <^>i wypisuje lub zwraca ciąg znaków wyrobg(biały, żółty, czerwony pomarańczowy, niebieski, zielony), który odpowiada ścieżce mrówki nad kostką.

Najkrótszy kod w bajtach wygrywa. Tiebreaker to wcześniejsza odpowiedź.

Notatki

  • Sześcian jest w powietrzu, a mrówka ma skuteczne pulvilli, dzięki czemu może przemierzać całą kostkę.
  • Kostka zawsze pozostaje w stanie rozwiązanym.
  • Kolor kwadratu jest rejestrowany tylko po przesunięciu w kwadrat, a nie po obrocie. Początkowy biały kwadrat nie powinien być zapisywany.
  • Pojedynczy opcjonalny znak nowej linii może być obecny na wejściu i / lub wyjściu.

Przypadki testowe

input : output
[empty string] : [empty string]
^ : w
< : [empty string]
> : [empty string]
><><<<>> : [empty string]
>^ : w
<<^> : w
^<^<^<^< : wwww
^^ : wr
<^^ : wb
>><<<<^^ : wo
<^^^<^^^^<>^>^^>^ : wbbboooggyo
^^^^^^^^^^^^^^ : wrrryyyooowwwr
<<<^<^>^<^<^<^>^^^^<^>>>>>^^<^>^^<^>^>^>^>< : wwgrwgggoooobbbbyrby
^^>^^<^^^ : wrrgggy


2
@ MartinBüttner Mrówki mają sześć nóg, sześciany mają sześć boków. <shrug> Nie wiem ...
Cyfrowa trauma

4
To nie jest wyzwanie dla początkujących graczy w golfa ... Tracę rozum, wymyślając układ współrzędnych, który nie jest sztywno zakodowany.
Matt

2
@DigitalTrauma To wyzwanie krzyczy o odpowiedź Hexagony :-)
Luis Mendo

1
Jestem tak blisko z najgorszym kodem PowerShell, jaki kiedykolwiek widziałeś.
Matt

Odpowiedzi:


18

Perl, 156 143 134 128 128 127 125 120 119 117 113 109 bajtów

Obejmuje +1 dla -p

Uruchom z ciągiem kontrolnym na STDIN, np

perl -p rubic.pl <<< "^^>^^<^^^"

rubic.pl:

@1=wryobg=~/./g;s##$n=w&$&;$y+=$x-=$y+=$x,@1[0,4,2,5,3,1]=@1while--$n%9;@{$n&&--$y%3}[3,0..2]=@1;$1[$n+9]#eg

Wyjaśnienie

Starsza wersja:

@f=gboyrw=~/./g;s##$n=w&$&;$y+=$x-=$y+=$x,@f=@f[2,4,1,3,0,5]while--$n%9;@f=@f[0,$y=1,5,2..4]if$n&&$y--<0;$f[$n+8]#eg

Wyzwaniem dla tego pytania jest znalezienie układu współrzędnych, który ułatwia śledzenie położenia i kierunku mrówki, a także łatwe identyfikowanie twarzy.

System, który wybrałem, polegał na umieszczeniu standardowych (x,y)współrzędnych na twarzy mrówki, tak aby mrówka zawsze była skierowana w ykierunku ujemnym, a środek jej twarzy był (0,0). Więc:

rotate right: (x',y') <- (-y,  x)
rotate left:  (x',y') <- ( y, -x)  alternatve: 3 right rotations
Step forward:   y' <- y-1

Jeśli ybyła już -1mrówka, opuści obecną twarz i wejdzie na następną. W nowym układzie współrzędnych xzachowuje swoją wartość, ale y'staje się 1.

Daje to łatwy układ współrzędnych w obrębie twarzy. Potrzebuję też czegoś dla samych twarzy. Tam używam tablicy składającej się z

The face to right of the ant            g in the initial position
The face to the left of of the ant      b
The face behind the ant                 o
The face opposite to the ant            y
The face before the ant                 r
The face the ant is on                  w

Tak więc początkowa tablica to (g,b,o,y,r,w). Przejście do następnej ściany odpowiada obróceniu ostatnich 4 elementów, więc przejście z białej na czerwoną czyni to (g,b,w,o,y,r). Skręcenie w prawo to permutacja pierwszych 5 elementów (o,r,b,y,g,w). Skręcanie w lewo jest symulacją permutacji, ale można to również zrobić, obracając w prawo 3 razy, więc zastosuj tę permutację 3 razy. W ogóle nie można odwrócić, stosując permutację 8 razy. W rzeczywistości skręcenie w prawo można również wykonać, stosując permutację 5 razy.

Wiedząc o tym, program jest raczej prosty:

@f=gboyrw=~/./g                 Set up the initial face orientation
s## ... #eg                     Process each control string character
                                {this is equivalent to s#.#...#eg because
                                the empty regex repeats the last
                                succesful regex)
$n=w&$&                         Calculate n, the number of right
                                rotations+1 modulo 9.
                                This abuses a coincidence of the control
                                characters:
                                 "<" & "w" = "4" -> 3 right rotations
                                 ">" & "w" = "6" -> 5 right rotations
                                 "^" & "w" = "V" = 0 but that is 9 mod 9
                                 so leads to 8 right rtations

$y+=$x-=$y+=$x,                 This is the same as ($x,$y)=(-$y,$x), so
                                a right rotation of the face coordinates
@f=@f[2,4,1,3,0,5]              Right rotation of the face array
   while --$n%9                 Rotate right n-1 times. After this n=0
                                If this was a step then n was effectively 0.
                                So rotate right 8 times leaving n=-9

    ... if $n                   If a step...
               $y--             ... decrease y ...
             &&$y--<0           ... but if y was already negative ...
@f=@f[0,$y=1,5,2..4]            ... change face and set y to 1

$f[$n+8]                        return the last element (current face)
                                if this was a step, otherwise empty

Tak więc dla tego ostatniego polecenia obroty prowadzą do pustego łańcucha, a kroki do przodu prowadzą do bieżącej ściany. Dlatego $_zostaje zastąpiony przez twarze odwiedzane na każdym kroku.


Jeśli rozumiem, co się tutaj dzieje, ten @1fragment jest niesamowitym nadużyciem czegoś, co wygląda jak przerażająca funkcja językowa.
Nie to, że Charles

@NotthatCharles Tak, to jest tak samo złe, jak się wydaje. W poważnych programach perlowych pierwszą rzeczą, którą robisz, jest wyłączenie tej funkcji use strict. Nawiasem mówiąc, dzięki za moduł 3.
Ton Hospel

12

Brachylog , 287 bajtów

:1:2222:"w":"y":["r":"b":"o":"g"]{h""|[L:I:N:A:B:[C:D:E:F]]hhM("^",(NhI,CwX,EY,B:D:A:FZ;AwX,BY,[C:D:E:F]Z),NhJ,(I1,2313O;I2,(Nh2,N$($(O;Nh1,2222O;Nbh1,3223O;3322O);3322N,2332O;3223N,2233O;2233N,3132O;2332N,3231O);IJ,AX,BY,(M"<",[C:D:E:F]$(Z,N$(O;M">",[C:D:E:F]$)Z,N$)O)),Lb:J:O:X:Y:Z:1&}

Oczekuje łańcuch zawierający ruchy jako wejście, a nie wyjście, np brachylog_main("^^>^^<^^^",_).wypisze wrrgggyna standardowe wyjście.

Wyjaśnienie

§ There are 3 types of tiles we can be on: centers (noted 1), edges (2) and corners (3)
§ When we are on a tile, we can denote adjacent tiles in order: front, left, back, right
§ Similarly, we can denote the adjacent colors depending on the current one of the face
§
§ We start on the center (1) of face white ("w"). The adjacent tiles are 4 edges (2222)
§ The adjacent colors of white are red, blue, orange and green ("r":"b":"o":"g")
§ Yellow is opposite of white ("y")

§ We pass those initial conditions in an array, with the sequence of moves as first
§ element, as input to subpredicate 1


:1:2222:"w":"y":["r":"b":"o":"g"]{...}


§ SUB-PREDICATE 1

h""  § If the sequence of moves is empty, terminate the recursion
|    § Else...

§ Here are the variables' names of the input (which correspond to what's described in
§ the first few paragraphs)
[L:I:N:A:B:[C:D:E:F]]

§ If the move is "^"...
hhM("^",

   § The only way we change from one face to another is if the tile we end up on is of the
   § same type as the tile we started from
   (NhI,      § If this is the case
    CwX,      § Then write the color of the face we're facing, this face will now be the
              § current color
    EY,       § The third color in the list is now the opposite color
    B:D:A:FZ  § The opposite color is now the one we face, the color behind us (the third
              § in the list) is the one we were on, and the other 2 don't change

    § If the tiles are not the same type, then we don't change color
    ; 
    AwX,         § Write the current color, this will remain the color
    BY,          § Opposite color stays the same
    [C:D:E:F]Z), § Other colors stay in the same order since we moved forward
    NhJ,              § The new tile type is the one we were facing
       (I1,2313O;     § If we were on the center, then the adjacent tiles are 2313
       I2,            § Else if we were on an edge
         (Nh2,N$($(O; § then if we were facing an edge (changed face), then the new types
                      § of tiles are a double circular permutation of the previous types
         Nh1,2222O;   § Else if we were facing a center, then the new tiles are 2222
         Nbh1,3223O;  § Else (corners) if the tile to our left is the center, then 3223
         3322O)       § Else 3322

       ;              § Else if we were on a corner
       3322N,2332O;   § then one of those 4 possibilities applies
       3223N,2233O;
       2233N,3132O;
       2332N,3231O)

§ Else if the move is NOT "^"
;
IJ,AX,BY,         § We stay on the same type of tile, same color, same opposite color
(M"<",            § if the move is "turn left"
    [C:D:E:F]$(Z, § Then we circular permute the adjacent colors to the left
    N$(O          § we also circular permute the adjacent tiles to the left
;M">",            § Else if the move is "turn right"
    [C:D:E:F]$)Z, § Then we do the same but with right circular permutations
    N$)O)
),
Lb:J:O:X:Y:Z:1&   § Recursively call sub-predicate 1 with the new input, and the next move

Odpowiednik kodu SWI-Prolog

Jeśli nie chcesz zawracać sobie głowy kompilatorem Brachylog, możesz uruchomić to rozwiązanie w SWI-Prolog przy użyciu następującego kodu (to jest generowane przez kompilator Brachylog):

:- style_check(-singleton).

:- use_module(library(clpfd)).

brachylog_main(Input,Output) :-
    1=1,
    brachylog_subpred_1([Input,1,2222,"w","y",["r","b","o","g"]],V0).


brachylog_subpred_1(Input,Output) :-
    1=1,
    brachylog_head(Input, "").

brachylog_subpred_1(Input,Output) :-
    1=1,
    [L,I,N,A,B,[C,D,E,F]] = Input,
    brachylog_head([L,I,N,A,B,[C,D,E,F]], V0),
    brachylog_head(V0, M),
    ( 1=1,
    "^" = M,
    ( 1=1,
    brachylog_head(N, I),
    brachylog_write(C, X),
    Y = E,
    Z = [B,D,A,F]
    ;
    1=1,
    brachylog_write(A, X),
    Y = B,
    Z = [C,D,E,F]
    ),
    brachylog_head(N, J),
    ( 1=1,
    I = 1,
    O = 2313
    ;
    1=1,
    I = 2,
    ( 1=1,
    brachylog_head(N, 2),
    brachylog_math_circular_permutation_left(N, V1),
    brachylog_math_circular_permutation_left(V1, O)
    ;
    1=1,
    brachylog_head(N, 1),
    O = 2222
    ;
    1=1,
    brachylog_behead(N, V2),
    brachylog_head(V2, 1),
    O = 3223
    ;
    1=1,
    O = 3322
    )
    ;
    1=1,
    N = 3322,
    O = 2332
    ;
    1=1,
    N = 3223,
    O = 2233
    ;
    1=1,
    N = 2233,
    O = 3132
    ;
    1=1,
    N = 2332,
    O = 3231
    )
    ;
    1=1,
    J = I,
    X = A,
    Y = B,
    ( 1=1,
    "<" = M,
    brachylog_math_circular_permutation_left([C,D,E,F], Z),
    brachylog_math_circular_permutation_left(N, O)
    ;
    1=1,
    ">" = M,
    brachylog_math_circular_permutation_right([C,D,E,F], Z),
    brachylog_math_circular_permutation_right(N, O)
    )
    ),
    brachylog_behead(L, V3),
    brachylog_call_predicate([V3,J,O,X,Y,Z,1], V4).



brachylog_behead(X,Y) :-
    string(X),!,
    sub_string(X, 1, _, 0, Y)
    ;
    number(X),!,
    number_codes(X,[_|T]),
    catch(number_codes(Y,T),_,Y=[])
    ;
    atom(X),!,
    atom_codes(X,[_|T]),
    atom_codes(Y,T)
    ;
    X = [_|Y].

brachylog_math_circular_permutation_left(X,Y) :-
    string(X),!,
    string_codes(X,C),
    C = [H|T],
    append(T,[H],D),
    string_codes(Y,D)
    ;
    number(X),!,
    number_codes(X,C),
    C = [H|T],
    append(T,[H],D),
    number_codes(Y,D)
    ;
    atom(X),!,
    atom_codes(X,C),
    C = [H|T],
    append(T,[H],D),
    atom_codes(Y,D)
    ;
    X = [H|T],!,
    append(T,[H],Y).

brachylog_math_circular_permutation_right(X,Y) :-
    string(X),!,
    string_codes(X,C),
    append(T,[H],C),
    D = [H|T],
    string_codes(Y,D)
    ;
    number(X),!,
    number_codes(X,C),
    append(T,[H],C),
    D = [H|T],
    number_codes(Y,D)
    ;
    atom(X),!,
    atom_codes(X,C),
    append(T,[H],C),
    D = [H|T],
    atom_codes(Y,D)
    ;
    append(T,[H],X),
    Y = [H|T].

brachylog_call_predicate(X,Y) :-
    reverse(X,R),
    R = [N|RArgs],
    number(N),
    reverse(RArgs, Args),
    (
    N = 0,!,
    Name = brachylog_main
    ;
    atom_concat(brachylog_subpred_,N,Name)
    ),
    (
    Args = [UniqueArg],!,
    call(Name,UniqueArg,Y)
    ;
    call(Name,Args,Y)
    ).

brachylog_write(X,Y) :-
    X = [List,Format],
    is_list(List),
    string(Format),!,
    format(Format,List),
    flush_output,
    Y = List
    ;
    write(X),
    flush_output,
    Y = X.

brachylog_head(X,Y) :-
    string(X),!,
    sub_string(X, 0, 1, _, Y)
    ;
    number(X),!,
    number_codes(X,[A|_]),
    number_codes(Y,[A])
    ;
    atom(X),!,
    atom_codes(X,[A|_]),
    atom_codes(Y,[A])
    ;
    X = [Y|_].

4

PowerShell, 882 bajty

Stosowanie

Zapisz kod w skrypcie i wywołaj go w ten sposób z wiersza poleceń. Zakładając, że katalog roboczy jest katalogiem bieżącym.

.\WalkingAntcg.ps1 "^^>^^<^^^"

Kod

$o=[char[]]"grbowy";[int]$c=4;[int]$global:x=1;[int]$global:y=1;[int]$f=1;[int]$n=5;
$u={$c=$args[0];$1="341504251435240503210123".Substring($c*4,4);$2=$1*2-match".$($args[1]).";$3=$Matches[0];"$3";"012345"-replace([char[]]"$1$c"-join"|")}
function t{param($o,$x,$y)if($o){switch($y){0{switch($x){0{$x=2}1{$y=1;$x=2}2{$y=2}}}1{switch($x){0{$y=0;$x=1}2{$y=2;$x=1}}}2{switch($x){0{$x=0;$y=0}1{$x=0;$y=1}2{$x=0}}}}}else{switch($y){0{switch($x){0{$y=2}1{$x=0;$y=1}2{$x=0}}}1{switch($x){0{$y=2;$x=1}2{$y=0;$x=1}}}2{switch($x){0{$x=2}1{$x=2;$y=1}2{$y=0;$x=2}}}}}$global:x=$x;$global:y=$y}
([char[]]$args[0]|%{switch($_){'^'{$global:y++;if($global:y-eq3){$global:y=0;$c="$f";$f="$n";$z=&$u $c $f;$f,$n="$($z[0][1])","$($z[1])"}$o[$c]}
"<"{$z=&$u $c $f;$f,$n="$($z[0][0])","$($z[1])";t 0 $global:x $global:y}
">"{$z=&$u $c $f;$f,$n="$($z[0][2])","$($z[1])";t 1 $global:x $global:y}}})-join""

Mniej golfowy kod z wyjaśnieniem

# Recorded order of cube colours and their indexes
# Green=0,Red=1,Blue=2,Orange=3,White=4,Yellow=5
$o=[char[]]"grbowy"
[int]$c=4   # Ant is currently on this colour
[int]$global:x=1   # X coordinate on this face
[int]$global:y=1   # Y coordinate on this face
[int]$f=1   # Colour that the Ant is facing
[int]$n=5   # Colour beyond that the ant is facing.
# If the ant moves of this cube to the next this value becomes the one he is facing.
# It is also the only colour not neighboring this current colour.

# Anonymous function that will return the colour facing left and right
$u = {
# Cube relationships relative to position. Groups of 4 colours that are important given the order...
# Green=0-3,Red=4-7,Blue=8-11,Orange=12-15,White=16-19,Yellow=20-23
# Get the colours surrounding the current colour we are on and the surrounding ones
# String version: "owrygwbyrwoybwgygrbogrbo"
$c=$args[0]
#  "341504251435240501230123"
$1="341504251435240503210123".Substring($c*4,4)
# double the string so that we can get the characters before and after the facing colour reliably
# Assign the output to surpress a boolean. $2 is not used. Shorter than a cast
$2=$1*2-match".$($args[1]).";$3=$Matches[0]
# Return two values. First is the colours to the left,current and right as a string.
# Second is the colour beyond the one we are facing. If we were to move forward two blocks
# we would end up on this colour
"$3";"012345"-replace([char[]]"$1$c"-join"|")
}

# function that will transpose the ants position based on right/left rotation.
# Using current x and y determines what the tranposed values are and return them.
function t{
    param($o,$x,$y)
    # X = $1; Y = $2
    # Left 0 Right 1
    if($o){
        # Right Transpose
        # All values are hard coded to rotate to their new positions
        switch($y){
            0{switch($x){0{$x=2}1{$y=1;$x=2}2{$y=2}}}
            # 1,1 is in the center and nothing changes
            1{switch($x){0{$y=0;$x=1}2{$y=2;$x=1}}}
            2{switch($x){0{$x=0;$y=0}1{$x=0;$y=1}2{$x=0}}}
        }
    }else{
        # Left Transpose
        # All values are hard coded to rotate to their new positions
        switch($y){
            0{switch($x){0{$y=2}1{$x=0;$y=1}2{$x=0}}}
            # 1,1 is in the center and nothing changes
            1{switch($x){0{$y=2;$x=1}2{$y=0;$x=1}}}
            2{switch($x){0{$x=2}1{$x=2;$y=1}2{$y=0;$x=2}}}
        }

    }
    # Update global variables with the ones from this function
    $global:x=$x
    $global:y=$y
}

# Process each character passed by standard input
([char[]]$args[0]|%{
    switch($_){
        # Moving Forward
        '^'{
        $global:y++
        if($global:y-eq3){
            # We have walked of the colour onto the next one. Update coordinates to the next colour
            $global:y=0
            $c="$f"
            $f="$n"
            # Get the new neighboring colour indexes
            $z=&$u $c $f
            $f,$n="$($z[0][1])","$($z[1])"
        }  
        # Output the colour we have just moved to.
        $o[$c]
        }
        # Turn Left
        "<"{$z=&$u $c $f;$f,$n="$($z[0][0])","$($z[1])"
        # Transpose the ants location by passing current location to the transposition function.
        t 0 $global:x $global:y
        }
        # Turn Right
        ">"{$z=&$u $c $f;$f,$n="$($z[0][2])","$($z[1])"
        # Transpose the ants location by passing current location to the transposition function.
        t 1 $global:x $global:y
        }
    }
}) -join ""
# Line above converts the output to a single string. 

Używanie wielu zmiennych jednoliterowych używanych do rejestrowania aktualnego stanu mrówki (kolor, położenie i orientacja). Mrówka zawsze jest skierowana do góry. Po odczytaniu instrukcji obrotu sześcian jest transponowany w tym kierunku. Zakodowane macierze transpozycji używane do określania nowej pozycji na podstawie aktualnej pozycji.

Kod spełnia wszystkie omawiane przykłady.


Można w to zagrać bardziej w golfa, ale teraz działa, więc muszę teraz spróbować usunąć część powtórzeń.
Matt

3

Tcl / Tk, 422 bajty

rename split S
array se {} [S wyywroorgbbg {}]
proc R a {foreach x [lassign $a y] {lappend b $x}
lappend b $y}
proc < {V H} {set ::H $V
set ::V [lreverse [R $H]]}
proc > {V H} [string map {V H H V} [info b <]]
proc ^ {V H} {
lassign $V x
lassign [set ::V [R $V]] y
set ::H [string map "$x $y $::($x) $::($y)" $::H]
puts -nonewline $y}
set V [S wwrrryyyooow {}]
set H [S wwgggyyybbbw {}]
foreach p [S {*}$argv {}] {$p $V $H}

Niestety, nie mogę tego zmniejszyć. Wersja nie zaciemniona:

array set opposites [split wyywroorgbbg {}]

proc lrotate xs {
  foreach x [lassign $xs y] {
    lappend ys $x
  }
  lappend ys $y
}

proc < {V H} {
  set ::H $V
  set ::V [lreverse [lrotate $H]]
}

proc > {V H} {
  set ::H [lreverse [lrotate $V]]
  set ::V $H
}

proc ^ {V H} {
  lassign $V x
  lassign [set ::V [lrotate $V]] y
  set ::H [string map [list $x $y $::opposites($x) $::opposites($y)] $::H]
  puts -nonewline $y
}

set V [split wwrrryyyooow {}]
set H [split wwgggyyybbbw {}]
foreach p [split {*}$argv {}] {$p $V $H}
puts {}

Działa poprzez utrzymywanie listy poziomych i pionowych kolorów komórek. ^ <i> to wszystkie polecenia, które poprawnie permutują listy. Bieżąca komórka jest pierwsza na każdej liście.


3

Ruby, 132

m=?w
g="bgoyr"
x=z=1
gets.bytes{|c|(m,g[2,3]=g[4],m+g[2,2]if(x+=1)%3<1
$><<m)if 93<c.upto(64){x,z,g=2-z,x,g[4]+g[2]+g[0]+g[3]+g[1]}}

Ten system pozycji jest niestety bardzo podobny do innych dostępnych odpowiedzi. xi zśledź swoją pozycję na bieżącej twarzy +xjako kierunek podróży. Naprzód jest zawsze x+=1, a granice każdej twarzy są podzielne przez 3 (nie dbamy o liczbę, tylko jej moduł z 3).

m jest bieżącą twarzą (to oszczędza niektóre bajty)

gjest umieszczony [left, right, behind, opposite, front]tak, że nie trzeba zmieniać g[0..1]na^

<odbywa się to po prostu >trzy razy.


2

Java, 619 605 bajtów

Cóż, tutaj nie ma nic ...

Przynajmniej pokonał PowerShell!

-14 bajtów dzięki @KevinCruijssen

String t(String f){int h[]={0,0,1},p[]={0,2,0},n[],i,s,r;String o="",d[]="w,g,r,b,o,y".split(",");for(char c:f.toCharArray()){r=r(p);n=h;if(c==94){s=3;for(i=0;i<3;i++)if(h[i]==p[i]&p[i]!=0){if(r==0)n[1]=-1;if(r==1)n[0]=1;if(r==2)n[2]=-1;if(r==3)n[0]=-1;if(r==4)n[2]=1;if(r==5)n[1]=1;s=i;break;}i=0;for(int a:n)p[i++]+=a;if(s<3)h[s]=0;o+=d[r(p)];}s=r>-1&r<2?2:r>2&r<5?1:0;i=r==3|r==5?2:r>0&r<3?1:0;r=h[s];if(c==62){if(r==0){h[s]=h[i];h[i]=0;}else{h[i]=-r;h[s]=0;}}if(c==60){if(r==0){h[s]=-h[i];h[i]=0;}else{h[i]=r;h[s]=0;}}}return o;}int r(int[] p){return p[0]>1?3:p[0]<-1?1:p[1]>1?0:p[1]<-1?5:p[2]>1?2:4;}

Wyjaśnienie:

W przeciwieństwie do niektórych innych odpowiedzi, w których wykorzystano układ współrzędnych 2-d, użyłem układu 3-d, aby śledzić, gdzie była mrówka.

Kierunek został również zachowany w trójwymiarowy sposób, aby ułatwić zmianę stron i ruch.

Każda twarz miała jedną ze współrzędnych, x, y lub z, ustawioną na 2 (lub -2 dla przeciwnej ściany), aby wskazać, która to była twarz.

Przełączanie twarzy zostało dokonane przez sprawdzenie, czy mrówka miała zamiar zgasnąć (pozycja i kurs mają wartość, która jest taka sama, ale nie 0), upewnij się, że spadnie ona po przekątnej na następną, i zmień nagłówek na inny -przekątna. To było zaskakująco łatwe.

Toczenie było trudniejsze. Upewnienie się, że zawsze będzie zmierzać w tym samym kierunku, wymagało dodatkowej instrukcji if-else dla każdego znaku, co kosztowało mnie wiele bajtów. Ponadto osie „w górę” i „w prawo” musiały być na stałe zakodowane dla każdej strony.

Nieskluczony kod

(Bez zmian w stosunku do poprzedniej edycji dla zachowania przejrzystości metody)

private static String[] sides="w,g,r,b,o,y".split(",");
public static String traverse(String commands)
{
  int[] heading = {0,0,1};
  int[] pos = {0,2,0};
  int[] newheading;
  int i;
  int saved;
  String out = "";
  for(char command:commands.toCharArray())
  {
     if(command=='^')
     {
        newheading=heading;
        saved=3;
        for(i=0;i<3;i++)
        {
           if(heading[i]==pos[i]&pos[i]!=0)
           {
              saved=determineSide(pos);
              if(saved==0)newheading[1]=-1;
              if(saved==1)newheading[0]=1;
              if(saved==2)newheading[2]=-1;
              if(saved==3)newheading[0]=-1;
              if(saved==4)newheading[2]=1;
              if(saved==5)newheading[1]=1;
              saved=i;
              break;
           }
        }
        i=0;
        for(int c:newheading)
        {
           pos[i++]+=c;
        }
        if(saved<3)heading[saved]=0;
        out+=sides[determineSide(pos)];
     }
     newheading=getPlane(determineSide(pos));
     if(command=='>')
     {
        saved=heading[newheading[0]];
        if(saved==0)
        {
           heading[newheading[0]]=heading[newheading[1]];
           heading[newheading[1]]=0;
        }
        else
        {
           heading[newheading[1]]=-saved;
           heading[newheading[0]]=0;
        }
     }
     if(command=='<')
     {
        saved=heading[newheading[0]];
        if(saved==0)
        {
           heading[newheading[0]]=-heading[newheading[1]];
           heading[newheading[1]]=0;
        }
        else
        {
           heading[newheading[1]]=saved;
           heading[newheading[0]]=0;
        }
     }
  }
  return out;
}
public static int determineSide(int[] pos)
{
  return pos[0]==2?3:pos[0]==-2?1:pos[1]==2?0:pos[1]==-2?5:pos[2]==2?2:4;
}
public static int[] getPlane(int side)
{
  int[] out=new int[2];
  out[0]=side==0|side==1?2:side==3|side==4?1:0;
  out[1]=side==3|side==5?2:side==1|side==2?1:0;
  //side==0?{2,0}:side==1?{2,1}:side==2?{0,1}:side==3?{1,2}:side==4?{1,0}:{0,2};
  return out;
}

1
To boli ... Przysięgam spróbować teraz golfa! :)
Matt

1
Wiem, że został opublikowany ponad rok temu, ale jest kilka drobnych rzeczy do gry w golfa: d[]={"w","g","r","b","o","y"}-> "w,g,r,b,o,y".split(",")(-1 bajt); 2x '^'-> 94(-2 bajty); 3x ==0-> <1(-3 bajty); 2x ==1-> <2(-2 bajty); etc ==2, ==3, ==4, ==5.
Kevin Cruijssen,

@KevinCruijssen Dziękujemy za wskazówki!
Blue
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.