Il y a une fourmi sur mon cube Rubik

44

Un cube de Rubik standard, résolu, 3 × 3 × 3 a 6 faces de couleurs différentes, où chaque face est une grille 3 × 3 de carrés d'une couleur. Le visage blanc est opposé au jaune, le rouge opposé à l'orange, le bleu opposé au vert et, lorsque le blanc pointe vers le haut, le rouge est à gauche du bleu:

Rubik's cube layout

Imaginez une fourmi assise sur le carré central du visage blanc, face au visage rouge. Vous pouvez lui donner 3 commandes:

  • Forward ( ^) - faites un pas dans la direction dans laquelle il se dirige vers le prochain carré de la grille, en passant par-dessus un bord du cube si nécessaire.
  • Right ( >) - faites pivoter le curseur vers la droite (dans le sens des aiguilles d'une montre) de 90 °, tout en restant dans le même carré de la grille.
  • Left ( <) - fait pivoter de 90 ° vers la gauche (dans le sens inverse des aiguilles d'une montre) en restant dans le même carré de la grille.

À partir d’une liste de commandes arbitraire, trouvez les couleurs des carrés visités par la fourmi (sans compter le carré blanc au début).

Par exemple, la séquence de commandes ^^>^^<^^^a un chemin qui ressemble à ceci:

exemple de chemin

Les couleurs des carrés de la grille visités dans l’ordre, sans compter le carré de départ, sont white red red green green green yellowou sont simplement wrrgggy.

Ecrivez un programme ou une fonction qui prend une chaîne de caractères de commande <^>et imprime ou retourne une chaîne de caractères wyrobg(blanc, jaune, rouge orange, bleu, vert) qui correspond au chemin de la fourmi sur le cube.

Le code le plus court en octets gagne. Tiebreaker est une réponse plus tôt.

Remarques

  • Le cube est dans les airs et la fourmi a des pulvilli efficaces, ce qui lui permet de parcourir l’ensemble du cube.
  • Le cube reste toujours dans son état résolu.
  • La couleur d'un carré n'est enregistrée que lors de son déplacement dans le carré, pas de rotation. Le carré blanc de départ ne doit pas être enregistré.
  • Une seule nouvelle ligne de fin facultative peut être présente dans l'entrée et / ou la sortie.

Cas de test

input : output
[empty string] : [empty string]
^ : w
< : [empty string]
> : [empty string]
><><<<>> : [empty string]
>^ : w
<<^> : w
^<^<^<^< : wwww
^^ : wr
<^^ : wb
>><<<<^^ : wo
<^^^<^^^^<>^>^^>^ : wbbboooggyo
^^^^^^^^^^^^^^ : wrrryyyooowwwr
<<<^<^>^<^<^<^>^^^^<^>>>>>^^<^>^^<^>^>^>^>< : wwgrwgggoooobbbbyrby
^^>^^<^^^ : wrrgggy
Les passe-temps de Calvin
la source
7
Qu'est-ce que c'est avec les fourmis sur les cubes ?
Martin Ender
2
@ MartinBüttner Les fourmis ont six pattes, les cubes ont six côtés. <haussement d'épaules> Je ne sais pas ...
Digital Trauma
4
Ce n'est pas un défi de golfeur débutant ..... Je perds la raison de penser à un système de coordonnées qui n'est pas codé en dur.
Matt
2
@DigitalTrauma Ce défi réclame une réponse à Hexagony :-)
Luis Mendo
1
Je suis si proche du pire code PowerShell que vous ayez jamais vu.
Matt

Réponses:

18

Perl, 156 143 134 128 127 125 125 120 119 117 113 109 octets

Inclut +1 pour -p

Exécuter avec la chaîne de contrôle sur STDIN, par exemple

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

Explication

Ancienne version:

@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

Le défi de cette question est de trouver un système de coordonnées qui facilite le suivi de la position et de la direction de la fourmi et qui permette d'obtenir facilement l'identité du visage.

Le système que j'ai choisi était de mettre des (x,y)coordonnées standard sur le visage de la fourmi, de sorte que celle-ci soit toujours orientée dans le ysens négatif , le centre de la face étant (0,0). Alors:

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

Si yétait déjà -1la fourmi quittera le visage actuel et passera au suivant. Dans le nouveau système de coordonnées, il xconserve sa valeur, mais y'devient 1.

Cela donne un système de coordonnées facile dans une face. J'ai aussi besoin de quelque chose pour les visages eux-mêmes. J'utilise un tableau composé de

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

Donc, le tableau initial est (g,b,o,y,r,w). Passer à la face suivante correspond à la rotation des 4 derniers éléments, ce qui permet de passer du blanc au rouge (g,b,w,o,y,r). Tourner à droite est une permutation des 5 premiers éléments (o,r,b,y,g,w). Tourner à gauche est une permutation simulaire, mais peut également être fait en tournant à droite 3 fois, donc en appliquant cette permutation 3 fois. Et ne pas tourner du tout peut également être fait en appliquant la permutation 8 fois. En fait, il est également possible de tourner à droite en appliquant la permutation 5 fois.

Sachant cela, le programme est assez simple:

@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

Donc, pour cette dernière instruction, les rotations mènent à la chaîne vide et les pas en avant mènent au visage actuel. Par conséquent, $_est remplacé par les visages visités sur chaque étape.

Ton Hospel
la source
Si je comprends ce qui se passe ici, ce @1morceau est un abus incroyable de ce qui ressemble à une caractéristique de langage horrible.
Pas que Charles
@NotthatCharles Oui, c'est exactement aussi méchant qu'il en a l'air. Dans les programmes Perl sérieux, la première chose à faire est de désactiver cette fonction use strict. Merci pour le modulo 3 au fait.
Ton Hospel
12

Brachylog , 287 octets

: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&}

Attend une chaîne contenant les déplacements en tant qu'entrée, et aucune sortie, par exemple brachylog_main("^^>^^<^^^",_)., écrira wrrgggydans STDOUT.

Explication

§ 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

Code SWI-Prolog équivalent

Si vous ne voulez pas vous occuper du compilateur Brachylog, vous pouvez exécuter cette solution dans SWI-Prolog en utilisant le code suivant (c'est ce qui est généré par le compilateur 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|_].
Fataliser
la source
4

PowerShell, 882 octets

Usage

Enregistrez le code dans un script et appelez-le comme ceci à partir de la ligne de commande. En supposant que le répertoire de travail est le répertoire actuel.

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

Code

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

Code moins joué avec explication

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

En utilisant beaucoup de variables d'une seule lettre utilisées pour enregistrer l'état actuel de la fourmi (couleur, position et orientation). La fourmi est toujours tournée vers le haut. Lorsqu'une instruction de rotation est lue, le cube est transposé dans cette direction. Les matrices de transposition codées en dur sont utilisées pour déterminer la nouvelle position en fonction de la position actuelle.

Code satisfait tous les exemples en question.

Mat
la source
Cela peut être joué plus souvent, mais cela fonctionne maintenant, donc je dois essayer d’éliminer une partie de la répétition maintenant.
Matt
3

Tcl / Tk, 422 octets

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}

Hélas, je ne peux pas le réduire. Version non-obscurcie:

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 {}

Cela fonctionne en maintenant une liste de couleurs de cellules horizontales et verticales. ^ <et> sont toutes des commandes qui permutent correctement les listes. La cellule en cours est la première de chaque liste.

Dúthomhas
la source
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]}}

Ce système de position est malheureusement très similaire aux autres réponses disponibles. xet zsuivez votre position sur le visage actuel avec +xle sens de la marche. Forward est toujours x+=1, et les limites de chaque face sont divisibles par 3 (on se fout du nombre, juste son module avec 3).

m est le visage actuel (cela économise quelques octets)

gest disposé de [left, right, behind, opposite, front]telle sorte que nous ne devons changer g[0..1]sur^

<se fait simplement en faisant >trois fois.

Pas que Charles
la source
2

Java, 619 605 octets

Eh bien, rien ne va ici ...

Au moins, il a battu Powershell!

-14 octets grâce à @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;}

Explication:

Contrairement à certaines des autres réponses, qui utilisaient un système de coordonnées 2-D, j’utilisais un système 3-D pour suivre l’emplacement de la fourmi.

La direction a également été maintenue en 3-D pour faciliter le changement de côté et de mouvement.

Chaque face a une des coordonnées, x, y ou z, définie sur 2 (ou -2 pour la face opposée) pour indiquer de quelle face il s’agit.

Pour changer de face, il fallait vérifier si la fourmi était sur le point de s’éteindre (la position et le cap ont la même valeur, mais pas 0), s’assurer qu’elle tomberait en diagonale sur la suivante et changer le cap pour qu’il ne soit pas -diagonale. C'était étonnamment facile.

Tourner était plus difficile. S'assurer qu'il irait toujours dans le même sens nécessitait une déclaration if-else supplémentaire dans la vérification de chaque caractère, ce qui m'a coûté de nombreux octets. De plus, les axes "haut" et "droit" devaient être codés en dur pour chaque côté.

Code non-liquéfié

(Inchangé par rapport à l'édition précédente pour plus de clarté dans la méthode)

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;
}
Bleu
la source
1
Cela fait mal ... Je m'engage à essayer le golf maintenant! :)
Matt
1
Je sais que cela a été posté il y a plus d'un an, mais il y a quelques petites choses au golf: d[]={"w","g","r","b","o","y"}-> "w,g,r,b,o,y".split(",")(-1 octet); 2x '^'-> 94(-2 octets); 3x ==0-> <1(-3 octets); 2x ==1-> <2(-2 octets); etc pour ==2, ==3, ==4, ==5.
Kevin Cruijssen
@KevinCruijssen Merci pour les conseils!
Blue