Cyprien JULLIEN

---

DETECTIVE PIKAPTCHA

Le détective Pikaptcha enquête sur une perturbation dans le continuum spacio-temporel. Il semblerait qu’un puissant poké-bot soit en train de déformer l’espace autour de notre héros pour le piéger. Aidez Pikaptcha à cartographier son environnement afin qu’il s'échappe et trouve le coupable !

_____

Les solutions

PIKAPTCHA I

    
#include < stdlib.h >
#include < stdio.h >
#include < string.h >
#include < stdbool.h >

#define M 100

char nbPossibiliti(char tab[][M],int w,int h,int y,int x)
{
    //return # si la case actuelle est #
    if(tab[y][x]=='#'){return '#';}

    //test dans les 4 directions
    char nb='0';
    if(y+1=0 && tab[y][x-1]=='0'){nb=nb+1;}
    if(y-1>=0 && tab[y-1][x]=='0'){nb=nb+1;}

    return nb;
}

int main()
{
    int width;
    int height;
    char tab[M][M];

    scanf("%d%d", &width, &height);
    
    //rangement de la carte dans un tableau 2D
    for (int y = 0; y < height; y++) {
        char line[256];
        scanf("%s", line);
        for(int x=0;x < width ;x++)
        {
            tab[y][x]=line[x];
        }
    }
    //parcours du tableau 2D
    for (int y = 0; y < height; y++) {
        

        for(int x=0;x < width ;x++)
        {
            //calcul du nombre de possibilitées
            //puis le renvoi
            printf("%c",nbPossibiliti(tab,width,height,y,x));
        }
    
        printf("\n");
    }

    return 0;
}
                    
                    
                

PIKAPTCHA II



#include < stdlib.h >
#include < stdio.h >
#include < string.h > 
#include < stdbool.h >

#define M 100

void Passage(char tab[][M],int w,int h,int y,int x)
{
    if(tab[y][x]!='>' && tab[y][x]!='v' && tab[y][x]!='<' &&tab[y][x]!='^')
    {
    char nb=tab[y][x];
    tab[y][x]=nb+1;
    }
    else
    {
        char nb='0';
        tab[y][x]=nb+1;
    }
}

void ProchaineDestination(char tab[][M],int w,int h,int *y,int *x,int *rot,int side)
{
    
    int tmp_y=*y,tmp_x=*x,tmp_rot=*rot;
    switch(*rot)
    {
     case 0:
        //faire la diagonal
        if(side == 1 && (*x+1=0 && tab[*y-1][*x+1]!='#' && tab[*y][*x+1]!='#') || side == 0 && (*x+13 ? 0: tmp_rot;
            }
            else
            {
                tmp_rot-=1;
                tmp_rot = tmp_rot<0 ? 3: tmp_rot;
            }

            Passage(tab,w,h,*y,*x);
        }
        //avancer
        else if(*x+13 ? 0: tmp_rot;
            }
        }

        break;
    case 1:
        //faire la diagonal
        if(side == 1 && (*x+1=0 && *y+13 ? 0: tmp_rot;
            }
            else
            {
                tmp_rot-=1;
                tmp_rot = tmp_rot<0 ? 3: tmp_rot;
            }

            Passage(tab,w,h,*y,*x);
        }
        //avancer
        else if(*y+13 ? 0: tmp_rot;
            }
        }

        break;
    case 2:
        //faire la diagonal
        if(side == 1 && (*x-1>=0 && *y+1=0 && *y-1>=0 && tab[*y-1][*x-1]!='#' && tab[*y][*x-1]!='#'))
        {
            tmp_x-=1;
            if(side==0)
            {
                tmp_rot+=1;
                tmp_rot = tmp_rot>3 ? 0: tmp_rot;
            }
            else
            {
                tmp_rot-=1;
                tmp_rot = tmp_rot<0 ? 3: tmp_rot;
            }

            Passage(tab,w,h,*y,*x);
        }
        //avancer
        else if(*x-1>=0 && tab[*y][*x-1]!='#')
        {
            tmp_x-=1;

            Passage(tab,w,h,*y,*x);
        }
        //tourner
        else
        {
            if(side==0)
            {
                tmp_rot-=1;
                tmp_rot = tmp_rot<0 ? 3: tmp_rot;
            }
            else
            {
                tmp_rot+=1;
                tmp_rot = tmp_rot>3 ? 0: tmp_rot;
            }
        }

        break;
    case 3:
        //faire la diagonal
        if(side == 1 && (*x-1>=0 && *y-1>=0 && tab[*y-1][*x-1]!='#' && tab[*y-1][*x]!='#') || side == 0 && (*x+1=0 && tab[*y-1][*x+1]!='#' && tab[*y-1][*x]!='#'))
        {
            tmp_y-=1;
            if(side==0)
            {
                tmp_rot+=1;
                tmp_rot = tmp_rot>3 ? 0: tmp_rot;
            }
            else
            {
                tmp_rot-=1;
                tmp_rot = tmp_rot<0 ? 3: tmp_rot;
            }

            Passage(tab,w,h,*y,*x);
        }
        //avancer
        else if(*y-1>=0 && tab[*y-1][*x]!='#')
        {
            tmp_y-=1;

            Passage(tab,w,h,*y,*x);
            
        }
        //tourner
        else
        {
            if(side==0)
            {
                tmp_rot-=1;
                tmp_rot = tmp_rot<0 ? 3: tmp_rot;
            }
            else
            {
                tmp_rot+=1;
                tmp_rot = tmp_rot>3 ? 0: tmp_rot;
            }
        }

            break;
        
    }

    //modif des co
    *y=tmp_y;
    *x=tmp_x;
    *rot=tmp_rot;
}

int main()
{

    int width;
    int height;

    char tab[M][M];

    //cartographier
    scanf("%d%d", &width, &height);
    for (int y = 0; y < height; y++) {
        char line[256];
        scanf("%s", line);

        for(int x=0;x < width ;x++)
        {
            tab[y][x]=line[x];
        }

    }
    char side[2];
    scanf("%s", side);

    int startPos_y;
    int startPos_x;
    int pos_y=0;
    int pos_x=0;
    int rotation=0;
    //code de la rotation
    //0=> ; 1=v ; 2=< ; 3= ^;

    int initialise =1;

    //initialiser Pika
    for (int y = 0; y < height && initialise; y++) {
        
        for(int x=0;x < width && initialise ;x++)
        {
            
            switch(tab[y][x])
            {
                case '>':
                    pos_y=y;
                    pos_x=x;
                    rotation=0;
                    startPos_y=y;
                    startPos_x=x;
                    initialise=0;
                    break;
                case 'v':
                    pos_y=y;
                    pos_x=x;
                    rotation=1;
                    startPos_y=y;
                    startPos_x=x;
                    initialise=0;
                    break;
                case '<':
                    pos_y=y;
                    pos_x=x;
                    rotation=2;
                    startPos_y=y;
                    startPos_x=x;
                    initialise=0;
                    break;
                case '^':
                    pos_y=y;
                    pos_x=x;
                    rotation=3;
                    startPos_y=y;
                    startPos_x=x;
                    initialise=0;
                    break;
                
            }
            
        }

    }

    //parcourir le tableau
    int start =0;

    while(pos_y!=startPos_y || pos_x!=startPos_x || start<4)
    {
        start++;
        if(side[0]=='R')
        {
            ProchaineDestination(tab,width,height,&pos_y,&pos_x,&rotation,0);
        }
        else
        {
            ProchaineDestination(tab,width,height,&pos_y,&pos_x,&rotation,1);
        }
        if(start ==4 && pos_y==startPos_y && pos_x==startPos_x)
        {
            tab[pos_y][pos_x]='0';
        }
    }

    for(int x=0;x < width ;x++)
    {
            
        printf("%c",tab[y][x]);
    }
    printf("\n");
    

    return 0;
}

                    
                    
                

_______

Explication de code

DETECTIVE PIKAPTCHA I

Dans un premier temps je crée un tableau en 2D, puis je range les valeurs de l'input à l'intérieur. Ensuite je viens faire un boucle sur le tableau 2D, afin de passer chaques élémens du tableau dans la fonction nbPossibiliti(), cette fonction va me renvoyer le nombre de case vide autour de la case demandée. Enfin je print les valeurs renvoyées.

Dans un premier temps je crée un tableau en 2D, puis je range les valeurs de l'input à l'intérieur. Ensuite je viens faire une premiere boucle afin de repérer les coordonée de la case de départ ainsi que sa rotations. Une fois fait je parcours le tableau 2D tant que Pika n'est pas sur son point de départ, dans cette boucle je vais appeller la fonction ProchaineDestination() qui va me permettre de déplacer Pika sur la prochaine case:

  • Soit la case devant est vide ainsi que celle en diagonale alors Pika va avancer devant et changer de rotation.
  • Soit il y a une case vide alors Pika va avancer.
  • Soit il y a un mur alors Pika va changer de rotation.
  • Sur chaque déplacement la fonction ProchaineDestination() va appeller la fonction Passage() qui va permetre de marquer la case et ainsi savoir combien de fois Pika est passé dessus. Enfin je fait une dernière boucle sur le tableau afin de print le tableau.

    DETECTIVE PIKAPTCHA II

    Test et exécutions

    Les test de pikaptcha sont intéligeament imposé, ils vont vérifier si le code ne prends pas trop de temps à être exécuté, les tests crée des situations ou le PIKA est enfermé (pour tester ainsi toutes les possibilitées), ou encore lorsque le Pika est face contre un mur.

    Solution de Mykeich

      
    #include < stdlib.h >
    #include < stdio.h >
    #include < string.h >
    
    typedef struct _pos {
        int x;
        int y;
    } Pos;
    
    Pos DIR[4] = { { 0, -1 }, { 1, 0 }, { 0, 1 }, { -1, 0 } };
    
    int main()
    {
        int width;
        int height;
        scanf("%d%d", &width, &height);
        int grid[width][height];
        Pos start;
        int dir = 0;
        for (int y = 0; y < height; y++) {//Read input grid
            char line[256];
            scanf("%s", line);
            for (int x = 0; x < width; x++) {
                grid[x][y] = 0;
                switch (line[x]) {
                case '#':
                    grid[x][y] = -1;
                    break;
                case '^':
                    dir = 0;
                    start.x = x;
                    start.y = y;
                    break;
                case '>':
                    dir = 1;
                    start.x = x;
                    start.y = y;
                    break;
                case 'v':
                    dir = 2;
                    start.x = x;
                    start.y = y;
                    break;
                case '<':
                    dir = 3;
                    start.x = x;
                    start.y = y;
                    break;
                }
            }
        }
        char side[2];
        scanf("%s", side);
        int s = -1;
        if (side[0] == 'R') {
            s = 1;
        }
        Pos now = start, next = start;
        int exit = 0;
        while (!exit) {
            dir+=s;
            for(int i = 0; i < 4; i++) {
                next = now;
                if (dir < 0) {
                    dir += 4;
                }
                if (dir > 3) {
                    dir -= 4;
                }
                next.x = now.x + DIR[dir].x;
                next.y = now.y + DIR[dir].y;
                if(next.x >= 0 && next.x < width && next.y >= 0 && next.y < height){
                    if(grid[next.x][next.y] >= 0){
                        now = next;
                        grid[now.x][now.y]++;
                        break;
                    }
                }
                if(s > 0){
                    dir--;
                }else{
                    dir++;
                }
            }
            if(now.x == start.x && now.y == start.y){
                exit = 1;
            }
        }
        for (int y = 0; y < height; y++) {
            for (int x = 0; x < width; x++) {
                if (grid[x][y] < 0) {
                    printf("#");
                } else {
                    printf("%d", grid[x][y]);
                }
            }
            printf("\n");
        }
        return 0;
    }
                        
                        

    Mykeich utilise une class pour y renseigner la position de Pika, il ustilise aussi un tableau de tuple qui sera les coordonées des cases adjacente du Pika. Mykeich commence par chercher les murs qu'il renseignera comme -1 dans un tableau 2D, et la position de départ du Pika ainsi que sa rotation. Ensuite il boucle jusqu'à retrouver la position de départ. Puis il vient de façon astucieuse récupérer la position next grace à la position now + les coordonées de la direction actuelle remplis dans son tableau où il a renseigné les cases ajacentes. Puis, si la position next n'est pas la même que la position now alors il ajoute 1 à l'élément x, y de grid. Enfin Mykeich vient faire une derniere boucle pour renvoyer son tableau et reremplacer les chiffre négatif par des # (ceci lui a permis de ne pas générer d'erreurs lors de la vérification des cases adjacentes).

    -
    Contactez-moi

    mail E-mail cypdevstuff@gmail.com
    photo_camera Instagram cyprien_jlln