Karel - stĺpcové odčítanie


  • Riešenie využíva fibonacciho postupnosť
  • Program nepoužíva premenné
  • Funkčnosť:
  • Robot Karel v cykle premiestňuje beepre z horneho riadku na spodny až do dosiahnutia bodu bez beeprov a v cykle toľko isto beeprov vráti na pôvodnú pozíciu.
  • Pri druhom čísle, ktoré sa odčítava je situácia rovnaká, avšak tu Robot beepre odoberá zo spodného riadku a tým upraví výsledok na správny.
  • Pre sčítanie je nutné krok odoberania beeprov odstrániť.
  • Počitočný stav:
    Koncový stav:

    Svet 1 - world.kw

    9 5 2 3 E 99
    
    B 3 3 4
    
    B 3 2 1
    
    B 4 3 5
    
    B 4 2 2
    
    B 5 3 6
    
    B 5 2 3
    

    Svet 2 - world2.kw

    10 10 3 9 E 99
    
    B 4 9 10
    
    B 4 8 9
    
    B 5 9 8
    
    B 5 8 2
    
    B 6 9 9
    
    B 6 8 8
    

    Svet 3 - world3.kw

    5 5 1 3 E 99
    
    B 2 3 5
    
    B 2 2 3
    
    B 3 3 8
    
    B 3 2 6
    
    B 4 3 9
    
    B 4 2 1
    

    Zdrojový kód odčítania:

    #include <karel.h>       // nalinkovanie kniznice karla
    #define SPEED 100              // definicia rychlosti pohybu
    void Switcher(void);
    void turnRight(void);
    void moveBack2x(void);
    void moveBack(void);
    void sub(void);
    void rewriteFirstNum(void);
    void minusSecondNum(void);
    // DEFINUJEME FUNKCIE
    void moveBack2x(void){        // funkcia s dvojitym pohybom dozadu a obratom, vyuzivana pri presune z horneho cisla pri prepise
    	loop(2){
    		turnLeft();
    	}
    	loop(2){
    		movek();
    	}
    	loop(2){
    		turnLeft();
    	}
    }
    
    void moveBack(void){     // funkcia s pohybom dozadu a obratom, vyuzivana pri presune o jedno cislo vyssie pri samotnom odcitani cisla
    	loop(2){
    		turnLeft();
    	}
    	movek();
    	loop(2){
    		turnLeft();
    	}
    }
    
    void Switcher(void){    // funkcia Switcher pre switchovanie medzi 2 funkciami, na druhu funkciu prepne az po korektnom vykonani prvej.
    	moveBack2x();
    	rewriteFirstNum();
    	movek();
    	minusSecondNum();
    }
    
    void rewriteFirstNum(void){  // funkcia prepisu prveho cisla v stlpci, funkcia vyuziva dvojnasobny pohyb dozadu
    	pickBeeper();
    	if(beepersPresent()){   // ak je na pozicii stale beeper, tak zdvihaj
    		rewriteFirstNum();
    	}
    	putBeeper(); // nakoniec na prazdne miesto poloz beeper
    	loop(2){
    		movek();
    	}
    	putBeeper(); //poloz beeper pod mensenca
    	moveBack2x();
    }
    
    void minusSecondNum(void){    //funkcia odcitania druheho cisla v stlpci s vyuzitim jedneho posunu dozadu
    	pickBeeper();
    	if(beepersPresent()){ //zdvihaj beeper, ak je stale na pozicii
    		minusSecondNum();
    	}
    	putBeeper();
    	movek();
    	pickBeeper(); //zober beeper od mensenca, odcitavam
    	moveBack();
    	}
    	void sub(void){ // hlavna funkcia, ktora plni odcitanie, obsahuje podfunkciu Switcher, ktora obsahuje dalsie 2 podfunkcie pre prepis a odcitanie cisla
    	movek();
    	turnRight();
    	loop(2){
    		movek();
    	}
    	Switcher();    //Switcher spusta prepis i odcitanie cisel vramci funkcii
    	loop(2){
    		turnRight();
    	}
    	movek();
    	turnRight();
    }
    
    void turnRight(void){    // funkcia pre otocenie doprava
    	loop(3){
    		turnLeft();
    	}
    }
    
    int main(){ //hlavna funkcia main, v ktorej sa vykonava samotny kod programu
    	turnOn("world.kw"); // spustenie sveta robota
    	setStepDelay(SPEED);    //rychlost krokov definovana SPEED-om --> definovany hore
    	loop(3){        //slucka 3x funkcia sub pre kompletne odcitanie troch stlpcov za sebou
    		sub();
    	}
    	movek();        //zaciatok pohybu do vyslednej  polohy robota
    	turnRight();
    	loop(2){
    		movek();
    	}
    	turnLeft();      //koniec pohybu do vyslednej polohy robota
    	turnOff();    //ukoncenie programu
    	return 0;
    }
    						

    Knižnica karel.h:

    #ifndef _KAREL_H
    #define	_KAREL_H
    
    #include <stdio.h>
    #include <stdbool.h>
    
    
    // loop() macro to replace for()
    #define loop(COUNT) for(size_t __loop_cntr = 0; __loop_cntr < COUNT; __loop_cntr++)
    
    
    // *************************************** Primitives 
    
    /**
     * Moves Karel one step forward
     * If there is wall or Karel is at the border of the world, he will be turned 
     * off automatically.
     */
    void movek();
    
    
    /**
     * Turns Karel 90 degrees left
     */
    void turnLeft();
    
    
    /**
     * Initializes the world of Karel the Robot
     * Function has one parameter, which defines the location of world file. If
     * the file doesn't exist, program will be terminated with error message.
     * @param path location of the world file
     */
    void turnOn(char* path);
    
    
    /**
     * Terminates  Karel's program
     */
    void turnOff();
    
    
    /**
     * Puts beeper at the current world position, if Karol has some
     */
    void putBeeper();
    
    
    /**
     * Picks beeper from current position if there is any and puts it to Karol's bag
     */
    void pickBeeper();
    
    
    // *************************************** Sensors
    
    /**
     * Checks, if there are beepers present at the corner
     * @return true, if there are beepers, false otherwise
     */
    bool beepersPresent();
    
    
    /**
     * Checks, if there are no beepers present at the corner
     * @return true, if there are no beepers, false otherwise
     */
    bool noBeepersPresent();
    
    
    /**
     * Checks, if there are any beepers in the bag
     * @return true, if there are some, false otherwise
     */
    bool beepersInBag();
    
    
    /**
     * Checks, if there are no beepers in the bag
     * @return true, if there are no beepers, false otherwise
     */
    bool noBeepersInBag();
    
    
    /**
     * Checks, if front of Karel is clear to go
     * @return true, if clear, false otherwise
     */
    bool frontIsClear();
    
    
    /**
     * Checks, if the front of Karel is not clear to go
     * @return true if it is not clear, false otherwise
     */
    bool frontIsBlocked();
    
    
    /**
     * Checks, if the corner on the left side of Karel is clear to go
     * @return true if it is clear, false otherwise
     */
    bool leftIsClear();
    
    
    /**
     * Checks, if the corner on the left side of Karel is not clear to go
     * @return true if it is not clear, false otherwise
     */
    bool leftIsBlocked();
    
    
    /**
     * Checks, if the corner on the right side of Karel is clear to go
     * @return true if it is clear, false otherwise
     */
    bool rightIsClear();
    
    
    /**
     * Checks, if the corner on the right side of Karel is not clear to go
     * @return true if it is not clear, false otherwise
     */
    bool rightIsBlocked();
    
    
    /**
     * Checks, if Karel is facing north
     * @return true, if yes, false otherwise
     */
    bool facingNorth();
    
    
    /**
     * Checks, if Karel is not facing north
     * @return true, if yes, false otherwise
     */
    bool notFacingNorth();
    
    
    /**
     * Checks, if Karel is facing east
     * @return true, if yes, false otherwise
     */
    bool facingEast();
    
    
    /**
     * Checks, if Karel is not facing east
     * @return true, if yes, false otherwise
     */
    bool notFacingEast();
    
    
    /**
     * Checks, if Karel is facing west
     * @return true, if yes, false otherwise
     */
    bool facingWest();
    
    
    /**
     * Checks, if Karel is not facing west
     * @return true, if yes, false otherwise
     */
    bool notFacingWest();
    
    
    /**
     * Checks, if Karel is facing south
     * @return true, if yes, false otherwise
     */
    bool facingSouth();
    
    
    /**
     * Checks, if Karel is not facing south
     * @return true, if yes, false otherwise
     */
    bool notFacingSouth();
    
    
    // *************************************** Functions
    
    /**
     * Sets the delay of one step
     * @param delay the delay in millis
     */
    void setStepDelay(int delay);
    
    
    /**
     * Returns the current value of Karel's step delay
     * @return the step delay value in millis
     */
    int getStepDelay();
    
    #endif	/* _KAREL_H */
    

    Knižnica internals.h:

    #include "karel.h"
    
    #ifndef _INTERNALS_H
    #define	_INTERNALS_H
    
    
    #define MULTIPLIER 1000
    #define MAX_WIDTH   30
    #define MAX_HEIGHT  30
    
    // global variables (application context)
    extern int stepDelay;
    extern bool summary_mode;
    extern struct world world;
    extern struct robot karel;
    
    enum block{
        CLEAR = 0,
        WALL = -1
    };
    
    
    /**
     * World definition
     */
    struct world{
        int width, height;  // world's width and height
        int **data;         // world data definition
    };
    
    
    /**
     * Available directions
     */
    enum direction{
        EAST = 0,
        NORTH = 90,
        WEST = 180,
        SOUTH = 270
    };
    
    
    /**
     * Robot definition
     */
    struct robot{
        int x, y;       // position
        enum direction direction;   // direction
        int steps;      // nr. of steps
        int beepers;    // nr. of beepers in bag
        bool isRunning; // robot's state
        char lastCommand[10];   // last executed command
    };
    
    
    enum Colors {
        RED_ON_BLACK = 1,
        YELLOW_ON_BLACK,
        WHITE_ON_BLACK
    };
    
    
    /**
     * Draws scene only
     * Draws only world, without karel and state info
     */
    void drawWorld(struct world world, struct robot karel);
    
    
    void render(struct world world, struct robot karel);
    void update(struct world world, struct robot karel, int dx, int dy);
    void errorShutOff(char* message);
    void initialize();
    void deinit();
    
    /**
     * Exports data about world and karel
     * Export is useful in summary mode only. Summary mode can be enabled 
     * with environment variable LIBKAREL_SUMMARY_MODE with it's value "true".
     * @param struct world world data
     * @param struct robot robot karel
     */
    void export_data(struct world world, struct robot karel);
    
    
    #endif	/* _INTERNALS_H */