summaryrefslogtreecommitdiffstats
path: root/šola/p1/wordle/Tekm_12345678.java
diff options
context:
space:
mode:
Diffstat (limited to 'šola/p1/wordle/Tekm_12345678.java')
-rw-r--r--šola/p1/wordle/Tekm_12345678.java141
1 files changed, 141 insertions, 0 deletions
diff --git a/šola/p1/wordle/Tekm_12345678.java b/šola/p1/wordle/Tekm_12345678.java
new file mode 100644
index 0000000..71d7360
--- /dev/null
+++ b/šola/p1/wordle/Tekm_12345678.java
@@ -0,0 +1,141 @@
+
+import java.util.*;
+
+//
+// Primer stroja za igro Wordle. Stroj vzdržuje množico slovarskih besed, ki
+// so združljive z vsemi dosedanjimi omejitvami, in vsakokrat izbere ``prvo''
+// besedo iz množice (tj. tisto, ki jo vrne iterator ob prvem klicu metode
+// next).
+//
+
+public class Tekm_12345678 implements Stroj {
+
+ // izhodiščna množica besed
+ // (nastavi se ob inicializaciji, potem pa se ne spreminja)
+ private Set<String> izhodiscneBesede;
+
+ // množica besed, ki še ustreza omejitvam
+ private Set<String> besede;
+
+ // nazadnje izbrana beseda
+ private String zadnjaIzbira;
+
+ //
+ // Nastavi izhodiščno množico besed.
+ //
+ @Override
+ public void inicializiraj(Set<String> besede) {
+ this.izhodiscneBesede = new TreeSet<>(besede);
+ }
+
+ //
+ // Na podlagi podanega odziva na prejšnjo izbiro vrne naslednjo izbiro.
+ //
+ // odziv[i]: odziv ('+', 'o' ali '-') na i-to črko prejšnje izbire;
+ // null, ko ogrodje zahteva prvo izbiro.
+ //
+ @Override
+ public String poteza(List<Character> odziv) {
+
+ if (odziv == null) {
+ // Prva ``poteza'': ponastavi množico besed.
+ this.besede = new TreeSet<>(this.izhodiscneBesede);
+
+ } else {
+ if (vseEnako(odziv, '+')) {
+ // Konec, naša zadnja izbira je bila pravilna!
+ return null;
+ }
+
+ if (this.besede.isEmpty()) {
+ // Množica besed je prazna, kljub temu da besede še nismo
+ // uganili.
+ throw new RuntimeException("Nekaj močno smrdi!");
+ }
+
+ // Iz množice odstranimo vse besede, ki niso združljive z odzivom
+ // na zadnjo izbiro.
+ Set<String> odstrani = new TreeSet<>();
+ for (String beseda: this.besede) {
+ if (!jeZdruzljiva(beseda, this.zadnjaIzbira, odziv)) {
+ odstrani.add(beseda);
+ }
+ }
+ this.besede.removeAll(odstrani);
+ }
+
+ // Vrnemo ``prvo'' besedo iz množice (tj. prvo, ki jo vrne iterator).
+ return this.zadnjaIzbira = this.besede.iterator().next();
+ }
+
+ //
+ // Vrne true natanko v primeru, če so vsi elementi podanega seznama enaki
+ // podanemu elementu.
+ //
+ private static <T> boolean vseEnako(List<T> seznam, T element) {
+ return seznam.stream().allMatch(e -> e.equals(element));
+ }
+
+ //
+ // Vrne true natanko v primeru, če je beseda <beseda> združljiva s
+ // podanim odzivom na podano izbiro.
+ //
+ private static boolean jeZdruzljiva(String beseda, String izbira, List<Character> odziv) {
+ int n = odziv.size();
+
+ // Izdelamo seznam znakov besed <beseda> in <izbira>
+ // (nizi so nespremenljivi, seznami pa niso).
+ // (npr. "znanka" -> ['z', 'n', 'a', 'n', 'k', 'a'].
+ List<Character> crkeBesede = new ArrayList<>();
+ List<Character> crkeIzbire = new ArrayList<>();
+ for (int i = 0; i < n; i++) {
+ crkeBesede.add(beseda.charAt(i));
+ crkeIzbire.add(izbira.charAt(i));
+ }
+
+ // Preverimo, ali za vse i-je, pri katerih je odziv[i] == '+',
+ // velja beseda[i] == izbira[i].
+ for (int i = 0; i < n; i++) {
+ if (odziv.get(i) == '+') {
+ if (crkeBesede.get(i) != crkeIzbire.get(i)) {
+ return false;
+ }
+
+ // Označimo, da smo ta položaj že pregledali
+ // (to je pomembno za pravilno obravnavo odzivov 'o').
+ crkeBesede.set(i, '#');
+ crkeIzbire.set(i, '_');
+ }
+ }
+
+ // Preverimo, ali za vse i-je, pri katerih je odziv[i] == 'o',
+ // velja, da <beseda> vsebuje črko izbira[i], a ne na indeksu <i>.
+ // Vsako tako črko beseda <izbira> je treba povezati z eno samo črko
+ // besede <beseda>.
+
+ for (int ixIzbira = 0; ixIzbira < n; ixIzbira++) {
+
+ if (odziv.get(ixIzbira) == 'o') {
+ char crka = crkeIzbire.get(ixIzbira);
+ int ixBeseda = crkeBesede.indexOf(crka);
+ if (ixBeseda < 0 || crkeBesede.get(ixIzbira) == crka) {
+ return false;
+ }
+
+ // Označimo, da smo pripadajoča položaja že pregledali.
+ crkeBesede.set(ixBeseda, '#');
+ crkeIzbire.set(ixIzbira, '_');
+ }
+ }
+
+ // Preverimo, ali za vse i-je, pri katerih je odziv[i] == '-',
+ // velja, da <beseda> ne vsebuje črke izbira[i].
+ for (int i = 0; i < n; i++) {
+ if (odziv.get(i) == '-' && crkeBesede.indexOf(crkeIzbire.get(i)) >= 0) {
+ return false;
+ }
+ }
+
+ return true;
+ }
+}