Skip to content

Instantly share code, notes, and snippets.

@volgar1x
Last active August 29, 2015 14:12
Show Gist options
  • Save volgar1x/dfb7e4312f72b5ec22dc to your computer and use it in GitHub Desktop.
Save volgar1x/dfb7e4312f72b5ec22dc to your computer and use it in GitHub Desktop.
/**
* Par Antoine CHAUVIN INFOB1
*/
object App {
import scala.util.Random
/**
* Vec represente un vecteur (x, y)
*/
case class Vec(x: Int, y: Int)
/**
* Vec contient des fonctions auxiliaires en rapport aux vecteurs
*/
object Vec {
/**
* Genere aleatoirement un vecteur unitaire
*/
def sample(implicit rand: Random) =
Vec(rand.nextInt(3) - 1, rand.nextInt(3) - 1)
}
/**
* Mat represente une matrice (N, M)
*/
class Mat[A](elems: Seq[Seq[A]]) { mat =>
/**
* Loc represente un point precis (a, b) de la matrice
*/
case class Loc(row: Int, col: Int) {
/**
* Recupere la valeur du point de la matrice
*/
def get(): A = mat.get(row, col)
// de grands pouvoirs impliquent de grandes responsabilites
def apply(): A = get()
def unary_~ = get()
/**
* Dirige ce point grace a un vecteur
*/
def map(vec: Vec): mat.Loc = mat.locate(row + vec.x, col + vec.y)
}
/**
* Recupere une point percis de la matrice
*/
def get(i: Int, j: Int): A = elems(i)(j)
def apply(i: Int, j: Int): A = get(i, j)
/**
* Localise et isole une point precis de la matrice
* Cette fonction respecte le principe de toricite
*/
def locate(i: Int, j: Int): this.Loc =
if (i < 0) locate(elems.length + i, j)
else if (i >= elems.length) locate(i % elems.length, j)
else if (j < 0) locate(i, elems(i).length + j)
else if (j >= elems(i).length) locate(i, j % elems(i).length)
else new Loc(i, j)
/**
* Transforme cette matrice par de nouvelles valeurs
*/
def map(fn: this.Loc => A): Mat[A] =
new Mat[A](for (i <- 0 until elems.length) yield
for (j <- 0 until elems(i).length) yield
fn(locate(i, j)))
/**
* Transforme cette matrice par de nouvelles valeurs deja presentes dans la matrice
*/
def flatMap(fn: this.Loc => this.Loc): Mat[A] = this map { fn(_).get() }
/**
* Multiplie cette matrice
*/
def multiply(x: A)(implicit n: Numeric[A]) = this map { loc => n.times(~loc, x) }
def *(x: A)(implicit n: Numeric[A]) = multiply(x)
/**
* Genere une representation humaine de la matrice
*/
override def toString: String =
elems map { _.mkString("[", " ", "]") } mkString("[", "\n ", "]")
}
/**
* Mat contient des fonctions auxiliaires en rapport aux matrices
*/
object Mat {
/**
* Genere une matrice vide de taille (M, N)
*/
def apply[A: Numeric](rows: Int, cols: Int): Mat[A] =
new Mat[A](Seq.fill[A](rows, cols)(implicitly[Numeric[A]].zero))
/**
* Genere une matrice vide carre de taille N
*/
def square[A: Numeric](len: Int): Mat[A] = apply(len, len)
/**
* Genere une matrice unitaire de taille N
*/
def unit[A](len: Int)(implicit n: Numeric[A]): Mat[A] = {
/**
* Genere une ligne de la matrice
*/
def line(i: Int): Seq[A] =
List.fill(i)(n.zero) ++ // on genere d'abord les zeros "a gauche" du un
List(n.one) ++ // ensuite on ajoute le un
List.fill(len - i - 1)(n.zero) // et on genere les zeros restants "a droite"
// genere les colonnes de la matrice
val elems: Seq[Seq[A]] = for (i <- 0 until len) yield line(i)
new Mat[A](elems)
}
/**
* Genere une matrice aleatoire de taille (M, N)
*/
def sample(rows: Int, cols: Int)(implicit rand: Random): Mat[Int] =
new Mat[Int](for (i <- 0 until rows) yield
for (j <- 0 until cols) yield
rand.nextInt())
}
/**
* Fais converger aleatoirement une matrice
*/
def converge[A](mat: Mat[A])(implicit rand: Random): Mat[A] = mat flatMap { _ map Vec.sample }
/**
* Point d'entree du programme
*/
def main(args: Array[String]): Unit = {
/**
* Utilise une instance implicite de Random
*/
implicit val rand = new Random
/**
* Comment se servir d'une matrice
*/
val u = Mat.unit[Int](3)
println(u * 2)
/**
* Et maintenant, faisons converger 1000 fois une matrice (10, 10)
*/
// on genere tout d'abord la matrice "graine"
val seed = Mat.sample(10, 10)
// on genere ensuite un flux de matrice constamment convergeant
val mats = Stream.iterate(seed) { converge(_) }
// on recupere enfin la 1000e matrice du flux convergeant
val mat = mats(1000)
println(mat)
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment