summaryrefslogblamecommitdiffstats
path: root/šola/p1/wordle/Tekm_63230317.java
blob: 7059642730bbdf067d44a1efa89bc03955be3545 (plain) (tree)
























































































































































































































                                                                                                                                                              
import java.util.*;
public class Tekm_63230317 implements Stroj {
	static class OpisBesede {
		TreeSet<Character> črkeVBesedi;
		boolean črkeNiVBesedi[];
		boolean črkeNiNaPoziciji[][]; // ko dobimo o si zabeležimo, da ta črka ni na tej poziciji
		char gotoveČrke[];
		public OpisBesede (int d) {
			črkeVBesedi = new TreeSet<>();
			črkeNiVBesedi = new boolean[256];
			gotoveČrke = new char[d];
			črkeNiNaPoziciji = new boolean[d][256];
		}
		public OpisBesede (OpisBesede o) {
			črkeVBesedi = new TreeSet<>(o.črkeVBesedi);
			črkeNiVBesedi = Arrays.copyOf(o.črkeNiVBesedi, o.črkeNiVBesedi.length);
			črkeNiNaPoziciji = Arrays.copyOf(o.črkeNiNaPoziciji, o.črkeNiNaPoziciji.length);
			gotoveČrke = Arrays.copyOf(o.gotoveČrke, o.gotoveČrke.length);
		}
		public void gotovaČrka (int pozicija, char črka) {
			gotoveČrke[pozicija] = črka;
			črkeVBesedi.add(črka);
		}
		public void možnaČrka (int pozicija, char črka) {
			črkeNiNaPoziciji[pozicija][črka] = true;
			črkeVBesedi.add(črka);
		}
		public booleanrkeNiNaPoziciji (int pozicija, char črka) {
			if (črkeNiVBesedi[črka])
				return true;
			if (črkeNiNaPoziciji[pozicija][črka])
				return true;
			return false;
		}
		public void informacije (String ugib, List<Character> odziv) {
			for (int i = 0; i < gotoveČrke.length; i++) {
				if (odziv.get(i) == '+')
					gotovaČrka(i, ugib.charAt(i));
				if (odziv.get(i) == '-')
					črkeNiVBesedi[ugib.charAt(i)] = true;
				if (odziv.get(i) == 'o')
					možnaČrka(i, ugib.charAt(i));
			}
		}
		public boolean opisuje (String beseda) {
			for (int i = 0; i < gotoveČrke.length; i++) {
				if (gotoveČrke[i] != '\000')
					if (gotoveČrke[i] != beseda.charAt(i)) {
						if (beseda.equals("tombak"))
							System.err.println("DEBUG1");
						return false;
					}
				if (rkeNiNaPoziciji(i, beseda.charAt(i))) {
					if (beseda.equals("tombak")) {
						System.err.println("DEBUG2, i=" + i + ", opis: "  + toString());
					}
					return false;
				}
			}
			for (Character znak : črkeVBesedi)
				if (beseda.indexOf(znak) < 0) {
					if (beseda.equals("tombak"))
						System.err.println("DEBUG3");
					return false;
				}
			return true;
		}
		@Override
		public String toString () {
			String r = "gotoveČrke: " + Arrays.toString(gotoveČrke) + ", črkeVBesedi: " + črkeVBesedi + ", črkeNiVBesedi: ";
			for (int i = 0; i < 256; i++)
				if (črkeNiVBesedi[i])
					r += Character.valueOf((char) i);
			r += ", črkeNiNaPoziciji: ";
			for (int i = 0; i < gotoveČrke.length; i++) {
				for (int j = 0; j < 256; j++)
					if (črkeNiNaPoziciji[i][j])
						r += Character.valueOf((char) j);
				if (i != gotoveČrke.length-1)
					r += ',';
			}
			return r;
		}
	}
	Set<String> slovar;
	Set<String> možneBesede;
	Set<String> besede;
	String zadnjaIzbira;
	String odpirač;
	OpisBesede opisbesede;
	int dolžina;
	public Tekm_63230317 () {
		zadnjaIzbira = "";
		odpirač = "odpira";
	}
	@Override
	public void inicializiraj(Set<String> besede) {
		slovar = new TreeSet<>(besede);
		možneBesede = new TreeSet<>(slovar);
		dolžina = besede.iterator().next().length();
	}
	class Odzivi implements Iterable<List<Character>> {
		class IteratorOdzivov implements Iterator<List<Character>> {
			int št;
			public IteratorOdzivov () {
				št = 0;
			}
			@Override
			public List<Character> next () {
				List<Character> odziv = new ArrayList<>();
				int š = št;
				char možnosti[] = new char[]{'-', 'o', '+'};
				for (int i = 0; i < dolžina; i++) {
					odziv.add(možnosti[š % 3]);
					š /= 3;
				}
				št++;
				return odziv;
			}
			@Override
			public boolean hasNext () {
				return št < Math.pow(dolžina, 3);
			}
		}
		@Override
		public Iterator<List<Character>> iterator () {
			return new IteratorOdzivov();
		}
	}
	class BitiBesede implements Comparable<BitiBesede> {
		String beseda;
		double biti;
		public BitiBesede (String beseda) {
			this.beseda = beseda;
			biti = 0;
			int možnihodzivov = 0;
			for (List<Character> odziv : new Odzivi()) {
				if (!jeZdružljiv(beseda, odziv, opisbesede))
					continue;
				možnihodzivov++;
			}
			for (List<Character> odziv : new Odzivi()) {
				if (!jeZdružljiv(beseda, odziv, opisbesede))
					continue;
				int možnihpougibu = 0;
				for (String b: besede) {
					new OpisBesede(opisbesede);
					opisbesede.informacije(beseda, odziv);
					if (opisbesede.opisuje(b))
						možnihpougibu++;
				}
				biti += (double) možnihpougibu*1/možnihodzivov;
			}
		}
		public int compareTo (BitiBesede d) {
			if (biti < d.biti)
				return -1;
			if (biti > d.biti)
				return 1;
			return 0;
		}
	}
	@Override
	public String poteza(List<Character> odziv) {
		System.err.println("poteza klicana z odzivom " + odziv + ". zadnja beseda je " + zadnjaIzbira);
		if (odziv == null) {
			možneBesede.remove(zadnjaIzbira);
			besede = new TreeSet<>(možneBesede);
			opisbesede = new OpisBesede(dolžina);
			return this.zadnjaIzbira = odpirač;
		}
		opisbesede.informacije(zadnjaIzbira, odziv);
		if (vseEnako(odziv, '+'))
			return null;
		Set<String> odstrani = new TreeSet<>();
		for (String beseda : besede)
			if (!opisbesede.opisuje(beseda))
				odstrani.add(beseda);
		besede.removeAll(odstrani);
		if (besede.isEmpty())
			throw new RuntimeException("množica 'besede' je prazna!");
		ArrayList<BitiBesede> rangiranje = new ArrayList<BitiBesede>();
		for (String beseda : besede)
			rangiranje.add(new BitiBesede(beseda));
		Collections.sort(rangiranje);
		zadnjaIzbira = rangiranje.get(rangiranje.size()-1).beseda;
		System.err.println("	... in rekel bom " + zadnjaIzbira);
		return zadnjaIzbira;
	}
	boolean jeZdružljiv (String beseda, List<Character> odziv, OpisBesede ob) { // a lahko dobimo tak odziv na besedo (glede na trenutno stanje ugibanja)
		for (int i = 0; i < dolžina; i++) {
			char znak = beseda.charAt(i);
			if (odziv.get(i) == '+') {
				if (ob.črkeNiVBesedi[znak])
					return false;
				if (ob.črkeNiNaPoziciji[i][znak])
					return false;
				continue;
			}
			if (odziv.get(i) == '-') {
				if (ob.črkeVBesedi.contains(znak))
					return false;
				continue;
			}
			if (odziv.get(i) == 'o') {
				if (ob.črkeNiVBesedi[znak])
					return false;
				if (ob.gotoveČrke[i] == znak)
					return false;
			}
		}
		return true;
	}
	private static <T> boolean vseEnako(List<T> seznam, T element) {
		return seznam.stream().allMatch(e -> e.equals(element));
	}
}