C'è una formica sul mio cubo di Rubik


44

Un cubo di Rubik 3 × 3 × 3 standard, risolto, ha 6 facce di colore diverso, in cui ogni faccia è una griglia 3 × 3 di quadrati di un colore. La faccia bianca è opposta al giallo, il rosso opposto all'arancione, il blu opposto al verde e quando il bianco punta verso l'alto, il rosso è a sinistra del blu:

Il layout del cubo di Rubik

Immagina che una formica si trovi sulla piazza centrale della faccia bianca, di fronte alla faccia rossa. Puoi dargli 3 comandi:

  • Avanti ( ^): fai un passo nella direzione in cui si trova di fronte al quadrato della griglia successivo, scavalcando un bordo del cubo se necessario.
  • Destra ( >): ruota di 90 ° verso destra (in senso orario), rimanendo nella stessa griglia.
  • Sinistra ( <): ruota a sinistra (in senso antiorario) di 90 °, rimanendo nella stessa griglia.

Dato un elenco arbitrario di comandi, trova i colori dei quadrati visitati dalla formica (escluso il quadrato iniziale bianco).

Ad esempio, la sequenza di comandi ^^>^^<^^^ha un percorso simile al seguente:

percorso di esempio

I colori dei quadrati della griglia visitati in ordine, senza contare il quadrato iniziale, sono white red red green green green yellowo solo wrrgggy.

Scrivi un programma o una funzione che accetta una stringa di caratteri di comando <^>e stampa o restituisce una stringa di caratteri wyrobg(bianco, giallo, rosso arancione, blu, verde) che corrisponde al percorso della formica sul cubo.

Vince il codice più breve in byte. Tiebreaker è la risposta precedente.

Gli appunti

  • Il cubo è a mezz'aria e la formica ha un efficace pulvilli, quindi può attraversare l'intero cubo.
  • Il cubo rimane sempre nel suo stato risolto.
  • Il colore di un quadrato viene registrato solo con il movimento nel quadrato, non con la rotazione. Il quadrato bianco iniziale non deve essere registrato.
  • Nell'input e / o output può essere presente una singola riga finale finale facoltativa.

Casi test

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 Le formiche hanno sei zampe, i cubi hanno sei lati. <shrug> Non lo so ...
Digital Trauma

4
Questa non è una sfida di golf da principiante ..... Sto perdendo la testa inventando un sistema di coordinate che non è codificato.
Matt

2
@DigitalTrauma Questa sfida sta gridando per una risposta esagonale :-)
Luis Mendo

1
Sono così vicino al peggior codice PowerShell che tu abbia mai visto.
Matt

Risposte:


18

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

Include +1 per -p

Esegui con la stringa di controllo su STDIN, ad es

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

Spiegazione

Versione precedente:

@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

La sfida di questa domanda è trovare un sistema di coordinate che renda facile tracciare la posizione e la direzione della formica e ottenere facilmente l'identità del viso.

Il sistema che ho scelto era di mettere le (x,y)coordinate standard sulla faccia su cui si trova la formica in modo tale che la formica sia sempre rivolta nella ydirezione negativa con il centro della faccia (0,0). Così:

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

Se yera già -1la formica lascerà la faccia corrente e passerà alla successiva. Nel nuovo sistema di coordinate xmantiene il suo valore, ma y'diventa 1.

Ciò fornisce un facile sistema di coordinate all'interno di una faccia. Ho anche bisogno di qualcosa per i volti stessi. Lì uso un array composto da

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

Quindi l'array iniziale è (g,b,o,y,r,w). Passare alla faccia successiva corrisponde a ruotare gli ultimi 4 elementi, quindi passare da bianco a rosso rende questo (g,b,w,o,y,r). Girare a destra è una permutazione dei primi 5 elementi che danno (o,r,b,y,g,w). Girare a sinistra è una permutazione simile ma può anche essere fatto girando a destra 3 volte, quindi applicando questa permutazione 3 volte. E non si può nemmeno girare affatto applicando la permutazione 8 volte. In effetti si può anche girare a destra applicando la permutazione 5 volte.

Sapendo questo il programma è piuttosto semplice:

@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

Quindi per quell'ultima istruzione le rotazioni portano alla stringa vuota e i passi avanti conducono alla faccia corrente. Pertanto $_viene sostituito dai volti visitati su ogni passaggio.


Se capisco cosa sta succedendo qui, quel @1pezzetto è un incredibile abuso di quella che sembra un'orribile funzionalità linguistica.
Non che Charles

@NotthatCharles Sì, è esattamente malvagio come sembra. Nei programmi perl seri la prima cosa che fai è disattivare quella funzione usando use strict. Grazie per il modulo 3 a proposito.
Ton Hospel,

12

Brachylog , 287 byte

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

Si aspetta una stringa contenente le mosse come Input e nessuna Output, ad es. brachylog_main("^^>^^<^^^",_).Scriverà wrrgggysu STDOUT.

Spiegazione

§ 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

Codice equivalente SWI-Prolog

Se non vuoi preoccuparti del compilatore di Brachylog, puoi eseguire questa soluzione in SWI-Prolog usando il seguente codice (questo è ciò che viene generato dal compilatore di 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 byte

uso

Salvare il codice in uno script e chiamarlo in questo modo dalla riga di comando. Supponendo che la directory di lavoro sia la directory corrente.

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

Codice

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

Meno codice golf con spiegazione

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

Utilizzando molte variabili a lettera singola utilizzate per registrare lo stato corrente della formica (colore, posizione e orientamento). La formica è sempre rivolta verso l'alto. Quando viene letta un'istruzione di rotazione, il cubo viene trasposto in quella direzione. Matrici di trasposizione codificate per determinare la nuova posizione in base alla posizione corrente.

Il codice soddisfa tutti gli esempi in questione.


Questo può essere giocato a golf di più, ma funziona ora, quindi devo provare a rimuovere parte della ripetizione ora.
Matt

3

Tcl / Tk, 422 byte

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}

Purtroppo, non riesco a rimpicciolirlo. Versione non offuscata:

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

Funziona mantenendo un elenco di colori di celle orizzontali e verticali. ^ <e> sono tutti comandi che consentono correttamente gli elenchi. La cella corrente è la prima in ogni elenco.


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

Questo sistema di posizioni è purtroppo molto simile ad altre risposte là fuori. xe ztraccia la tua posizione sulla faccia corrente con +xla direzione del viaggio. Avanti è sempre x+=1e i limiti di ogni faccia sono divisibili per 3 (non ci interessa il numero, ma solo il suo modulo con 3).

m è la faccia corrente (questo salva alcuni byte)

gè organizzato [left, right, behind, opposite, front]in modo tale che non abbiamo bisogno di cambiamento g[0..1]su^

<è fatto semplicemente facendo >tre volte.


2

Java, 619 605 byte

Bene, qui non va niente ...

Almeno ha battuto Powershell!

-14 byte grazie a @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;}

Spiegazione:

A differenza di alcune delle altre risposte, che utilizzavano un sistema di coordinate 2D, utilizzavo un sistema 3D per tenere traccia di dove fosse la formica.

La direzione è stata inoltre mantenuta in modo tridimensionale per facilitare il passaggio laterale e il movimento.

Ogni faccia aveva una delle coordinate, x, yo z, essere impostata su 2 (o -2 per la faccia opposta) per indicare quale faccia era.

La commutazione delle facce è stata effettuata controllando se la formica stava per spegnersi (posizione e rotta hanno un valore uguale, ma non 0), assicurarsi che "cadano" in diagonale sulla successiva e cambiare l'intestazione in modo che non sia -diagonale. Questo è stato sorprendentemente facile.

Girare era più difficile. Accertarsi che andasse sempre nella stessa direzione richiedeva un'istruzione if-else aggiuntiva all'interno del controllo per ciascun personaggio, che mi costava molti byte. Inoltre, gli assi "su" e "giusto" dovevano essere codificati per ciascun lato.

Codice Ungolfed

(Invariato rispetto alla modifica precedente per chiarezza nel metodo)

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
Mi fa male .... Giuro di provare a giocare a golf adesso! :)
Matt,

1
So che questo è stato pubblicato più di un anno fa, ma ci sono alcune piccole cose da golf: d[]={"w","g","r","b","o","y"}-> "w,g,r,b,o,y".split(",")(-1 byte); 2x '^'-> 94(-2 byte); 3x ==0-> <1(-3 byte); 2x ==1-> <2(-2 byte); ecc per ==2, ==3, ==4, ==5.
Kevin Cruijssen il

@KevinCruijssen Grazie per i suggerimenti!
Blu
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.