Advertisement
Guest User

Untitled

a guest
Feb 20th, 2020
88
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 3.47 KB | None | 0 0
  1. package intra
  2.  
  3. import java.io.PrintWriter
  4.  
  5. import scala.collection.SortedSet
  6. import scala.collection.immutable.HashSet
  7. import scala.io.Source
  8. import scala.util.{Failure, Success, Using}
  9.  
  10. case class Book(id: Int, value: Int)
  11.  
  12. case class Library(id: Int, signUp: Int, capacity: Int, books: SortedSet[Book])
  13.  
  14. case class FinalLibrary(id: Int, books: Vector[Int])
  15.  
  16. object Tests extends Enumeration {
  17. case class Val(file: String) extends super.Val
  18.  
  19. val A: Val = Val("a_example.txt")
  20. val B: Val = Val("b_read_on.txt")
  21. val C: Val = Val("c_incunabula.txt")
  22. val D: Val = Val("d_tough_choices.txt")
  23. val E: Val = Val("e_so_many_books.txt")
  24. val F: Val = Val("f_libraries_of_the_world.txt")
  25. }
  26.  
  27. object Main {
  28.  
  29. def main(args: Array[String]): Unit = {
  30. val (_, libraries, scanningDays) = read(Tests.A.file)
  31. val result = loop(libraries, HashSet.empty[Book], scanningDays, Vector.empty[FinalLibrary])
  32. write(result, Tests.A.file)
  33. }
  34.  
  35. @annotation.tailrec
  36. def loop(libraries: Vector[Library], scanned: Set[Book], scanningDays: Int, result: Vector[FinalLibrary]): Vector[FinalLibrary] = {
  37. if (libraries.isEmpty || scanningDays <= 0) result else {
  38. val filtered = libraries.map(lib => lib.copy(books = lib.books.diff(scanned))).sortBy {
  39. library =>
  40. val taken = takenBooks(library, scanningDays)
  41. valueFunction(taken)
  42. }
  43. val first = filtered.head
  44. val books = takenBooks(first, scanningDays)
  45.  
  46. val resLibrary = FinalLibrary(first.id, books.toVector.map(_.id))
  47. loop(filtered.tail, scanned ++ books, scanningDays - first.signUp, result :+ resLibrary)
  48. }
  49. }
  50.  
  51. def magic(scanningDays: Int, signUp: Int, capacity: Int): Int = (scanningDays - signUp) * capacity
  52.  
  53. def takenBooks(library: Library, scanningDays: Int): SortedSet[Book] = {
  54. val n = magic(scanningDays, library.signUp, library.capacity)
  55. library.books.take(n)
  56. }
  57.  
  58. def valueFunction(books: SortedSet[Book]): Long = books.map(_.value).sum
  59.  
  60. def read(file: String): (Vector[Book], Vector[Library], Int) = {
  61. Using(Source.fromFile(file)) { source =>
  62. val lines = source.getLines.toVector
  63. var currLine = 0
  64.  
  65. def nextLine: String = {
  66. val line = lines(currLine)
  67. currLine += 1
  68. line
  69. }
  70.  
  71. implicit def vectorOrdering: Ordering[Book] = (x: Book, y: Book) => y.value.compareTo(x.value)
  72.  
  73. val booksCount :: librariesCount :: scanningDays :: Nil = nextLine.split(' ').map(_.toInt).toList
  74. val books = nextLine.split(' ').map(_.toInt).zipWithIndex.map { case (book, idx) => Book(idx, book) }
  75. val libraries = for (libraryIdx <- 0 until librariesCount) yield {
  76. val libraryBooksCount :: signUpDays :: booksPerDay :: Nil = nextLine.split(' ').map(_.toInt).toList
  77. val libraryBooks = nextLine.split(' ').map(_.toInt).map(books)
  78. Library(libraryIdx, signUpDays, booksPerDay, SortedSet.from(libraryBooks))
  79. }
  80.  
  81. (books.toVector, libraries.toVector, scanningDays)
  82. }
  83. } match {
  84. case Failure(exception) => throw new IllegalStateException(s"Input parsing failed with exception $exception")
  85. case Success(value) => value
  86. }
  87.  
  88. def write(vector: Vector[FinalLibrary], file: String): Unit = {
  89. Using(new PrintWriter("out_" + file)) { writer =>
  90. writer.println(vector.size)
  91. for (lib <- vector) {
  92. writer.println(s"${lib.id} ${lib.books.size}")
  93. writer.println(lib.books.mkString(" "))
  94. }
  95. }
  96. }
  97. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement