Demo 9 (tutkimus)
Palauta viimeistään ma 16.3. klo 11:59.
DEMOTILAISUUS ZOOMISSA MAANANTAINA.
Klikkaa tästä itsesi kokoukseen: https://jyufi.zoom.us/j/227987027 (alk. ma klo 12:10)
Tutkimus
Tämän sivun tehtävät 4-7 ovat osa pro gradu -tutkimusta, jossa tutkitaan lambda-lausekkeiden hyödyllisyyttä. Vastaamalla tehtäviin hyväksyt vastaustesi käytön tutkimustarkoituksessa. Vastauksia käsitellään anonyymisti eikä henkilötietojasi hyödynnetä tutkimuksessa, eikä vastauksia ja henkilötietojasi voi yhdistää tutkimuksen raportista. Lisätietoa tutkimuksen tietosuojasta
Tutkimukseen osallistumisesta saa yhden ylimääräisen demopisteen. Lisäksi voit halutessasi osallistua kolmen 20€ arvoisen S-ryhmän lahjakortin arvontaan :)
Mikäli et sittenkään halua osallistua tutkimukseen, siirry tavalliselle demosivulle.
HUOM! Vaikka tehtävät 1 ja 2 on merkitty tähtitehtäviksi, ne eivät ole pakollisia tutkimukseen osallistuville! Sen sijaan tutkimukseen osallistuville ovat pakollisia tehtävät 4-7. Vaikka pakollisia tehtäviä on enemmän, niin ne ovat lyhyempiä kuin tavallisesti :)
Ajankäyttösi tällä viikolla
Työtuntien kirjaamisesta saa 0.5 demopistettä. Aseta pisteesi Set Custom Points -toiminnolla.
Demokerran päätteeksi kirjoita arvio tällä viikolla käyttämästäsi työmäärästä. Laske työmäärään mukaan kaikki tällä viikolla käyttämäsi aika: lähiopetukseen osallistuminen, oppimateriaalin lukeminen, demotehtävien tekeminen, luentovideon katsominen, demojen purkutilaisuuteen osallistuminen (maanantaina) ja niin edelleen. Voit päivittää lukua viikon edetessä, se voi helpottaa arvion tekemistä. Huom! Siis tähän ei laiteta kurssin alusta kaikkia tunteja yhteensä, vaan vain tämän viikon tunnit.
Jokaisella opiskelijalla on oikeus ja velvollisuus arvioida itse omien pisteidensä oikeellisuus. Mikäli ohjelmasi ei toimi, niin aseta itsellesi Custom pointsit itsearviosi mukaisesti, esim. mikäli ajattelet että olet saavuttanut 50% tehtävän tavoitteista niin silloin laitat itsellesi enintään 0.5 pistettä. Vastaavasti, jos arvioit että tehtäväsi on 90%:sti oikein, mutta automaattinen arviointi antaa sinulle jostain syystä vähemmän pisteitä, aseta itsellesi 0.9 pistettä.
PP4, perjantai 15.3.
PP-tehtävät (näistä saa pisteitä vain käymällä perjantain PP-ryhmässä. Tulevan perjantain PP-tehtävät jaetaan perjantaina.) Mitä ovat PP-tehtävät?
Harjoittelutehtäviä
Jos tehtävissä 1 tai 2 on yhtään haasteita, niin kokeile harjoittelutehtäviä. Harjoittelutehtävien tarkoitus on viedä opiskelija ohjatusti vaihe vaiheelta kohti tehtävän ratkaisua.
Tehtävä 1*
M: 15. Taulukot.
Toteuta funktio PisinNouseva
, joka palauttaa int
-lukuja sisältävän taulukon pisimmän aidosti kasvavan osajonon pituuden. Huomaa, että mikäli perättäiset alkiot ovat yhtä suuria, niin silloin kyseinen kahden alkion osajono ei ole aidosti kasvava. Tee funktiolle myös vähintään kolme erilaista testiä, joista yksi on alla olevan esimerkin mukainen.
Huomaa, että funktio palauttaa nimenomaan jonon pituuden, eli yhden kokonaisluvun.
Esimerkkejä:
- Taulukon
3, 3, 4, 4, 4, 0, 3, 4, 6, 6, 2
pisin aidosti kasvava osajono on0, 3, 4, 6
. Sen pituus on 4, joten funktio palauttaa arvon 4. - Taulukon
2, 2, 2
pisimmän aidosti kasvavan osajonon pituus on 1 (osajono jossa on vain alkio2
).
Huomaa, että ratkaisussasi et saa olettaa että parametrina tuleva taulukko on aina juuri kyseinen yllä oleva taulukko; ratkaisusi tulee toimia kaikenlaisilla taulukoilla.
PisinNouseva(new int[] { 2, 2, 2, 2, 2 } === 0 vai 1?
—1
—Pisteytys: 0.5 pistettä kun funktio kääntyy, 0.4 pistettä itse tehdyistä ja läpi menevistä testeistä, ja 0.1 pistettä dokumentaatiosivun luomisesta ja tämän sivun avaamisesta (Document-linkki vastauslaatikon alapuolella).
Halutaan siis etsiä alkuperäisestä jonosta t
pisin osajono, missä kaikki alkiot toteuttavat ehdon t[i] < t[i+1]
.
Tässä vielä toinen esimerkki ko. tehtävään:
Lukujonon
3, 5, 4, 4, 0, 1, 4, 6, 2
pisin aidosti kasvava osajono on
0, 1, 4, 6
ja tämä kyseinen osajono siis "alkaa" alkuperäisen jonon viidennestä alkiosta (luku 0) ja päättyy alkuperäisen jonon kahdeksanteen alkioon (luku 6).
error CS2001: Source file ‘/home/agent/D9T1Test.cs’ could not be found.001 using System; #- Kääntyvästä funktiosta 0.5, mutta miksi testit eivät mene läpi TIMissä?
—Paina Näytä koko koodi
: mitään ennalta kirjoitettua testiä ei ole. Siispä sinun tulee kirjoittaa omat testit tehtävää varten. -DZ
Onko testeissä oikein PisinNouseva(new int[]{0}) === 0; ? Jotenkin ajattelen, että vastauksen pitäisi olla 1 jos taulukossa on edes yksi luku.
—Vinkki: Jos algoritmi ei ole kristallin kirkas, harjoittele Taunolla ja/tai kynällä ja paperilla.
Tehtävä 2*
Palataan hetkeksi kurssin alkupuolen laatikkotehtävään. Muuta ohjelmaa siten, että PiirraNelio
-aliohjelmalle viedään Vector
-olio kahden reaaliluvun (ja koon) sijaan. Tämä vektori toimii piirrettävän laatikon vasemman alakulman pisteenä. Funktio piirtää laatikon ja palauttaa sitten piirtämänsä laatikon oikean yläkulman koordinaatin. Nyt seuraavan laatikon piirtäminen on yksinkertaista koska se voidaan aloittaa edellisen kutsun palauttamasta paikasta.
Begin
-aliohjelma näyttäisi tältä.
Tuo “laatikkotehtävän” linkki ei toimi.
—Kiitos, linkki korjattu. -AJL
—public override void Begin()
{
Vector piste = new Vector(0, 0);
piste = PiirraNelio(piste);
piste = PiirraNelio(piste);
piste = PiirraNelio(piste);
}
Piirrä vielä pieni punainen ympyrä, joka on pisteessä (0, 0). Ympyrän saat muiden olioiden päälle varmasti kun lisäät sen "ylemmälle" tasolle
Add(pallo, 1);
// Huomaa: luku 1 tarkoittaa tasoa numero 1.
// Add(pallo) lisäisi pallon tasolle 0
Kuva siitä, miltä toimiva ohjelma näyttää ruudulla:

Mistä tämä johtuu: D9T2.cs(9,17): error CS7036: There is no argument given that corresponds to the required formal parameter ‘piste’ of ‘Peli.PiirraNelio(PhysicsGame, Vector)’
—PiirraNelio
-aliohjelma ottaa 2 parametriä (PhysicsGame ja Vector tyyppiset), mutta olet antanut kutsuissa vain yhden. -ATar
Tehtävä 3 (1-2 p.)
Varsinainen tehtävä (1 p.): Tee funktio nimeltä OnkoSummaa
, joka ottaa kaksi parametria: int
-taulukon ja int
-luvun. Funktio palauttaa bool
-arvon sen perusteella, löytyykö annetusta taulukosta lukupari, jonka summa on parametrina annettu int
-luku.
Esimerkiksi kutsu
int[] t = new int[] {1, 2, 3, 9};
OnkoSummaa(t, 8);
palauttaisi false
, sillä taulukosta ei löydy kahta lukua jotka summautuisivat lukuun 8. Sen sijaan kutsu
int[] t = new int[] {1, 2, 4, 4};
OnkoSummaa(t, 8);
palauttaisi true
, sillä 4 + 4 = 8.
Jatko-osa (+ 1 p.): Oletetaan että saatu aineisto on suuruusjärestyksessä. Käytä Array.Sort
-metodia järjestääksesi kokonaislukutaulukko. Ota alla oleva mallikoodi Visual Studioon ja kokeile, kuinka kauan funktiosi ajo kestää 100,000 alkiolle. Jos saat ajan alle 50 millisekuntiin, voit merkitä itsellesi tästä toisen pisteen.
Sain toteutettua tehtävän alle 500 millisekunnissa ja on vaikea kuvitella, että saisin sen toteutettua yhtään nopeammin. Onko toi “50 millisekuntiin” kirjoitusvirhe vai onko oikeasti mahdollista vieläkin nopeuttaa tätä tehtävää? Vinkkiä miten?
—On hyvinkin mahdollista saada noin millisekunnin kertaluokkaan.
Tässä (sopivasti) epäspesifi vinkki yhdelle ajatustavalle: Olkoon esimerkiksi taulukko t = {1, 2, 3, 4, 5}
ja etsittävä luku n = 8
. Nyt t[0] + t[t.Length - 1] = 1 + 5 = 6
on pienempi kuin etsittävä luku, eli summa pitäisi saada kasvatettua. Tiedät kuitenkin, että koska taulukko on järjestetty, on t[0] <= t[1]
, eli summa saa suuremmaksi vaihtamalla t[0]
t[1]
:ksi. Onko t[1] + t[t.Length - 1] == n
? Pitääkö kasvattaa tai vähentää?
Toista sama päättelyketju kumpaankin suuntaan.
-DZ
—0,6167 millisekuntia is true
—Huom: koska mukana on satunnaisuutta, niin riittää, että "tavallisesti" ajo menee tuohon alle 50 millisekuntiin. Ei haittaa jos joissain yksittäisissä tapauksissa menisikin hieman kauemmin, kunhan tulokset eivät ole tuhansien millisekuntien luokkaa kuten raakaan voimaan perustuvissa algoritmeissa. Toimiva ratkaisu läpäisee myös Main
in alussa olevan pienimuotoisen toiminnallisuustestin.
using System;
using System.Collections.Generic;
using System.Diagnostics;
public class Summa
{
public static void Main()
{
int[] testi = new int[] {1,2,2,3,5};
bool testiLapi = !OnkoSummaa(testi,1) && !OnkoSummaa(testi,2) &&
OnkoSummaa(testi,4) && OnkoSummaa(testi,6);
Console.WriteLine(testiLapi ? "Testit läpäisty." :
"Testit epäonnistuivat, virheellinen toteutus!");
const int MONTAKO = 100000;
int[] luvut = LuoSatunnainenTaulukko(MONTAKO, 0, MONTAKO / 2);
Array.Sort(luvut);
Stopwatch sw = Stopwatch.StartNew();
bool loytyykoPari = OnkoSummaa(luvut, MONTAKO);
sw.Stop();
double ms = sw.Elapsed.TotalMilliseconds;
Console.WriteLine("Kesti: " + ms + " millisekuntia.");
}
private static int[] LuoSatunnainenTaulukko(int pituus, int min, int max)
{
Random r = new Random();
int[] luvut = new int[pituus];
for (int i = 0; i < luvut.Length; i++)
luvut[i] = r.Next(min, max);
return luvut;
}
}
Tutkimusinfo
Seuraavat 4 tehtävää eli tehtävät 4-7 ovat osa pro gradu -tutkimusta, jossa tutkitaan lambda-lausekkeiden hyödyllisyyttä. Tutkimuksessa kurssin opiskelijat on jaettu satunnaisesti kahteen erilliseen ryhmään, joilla on hieman erilaiset tehtävät. Älkää siis ihmetelkö, mikäli seuraavat neljä tehtävää ja niiden ohjeistus ovat teille erilaisia kuin kaverille. Pyrkikää tekemään tehtävät itsenäisesti. Koska kyseessä on kuitenkin demotehtävät, niin tehtäviin saa ja pitää kysyä apua, mikäli ne eivät meinaa onnistua.
Kirjaa ylös näihin tehtäviin käyttämäsi aika.
Tehtävä 4* (0.5 p.)
Tee funktio SuuremmanIndeksi
, joka ottaa parametrina yhden kokonaisluvun ja lisäksi kokonaislukulistan (List<int>
). Funktion tulee etsiä listasta ensimmäinen parametrina annettua lukua suurempi suurempi alkio ja palauttaa sen indeksi. Mikäli annettua lukua suurempaa alkiota ei listassa ole, funktion tulee palauttaa -1.
Tehtävänannosta ei selviä, mitä ohjelman pitää tulostaa tilanteessa, jossa annettu kokonaisluku on suurempi kuin mikään listalla olevista alkioista.
—Tehtävänantoa täsmennetty.
—Tehtävä 5* (0.5 p.)
Tee funktio KerroKaikki
. Funktio ottaa parametrina kokonaislukulistan ja palauttaa luvun, joka saadaan, kun kaikki listan luvut kerrotaan keskenään. Esimerkiksi jos listassa on luvut 2, 3 ja 4, niin tulos olisi 2 * 3 * 4 = 24. Mikäli lista on tyhjä, niin tulee palauttaa luku 1.
Yritän täydentää vastauksia. Ei onnistu, mikä ongelma?
VL: mitä tarkoittaa? Sulla on 18:04 tallentunut vastaus.
—Tehtävä 6* (1 p.)
Tee aliohjelma TuhoaSuuret
, joka ottaa parametrina listan fysiikkaolioista (List<PhysicsObject>
) ja tuhoaa niistä kaikki, joiden leveys (Width
) on yli 50.
Tehtävä 7* (1 p.)
Tee funktio VaihdaVari
. Funktio ottaa parametrina listan fysiikkaolioita (List<PhysicsObject>
), etsii listasta kaikki punaiset (Color.Red
) suorakulmiot, ja vaihtaa niiden värin siniseksi (Color.Blue
). Funktio palauttaa listan kaikista olioista, joiden väriä se muutti.
Tein mielestäni tehtävän oikein ja kuva näyttää oikealta, mutta pisteitä tuli vain 0.2? Custom pointsillakaan ei saanut laitettua täysiä pisteitä, vaikka tuosta oletettavasti saisi sen 1 pisteen?
—Tehtävässä piti palauttaa lista (vain) niistä olioista joiden väriä muutettiin. -AJL
—Kysely (1 p.)
Kuinka helpoksi tai vaikeaksi koit ylläolevat tehtävät 4-7? 1 = erittäin vaikea, 10 = erittäin helppo
Kuinka kauan tehtävien tekemiseen meni?
Voit halutessasi jättää myös vapaata palautetta tehtävistä. Voit esimerkiksi kertoa, mikäli tehtävissä oli jotain erityisen vaikeaa.
V1
Tällä viikolla ei ole uusia Ville-tehtäviä. Voit halutessasi tehdä 5 kappaletta tekemättömiä silmukka- ja/tai taulukkotehtäviä tai muita, joita et aikaisemmin ymmärtänyt. Muista Villen käyttöohje.
TDD1
Jos tarkistat vähintään kahden funktion toiminnan itse kirjoittamillasi automaattisilla testeillä (ComTest), saat tästä tehtävästä yhden pisteen. Kirjoita, minkä tehtävän ja minkä funktion/funktioiden toiminnan testasit ja millaisilla testeillä. Voit antaa samassa tiedostossa palautetta ja kehitysehdotuksia Comtestin käytöstä.
B1
Tee tehtävän 6 ohjelmasta interaktiivinen siten, että käyttäjä voi syöttää sanan kirjain kerrallaan, ja ohjelma näyttää tulokset heti. Katso video.
B2-3
Tee seuraava Console Application -peli.
Kaksi pelaajaa kilpailee siitä, kumpi saa noppaa heittämällä ensin 100 pistettä. Jokaisella vuorolla pelaaja heittää toistuvasti noppaa, kunnes saa joko numeron 1 tai pelaaja sanoo "pankki" jolloin hänen vuorollaan heitettyjen silmälukujen summa lisätään hänen kokonaispistemääräänsä.
Pelaaja kullakin heittokerralla joutuu siis tekemään seuraavan valinnan
- heitto - arvotaan nopan silmäluku 1-6, ja jos tulos on
- 1: pelaaja menettää kaikki omalla vuorollaan heittämänsä pisteet ja vuoro vaihtuu vastustajalle
- 2-6: silmäluku lisätään pelaajan "turn totaliin" ja pelaajan vuoro jatkuu
- pankki - pelaajan omalla vuorollaan heittämät pisteet (eli "turn total") lisätään hänen kokonaispistemääräänsä ja vuoro vaihtuu vastustajalle
B4
Tee algoritmi kokonaislukutaulukon sekoittamiseksi. Tee void-
aliohjelma, joka ottaa parametrina int
-taulukon ja sekoittaa sen alkiot. Testaa algoritmiasi taulukolla, johon on alustettu järjestyksessä luvut 1, 2, 3, ..., 52. Palauta toimiva ohjelmakoodi, jossa on hyvin kommentoituna mitä algoritmissa tehdään.
Lukuja 1, 2, 3, ..., 52 ei tietenkään kannata laittaa taulukkoon manuaalisesti, koska helpompiakin tapoja on jo opittu ;).
Huom: Tässä ei ole tarkoitus "keksiä" omaa algoritmia, vaan käyttää ideaa jostakin valmiista algoritmista sekoittamiseen. Hyvä algoritmi on esim: Fisher-Yates shuffle. Tästä on toteutus Jypelin RandomGen -luokan Shuffle-aliohjelmassa. Jos matkit tätä, niin vaihda T
:n tilalle int
ja listan tilalle int
-taulukko. Funktion alkuun pitää lisätä nyt Random rand = new Random();
jotta Random
-olio on olemassa. Jypelin esimerkissä se on luokan attribuutti.
G1-2
Tee aliohjelma ToistotonTaulukko
, joka saa parametrinaan taulukon, jossa on kokonaislukuja, ja palauttaa taulukon, jossa on alkuperäisen taulukon alkiot kukin vain yhden kerran järjestettynä niiden esiintymiskertojen määrän mukaan nousevaan järjestykseen. (1,5 p.) Täysiä pisteitä varten kirjoita aliohjelmalle myös testit. (0,5 p.)
Esim. taulukosta {1, 2, 3, 34, 34, 2, 1, 34, 1, 1, 1}
palautetaan {3, 2, 34, 1}
.
Tehtävissä ei rajoiteta onko sallittu tehdä tehtävä käyttäen apualiohjelmia vai pitääkö hoitaa koko homman yhdessä ainoassa aliohjelmassa
—Saa käyttää useita aliohjelmia/funktioita. -AJL
—These are the current permissions for this document; please modify if needed. You can always modify these permissions from the manage page.