Oppimateriaali perustuu kevään 2010 kurssiversion materiaaliin ja Arto Wiklan ohjelmointisivustoon. Materiaalin copyright © (aakkosjärjestyksessä): Matti Luukkainen, Matti Paksula, Arto Vihavainen, Arto Wikla. Materiaalia saa vapaasti käyttää itseopiskeluun. Muu käyttö vaatii luvan.

Ohpe-harjoitukset s2010: 2/6 (13.-17.9.)

(Muutettu viimeksi 6.9.2010, sivu perustettu 26.8..2010.)

Nämä harjoitukset liittyvät oppimateriaalin lukuihin I Algoritmeja (Scala): 16-25.

Harjoitustehtävien otsikoilla on värikoodaus: Vihreät tehtävät on syytä tehdä joka tapauksessa. Värittämättömiä ei ole ihan pakko tehdä, mutta nekin ovat hyvin hyödyllisiä ja myös vaikuttavat pisteisiin. Keltaiset tehtävät ovat vähän haastavampia. Nekin lasketaan mukaan harjoituspisteitä määrättäessä, mutta ilmankin niitä harjoituksista voi saada maksimipisteet.

Huom: Jokaisen ohjelmatiedoston alkuun on kirjoitettava kommenttina harjoituskerta, tehtävän numero ja tekijän nimi tyyliin:

// 2. harjoitukset, tehtävä 1.3, Oili Opiskelija

Laskentaa ja toistamista

Tässä kohdassa ei vielä taulukoita, mutta kohta toki niitäkin...

Tästä vuosi eteenpäin

Anna kuukauden järjestysnumero: 9
Seuraavat 12 kuukautta ovat:
10 11 12 1 2 3 4 5 6 7 8 9

Sekunnit tunneiksi

Tee ohjelma, joka laskee ja ilmoittaa, kuinka monta kokonaista tuntia on käyttäjän syöttämässä sekuntien määrässä.

Anna sekuntien määrä: 123456
Kokonaisia tunteja siihen mahtuu 34

Sekunnit tunneiksi ja minuuteiksi

Kirjoita ohjelma jolle annetaan sekunnit syötteenä. Ohjelma laskee ja tulostaa tunnit, minuutit ja sekunnit.

Anna sekuntien määrä: 123456
Se on 34 tuntia, 17 minuuttia ja 36 sekuntia.

Sekuntikello (oikeastaan 60-laskuri)

Laadi ohjelma, joka kasvattaa sekunteja yhdellä, kun käyttäjä syöttää tyhjän rivin painamalla enter-näppäintä. Mikä tahansa muu syöte lopettaa ohjelman toiminnan. Sekuntikello pyörähtää nollaan aina arvon 59 jälkeen.


0

1

2

3

...

58

59

0

1
jotain muuta kuin tyhjä rivi
Moi!

Vihje: Tyhjän rivin voi todeta ehdolla (rivi == "").

Taulukon indeksointia ja alkioiden läpikäyntiä

Seuraavissa esimerkeissä käyteään taulukkoa var taulukko = Array(5,11,3,84,2); Laadi tämän kohdan ohjelmat sellaisina, että ne toimivat kaiken kokoisilla taulukoilla. Kokeile siis muitakin kuin esimerkkitaulukkoa. Vaihda tässä vaiheessa vain taulukon määrittelyä ohjelmassasi. Arvojen lukeminen taulukkoon aloitetaan vasta seuraavassa kohdassa.

Ensimmäinen ja viimeinen

Tee ohjelma joka tulostaa taulukon ensimmäisen ja viimeisen alkion.

Ensimmäinen: 5
Viimeinen:   2

Keskimmäinen

Tee ohjelma joka tulostaa taulukon keskimmäisen alkion. Mikä on keskimmäinen, jos alkioita on parillinen määrä?

Alkioiden summa

Tee ohjelma, joka tulostaa taulukon alkiot ja alkoiden summan.

Taulukon alkiot:
5
11
3
84
2
Summa: 105

Läpikäynti käänteisessä järjestyksessä

Taulukon alkiot käänteisessä järjestyksessä:
2
84
3
11
5

Tulostus pilkulla erottaen

Tulosta taulukon alkiot tyylikkäästi siten, että niiden väliin tulee pilkku ja välilyönti. Huomaa, että lauseen lopussa ei saa olla pilkkua, siellähän on piste!

Taulukon alkiot ovat 5, 11, 3, 84, 2.

Onko luku taulukossa 1

Ohjelmassasi on taulukko, jossa on arvoja. Ohjelma kysyy käyttäjältä lukua ja selvittää, onko luku taulukossa. Suoritus esimerkkitaulukolla var t = Array(1, 53, 2, 3, 100);

Arvaa luku: 2
Löytyy!

Syötteitä taulukkoon tutkittaviksi

Lue ja tulosta

Lue taulukkoon var luvut = new Array[Int](7); seitsemän kokonaislukua ja tulosta luetut luvut kauniisti.

Syötä seitsemän kokonaislukua!
1
32
6
8
12
17
22

Syötit luvut: 1, 32, 6, 8, 12, 17, 22.

Onko luku taulukossa 2

Ohjelmassasi on taulukko, jossa on arvoja. Ohjelma kysyy käyttäjältä lukua ja jatkaa kyselyä niin kauan, kunnes käyttäjä arvaa jonkin taulukossa olevan luvun. Suoritus esimerkkitaulukolla var t = Array(1, 53, 2, 3, 100);

Arvaa luku: 4
Ei löydy!

Arvaa luku: 101
Ei löydy!

Arvaa luku: 2
Löytyi!

Syötä ja arvaa

Yhdistä kahden edellisten tehtävien ratkaisuja peliksi:

Syötä 7 lukua:
1
32
6
8
12
17
22
Selvä! Aloitetaan peli..

Arvaa luku: 4
Ei löydy!

Arvaa luku: 101
Ei löydy!

Arvaa luku: 6
Löytyi!

Arvauspeli

Kehittelemällä edellisten tehtävien ideoita voit toteuttaa yksinkertaisen tietokonepelin: Ensin ohjelma pyytää syötettävien lukujen määrän pelinjohtajalta ja sitten itse luvut. Sovitaan että tässä pelissä sallittuja ovat vain luvut 1–21, muut hylätään. Sama luku saa esiintyä useampaankin kertaan.

Tämän jälkeen pelaaja istuu koneen ääreen ja peli alkaa. Pelaaja yrittää arvata koneelle syötettyjä lukuja. Peli päättyy, kun pelaaja arvaa jonkin pelinjohtajan syöttämistä luvuista, ja tulos on tarvittujen arvauskertojen lukumäärä. Pelin realistisuuden kannalta voi olla hyvä idea, että pelinjohtajan syötettyä arvattavat luvut ohjelma tulostaa riittävästi tyhjiä rivejä, jotta luvut eivät paljastu pelaajalle!

Montako arvattavaa lukua annat?
6
Syötä arvattavat luvut. Sallittuja ovat 1, 2, 3, ..., 21.
1. luku: 11
2. luku: 17
3. luku: 6
4. luku: 23
Ei kelpaa! Sallittuja ovat 1, 2, 3, ..., 21.
4. luku: 8
5. luku: 12
6. luku: 17

              ... tähän sitten niitä tyhjiä rivejä ...

Arvauspeli (lukuja on 6 kappaletta)
**********

Arvaa luku väliltä 1-21!
4
Ei löydy!

Arvaa luku väliltä 1-21!
101
Ei tietenkään löydy! Oletko hölmö?

Arvaa luku väliltä 1-21!
-666
Ei tietenkään löydy! Oletko hölmö?

Arvaa luku väliltä 1-21!
18
Ei löydy! 

Arvaa luku väliltä 1-21!
12
Jo löytyi!
Tuloksesi on 5 arvausta.

Merkkijonotalukko ja kokonaislukutaulukko rinta rinnan 1

Kurssimateriaalissa on esimerkki:

var henkilot = Array("Matti", "Maija", "Pekka", "Liisa");
var ika      = Array(     29,      22,     19,       27);
//...

Tee ohjelma, joka tällaisessa tietorakenteessa kasvattaa jokaisen henkilön ikää yhdellä ja onnittelee jokaista, joka täyttää tasavuosia.

Merkkijonotalukko ja kokonaislukutaulukko rinta rinnan 2

Jatketaan edellisen tehtävän hengessä. Tee ohjelma, joka kysyy ensin henkilöiden lukumäärän, sitten yksitellen jokaisen nimen ja iän. Sitten ohjelmalta voi kysellä henkilöiden ikää. Ohjelma voisi alkaa seuraavaan tapaan:

println("Montako henkilöä?");
var lukumaara = readInt;
var henkilot = new Array[String](lukumaara);
var ika      = new Array[Int](lukumaara);
for (i <- 0 to lukumaara-1) {
  // kysele nimi ja ikä
  // ...
};
// Sitten se palvelu
// ...

Palvelun käyttö voisi olla seuraavan näköistä:

Kenen iän haluat tietää?
Maija
Maija on 27-vuotias.
Kenen iän haluat tietää?
Matti
Matti on tuntematon!
Kenen iän haluat tietää?
...

Päätä itse, miten ohjelmalle ilmaistaan lopettaminen.

Aliohjelmia – funktioita

Näissä tehtävissä on funktioiden lisäksi toteutettava myös pieni ohjelma, joka havainnollistaa funktioiden käyttöä. Tulostusesimerkit havainnollistavat, miten ohjelman halutaan toimivan.

Pienemmän tulostaja

Tee aliohjelma (funktio), jolle annetaan parametrina kaksi lukua. Aliohjelma itse tulostaa näistä pienemmän. Jos luvut ovat yhtä suuret, kumpi vain kelpaa.

Anna 1. luku: 4
Anna 2. luku: 3

Luku 3 on pienempi!

Suuremman valitsija

Kirjoita funktio, jolle annetaan parametrina kaksi lukua. Funktio palauttaa arvonaan luvuista suuremman. Jos luvut ovat yhtä suuret, kumpi vain kelpaa. Funktion kutsuja suorittaa tulostuksen, funktio itse ei tulosta mitään.

Vihje: Funktion otsikko voi olla esim. def suurempi(eka: Int, toka: Int): Int ...

Anna 1. luku: 4
Anna 2. luku: 3
Luku 4 on suurempi!

Suuremman tietäjä

Kuten edellinen, mutta funktio palauttaa totuusarvon true jos ensimmäinen luku on suurempi. Jos luvut ovat yhtä suuret, kumpi vain kelpaa.

Vihje: Funktion otsikko voi olla esim. def suurempi(eka: Int, toka: Int): Boolean ...

Anna 1. luku: 4
Anna 2. luku: 3
Luku 4 on suurempi!

Sekunnit tunneiksi (2)

Ohjelmoi vanha tuttu juttu tällä kertaa funktiota käyttäen. Otsikko voi olla def tunneiksi(sekunnit: Int): Int; Funktio palauttaa arvonaan tiedon, montako kokonaista tuntia mahtuu annettuun sekuntimäärään.

Anna sekuntien määrä: 123456
Kokonaisia tunteja siihen mahtuu 34

Taulukon pienin

Tee funktio taulukonPienin(taulukko: Array[Int]): Int, joka palauttaa taulukon pienimmän arvon. Esimerkki kun taulukko on var t = Array(12, 53, 2, 3, 100);

Taulukon pienin luku on 2

Taulukon suurin

Tee vastaava funktio taulukon suurimman arvon löytämiseen.

Taulukon suurin luku on 100

Taulukon pienimmän alkion indeksi

Tee funktio taulukonPienimmanIndeksi(taulukko: Array[Int]): Int, joka palauttaa taulukon pienimmän alkion indeksin. Esimerkki kun taulukko on var t = Array(12, 53, 5, 4, 100);

Taulukon pienimmän alkion indeksi on 3

Taulukon suurimman alkion indeksi

Tee vastaava funktio taulukon suurimman arvon löytämiseen.

Taulukon suurimman alkion indeksi on 4

Taulukon alkioiden keskiarvo

Tee funktio keskiarvo(taulukko: Array[Int]): Double, joka laskee taulukon lukujen keskiarvon ja palauttaa sen arvonaan.

Yhteisiä alkioita?

Tee funktio onkoSamoja(taulukko1: Array[Int], taulukko2: Array[Int]): Boolean, joka palauttaa arvon true, jos taulukoissa on yksikin sama alkio. Ellei yhtään ole, funktio palauttaa arvon false.

Arvauspeli (2)

Edellä toteutettiin seuraava peli:

Tuo ohjelma oli jo sen verran monimutkainen, että on perusteltua jakaa ohjelma osiin – käyttää aliohjelmia ohjelmalogiikan selkeyttämiseen.

Mieti, suunnittele ja toteuta tuo peli aliohjelmia käyttäen. Voit halutessasi myös laajentaa peliä siten, että pelinjohtaja saa antaa ohjelmalle myös lukuvälin, joka edellä oli kiinteä 1–21.

Tällaista (toimivan) ohjelman rakenteen uudistamista selkeämmäksi kutsutaan usein hienolla nimellä refaktorointi.