University stuff.
Ви не можете вибрати більше 25 тем Теми мають розпочинатися з літери або цифри, можуть містити дефіси (-) і не повинні перевищувати 35 символів.

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345
  1. import java.io.File;
  2. import java.util.Scanner;
  3. import java.util.ArrayList;
  4. import java.util.List;
  5. class Brett {
  6. class Rute {
  7. int verdi;
  8. Rad rad;
  9. Kolonne kolonne;
  10. Boks boks;
  11. Brett brett;
  12. Rute neste = null;
  13. Rute(int verdi, Brett brett) {
  14. this.verdi = verdi;
  15. this.brett = brett;
  16. }
  17. public boolean harVerdi() {
  18. return verdi != -1;
  19. }
  20. public int[] finnAlleMuligeTall() {
  21. ArrayList<Integer> ugyldige = new ArrayList<>();
  22. for (Rute r: rad.ruter) {
  23. if (r.harVerdi()) {
  24. ugyldige.add(r.verdi);
  25. }
  26. }
  27. for (Rute r: kolonne.ruter) {
  28. if (r.harVerdi()) {
  29. ugyldige.add(r.verdi);
  30. }
  31. }
  32. for (Rute r: boks.ruter) {
  33. if (r.harVerdi()) {
  34. ugyldige.add(r.verdi);
  35. }
  36. }
  37. ArrayList<Integer> gyldige = new ArrayList<>();
  38. for (int i = 1; i <= brett.storrelse; ++i) {
  39. if (!ugyldige.contains(i)) {
  40. gyldige.add(i);
  41. }
  42. }
  43. int[] res = new int[gyldige.size()];
  44. for (int i = 0; i < res.length; ++i) {
  45. res[i] = gyldige.get(i);
  46. }
  47. return (int[])res;
  48. }
  49. /*
  50. * fyllUtDenneRuteOgResten
  51. * Jeg ga den et annet navn, som jeg mener er bedre. Maalet er ikke
  52. * aa fylle ut ruten, men aa finne losninger.
  53. */
  54. public List<List<Integer>> finnLosning() {
  55. // Bare skip denne ruten hvis vi har en verdi; ingenting aa lose
  56. if (harVerdi()) {
  57. List<List<Integer>> losninger;
  58. if (neste != null) {
  59. losninger = neste.finnLosning();
  60. } else {
  61. losninger = new ArrayList<>();
  62. losninger.add(new ArrayList<>());
  63. }
  64. for (List<Integer> losning: losninger) {
  65. losning.add(verdi);
  66. }
  67. return losninger;
  68. }
  69. List<List<Integer>> losninger = new ArrayList<>();
  70. int[] mulige = finnAlleMuligeTall();
  71. for (int mulig: mulige) {
  72. verdi = mulig;
  73. List<List<Integer>> nestesLosninger;
  74. if (neste == null) {
  75. nestesLosninger = new ArrayList<>();
  76. List<Integer> l = new ArrayList<Integer>();
  77. nestesLosninger.add(l);
  78. } else {
  79. nestesLosninger = neste.finnLosning();
  80. }
  81. for (List<Integer> l: nestesLosninger) {
  82. l.add(verdi);
  83. losninger.add(l);
  84. }
  85. }
  86. verdi = -1;
  87. return losninger;
  88. }
  89. }
  90. class Kolonne {
  91. private int index = 0;
  92. Rute[] ruter;
  93. Kolonne(int storrelse) {
  94. ruter = new Rute[storrelse];
  95. }
  96. public void settInn(Rute r) {
  97. ruter[index++] = r;
  98. }
  99. }
  100. class Rad {
  101. private int index = 0;
  102. Rute[] ruter;
  103. Rad(int storrelse) {
  104. ruter = new Rute[storrelse];
  105. }
  106. public void settInn(Rute r) {
  107. ruter[index++] = r;
  108. }
  109. }
  110. class Boks {
  111. private int index = 0;
  112. Rute[] ruter;
  113. int bredde;
  114. int hoyde;
  115. Boks(int bredde, int hoyde) {
  116. this.bredde = bredde;
  117. this.hoyde = hoyde;
  118. ruter = new Rute[bredde * hoyde];
  119. }
  120. public void settInn(Rute r) {
  121. ruter[index++] = r;
  122. }
  123. }
  124. File fil;
  125. int raderPerBoks;
  126. int kolonnerPerBoks;
  127. int antallBokserX;
  128. int antallBokserY;
  129. int storrelse;
  130. Rute[] ruter;
  131. Rad[] rader;
  132. Kolonne[] kolonner;
  133. Boks[] bokser;
  134. Brett(File fil) {
  135. this.fil = fil;
  136. try {
  137. read();
  138. } catch (Exception ex) {
  139. System.out.println(ex.toString());
  140. System.exit(1);
  141. }
  142. }
  143. public SudokuBeholder los() {
  144. List<List<Integer>> losninger = ruter[0].finnLosning();
  145. SudokuBeholder sb = new SudokuBeholder(this);
  146. for (List<Integer> losning: losninger) {
  147. SudokuBeholder.Losning l = new SudokuBeholder.Losning();
  148. for (int i = losning.size() - 1; i >= 0; --i) {
  149. Rute r = ruter[losning.size() - 1 - i];
  150. l.leggTil(losning.get(i), r.harVerdi());
  151. }
  152. sb.leggTil(l);
  153. }
  154. return sb;
  155. }
  156. public void print() throws Exception {
  157. int x = 0;
  158. int y = 1;
  159. int modX = storrelse / antallBokserX;
  160. int modY = storrelse / antallBokserY;
  161. for (Rute r: ruter) {
  162. if (x % modX == 0 && x != 0) {
  163. System.out.print("|");
  164. }
  165. if (r.harVerdi()) {
  166. System.out.print(toChar(r.verdi));
  167. } else {
  168. System.out.print(" ");
  169. }
  170. x += 1;
  171. if (x >= storrelse) {
  172. x = 0;
  173. if (y % modY == 0 && y < storrelse) {
  174. System.out.println("");
  175. for (int i = 0; i < storrelse; ++i) {
  176. if (i % modX == 0 && i != 0) {
  177. System.out.print("+");
  178. }
  179. System.out.print("-");
  180. }
  181. }
  182. System.out.println("");
  183. y += 1;
  184. }
  185. }
  186. }
  187. public int toInt(char c) throws Exception {
  188. if (c == '.') {
  189. return -1;
  190. } else if (c >= '1' && c <= '9') {
  191. return (int)c - 49 + 1;
  192. } else if (c >= 'A' && c <= 'Z') {
  193. return (int)c - 65 + 10;
  194. } else if (c == '@') {
  195. return 36;
  196. } else if (c == '#') {
  197. return 37;
  198. } else if (c == '&') {
  199. return 38;
  200. } else if (c >= 'a' && c <= 'z') {
  201. return c - 97 + 39;
  202. } else {
  203. throw new IllegalArgumentException();
  204. }
  205. }
  206. public char toChar(int c) throws Exception {
  207. if (c == -1) {
  208. return '.';
  209. } else if (c >= 1 && c <= 9) {
  210. return (char)(c + 49 -1);
  211. } else if (c >= 10 && c <= 35) {
  212. return (char)(c + 65 - 10);
  213. } else if (c == 36) {
  214. return '@';
  215. } else if (c == 37) {
  216. return '#';
  217. } else if (c == 38) {
  218. return '&';
  219. } else if (c >= 39 && c <= 64) {
  220. return (char)(c + 97 - 39);
  221. } else {
  222. throw new IllegalArgumentException();
  223. }
  224. }
  225. private void read() throws Exception {
  226. Scanner s = new Scanner(fil);
  227. raderPerBoks = Integer.parseInt(s.nextLine());
  228. kolonnerPerBoks = Integer.parseInt(s.nextLine());
  229. storrelse = raderPerBoks * kolonnerPerBoks;
  230. antallBokserX = storrelse / kolonnerPerBoks;
  231. antallBokserY = storrelse / raderPerBoks;
  232. if (storrelse > 64) {
  233. throw new Exception("For stort brett!");
  234. }
  235. ruter = new Rute[storrelse * storrelse];
  236. // Les inn alle ruter
  237. int i = 0;
  238. Rute forrige = null;
  239. for (int y = 0; y < storrelse; ++y) {
  240. if (!s.hasNextLine()) {
  241. throw new Exception("For faa rader!");
  242. }
  243. char[] rad = s.nextLine().toCharArray();
  244. if (rad.length > storrelse) {
  245. throw new Exception("For mange kolonner i rad "+(y+1)+"!");
  246. }
  247. for (int x = 0; x < storrelse; ++x) {
  248. char c;
  249. try {
  250. c = rad[x];
  251. } catch (ArrayIndexOutOfBoundsException ex) {
  252. throw new Exception("For faa kolonner i rad "+(y+1)+"!");
  253. }
  254. Rute r = new Rute(toInt(c), this);
  255. if (forrige != null) {
  256. forrige.neste = r;
  257. }
  258. ruter[i++] = r;
  259. forrige = r;
  260. }
  261. }
  262. if (s.hasNextLine()) {
  263. throw new Exception("For mange rader!");
  264. }
  265. // Opprett rader, kolonner, og bokser
  266. // (obligens `void opprettDatastruktur()`, jeg mener det ikke gir mening
  267. // aa ha det som en egen metode, da det vil skje hvis og bare hvis vi
  268. // leser inn ny informasjon)
  269. rader = new Rad[storrelse];
  270. kolonner = new Kolonne[storrelse];
  271. bokser = new Boks[storrelse];
  272. for (i = 0; i < storrelse; ++i) {
  273. rader[i] = new Rad(storrelse);
  274. kolonner[i] = new Kolonne(storrelse);
  275. bokser[i] = new Boks(kolonnerPerBoks, raderPerBoks);
  276. }
  277. int x = 0;
  278. int y = 0;
  279. for (Rute r: ruter) {
  280. r.rad = rader[y];
  281. rader[y].settInn(r);
  282. r.kolonne = kolonner[x];
  283. kolonner[x].settInn(r);
  284. int boxx = (x / kolonnerPerBoks) % antallBokserX;
  285. int boxy = (y / raderPerBoks) % antallBokserY;
  286. int boxi = boxx + (boxy * antallBokserX);
  287. bokser[boxi].settInn(r);
  288. r.boks = bokser[boxi];
  289. x += 1;
  290. if (x >= storrelse) {
  291. x = 0;
  292. y += 1;
  293. }
  294. }
  295. }
  296. }