Skip to content

Commit b6ae4e3

Browse files
committed
week1 kodutöö lahendus
1 parent 131fa0e commit b6ae4e3

1 file changed

Lines changed: 145 additions & 0 deletions

File tree

sols/week1/MiniAktk.java

Lines changed: 145 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,145 @@
1+
package week1;
2+
3+
import java.io.BufferedReader;
4+
import java.io.IOException;
5+
import java.nio.charset.StandardCharsets;
6+
import java.nio.file.Files;
7+
import java.nio.file.Path;
8+
import java.nio.file.Paths;
9+
import java.util.HashMap;
10+
import java.util.Map;
11+
12+
public class MiniAktk {
13+
14+
static void main(String[] args) throws IOException {
15+
if (args.length != 1) {
16+
throw new RuntimeException("Exactly one command line argument (path) required");
17+
}
18+
19+
Path path = Paths.get(args[0]);
20+
try (BufferedReader reader = Files.newBufferedReader(path, StandardCharsets.UTF_8)) {
21+
22+
Map<Character, Integer> environment = new HashMap<>();
23+
24+
String line;
25+
while ((line = reader.readLine()) != null) {
26+
line = removeComment(line);
27+
28+
if (line.startsWith("print ")) { // print järel peab olema tühik
29+
String expression = line.substring(6);
30+
System.out.println(evaluateExpression(expression, environment));
31+
}
32+
else if (line.contains("=")) {
33+
String[] parts = line.split("=");
34+
if (parts.length != 2) {
35+
throw new RuntimeException("Malformed assignment");
36+
}
37+
String trimmed = parts[0].trim();
38+
if (trimmed.length() != 1) {
39+
throw new RuntimeException("Variable name must be 1 character");
40+
}
41+
char variableName = trimmed.charAt(0);
42+
if (!Character.isLetter(variableName)) {
43+
throw new RuntimeException("Variable name must be a letter");
44+
}
45+
String expression = parts[1];
46+
environment.put(variableName, evaluateExpression(expression, environment));
47+
}
48+
else if (!line.trim().isEmpty()) { // tühi rida pole viga
49+
throw new RuntimeException("Malformed line: " + line);
50+
}
51+
}
52+
}
53+
}
54+
55+
56+
/**
57+
* Eemaldab realt kommentaari, kui see seal on.
58+
*/
59+
private static String removeComment(String line) {
60+
if (line.contains("#")) return line.substring(0, line.indexOf('#'));
61+
else return line;
62+
}
63+
64+
private static int evaluateExpression(String expression, Map<Character, Integer> environment) {
65+
// Ümbritseme liitmised tühikutega, asendame lahutamise negatiivse arvu liitmisega,
66+
// näiteks teisendame "a +b-c" kujule "a + b + -c", siis saab arvud lihtsalt kokku liita!
67+
// (Eeldame, et esialgses avaldises on ainult märgita täisarvud)
68+
expression = expression.replace("+", " + ").replace("-", " + -");
69+
String[] summands = expression.split("\\+");
70+
71+
int sum = 0;
72+
for (String summand : summands) {
73+
sum += evaluateSummand(summand.trim(), environment);
74+
}
75+
return sum;
76+
}
77+
78+
/*
79+
* Väärtustab märgita või miinusega täisarvu või muutujanime.
80+
*/
81+
private static int evaluateSummand(String summand, Map<Character, Integer> environment) {
82+
int sign = 1;
83+
summand = summand.trim();
84+
if (summand.startsWith("-")) {
85+
sign = -1;
86+
summand = summand.substring(1).trim();
87+
}
88+
// proovime täisarvuna tõlgendada, kui ei saa, siis peaks olema muutuja
89+
try {
90+
return sign * Integer.parseInt(summand);
91+
} catch (NumberFormatException e) {
92+
char variableName = summand.charAt(0);
93+
if (environment.containsKey(variableName)) {
94+
return sign * environment.get(variableName);
95+
}
96+
else {
97+
throw new RuntimeException("Variable " + variableName + " undefined");
98+
}
99+
}
100+
}
101+
102+
/**
103+
* Alternatiivne lahendus: sümbolhaaval avaldise väärtustamine.
104+
* Võrdle Exercise3 eval näidislahendusega:
105+
* * Miinustega arvestamiseks piisab sign muutuja lisamisest.
106+
* * Vigade tuvastamiseks läheb vaja ebatriviaalseid abimuutujate kombinatsioone.
107+
*/
108+
private static int evaluateExpressionAlt(String expression, Map<Character, Integer> environment) {
109+
// avaldise väärtustamiseks vajalikud muutujad
110+
int sum = 0;
111+
int sign = 1; // "märk" (1 või -1) millega järgmine number/muutuja liidetakse
112+
int current = 0;
113+
// vigaste avaldiste tuvastamiseks vajalikud muutujad
114+
boolean needOperand = true; // kas järgmine sümbol PEAB olema number või muutuja nimi?
115+
boolean acceptDigit = true; // kas järgmine sümbol VÕIB olla number?
116+
117+
for (char c : expression.toCharArray()) {
118+
if (Character.isDigit(c) && acceptDigit) {
119+
current = 10 * current + Character.getNumericValue(c);
120+
needOperand = false;
121+
// endiselt acceptDigit on true
122+
} else if (Character.isLetter(c) && needOperand) {
123+
current = environment.get(c);
124+
acceptDigit = needOperand = false;
125+
} else if ((c == '+' || c == '-') && !needOperand) {
126+
sum += sign * current;
127+
sign = c == '+' ? 1 : -1;
128+
current = 0;
129+
acceptDigit = needOperand = true;
130+
} else if (c == ' ') {
131+
if (!needOperand) {
132+
acceptDigit = false;
133+
}
134+
} else {
135+
// raske öelda, mis nüüd täpselt viga oli
136+
throw new RuntimeException("Malformed expression");
137+
}
138+
}
139+
if (needOperand) {
140+
throw new RuntimeException("Expected operand at the end of expression");
141+
}
142+
143+
return sum + sign * current;
144+
}
145+
}

0 commit comments

Comments
 (0)