Selle aasta pidulik gala Spordiaasta Tähed 2011 Nokia Kontserdimajas toimus oma tavapärases headuses, kuid lõbus naer vallandus mu mõtetes kui nägin laval nelja Kristjan Palusalu robotit ringi vuramas.
Välja kuulutati Gerd Kanter kui Eesti Meessportlane 2011 ja Triin Aljand kui Eesti Naissportlane 2011.
Ja selliste tippudega koos on laval 4 robotit – see on super-lahe näide selle kohta et kus kohtuvad tippsport ja robootika.
Me oleme õigel teel
Pilt võetud Õhtulehe galeriist.http://www.ohtuleht.ee/457802
http://www.teaduskool.ut.ee/orb.aw/class=file/action=preview/id=6379/poh.et.pdf
3. Jada - 1 sekund - 50 punkti
Vaatleme (lõpmatut) numbrijada, mille saame kõigi positiivsete täisarvude kasvavas järjekorras üksteise järele kirjutamisega: 123456789101112131415...
Kirjutada programm, mis leiab selles jadas positsioonidel N ja N + 1 olevad numbrid.
Sisend. Tekstifaili jada.sis ainsal real on täisarv N (1 <= N <= 109).
Väljund. Tekstifaili jada.val ainsale reale väljastada kaks numbrit — jada otsitavad elemendid. Numbrid väljastada vahetult üksteise kõrvale, ilma tühikuteta.
Näide. jada.sis 5 | jada.val 56 |
Näide. jada.sis 14 | jada.val 12 |
Hindamine. Testides summaarse väärtusega 30 punkti on N <= 106 ja nende hulgas testides summaarse väärtusega 15 punkti on N <= 103.
Selle lahenduse väljamõtlemine oli kõige keerulisem. Siin tekkis mitu lahendusvarianti kuid kas alljärgnev on kõige efektiivsem, selles pole ma kindel. Sisetunne ütleb, et seda saaks intelligentsemalt teha, kuid minu arvuridade seaduspärade õppimine on üsna kaugesse kooliaega libisenud seega lähenesin nö. “brutal force” meetodil ülesande lahendamisele.
Alljärgnevaga on ülesanne lahendatud, aga äkki on kellelgi parem meetod?
Code Snippet
- #include <stdio.h>
-
- FILE *jada, *valf;
-
- int _tmain(int argc, _TCHAR* argv[])
- {
- int temp;
- int sisend;
- int i;
- int tulemus;
- int jrk;
- int end = 0;
-
- jada = fopen("jada.sis", "r");
- fscanf( jada, "%i", &sisend);
-
- for(i=1; i<100000000; i++)
- {
- temp = i;
- jrk = 0;
- //järgmise while tsükli abil saame teada mis number on sisend positsioonil
- //ja mitmendal kohal antud numbri sees on otsitav arv
- while(temp > 0) {
- temp = temp/10;
- end++;
- jrk++;
- if(end == sisend)
- break;
- }
- if(end == sisend)
- break;
- }
-
- //saame teada numbri positsioonide arvu
- temp = i;
- end = 0;
- while(temp > 0) {
- temp = temp/10;
- end++;
- }
-
- //vastavalt postisioonile leiame numbri seest arvu
- temp = i;
- for(int k = jrk; k <= end; k++)
- {
- tulemus = temp%10;
- temp = temp/10;
- }
-
- printf("arv on %i\n", tulemus);
- valf = fopen("jada.val", "w");
- fprintf(valf, "%i%i\n", tulemus, tulemus+1);
- fclose(valf);
- return 0;
- }
http://www.teaduskool.ut.ee/orb.aw/class=file/action=preview/id=6379/poh.et.pdf
2. Kurgid - 1 sekund - 30 punkti
Talunikul on ristküliku kujuline põld ja ta tahab sellele teha kurgipeenra. Selleks, et peenart oleks parem masinatega harida, peab ka peenar olema ristküliku kujuline ja selle servad peavad olema paralleelsed põllu servadega.
Põllul on kaks mobiilimasti. Selleks, et peenart saaks öökülmade kaitseks kilega katta, ei tohi mastid olla peenra sees.
Kirjutada programm, mis leiab peenra maksimaalse võimaliku pindala.
Sisend. Tekstifaili kurgid2.sis esimesel real on põllu pikkus X (0 < X <= 109) ja laius Y (0 < Y <= 109). Faili teisel real on esimese masti koordinaadid X1 (0 <= X1 <= X) ja Y1 (0 <= Y1 <= Y ), mis näitavad, et mast on põllu vasakust otsast kaugusel X1 ja alumisest küljest kaugusel Y1. Faili kolmandal real on teise masti koordinaadid X2 ja Y2. Kõik arvud on täisarvud. Masti läbimõõt on põllu suurusega võrreldes nii väike, et seda pole vaja arvestada.
Väljund. Tekstifaili kurgid2.val ainsale reale väljastada täisarv S — otsitav pindala.
Näide. kurgid2.sis 10 5 4 1 8 4 | kurgid2.val 32 |
Näide. kurgid2.sis 10 5 4 1 7 4 | kurgid2.val 30 |
Alloleval joonisel on vasakul kujutatud esimese ja paremal teise näite lahendus.
Hindamine. Testides summaarse väärtusega 10 punkti on X <= 100 ja Y <= 100.
Kuna selle kohta initsiaalset (ka mittetöötavat) lahendust polnud siis siin on puhtalt minu lahendusvariant.
Code Snippet
- #include <stdio.h>
- #include <stdlib.h>
-
- FILE *sisf;
- FILE *valf;
-
- int main(int argc, char *argv[])
- {
- int x, y, x1, y1, x2, y2;
- int val[4];
-
- sisf = fopen( "kurgid2.sis", "r" );
- fscanf( sisf, "%i %i\n%i %i\n%i %i", &x, &y, &x1, &y1, &x2, &y2 );
-
- val[0]= abs((x2-x1)*y);
- val[1] = abs((y2-y1)*x);
-
- val[2] = x1>x2 ? (x-x2)*y1 : (x-x1)*y2;
- val[3] = y1>y2 ? (y-y2)*x1 : (y-y1)*x2;
-
- int max = val[0];
- for(int i=0; i<4;i++)
- max = max < val[i] ? val[i] : max ;
-
- printf("Max on %i\n", max);
-
- valf = fopen("kurgid2.val", "w");
- fprintf(valf, "%i\n", max);
- fclose(valf);
- return 0;
- }
Põhikooli ja muidugi ka gümnaasiumi õpilased on ikka mega-targad. Informaatika olümpiaad tekkis sel aastal päevakorda ning siis mõtlesin, et proovin kõige lihtsamad ehk põhikooli ülesanded ära lahendada. No ausalt öeldes võttis mul ikka aega, et meelde tuletada mingeid lihtsaid matemaatika põhitõdesid ja alljärgnevale ülesandele lahendus kirjutada. Keeleks valisin puhta C, mis lisas omakorda veidi keerukust keele õppimise näol.
http://www.teaduskool.ut.ee/orb.aw/class=file/action=preview/id=6379/poh.et.pdf
1. Summa - 0,5 sekundit - 20 punkti
Kirjutada programm, mis leiab antud täisarvude A ja B vahele jäävate täisarvude summa (A ja B ise kaasa arvatud).
Sisend. Tekstifaili summa.sis ainsal real on tühikuga eraldatud täisarvud A (−109 <= A <= 109) ja B (−109 <= B <= 109).
Väljund. Tekstifaili summa.val ainsale reale väljastada täisarv S — otsitav summa.
Näide. summa.sis 1 5 | summa.val 15 |
Näide. summa.sis 3 2 | summa.val 5 |
Hindamine. Testides summaarse väärtusega 10 punkti on liidetavate arv <= 10 000.
Lahenduse tegemisel võtsin aluseks Rao koodi ning täiendasin seda viisil, et tööle hakkaks.
Code Snippet
- #include <stdio.h>
- #include <stdlib.h>
-
- FILE *sisf;
- FILE *valf;
-
- int main(int argc, char *argv[])
- {
- int x, y, hoidja;
- double summa;
-
- sisf = fopen( "summa.sis", "r" );
- fscanf( sisf, "%i %i", &y, &x );
-
- printf("X on %i\n", x);
- printf("Y on %i\n", y);
- if(y > x)
- {
- hoidja = y;
- y = x;
- x = hoidja;
- }
-
- for(summa = 0; y <= x; y++)
- {
- summa += y;
- }
-
- printf("Summa on %.f\n", summa);
- valf = fopen("summa.val", "w"); /* avame faili kirjutamiseks */
- fprintf(valf, "%.f\n", summa); /* v?¤ljastame */
- fclose(valf); /* sulgeme faili */
- return 0;
- }
Ülesanne 4
Ehita BOT, millel on peal mootoriga Ultrasonic ning allpool asuvate objektide jaoks lülitiandur.
Kirjuta programm, mille käigus robot sõidab otse kuni näeb ees seina 20 cm kaugusel või põrkab lülitiga mõne väiksema takistuse vastu. Takistuse avastamisel robot peatub, vaatab Ultrasonic anduriga paremale / vasakule ning see kummal pool on rohkem ruumi (ehk US andur näeb kaugemale), sinna sõidab.
Lahendus
Käesolev explorer kasutab kahte andurit, seega lisandub veidi keerukust roboti programmeerimisele.
task main(){
SetSensorLowspeed(S1);
SetSensorTouch(S2);
int Kaugus;
int ParemPool;
int VasakPool;
Kaugus = 20;
while (TRUE){
if(SensorUS(S1) < Kaugus || Sensor(S2)){
Off(OUT_BC);
if(Sensor(S2))
{
RotateMotor(OUT_BC, -50, 360);
}
RotateMotor(OUT_A, 50, 90);
ParemPool = SensorUS(S1);
RotateMotor(OUT_A, -50, 180);
VasakPool = SensorUS(S2);
RotateMotor(OUT_A, 50, 90);
if(ParemPool > VasakPool)
RotateMotorEx(OUT_BC, 50, 217, -100, TRUE, TRUE);
else
RotateMotorEx(OUT_BC, 50, 217, 100, TRUE, TRUE);
}
else{OnFwd(OUT_BC, 100);}
}
}
Ülesanne 3 (Exploreri sarjast)
Ehita BOT, millel on peal mootoriga Ultrasonic andur.
Kirjuta programm, mille käigus robot sõidab otse kuni näeb ees seina 20 cm kaugusel. Seina nägemisel robot peatub, vaatab Ultrasonic anduriga paremale / vasakule ning see kummal pool on rohkem ruumi (ehk US andur näeb kaugemale), sinna sõidab.
Lahendus
Ultrasonic anduriga paremalt-vasakult kaugust mõõtes peab selle salvestama muutujatesse ning siis neid omavahel võrdlema. Selle põhjal otsustab robot kuhu keerata.
task main(){
SetSensorLowspeed(S1);
int Kaugus;
int ParemPool;
int VasakPool;
Kaugus = 20;
while(TRUE){
if(SensorUS(S1) < Kaugus){
Off(OUT_BC);
RotateMotor(OUT_A, 25, 90);
ParemPool = SensorUS(S1); //mõõdab paremal kaugust
RotateMotor(OUT_A, 25, -180);
VasakPool = SensorUS(S1); //mõõdab vasakult poolt kaugust
RotateMotor(OUT_A, 25, 90);
if(ParemPool > VasakPool){
RotateMotorEx(OUT_BC, 50, 217, 100, TRUE, TRUE); //keerab paremale
}
else{
RotateMotorEx(OUT_BC, 50, 217, -100, TRUE, TRUE); //keerab vasakule
}
}
else{
OnFwdSync(OUT_BC, 100, 0);
}
}
}
Ülesanne 1
Ehita BOT, millel on ees Ultrasonic kauguseandur.
Kirjuta programm, mille käigus robot sõidab otse kuni näeb ees seina 20 cm kaugusel. Seina nägemisel robot peatub, tagurdab ja keerab kas paremale või vasakule (valitakse juhuslikkuse meetodil, funktsiooniga Random()).
Ülesanne 2
Ehita BOT, millel on ees lülitiandur.
Kirjuta programm, mille käigus robot sõidab otse kuni lüliti vajutamiseni ehk seina vms takistuseni. Takistuse avastades robot peatub, tagurdab ja keerab kas paremale või vasakule (valitakse juhuslikkuse meetodil, funktsiooniga Random()).
Lahendus ülesannetele 1 ja 2
Mõlemad ülesanded on sarnased, erinedes ainult selle poolest, et ühel puhul keerab robot tagasi kauguseandurist saabuva signaali tõttu ning teisel juhul lülitist saabuva signaali tõttu.
Alljärgnevas näites on kasutatud switch-elementi, kuid selle võib asendada ka if-else lausega.
task main(){
/*
KAUGUS muutuja abil määrab robot kas peab tagasi sõitma
RAND muutuja abil määrab robot kas ta sõidab paremale või vasakule
*/
SetSensorLowspeed(S4);
int KAUGUS = 20;
int RAND;
while (TRUE){
if (SensorUS(S4) < KAUGUS){ //Kui robot näeb seina lähedamal kui 20 cm siis ta sõidab tagasi
RAND = Random(2);
switch (RAND)
{
case 0: //Robot sõidab paremale
RotateMotorEx(OUT_BC, 100, 335, -50, TRUE, TRUE);
break;
case 1: //Robot sõidab vasakule
RotateMotorEx(OUT_BC, 100, 335, 50, TRUE, TRUE);
break;
}
}
else {
OnRevSync(OUT_BC, 100, 0); //Muidu sõidab robot edasi
}
}
}
FLL ehk Lego-roboti võistlus mis on suunatud põhikoolile vanuses 9-16 aastased saavutas tiim Robootika.COM 2. koha.
Tegelikult koosnes võistlus 4-st osast, millest kõige vaatemängulisem on muidugi roboti platsivõistlus, kus robot peab 2,5 minuti jooksul ära lahendama suure hulga keerulisi ülesandeid. Platsivõistlusel saavutas Kivilinn 147 punkti ning Robootika.COM tiim 140 punkti. Kolmas koht Master (Narva) saavutas 128 punkti.
Kui aga võistluse kolm ülejäänud ala juurde arvestati – projekt koos esitlusega, roboti disaini ning programmeerimise hindamine ja tiimitöö tulemuslikkus - jäi lõpptulemus ikka samaks, ehk esikohad on järgmised, vahetus vaid kolmas koht.
- Kivilinna gümnaasium
- Robootika.COM
- Öökullid
Vähemalt kahel esimesel kohal oli robot arvestatud tegema ca 200 punkti, kuid mõlema tiimi robot tegi platsil ettearvamatuid liigutusi ja nõnda jäid kodustes testides saavutatud paremad punktid võistlusel täitmata.
Igatahes minu poolt tiimile PALJU ÕNNE!
Te kõik olite väga tublid ning täna võite julgelt öelda, et te olete Eesti ainukese segakoolide tiimina Eesti teine koht!!
Kui programmeerimises olite selgelt Eesti parim! Selle eest ka pildil nähaolev karikas.
Veelkord palju õnne tiimile Robootika.COM!
Robotexi joonejälgimise võistlusel oli palju vingeid joonejälgijaid ning esikohad läksid kõik välismaale.
Lego-robotite hulgast oli tiimi Robootika.COM robot nimega LegoPID kõige kiirem. Kui arvestada et kokku oli roboteid umbes 30 ja kolm esikohta läksid Eestist välja, on LegoPID roboti saavutatud ca 10. koht ülikõva tulemus. Joonejälgija klassis olid ülejäänud võistlejad valdavalt kõrgkoolidest.
Täpsustan lõpliku tulemuse kui need üles laetakse.
Rao LegoPID joonejälgija robotiga
Laupäeval toimus järjekordne xbox party. Meil oli seal ülilõbus, mängisime Halo 3, Halo CE anniversary ja ka palju Kinecti mänge. Oli väga lahe, ootan huviga järgmist partyt