INF2100 ?velsesoppgaver uke 45 7.-11.11.2005 Etter noen uker med fokus p? oblig 1 og parsering er det p? tid ? friske opp kunnskapene om programmering i Minila og Flink-maskinen. Her er et Java-program som ber brukeren om en dato og s? regner ut hvilken ukedag det er. (Det er ikke skrevet optimalt som Java-program, men er utformet for ? v?re rimelig enkelt ? oversette til Minila. Om du ikke kjenner easyIO, kan du se bort fra bruken av den pakken -- den er bare for ? kunne lese inn tall p? en enklere m?te enn det Java tilbyr.) import easyIO.*; class Ukedag { static int dag, maaned, aar; static int mod400 (int v) { // Beregn ?v mod 400? (= v%400): return v - (v/400)*400; } static int mod100 (int v) { // Beregn ?v mod 100? (= v%100): return v - (v/100)*100; } static int mod7 (int v) { // Beregn ?v mod 7? (= v%7): return v - (v/7)*7; } static int mod4 (int v) { // Beregn ?v mod 4? (= v%4): return v - (v/4)*4; } static int jan1 () { // Hvilken ukedag har 1. januar i gitte ?r? int ax = aar-1; return 365*ax + ax/4 - ax/100 + ax/400; } static int skuddaar () { // Er ?ret et skudd?r? 1 betyr ja, 0 betyr nei. if (mod400(aar) == 0) return 1; if (mod100(aar) == 0) return 0; if (mod4(aar) == 0) return 1; return 0; } static int ukedag () { // Hvilken ukedag har gitte dato? 1=mandag, 2=tirsdag, ..., 7=s?ndag. int d = jan1(); for (int m = 1; m < maaned; ++m) { d += mtab[m]; if (m == 2) { if (skuddaar() == 1) ++d; } } return mod7(d+dag-1)+1; } static int mtab[] = new int[13]; public static void main (String arg[]) { mtab[ 1] = 31; mtab[ 2] = 28; mtab[ 3] = 31; mtab[ 4] = 30; mtab[ 5] = 31; mtab[ 6] = 30; mtab[ 7] = 31; mtab[ 8] = 31; mtab[ 9] = 30; mtab[10] = 31; mtab[11] = 30; mtab[12] = 31; System.out.print("Gi en dato (dd mm ????): "); In tastatur = new In(); dag = tastatur.inInt(); maaned = tastatur.inInt(); aar = tastatur.inInt(); System.out.println("Ukedagen er " + ukedag()); } } Oppgave 1 Oversett Java-koden til Minila. Oppgave 2 Mitt forslag til oversettelse av funksjonen `mod7' ser slik ut: proc mod7 in v out m; -- Beregn ?v mod 7? (= v%7): var vx; begproc vx := v / 7 * 7; m := v - vx; endproc; Standardutgaven av Minila-kompilatoren oversetter dette til f?lgende kode (som man f?r se om man benytter opsjonen ?-I?): ---I(resVar) 21: 1 returadr: mod7 ---I(resVar) 22: 1 v ---I(resVar) 23: 1 m ---I(resVar) 24: 1 vx ---I(Instr) 25: STC(4) 21 0 ---I(Instr) 26: STI(2) 22 0 ---I(Instr) 27: LDI(1) 22 0 ---I(resConst) 25: 7 ---I(Instr) 28: DIVI(8) 25 0 ---I(resConst) 26: 7 ---I(Instr) 29: MULI(7) 26 0 ---I(Instr) 30: STI(2) 24 0 ---I(Instr) 31: LDI(1) 22 0 ---I(Instr) 32: SUBI(6) 24 0 ---I(Instr) 33: STI(2) 23 0 ---I(Instr) 34: LDI(1) 23 0 ---I(Instr) 35: LDC(3) 21 0 ---I(Instr) 36: JMP(12) 0 1 Det settes av 6 lokasjoner i heltallsminnet (returadressen, variablene v, m og vx samt konstanten 7 -- to ganger) og 12 instruksjoner. Kan du klare ? skrive funksjonen med f?rre instruksjoner og f?rre lokasjoner i minnet?