Campeón Frogger

11

El juego

La mayoría de nosotros conocemos a Frogger , el juego de arcade de la era de los 80 en el que el objetivo es saltar a una rana de forma segura a través de una carretera concurrida y un estanque lleno de peligros para llegar a salvo a casa.

Hace unos meses se lanzó un desafío para desarrollar un clon de Frogger. Pero, ¿por qué clonar Frogger cuando puedes jugar a Frogger? :)

Considere la siguiente cuadrícula de juego simplificada:

 XXXXXXXXXXXXXXXXXXXXXXX  North Safe Zone
 -----------------------
|                       | <<<<       Express Lane West        (Lane 1)
|                       |     >      Gridlock East            (Lane 2)
|                       |   <<       Freeflowing Traffic West (Lane 3)
|                       |    <       Gridlock West            (Lane 4)
|                       |     >>>>   Express Lane East        (Lane 5)
 -----------------------
 XXXXXXXXXXX@XXXXXXXXXXX  South Safe Zone
 \__________ __________/
            '
  23 cells horizontally

Tenemos cinco carriles de tráfico, cada uno de 23 celdas de ancho, y dos zonas seguras (donde la rana puede moverse con seguridad de izquierda a derecha), también de 23 celdas de ancho. Puede ignorar los bordes derecho e izquierdo, ya que estos son para mayor claridad pictórica.

Nuestra rana comienza en la zona segura del sur, en la celda central (12), como se indica con a @en la figura anterior.

El tiempo en el juego se divide en pasos discretos llamados marcos. Froggy es una rana rápida y puede saltar una celda en cualquier dirección (arriba, abajo, derecha, izquierda) por cuadro. También puede optar por permanecer estacionario para cualquier cuadro. El tráfico en los cinco carriles se mueve a velocidades constantes de la siguiente manera:

  • el tráfico en el carril expreso oeste (carril 1) mueve 2 celdas a la izquierda de cada cuadro
  • el tráfico en el carril este del embotellamiento (carril 2) se mueve 1 celda a la derecha cada segundo cuadro
  • el tráfico en el carril oeste de tráfico libre (carril 3) se mueve 1 celda a la izquierda de cada cuadro
  • el tráfico en el carril oeste del embotellamiento (carril 4) se mueve 1 celda a la izquierda cada segundo cuadro
  • el tráfico en el carril expreso este (carril 5) mueve 2 celdas a la derecha en cada cuadro

El tráfico en sí está definido de manera única por aprox. 3.000 pasos en este archivo de texto . El 'tráfico' consiste en vehículos y espacios entre los vehículos. Cualquier personaje que no sea un espacio es parte de un vehículo. El archivo de texto contiene cinco líneas, correspondientes a los cinco carriles de tráfico (con el mismo orden).

Para los carriles hacia el oeste, al comienzo del cuadro 0 (el inicio del juego), consideramos que el primer vehículo en el carril está más allá del borde derecho de la cuadrícula de juego.

Para los carriles hacia el este, la cadena de tráfico debe considerarse "hacia atrás" en el sentido de que los vehículos aparecen comenzando al final de la cadena. Al comienzo del cuadro 0, consideramos que el primer vehículo en estos carriles está más allá del borde izquierdo del campo de juego.

Considere como un ejemplo:

Traffic Lane 1:  [|==|  =
Traffic Lane 2:  |) =  o
Traffic Lane 3:  (|[]-[]:
Traffic Lane 4:  <| (oo|
Traffic Lane 5:  |==|] :=)

Entonces la cuadrícula de juego aparecerá de la siguiente manera:

Start of Frame 0       XXXXXXXXXXXXXXXXXXXXXXX
                                              [|==|  =
                |) =  o
                                              (|[]-[]:
                                              <| (oo|
              |==|] :=)
                       XXXXXXXXXXXXXXXXXXXXXXX

Start of Frame 1       XXXXXXXXXXXXXXXXXXXXXXX
                                            [|==|  =
                |) =  o
                                             (|[]-[]:
                                              <| (oo|
                |==|] :=)
                       XXXXXXXXXXXXXXXXXXXXXXX

Start of Frame 2       XXXXXXXXXXXXXXXXXXXXXXX
                                          [|==|  =
                 |) =  o
                                            (|[]-[]:
                                             <| (oo|
                  |==|] :=)
                       XXXXXXXXXXXXXXXXXXXXXXX

Start of Frame 3       XXXXXXXXXXXXXXXXXXXXXXX
                                        [|==|  =
                 |) =  o
                                           (|[]-[]:
                                             <| (oo|
                    |==|] :=)
                       XXXXXXXXXXXXXXXXXXXXXXX

Después de que todo el tráfico en un carril se "agota" (es decir, la cadena se agota), consideramos que todos los caracteres de la cadena son espacios.

Nuestra rana se aplasta si ocurre algo de lo siguiente:

  • la rana ocupa una celda ocupada por un vehículo, en cualquier marco
  • la rana permanece estacionaria en un carril rápido y un vehículo de 1 celda de ancho pasa sobre él en ese marco
  • la rana salta al este "a través" de un vehículo que se dirige hacia el oeste, o salta al oeste a través de un vehículo que se dirige al este
  • la rana salta fuera de la cuadrícula de juego 7 (línea) por 23 (celda), en cualquier cuadro

Tenga en cuenta que estas son las únicas condiciones bajo las cuales se aplasta una rana. En particular, una rana que salta junto con el tráfico "con" es permisible, como lo es una rana que salta dentro o fuera de una celda en un carril expreso que es pasado por un vehículo de ancho 1 en el mismo marco.

Objetivo y puntuación

El objetivo del desafío de programación es hacer que la rana cruce la carretera tantas veces como sea posible antes de que el último vehículo salga de la parrilla de juego . Es decir, el programa termina inmediatamente después de completar el cuadro X , donde el cuadro X es el primer cuadro que lleva la cuadrícula a un estado en el que no hay más vehículos presentes.

La salida de su programa debe ser una cadena (o archivo de texto) que contenga la secuencia de movimientos para la rana usando la siguiente codificación:

<   frog moves left
>   frog moves right
^   frog moves up
v   frog moves down
.   frog remains stationary

Por ejemplo, la cadena <<^.^indica que la rana se mueve hacia la izquierda dos veces, luego hacia arriba, luego hace una pausa por un cuadro y luego se mueve hacia arriba nuevamente.

Se puntúa un punto cada vez que la rana cruza desde la zona segura del sur hacia la zona segura del norte, y un punto se puntúa cuando la rana cruza desde la zona segura del norte hacia la zona segura del sur.

Algunas reglas importantes:

  1. La rana no debe ser aplastada.
  2. Publique su solución (secuencia de movimientos) junto con su código de programa, ya sea en línea o como un archivo de texto (por ejemplo, usando pastebin.com).
  3. Nuestra rana es premonitoria y precognitiva, por lo tanto, su programa puede utilizar todos los datos de tráfico en cualquier marco mientras busca soluciones. Esto incluye datos para el tráfico que aún no ha llegado a la grilla de juego.
  4. La cuadrícula no se ajusta. Salir de la cuadrícula hará que la rana se aplaste y, por lo tanto, no está permitido.
  5. En ningún momento el tráfico se "reinicia" o la rana se "teletransporta". La simulación es continua.
  6. La rana puede regresar a la zona segura del sur después de salir, pero esto no se cuenta como un punto. Asimismo para la zona segura norte.
  7. El ganador del concurso es el programa que genera la secuencia de movimiento que produce el mayor número de cruces.
  8. Para cualquier pregunta o inquietud adicional, no dude en preguntar en la sección de comentarios.

Para un incentivo adicional, agregaré una recompensa de +100 repeticiones al programa ganador cuando pueda hacerlo.

Bonos

+ 2.5% al puntaje base * (hasta + 10%) por cada esquina de la cuadrícula de juego que toque la rana. Las cuatro esquinas de la cuadrícula son las celdas más a la izquierda y a la derecha de las dos zonas seguras.

+ 25% al puntaje base * si su secuencia de movimientos mantiene a la rana confinada dentro de +/- 4 celdas a la izquierda o derecha de su celda inicial durante toda la simulación (por supuesto, puede moverse libremente verticalmente).

No hay bonificación de puntuación, pero los accesorios especiales en el OP irán a cualquiera que publique un validador de solución rápida y sucia para que no tenga que programar uno. ;) Un validador simplemente aceptaría una secuencia de movimientos, garantizaría su legalidad (según las reglas y el archivo de tráfico) e informaría su puntaje (es decir, el número total de cruces).

* El puntaje total es igual al puntaje base más el bono, redondeado al entero más cercano.

Buena suerte rana!

COTO
fuente
Para cualquiera que quiera publicar un validador de soluciones: no lo publique como respuesta .
Geobits
En efecto. Un enlace al código en un comentario, o como una adición a una solución, sería la forma preferida de enviar un validador.
COTO
¿El primer cuadro en el que avanzan los carriles lentos será el mismo que el primer cuadro en el que avanzan los otros carriles, o un cuadro después?
feersum
Además, ¿es posible anotar alcanzando la zona final en el primer cuadro en el que todos los autos han despejado el campo?
Feersum
@feersum: los carriles lentos avanzan un cuadro más tarde. Permanecen inmóviles en el primer fotograma, como se indica en el ejemplo. En cuanto a la puntuación de la rana en el último cuadro: sí, es posible. Si la rana se ha movido a una zona segura en el mismo cuadro en el que el último vehículo sale del campo de juego, se puntúa un punto.
COTO

Respuestas:

5

C ++: 176

Salida:

176
^^^^^^>vvvvvv>^^^^>^^>>>>>>><<<.vv>v<<<.vvv<<<<<<^.^.^.^.>.>^^<.>>>>>>v>v>.>v<<<<v.<.vv<<<<<^^.<^<<<<<<^.^^>>>>vv>.>.v<v.vv>>^>>^<^<<<<<<<^>.>^^<<<.>>>>>vv>v<vvv<<<<<^^.<^^^^.....vv>.>.>.>v<<vvv<<>>>>^>^<.<.^^>^^>>>>vv.>v<vv.v^>^<.<.<^<^>.>^^>>>>vv.v<<<<<<.vvv<<<<^^^<<v^^.>.^^..>>>>>>vv>.>.v.vvv>>>^>^^<<<<<<<<<^>.>^^>>>>vvv<<v.<.vv<<<<<<>>>>>^^^<<<^^^<<>>vv>.v<<>vvv<<><>>>>>>>^>^^<^^^<.>>>>>>>>vv>.>v<<<vvv<<<<<^^^<<v.<.<^<<^.^<<^...>>>>>>>>>>>>>vv>v<vvv<<<<<<<<^>^.<.^^>.>^^<<<<<<<..>>>>vv>.vvvv<<<<>^.v>>>^^.^^>^<^<>>>>>>>>>vv>vvvv<<<<^^^<^>^<<^.>>vv>v<vvv<<<<<<<>>>>>>>^>^^^.^^>>>>>vvv<<vvv<<<^^^^^^<vvv<<<<<<<vvv<<<>>>>>>>>^^.<.<.^.^.^<^<>>>>>>>>>>vvv<<.vvv<<<^^<^<<^^<<^<<<>>>>vv>.vvvv>>^>>^<.<.<^<<<<<.^^<<^.......>vv.>.>.>v<vvv>>>>>>^>^.<.<^<.^^^<.>>>>>>>vvv<<<v.<vv<<<^^<.<.<.<^<<<^>^^..........v<vvvv>v>>>>>^>>^^^>^^>>>vv>v<vvv<<<<<<<<>^^.<.<^<^^^<.........>vv.>.vvvv>>>>^^<.<.<^^^<^<<.v<v>.>.>.>.>.>.>.vvv.v<<<<<^^<^<^>.>.>.>.^<^.>>>>>>>>vv>v<<vvv<<>>>>>^^^.^.>^<^<<<<<<<<.vv.>.v<<<.vvv<>>>>>^>^.<.<.<.<^^.^<<^<.....>>vvv<.>>vvv<<<>>>>>>>>^^^<<<.^.>.>^^.>>>>>vv.>v<vvv<<<>>>>>>^>^<^<<^.^^<vvv<<<<<vv.v<>>>>>>>>>>^>^.^^>^^<<<<.>vv.>.vvvv>^>>^.<.<.<^<<<^>^^>>>vv>v<<<<<vvv<<<>>>>>^^<.<.<.<.<^<^>.^^.>>>>>vv>v<>vvv<<<<<<<^>^.<^<<<<<<<^^^.>>>>>vv>v<>vvv>>>^^<.<^<<<^>^^.>>>>vv>.v<<vvv<<<<<^^^<<<<<^>.^^<>>>>>>>vv>.>v<<vvv<<<<<<<>>>^>>.>^^^.>^^<>>>>>>vv>vv.<.<.vv>>>>^^<.<.<.<^<<^.>^^.>>>>>vv.>.>v<<vvv<<>>>>>^^<.<.<.^^>.>.>^^<<<<<<<<.>>>>>>vv>v<<v.<.<vv<<<<^^.<^<<<.^^^<.vv.>v<vvv<<<>>>>>>^>^<^<<^.^<^<<.>>vv>.>.>.>vvvv>>>>>>^>^^^^^<<<.vvv<<<<<<vvv>>>>>^>^<.<^<<^.>.>.^^>>>>vv>.>v<<<<<<vvv<<<<^^^<.^.>^^>>>>vvv<<v.vv<<<^>>^^<<<.^^<<^>>>>>>>>>vvv.v.vv<>>>>>^>^^<<<<<<<<<<<<<<<<^^^..>>>>>vv>.>.>.>v<<v.<.<.vv<<<<<^^^<^>.^^...>>>>>>>>vv.v<.vvv>>>^>^<.<^^^^>>>vv>v<<<vvv<<<<>>>>>>^>^.<.<^<^>.>^^.>>>>>vv.v<<<<<<<<vvv<<<<^^<^<<<<<><^>.>^^>>>>vv.>.>.vvv.v>>>>>>>^^<.<^<<^^^>>>vv>.>.>.>.>v<<v.<.<vv>>>>^^^<<<<<.^.>^^>>>vv>.>v<vvv<<<<^^<.<.<.^^>^^>>>vv>.>.v<<<v.<vv<<<<^^.<^<<<^^^>>>>vvvvvv<<<<<<<<>^^.^>>^^^<>>>>>>>vvv<<<v.vv>>>>>^>>^^<<<<<^>.^^>>>>vv>.>v<<<<vvv<<<^^<.<.<.<^<<<<<^>^^>>>>vv.>vv.v.v<^>.>^.<.^^^^>>>>vv>.>.>.v<<<<<<vvv>>>>^^<.<.<^<<^^<^>>>>>>vv>v<<.vvv^>^^<<<^>^^<<<<<<.vvv<<vv>.v>>>>>>^>.>^^<<<<<^>.>.>.>.>.^^>>>>vv>.>.>v<<<<<vvv<<<<^^<^<<^.^^>>>>vv>.>.>.>v<vvv<<<<<^^.<.<^<<^^^>>>>>>>>>>>vv>.>.>.>.>vvvv<<<<^^.<.<^<^^^<<<<<<vvv<v.<vv<<<<^v>>>>>>>>>>^^^<.^.>.>.^^>>>>vvv<<<<<<<vvv<<<<<<<>^^.<^<.^^^.>>>>vv>v<vvv<>>>>^^.<.^.^.>.^<^>>>>>>>>vvvv.<.<vv<<<<^^^<<<<<^>.^^<.vv>.v<<vvv<<><>>>>>^>>^.<^<^^^<<<.>>vv>.>v<<<<v.vv>^>>^.<^^.^^.>>>>>vv>.>.>.v<v.<vv<<<<<^.^^^.>^^<>>>>>>vv>.v<<<v.<vv<<<<>>>>>>>>>>>^^<.<.<.<.<^<<^^<^<<<>>>>>>>vv>v<<<vv.v>>>>>>>>^>^<.<^<<<<<<<<<<<.^.>^^<<<vvv.v.<vv<<<^.>>^.<^^.>.>^^<<......vv.v>vvv>>>^.v^>>^^<<^^^<.>>>>>>>vvv<v.<.<.vv<<<<^^<.<.<.^^^^<.>>>>>>>>vvv<v.<vv^.>^^<<^^^vv>vvvv^>>>>>>>^^^^^vvvvvv^^^^^^vvvvvv>>>>

Hay menos de 8 millones de combinaciones de estados de posición X tiempo X conjunto de esquinas visitadas, por lo que se pueden buscar exhaustivamente en menos de 1 segundo. Si el código no tiene errores, debería ser imposible de superar. La estrategia óptima era usar toda la tabla, ya que eso permite que la rana cruce la carretera 160 veces, frente a aproximadamente 120 cuando está confinada al centro. Visitar las esquinas no costó ningún cruce ya que el tráfico era muy pesado.

/* feersum  2014/9
 /codegolf/37975/frogger-champion */

#include <iostream>
#include <fstream>
#include <string>
#include <algorithm>
#include <cstring>

#define B(F, CST, X, Y) best[ ((F)*NCST + (CST)) * BS + (Xmax-Xmin+1) * ((Y)-Ymin) + (X)-Xmin]
#define TL(i) ((int)t[i].length())
#define ABSPEED(I) (speed[i]<0?-speed[i]:speed[i])
#define errr(X) { cout<<"ERROR!!!!!!!!"; return X; }

#define DRAW 0
#if DRAW
    #include <unistd.h>
#endif


using namespace std;

int bc(int cs) {
    int c = 0;
    while(cs) {
        c += cs&1;
        cs >>= 1;
    }
    return c;
}

int main()
{
    const bool bonusTwentyfive = false;
    const int COLS = 23, T_ROWS = 5, YGS = T_ROWS + 2, XGS = COLS + 2;
    string t[5];
    int speed[] = {-4, 1, -2, -1, 4};
    ifstream f("t.txt");
    for(int i = 0; i < T_ROWS; i++)
        getline(f, t[i]);
    if(f.fail())
        return 1;
    f.close();
//for(int i = 0; i < 5; i ++)t[i]="xxx";

    char g[XGS][YGS];

    int mov[][3] = { {-1,  0, '<'},
                     {+1,  0, '>'},
                     { 0, -1, '^'},
                     { 0, +1, 'v'},
                     { 0,  0, '.'} };


    int Ymin = 0, Ymax = YGS-1;


    const int Xstart = 11, Xmaxmove = bonusTwentyfive ? 4 : 10;
    const int Xmin = Xstart - Xmaxmove, Xmax = Xstart + Xmaxmove;

    const int NCST = bonusTwentyfive ? 1 : 1<<4;

    int maxfr = 0;
    for(int i = 0; i < T_ROWS; i++) {
        if(speed[i] < 0) {
            for(int m = 0, n = t[i].length()-1; m < n; ++m,--n)
                swap(t[i][m], t[i][n]);
        }
        int carslen = TL(i);
        for(char*c = &t[i][speed[i]>0?TL(i)-1:0]; carslen; carslen--, speed[i]>0?--c:++c)
            if(*c != ' ')
                break;
        if(carslen)
            maxfr = max(maxfr, ( (carslen + COLS) * 2 + ABSPEED(i)-1 ) / ABSPEED(i));
    }
    const int BS = (Xmax-Xmin+1)*(Ymax-Ymin+1);
    int *best = new int[(maxfr+1)*NCST*BS];
    memset(best, 0xFF, (maxfr+1)*NCST*BS*sizeof(int));
    memset(g, ' ', sizeof(g));
    B(0, 0, Xstart, Ymax) = 0;

    for(int fr = 0; fr < maxfr; fr++) {
        for(int r = 0; r < T_ROWS; r++) {
            for(int x = 0; x < XGS; x++) {
                int ind = speed[r] > 0 ? TL(r)-1 + x - fr*speed[r]/2 : x - (XGS-1) - fr*speed[r]/2;
                g[x][r+1] = ind >= 0 && ind < TL(r) ? t[r][ind] : ' ';
            }
        }
        for(int x = Xmin; x <= Xmax; x++) {
            for(int y = Ymin; y <= Ymax; y++) {
                if(g[x][y] != ' ')
                    continue;
                for(unsigned m = 0; m < sizeof(mov)/sizeof(mov[0]); m++) {
                    int X = x + mov[m][0], Y = y + mov[m][1];
                    if(X < Xmin || X > Xmax || Y < Ymin || Y > Ymax)
                        continue;
                    if(!(mov[m][0]|mov[m][1]) && y > 0 && y > T_ROWS && g[x][y-speed[y-1]/4] != ' ')
                        continue;

                    int csor = ((X==Xmin|X==Xmax)&(Y==Ymin|Y==Ymax)&!bonusTwentyfive) << ((X==Xmax) + 2*(Y==Ymax));

                    for(int cs = 0; cs < NCST; cs++) {
                        int N = B(fr, cs, x, y);
                        if(!~N)
                            continue;
                        if((!(N&1) && y == 1 && Y == 0) ||
                              (N&1 && y == T_ROWS && Y == T_ROWS+1))
                            ++N;
                        if(N > B(fr+1, cs|csor, X, Y))
                            B(fr+1, cs|csor, X, Y) = N;
                    }


                }
            }
        }
    }

    int score = 0, xb, yb, cb, nb;
    for(int x = Xmin; x <= Xmax; x++) {
        for(int y = Ymin; y <= Ymax; y++) {
            for(int cs = 0; cs < NCST; cs++) {
                if(B(maxfr, cs, x, y) * (40 + bc(cs)) / 40 >= score) {
                    score = B(maxfr, cs, x, y) * (40 + bc(cs)) / 40;
                    xb = x, yb = y, cb = cs, nb = B(maxfr, cs, x, y);
                }
            }
        }
    }
    char *mvs = new char[maxfr+1];
    mvs[maxfr] = 0;

    for(int fr = maxfr-1; fr >= 0; --fr) {
        for(int r = 0; r < T_ROWS; r++) {
            for(int x = 0; x < XGS; x++) {
                int ind = speed[r] > 0 ? TL(r)-1 + x - fr*speed[r]/2 : x - (XGS-1) - fr*speed[r]/2;
                g[x][r+1] = ind >= 0 && ind < TL(r) ? t[r][ind] : ' ';
            }
        }
        for(int x = Xmin; x <= Xmax; x++) {
            for(int y = Ymin; y <= Ymax; y++) {
                if(g[x][y] != ' ')
                    continue;

                for(unsigned m = 0; m < sizeof(mov)/sizeof(mov[0]); m++) {
                    int X = x + mov[m][0], Y = y + mov[m][1];
                    if(X < Xmin || X > Xmax || Y < Ymin || Y > Ymax)
                        continue;
                    if(!(mov[m][0]|mov[m][1]) && y > 0 && y > T_ROWS && g[x][y-speed[y-1]/4] != ' ')
                        continue;

                    int csor = ((X==Xmin|X==Xmax)&(Y==Ymin|Y==Ymax)&!bonusTwentyfive) << ((X==Xmax) + 2*(Y==Ymax));

                    for(int cs = 0; cs < NCST; cs++) {
                        int N = B(fr, cs, x, y);
                        if(!~N)
                            continue;
                        if((!(N&1) && y == 1 && Y == 0) ||
                              (N&1 && y == T_ROWS && Y == T_ROWS+1))
                            ++N;
                        if(X==xb && Y==yb && N == nb && (cs|csor) == cb) {
                            mvs[fr] = mov[m][2];
                            xb = x, yb = y, nb = B(fr, cs, x, y), cb = cs;
                            goto fr_next;
                        }
                    }
                }
            }
        }
        errr(3623);
        fr_next:;
    }

    if((xb-Xstart)|(yb-Ymax)|nb)
        errr(789);
    #if DRAW

        for(int fr = 0; fr <= maxfr; ++fr) {
            memset(g, ' ', sizeof(g));
            for(int r = 0; r < T_ROWS; r++) {
                for(int x = 0; x < XGS; x++) {
                    int ind = speed[r] > 0 ? TL(r)-1 + x - fr*speed[r]/2 : x - (XGS-1) - fr*speed[r]/2;
                    ind >= 0 && ind < TL(r) ? g[x][r+1] = t[r][ind] : ' ';
                }
            }
            g[xb][yb] = 'F';
            for(int y = 0; y < YGS; y++) {
                for(int x = 0; x < XGS; x++)
                    cout<<g[x][y];
                cout<<endl;
            }
            cout<<string(XGS,'-')<<endl;
            usleep(55*1000);
            for(int i = 0; i < 5; i++) {
                if(mvs[fr] == mov[i][2]) {
                    xb += mov[i][0];
                    yb += mov[i][1];
                    break;
                }
            }
        }

    #endif
    cout<<score<<endl;
    cout<<mvs<<endl;
}
Feersum
fuente
1
No estoy seguro de cómo estás definiendo "estados". Si consideramos que el estado del sistema es el perfil de tiempo del movimiento de la rana, hay aproximadamente 5 ^ 3000 estados, que corresponden al perfil de movimiento para las 5 ^ 3000 entradas posibles (cinco entradas posibles por ~ 3000 cuadros). Obviamente, solo una fracción de estos resultará admisible, pero el número de estados admisibles sería imposible de buscar por muchos cientos de órdenes de magnitud. Cuando envíe su respuesta final, envíe una lista de movimientos junto con ella.
COTO
Además, en caso de que no esté claro, tenga en cuenta que la rana puede saltar de izquierda a derecha mientras está en el tráfico, siempre que no se viole ninguna de las reglas "aplastadas". No está limitado a esperar ventanas donde la rana pueda saltar verticalmente sin movimiento lateral.
COTO
@COTO En mi cálculo de "estados", olvidé una cosa importante, a saber, el número de cruces hasta ahora, así que traté de dar una explicación más clara. La especificación estaba bastante bien escrita. Parece que he interpretado todos estos problemas en particular correctamente la primera vez.
fiesta del
Calculo el óptimo como 162 + 10% = 178 cruces, pero el suyo está lo suficientemente cerca. Realmente no quería que esto resultara tener fuerza bruta, pero evidentemente debería haber pensado más en el problema. Para ser justos, te otorgaré las 100 repeticiones.
COTO
Aparentemente tengo que esperar 24 horas antes de otorgar la "recompensa". Por qué razón: quién sabe. SE no debe querer respuestas recompensadas puntualmente. Si hiciéramos eso, los terroristas ganarían. : O
COTO