Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- import java.io._
- import scala.io.Source
- object xdxdxd extends App{
- val t1 = System.nanoTime
- //{0,0,0,0}
- //top, left, right, down
- //filene den leser og lagrer dataen
- val unsolved_puzzle_path = "puzzle_unsolved.txt"
- val solved_puzzle_path = "puzzle_solved.txt"
- //selve løsninga
- val sol = solveNeighbours(unsolved_puzzle_path);
- //printer ut løsninga
- println(sol)
- //lagrer løsninga i fila
- writeSolutionToFile(sol, solved_puzzle_path)
- //løsninga
- def solveNeighbours(path:String):String = {
- val lines = Source.fromFile(path).getLines.toList
- val numPuzzles = lines.head
- //println(numPuzzles)
- //puzzlestart = linja puzzelet starter på. Øker etter at den er ferdig med et puzzle for at den skal bli til linja det neste puzzelet starter
- var puzzlestart = 2;
- //lagrer hvor mange puzzles det er i fila
- val puzzleamountstring = lines(0)(8).toString
- val puzzleamount = puzzleamountstring.toInt
- //sol er linja løsninga lagres i, den som skrives inn i løsningsfila
- var sol = numPuzzles + "\n"
- //fordi vi har lagra hvor mange puzzles det er i fila, og vi løser et puzzle om ganga, bruker vi for loop til å kjøre den like mange ganger som antall puzzles
- for(puzzles<- 1 to puzzleamount) {
- //størrelsen på puzzelet den løser nå
- val sizestring = lines(puzzlestart-1)(5).toString
- val size = sizestring.toInt;
- //liste som går fra 1 til størrelsen, brukes som x og y verdiene til boksene
- val listeentilsize = List.range(1, size + 1);
- //liste som går fra 2 til størrelsen, brukes når man sletter hvis de IKKE er naboer da de med bare 1 forskjell skal bli
- val listeremove = List.range(2, size + 1);
- //classen for boksene
- class Square(xNumber: Int, yNumber: Int,
- values: List[Int] = listeentilsize, solved: Boolean = false, neighbours: List[Int] = List(0, 0, 0, 0)) {
- val possibleValues = values;
- val x = xNumber;
- val y = yNumber;
- val isSolved = solved;
- val neighbours1 = neighbours;
- //brukes til å skrive ut en spesifikk boks som en string
- override def toString() = {
- "x:" + xNumber + " y:" + yNumber + " " + possibleValues.mkString(",");
- }
- //setter valuen til en boks med å slette den gamle, og lage en ny boks med de nye valuene. endrer ikke bare den eksisterende fordi det må være funksjonell programmering
- def setValue(solution: List[Int], neighbours: List[Int]): Square = {
- var asd = false
- if (solution.length == 1) {
- asd = true
- }
- return new Square(this.x, this.y, solution, asd, neighbours);
- }
- //fjerner en value fra en boks. ^^^^^^^^^samme som ovenfor
- def removeValue(wrongSolution: Int): Square = {
- val newlist = possibleValues.filter(_ != wrongSolution);
- if (newlist.length == 1) {
- return new Square(this.x, this.y, newlist, solved = true, this.neighbours1);
- }
- return new Square(this.x, this.y, newlist, solved = false, this.neighbours1);
- }
- }
- //lagrer alle squares i en liste
- var allSquares = List[Square]();
- for (xvalue <- listeentilsize) {
- for (yvalue <- listeentilsize) {
- val s = new Square(xvalue, yvalue);
- allSquares = allSquares :+ s;
- }
- }
- //lagrer alle squares med en spesifikk x verdi i en liste
- def getAllFromX(i: Int): List[Square] = {
- return allSquares.filter((s: Square) => s.x == i);
- }
- // ^^^^^^^^^^ y verdi
- def getAllFromY(i: Int): List[Square] = {
- //allSquares.filter((s:Square)=>s.y==i);
- allSquares.filter(_.y == i);
- }
- //finner en spesifikk square
- def getSquare(x: Int, y: Int): Square = {
- return allSquares.filter(_.x == x).filter(_.y == y)(0)
- }
- //setvalue igjen, bruker setvalue funskjonen som er inne i boks objektene men oppdaterer også lista for allsquares
- def setValue(x: Int, y: Int, solution: List[Int], neighbours: List[Int]) = {
- var s = getSquare(x, y);
- allSquares = allSquares.filter(_ != s);
- s = s.setValue(solution, neighbours);
- allSquares = allSquares :+ s;
- }
- //^^^^^^^^^^ removevalue
- def removeValue(x: Int, y: Int, wrongSolution: Int) = {
- var s = getSquare(x, y);
- if (s.isSolved != true) {
- allSquares = allSquares.filter(_ != s);
- s = s.removeValue(wrongSolution);
- allSquares = allSquares :+ s;
- }
- }
- //Reading the puzzles from a file
- //helt jævlig ikke bruk tid på d kan prøve å skrive om det selv
- for (a <- 0 to (size * 2 - 2) by 2) {
- for (b <- 0 to size * 4 - 4 by 4) {
- var naboopp = 0
- var nabovenstre = 0
- var nabohøyre = 0
- var naboned = 0
- if (a > 0) {
- if (lines(puzzlestart + a - 1)(b) == 'x')
- naboopp = 1
- }
- if (a < size * 2 - 2) {
- if (lines(puzzlestart + a + 1)(b) == 'x') {
- naboned = 1
- }
- }
- if (b < size * 3) {
- if (lines(puzzlestart + a)(b + 2) == 'x')
- nabohøyre = 1
- }
- if (b > 0) {
- if (lines(puzzlestart + a)(b - 2) == 'x')
- nabovenstre = 1
- }
- val naboerxd = List(naboopp, nabovenstre, nabohøyre, naboned)
- if (lines(puzzlestart + a)(b) == '_') {
- setValue((size - (a / 2 + 1) + 1), (b / 4 + 1), listeentilsize, naboerxd)
- };
- else {
- val verdi123 = lines(puzzlestart + a)(b).toString
- val verdi1234 = verdi123.toInt
- setValue((size - (a / 2 + 1) + 1), (b / 4 + 1), List(verdi1234), naboerxd)
- }
- }
- }
- //skriver ut hele puzzelet
- def printIt(): Unit = {
- for (x <- listeentilsize) {
- for (y <- listeentilsize) {
- val s = getSquare(x, y);
- print(s.possibleValues);
- }
- println("");
- }
- }
- //sletting for naboer. hvis de er naboer sletter den alle utenom det tallet som er +1 eller -1
- def deleteifnabo(x:Int, y:Int, ss:Square) = {
- //listermove går fra 2 til size så den sletter alle som er +2, +3, +4 osv men beholder de som er +1 og -1
- for (a <- listeremove) {
- removeValue(x, y, ss.possibleValues(0) + a)
- removeValue(x, y, ss.possibleValues(0) - a)
- }
- }
- //sletting hvis de ikke er naboer. sletter tallene som er +1 og -1
- def deleteifnotnabo(x:Int, y:Int, ss:Square ) = {
- removeValue(x, y, ss.possibleValues(0) + 1)
- removeValue(x, y, ss.possibleValues(0) - 1)
- }
- //en av hovedfunksjonene, sjekker alle boksene sine values og fjerner alle som ikke er valid.
- def isValid(x: Int, y: Int, solution: Int): Boolean = {
- for (s <- getAllFromX(x) ::: getAllFromY(y)) {
- val oneSquare = s.asInstanceOf[Square];
- //sjekker om en boks som er løst sin value oppstår i raden/kollonna, sletter fra de andre hvis den finner
- if (x != oneSquare.x || y != oneSquare.y) {
- if (oneSquare.isSolved == true && oneSquare.possibleValues(0) == solution) {
- //println("Has solution " + oneSquare.x, oneSquare.y, oneSquare.possibleValues);
- return false;
- }
- //lagrer en square fra x og y verdiene
- val s = getSquare(x, y)
- //nabolista er
- //(0,0,0,0)
- //(opp,venstre,høyre,ned)
- //der 0 = ikke nabo, 1 = nabo
- //opp
- //hvis opp = nabo
- if (s.neighbours1(0) == 1) {
- if (x < size) {
- val ss = getSquare(x + 1, y)
- if (ss.isSolved == true) {
- deleteifnabo(x,y,ss)
- }
- }
- }
- //hvis opp = ikke nabo
- if (s.neighbours1(0) == 0) {
- if (x < size) {
- val ss = getSquare(x + 1, y)
- if (ss.isSolved == true) {
- deleteifnotnabo(x,y,ss)
- }
- }
- }
- //venstre
- if (s.neighbours1(1) == 1) {
- if (y > 1) {
- val ss = getSquare(x, y - 1)
- if (ss.isSolved == true) {
- deleteifnabo(x,y,ss)
- }
- }
- }
- if (s.neighbours1(1) == 0) {
- if (y > 1) {
- val ss = getSquare(x, y - 1)
- if (ss.isSolved == true) {
- deleteifnotnabo(x,y,ss)
- }
- }
- }
- //høyre
- if (s.neighbours1(2) == 1) {
- if (y < size) {
- val ss = getSquare(x, y + 1)
- if (ss.isSolved == true) {
- deleteifnabo(x,y,ss)
- }
- }
- }
- if (s.neighbours1(2) == 0) {
- if (y < size) {
- val ss = getSquare(x, y + 1)
- if (ss.isSolved == true) {
- deleteifnotnabo(x,y,ss)
- }
- }
- }
- //ned
- if (s.neighbours1(3) == 1) {
- if (x > 1) {
- val ss = getSquare(x - 1, y)
- if (ss.isSolved == true) {
- deleteifnabo(x,y,ss)
- }
- }
- }
- if (s.neighbours1(3) == 0) {
- if (x > 1) {
- val ss = getSquare(x - 1, y)
- if (ss.isSolved == true) {
- deleteifnotnabo(x,y,ss)
- }
- }
- }
- }
- }
- return true;
- }
- //sjekker alle possible values i en rad, og ser om det er et tall som bare oppstår i en av possible values listene.
- def isOnlyOnePossible(x: Int) = {
- val listex = getAllFromX(x)
- val listenullasd = List.range(0, size);
- for (lookfornumber <- listeentilsize) {
- var countx = 0
- var rowx = 100
- var yvalue = 100
- for (boxnumberx <- listenullasd) {
- if (listex(boxnumberx).possibleValues.contains(lookfornumber) == true) {
- countx = countx + 1;
- rowx = boxnumberx + 1;
- yvalue = listex(rowx - 1).y
- }
- }
- if (countx == 1) {
- if (getSquare(x, yvalue).isSolved != true) {
- for (c <- listeentilsize) {
- if (c != lookfornumber) {
- removeValue(x, yvalue, c);
- removeValue(1, 1, 100);
- }
- }
- }
- }
- }
- }
- def isOnlyOnePossibley(y: Int) = {
- val listey = getAllFromY(y)
- val listenullasd = List.range(0, size);
- for (lookfornumber <- listeentilsize) {
- var countx = 0
- var rowx = 5
- var yvalue = 100
- for (boxnumberx <- listenullasd) {
- if (listey(boxnumberx).possibleValues.contains(lookfornumber) == true) {
- countx = countx + 1;
- rowx = boxnumberx + 1;
- yvalue = listey(rowx - 1).x
- }
- }
- if (countx == 1) {
- if (getSquare(yvalue, y).isSolved != true) {
- for (c <- listeentilsize) {
- if (c != lookfornumber) {
- removeValue(yvalue, y, c);
- removeValue(1, 1, 100);
- }
- }
- }
- }
- }
- }
- def removeIfNotValid(x: Int, y: Int, solution: Int) {
- if (!isValid(x, y, solution)) {
- //println("Removing", x, y, solution);
- removeValue(x, y, solution);
- }
- }
- def checkifallsolved():Boolean = {
- val listeavboxer = allSquares;
- for(a<-listeavboxer)
- if(a.isSolved!=true)
- return false
- return true
- }
- //Actual brute force
- while(checkifallsolved()==false) {
- for (x <- listeentilsize) {
- for (y <- listeentilsize) {
- for (s <- listeentilsize) {
- removeIfNotValid(x, y, s);
- }
- }
- }
- for (a <- listeentilsize) {
- isOnlyOnePossible(a);
- isOnlyOnePossibley(a);
- }
- }
- printIt()
- println("\n")
- sol += "size " + size + "x" + size + "\n"
- for (x <- size to 1 by -1) {
- for (y <- 1 to size) {
- sol += getSquare(x, y).possibleValues(0) + " "
- }
- sol += "\n"
- }
- puzzlestart = puzzlestart + 2*size
- }
- return sol
- }
- def writeSolutionToFile(obj:String, path:String):Unit = {
- val out = new BufferedWriter(new FileWriter(new File(path)))
- out.write(obj)
- out.close()
- }
- val duration = (System.nanoTime - t1) / 1e9d
- println(duration)
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement