На кубі Рубіка є мураха


44

Стандартний, вирішений, 3 × 3 × 3 кубик Рубіка має 6 граней різного кольору, де кожне обличчя - 3 × 3 сітки квадратів одного кольору. Біле обличчя знаходиться навпроти жовтого, червоне - протилежне оранжеве, синє - навпроти зеленого, а коли біле вказує вгору, червоне - зліва від синього:

Розкладка кубика Рубіка

Уявіть, що мурашка сидить на центральній площі білого обличчя, зверненою до червоного обличчя. Ви можете дати йому 3 команди:

  • Вперед ( ^) - зробіть крок у напрямку, який він стикається до наступного квадрату сітки, переступивши край куба при необхідності.
  • Праворуч ( >) - поверніть праворуч (за годинниковою стрілкою) на 90 °, залишаючись у тому ж квадраті сітки.
  • Вліво ( <) - повернути ліворуч (проти годинникової стрілки) на 90 °, залишаючись у тому ж квадраті сітки.

Давши довільний перелік команд, знайдіть кольори квадратів, які відвідує мураха (не включаючи білий початковий квадрат).

Наприклад, командна послідовність ^^>^^<^^^має шлях, який виглядає приблизно так:

Приклад шляху

Кольори сітчастих квадратів, відвіданих для того, не рахуючи початковий квадрат, є white red red green green green yellow, або просто wrrgggy.

Напишіть програму або функцію, яка містить рядок командних символів <^>і друкує або повертає рядок символів wyrobg(білий, жовтий, червоний помаранчевий, синій, зелений), який відповідає шляху мурашки через куб.

Виграє найкоротший код у байтах. Тирбейкер - це відповідь раніше.

Примітки

  • У кубика знаходиться в повітрі, а мураха має ефективні пульві, тому він може пройти весь куб.
  • Куб завжди залишається в розв’язаному стані.
  • Колір квадрата записується лише при русі на квадрат, а не повороті. Початковий білий квадрат не повинен записуватися.
  • Один необов'язковий кінцевий новий рядок може бути присутнім у вході та / або виході.

Випробування

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 Мурахи мають шість ніжок, кубики - шість сторін. <shrug> Я не знаю ...
Digital Trauma

4
Це не виклик для гольфу для початківців ..... Я втрачаю розум, придумуючи систему координат, яка не важко кодована.
Метт

2
@DigitalTrauma Це виклик кричить на відповідь "Гексагоні" :-)
Луїс Мендо

1
Я так близько до найгіршого коду PowerShell, який ви коли-небудь бачили.
Метт

Відповіді:


18

Perl, 156 143 134 128 127 125 120 119 117 113 109 байт

Включає +1 для -p

Запустіть контрольну рядок на STDIN, наприклад

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

Пояснення

Старіша версія:

@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

Завдання цього питання полягає у пошуку системи координат, яка дозволяє легко відстежувати положення та напрямок мурашки та все ще легко отримувати особу обличчя.

Я вибрав систему, щоб нанести стандартні (x,y)координати на обличчя мурашника на такій формі, щоб мурашка завжди стикалася в негативному yнапрямку з центром обличчя, що знаходиться (0,0). Тому:

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

Якщо yвже був -1мураш, покине поточне обличчя і перейде на наступне. У новій системі координат xзберігається її значення, але y'стає 1.

Це дає просту систему координат всередині обличчя. Мені теж потрібно щось для самих облич. Там я використовую масив, що складається з

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

Отже, початковий масив є (g,b,o,y,r,w). Перехід до наступного обличчя відповідає обертанню останніх 4 елементів, тому перехід від білого до червоного робить це (g,b,w,o,y,r). Поворот праворуч - перестановка перших 5 елементів, що надають (o,r,b,y,g,w). Повернути ліворуч - це симуляційна перестановка, але її також можна зробити, повернувши праворуч 3 рази, тому застосувавши цю перестановку 3 рази. І зовсім не повертати можна також, застосувавши перестановку 8 разів. Насправді повернути праворуч можна також, застосувавши перестановку 5 разів.

Знаючи це програма досить проста:

@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

Тож для цього останнього обертання оператора ведуть до порожнього рядка, а кроки вперед ведуть до поточного обличчя. Тому $_його замінюють обличчя, відвідувані на кожному кроці.


Якщо я розумію, що тут відбувається, цей @1біт - це дивовижне зловживання тим, що виглядає як жахлива мовна особливість.
Не те, що Чарльз

@NotthatCharles Так, це так само зло, як виглядає. У серйозних програмах Perl перше, що ви робите, - це вимкнути цю функцію за допомогою use strict. Дякую за модуль 3, до речі.
Тон Євангелія

12

Брахілог , 287 байт

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

Очікує рядок, що містить рухи як Вхідні дані, а не Вихідні дані, наприклад brachylog_main("^^>^^<^^^",_)., запише wrrgggyв STDOUT.

Пояснення

§ 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

Еквівалентний код SWI-Prolog

Якщо ви не хочете турбуватися про компілятор Brachylog, ви можете запустити це рішення в SWI-Prolog, використовуючи наступний код (саме це отримує компілятор 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 байти

Використання

Збережіть код у скрипті та назвіть його так у командному рядку. Припустимо, що робочий каталог - це поточний каталог.

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

Код

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

Менше коду для гольфу з поясненням

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

Використання безлічі змінних однієї літери, що використовуються для запису поточного стану мурашки (колір, положення та орієнтація). Мурашка завжди звернена вгору. Коли читається інструкція з обертання, куб переміщується в цьому напрямку. Матриці транспозиції з твердим кодом, що використовуються для визначення нового положення на основі поточного положення.

Код задовольняє всі розглянуті приклади.


Це може бути більше гольфу, але це працює зараз, тому мені потрібно спробувати видалити частину повторів зараз.
Мет

3

Tcl / Tk, 422 байти

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}

На жаль, я не можу отримати його менше. Неприхована версія:

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

Це працює, підтримуючи список горизонтальних та вертикальних кольорів комірок. ^ <і> - це всі команди, які правильно переставляють списки. Поточна комірка є першою у кожному списку.


3

Рубі, 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]}}

Ця система позицій, на жаль, дуже схожа на інші відповіді. xі zвідстежуйте своє положення на поточному обличчі +x, визначаючи напрямок подорожі. Вперед завжди x+=1, а межі кожної грані поділяються на 3 (число нас не хвилює, просто його модуль з 3).

m поточне обличчя (це економить кілька байт)

gвлаштована [left, right, behind, opposite, front]так , що нам не потрібно міняти g[0..1]на^

<робиться просто, роблячи >три рази.


2

Java, 619 605 байт

Ну, тут нічого не йде ...

Принаймні, це перемогло панщину!

-14 байт завдяки @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;}

Пояснення:

На відміну від деяких інших відповідей, які використовували 2-d систему координат, я використовував 3-d систему, щоб відстежувати, де знаходиться мураха.

Напрям також зберігався в 3-денному режимі для полегшення перемикання сторін і руху.

Кожне обличчя мало одну з координат, x, y або z, встановлену на 2 (або -2 для протилежної грані), щоб означати, якою вона була.

Перемикання облич було здійснено шляхом перевірки, чи збирається мураха вимкнутись (позиція та заголовок мають те саме значення, але не 0), переконайтесь, що воно "впаде" по діагоналі на наступне, і змініть заголовок на не -діагональний. Це було напрочуд легко.

Поворот було складніше. Щоб переконатися, що він завжди піде в одному напрямку, потрібна додаткова операція if-else всередині чека для кожного символу, що коштувало мені багатьох байтів. Окрім того, "вгору" та "правильно" осі повинні були бути жорстко закодовані для кожної сторони.

Невикористаний код

(Незмінно від попереднього редагування для наочності методу)

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
Це боляче .... Я обіцяю спробувати це зараз у гольф! :)
Метт

1
Я знаю, що це було розміщено більше року тому, але в гольфі є кілька дрібниць: d[]={"w","g","r","b","o","y"}-> "w,g,r,b,o,y".split(",")(-1 байт); 2x '^'-> 94(-2 байти); 3x ==0-> <1(-3 байти); 2x ==1-> <2(-2 байти); і т.д. для ==2, ==3, ==4, ==5.
Кевін Кройсейсен

@KevinCruijssen Дякую за поради!
Синій
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.