Takaisin kurssin pääsivulle

Tehtävät, osa 3

Kesän 2011 Ohjelmoinnin jatkokurssi muodostuu kolmesta tehtäväsarjasta, joissa jokaisessa on 16 tehtävää:

Palautus

Tehtävät palautetaan esittelemällä niitä ohjaajalle ohjelmointipajassa. Osan 3 tehtävien viimeinen palautuspäivä on tiistai 21.6., mutta tehtäviä voi mielellään palauttaa aiemminkin.

Koodarit ja pomot

Tee tätä tehtäväsarjaa varten NetBeans-projekti KoodaritJaPomot.

Lue materiaalista luku 7 ja tee seuraavat tehtävät:

33. Tyontekija ja Koodari

Tee rajapinta Tyontekija, joka vaatii toteuttamaan metodin laskeAlaiset. Metodin tarkoituksena on palauttaa työntekijän alaisten määrä yrityksessä.

Tee lisäksi luokka Koodari, joka toteuttaa rajapinnan Tyontekija. Luokan sisältönä on koodarin nimi. Koodarin alaisten määrä on aina nolla.

Seuraava pääohjelma testaa luokkaa:

public class Main {
    public static void main(String[] args) {
	Tyontekija aapeli = new Koodari("Aapeli");
	System.out.println(aapeli.laskeAlaiset());
    }
}

Ohjelman tulostuksen tulisi olla seuraava:

0

34. Pomo

Tee luokka Pomo, joka toteuttaa rajapinnan Tyontekija. Lisää luokkaan myös metodi lisaaAlainen, joka lisää pomolle uuden alaisen. Tallenna alaiset ArrayList-rakenteeseen, joka sisältää Tyontekija-rajapinnan toteuttavia olioita.

Seuraava pääohjelma testaa luokkia:

public class Main {
    public static void main(String[] args) {
	Pomo petteri = new Pomo("Petteri");
	petteri.lisaaAlainen(new Koodari("Aapeli"));
	petteri.lisaaAlainen(new Koodari("Maija"));
	petteri.lisaaAlainen(new Koodari("Uolevi"));
	System.out.println(petteri.laskeAlaiset());
    }
}

Ohjelman tulostuksen tulisi olla seuraava:

3

Vihje: Toteuta pomon alaisten laskeminen niin, että summaan lisätään pomon alaisten määrä sekä silmukassa kunkin alaisen alaisten määrä. Voit luottaa siihen, että jokaisella alaisella on metodi laskeAlaiset.

35. Työntekijähierarkia

Tee ohjelma, joka määrittelee seuraavan työntekijähierarkian:

Lisää ohjelmaan rivi, joka tulostaa Kaisan alaisten määrän, ja varmista, että tulokseksi tulee 7.

Vertailtavuus

Tee tätä tehtäväsarjaa varten NetBeans-projekti Vertailtavuus.

36. DNA-ketju

DNA-ketju on merkkijono, joka muodostuu merkeistä A, C, G ja T. Esimerkiksi merkkijono ACTAGGCAT on DNA-ketju.

Tee luokka DNAKetju, jonka sisältönä on DNA-ketju. Tee luokalle konstuktori ja metodi toString. Lisää konstruktoriin tarkistus, että annettu merkkijono on kelvollinen DNA-ketju eli siinä on vain merkkejä A, C, G ja T. Jos merkkijono ei ole kelvollinen, luokan sisällöksi tulee pelkkä merkkijono X.

Seuraava pääohjelma testaa luokkaa:

public class Main {
    public static void main(String[] args) {
	DNAKetju testi = new DNAKetju("ACTAGGCAT");
	System.out.println(testi);
	DNAKetju huono = new DNAKetju("AAPELI");
	System.out.println(huono);
    }
}

Ohjelman tulostuksen tulisi olla seuraava:

ACTAGGCAT
X

37. Ketjujen vertailu

Lisää DNAKetju-luokkaan metodi compareTo ja ilmoita, että se toteuttaa rajapinnan Comparable. Toteuta vertailu siten, että ensisijainen vertailutapa on ketjun pituus ja toissijainen vertailutapa on aakkosjärjestys.

Seuraava pääohjelma testaa luokkaa:

import java.util.*;

public class Main {
    public static void main(String[] args) {
	ArrayList<DNAKetju> lista = new ArrayList<DNAKetju>();

	lista.add(new DNAKetju("TAAC"));
	lista.add(new DNAKetju("AACACA"));
	lista.add(new DNAKetju("CTAG"));
	lista.add(new DNAKetju("CTTACTTTA"));

	Collections.sort(lista);
	System.out.println(lista);
    }
}

Ohjelman tulostuksen tulisi olla seuraava:

[CTAG, TAAC, AACACA, CTTACTTTA]

38. Lukujoukko

Tee luokka Lukujoukko, jonka sisältönä on joukko lukuja. Lisää luokkaan metodi lisaaLuku, joka lisää luvun joukkoon, jos sitä ei ole siinä valmiiksi. Lisää myös metodi toString, joka muodostaa merkkijonoesityksen tallennetuista luvuista.

Seuraava pääohjelma testaa luokkaa:

public class Main {
    public static void main(String[] args) {
	Lukujoukko luvut = new Lukujoukko();
	luvut.lisaaLuku(4);
	luvut.lisaaLuku(7);
	luvut.lisaaLuku(2);
	luvut.lisaaLuku(4);
	luvut.lisaaLuku(5);
	System.out.println(luvut);
    }
}

Ohjelman tulostuksen tulisi olla seuraava:

[2, 4, 5, 7]

Huomaa, että luku 4 esiintyy joukossa vain kerran, vaikka se yritettiin laittaa sinne kahdesti.

39. Joukkojen vertailu

Lisää luokkaan Lukujoukko metodi lukujenMaara, joka palauttaa joukossa olevien lukujen määrän. Lisää sitten metodi compareTo ja ilmoita, että luokka toteuttaa rajapinnan Comparable. Järjestyksen ratkaisee joukon lukujen määrä.

Seuraava pääohjelma testaa luokan toimintaa:

import java.util.*;

public class Main {
    public static void main(String[] args) {
	ArrayList<Lukujoukko> lista = new ArrayList<Lukujoukko>();

	Lukujoukko eka = new Lukujoukko();
	eka.lisaaLuku(1);
	eka.lisaaLuku(2);
	Lukujoukko toka = new Lukujoukko();
	toka.lisaaLuku(3);
	toka.lisaaLuku(4);
	toka.lisaaLuku(5);
	Lukujoukko kolmas = new Lukujoukko();
	kolmas.lisaaLuku(6);

	lista.add(eka);
	lista.add(toka);
	lista.add(kolmas);

	Collections.sort(lista);
	System.out.println(lista);
    }
}

Ohjelman tulostuksen tulisi olla seuraava:

[[6], [1, 2], [3, 4, 5]]

Tuotevarasto

Tee tätä tehtäväsarjaa varten NetBeans-projekti Tuotevarasto.

Lue materiaalista luku 8 ja tee seuraavat tehtävät:

40. Varasto

Tee luokka Varasto, jonka sisältönä on tuotteen määrä varastossa. Lisää luokkaan metodit lisaaTuote ja poistaTuote. Tee metodi poistaTuote niin, että tuotteen määrä ei voi mennä negatiiviseksi. Lisää myös luokkaan metodi toString, joka toimii esimerkin mukaisesti.

Seuraava pääohjelma testaa luokkaa:

public class Main {
    public static void main(String[] args) {
	Varasto omenat = new Varasto();
	System.out.println(omenat);
	omenat.lisaaTuote();
	omenat.lisaaTuote();
	System.out.println(omenat);
	omenat.poistaTuote();
	System.out.println(omenat);
	omenat.poistaTuote();
	System.out.println(omenat);
	omenat.poistaTuote();
	System.out.println(omenat);
    }
}

Ohjelman tulostuksen tulisi olla seuraava:

0 kpl
2 kpl
1 kpl
0 kpl
0 kpl

41. Historia

Tee luokka Historia, jonka tarkoituksena on pitää kirjaa tuotteen määrästä varastossa eri ajanhetkinä. Seuraavassa tehtävässä luokka kytketään luokkaan Varasto, mutta toistaiseksi se on erillinen luokka. Lisää luokkaan metodi lisaaMerkinta sekä metodi toString.

Seuraava pääohjelma testaa luokkaa:

public class Main {
    public static void main(String[] args) {
	Historia maarat = new Historia();
	maarat.lisaaMerkinta(5);
	maarat.lisaaMerkinta(7);
	System.out.println(maarat);
	maarat.lisaaMerkinta(4);
	System.out.println(maarat);
    }
}

Ohjelman tulostuksen tulisi olla seuraava:

[5, 7]
[5, 7, 4]

42. MuistavaVarasto

Tee luokka MuistavaVarasto, joka perii luokan Varasto. Lisää luokan osaksi Historia-olio ja tee konstruktoreista sekä metodeista lisaaTuote ja poistaTuote uudet versiot, jotka merkitsevät muistiin varaston tilanteen. Tee myös uusi metodi haeHistoria, joka palauttaa muutoshistorian.

Seuraava pääohjelma testaa luokkaa:

public class Main {
    public static void main(String[] args) {
	MuistavaVarasto omenat = new MuistavaVarasto();
	omenat.lisaaTuote();
	omenat.lisaaTuote();
	omenat.poistaTuote();
	omenat.lisaaTuote();
	omenat.lisaaTuote();
	omenat.poistaTuote();
	omenat.poistaTuote();
	omenat.lisaaTuote();
	omenat.lisaaTuote();
	omenat.lisaaTuote();
	omenat.poistaTuote();
	System.out.println(omenat.haeHistoria());
    }
}

Ohjelman tulostuksen tulisi olla seuraava:

[0, 1, 2, 1, 2, 3, 2, 1, 2, 3, 4, 3]

43. Pylväsdiagrammi

Tee vielä luokkaan MuistavaVarasto metodi piirraTilasto, joka piirtää pylväsdiagrammin varaston muutoshistoriasta.

Seuraava pääohjelma testaa luokkaa:

public class Main {
    public static void main(String[] args) {
	MuistavaVarasto omenat = new MuistavaVarasto();
	omenat.lisaaTuote();
	omenat.lisaaTuote();
	omenat.poistaTuote();
	omenat.lisaaTuote();
	omenat.lisaaTuote();
	omenat.poistaTuote();
	omenat.poistaTuote();
	omenat.lisaaTuote();
	omenat.lisaaTuote();
	omenat.lisaaTuote();
	omenat.poistaTuote();
	omenat.piirraTilasto();
    }
}

Ohjelman tulostuksen tulisi olla seuraava:

          #
     #   ###
  # ### ####
 ###########

Lisätehtävät alkavat tästä:

15-peli

Tee tätä ja seuraavaa tehtäväsarjaa varten NetBeans-projekti Viisitoista.

15-pelissä 4x4-ruudukko sisältää kokonaisluvut 1–15 ja yhden tyhjän ruudun. Tavoitteena on saada luvut seuraavaan järjestykseen:

1234
5678
9101112
131415 

Jokaisella siirrolla voi siirtää tyhjän ruudun vieressä (vaakasuunnassa tai pystysuunnassa) olevan luvun tyhjään ruutuun. Mitä vähemmän siirtoja lukujen järjestämiseen tarvitsee, sen parempi.

Seuraava sivu selventää, miten pelin kuuluisi toimia:

Kaksiulotteinen taulukko on hyödyllinen tässä tehtäväsarjassa.

44. Peruslogiikka

Tee luokka Viisitoista, joka toteuttaa 15-pelin peruslogiikan. Luokan sisältönä on 15-pelin tilanne, ja konstruktori lisää luvut järjestykseen ruudukkoon. Luokassa on myös metodit, joilla voi siirtää tyhjää ruutua sekä hakea tietyssä ruudussa olevan luvun.

Lue materiaalista luku 9 ja tee seuraavat tehtävät:

45. Käyttöliittymä

Tee luokka Kayttoliittyma, joka toteuttaa 15-pelille graafisen käyttöliittymän. Pelin toiminnallisuus on edelleen luokassa Viisitoista. Tässä vaiheessa riittää, että graafinen käyttöliittymä pystyy piirtämään 15-pelin tilanteen hakemalla ruuduissa olevat luvut luokasta Viisitoista.

Peli voisi näyttää tässä vaiheessa seuraavalta:

46. Pelin toiminta

Lisää peliin näppäimistönkäsittely, jotta pelaaja voi siirtää ruudukossa olevia lukuja. Lisää luokkaan Viisitoista myös metodi, jolla ruudukon sisällön voi sekoittaa, ja anna pelaajalle mahdollisuus tähän.

Huom! Mikä tahansa satunnainen 15-pelin tilanne ei ole ratkaistavissa. Keksi keino, jolla sekoittaja tuottaa aina ratkaistavan tilanteen.

47. Pelin viimeistely

Lisää peliin laskuri, joka pitää kirjaa siirtojen määrästä. Pelin pitäisi myös tunnistaa, kun pelaaja saa luvut järjestykseen. Voit myös tarjota pelaajalle mahdollisuuden aloittaa pelin tietystä tilanteesta ja lisätä peliin muita ominaisuuksia haluamasi mukaan.

Pähkinä

48. 15-pelin ratkaisija

Tee ohjelma, joka ratkaisee annetun 15-pelin aloitustilanteen.

Ohjelman toiminnan tulisi näyttää tältä:

Anna aloitustilanne:
1 2 3 4 5 6 0 8 9 10 7 12 13 14 11 15

Ratkaisu (3 siirtoa):

  1  2  3  4
  5  6     8
  9 10  7 12
 13 14 11 15

  1  2  3  4
  5  6  7  8
  9 10    12
 13 14 11 15

  1  2  3  4
  5  6  7  8
  9 10 11 12
 13 14    15

  1  2  3  4
  5  6  7  8
  9 10 11 12
 13 14 15

Voit suunnitella ohjelman toiminnan itse tai tutustua aihetta käsittelevään kirjallisuuteen (15-peli on englanniksi 15 puzzle). Lyhimmän 15-pelin ratkaisevan siirtosarjan voi etsiä IDA*-algoritmilla sopivan heuristiikan avulla.

Bonuspähkinä

Tee tätä tehtäväsarjaa varten NetBeans-projekti ItsensaTulostaja.

49. Itsensä tulostaja

Seuraava ohjelma tulostaa toisen ohjelman koodin:

public class Tulostaja {
    public static void main(String[] args) {
	System.out.println("public class Tervehtija {");
	System.out.println("    public static void main(String[] args) {");
	System.out.println("        System.out.println(\"Heipparallaa!\");");
	System.out.println("    }");
	System.out.println("}");
    }
}

Ohjelman tulostus on seuraava:

public class Tervehtija {
    public static void main(String[] args) {
	System.out.println("Heipparallaa!");
    }
}

Tee ohjelma, joka tulostaa oman koodinsa (eli ohjelman koodi ja tulostus ovat samat).

Huom! Ohjelman ei ole tarkoitus lukea koodia tiedostosta. Myöskään mitkään Java-kielen erikoisominaisuudet eivät ole tarpeen.