Last active
May 31, 2016 00:09
-
-
Save tOverney/d42b2618bf955e93c65748cb93b426cb to your computer and use it in GitHub Desktop.
Google Code Jam 2016 (Online Qualification)
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package main.scala | |
import scala.io.Source | |
object Sheeps extends App { | |
val fullSet = Set('0','1','2','3','4','5','6','7','8','9') | |
val path = "/Users/TristanO/Documents/projects/scalaFun/CodeJam/input.txt" | |
val lineIter = Source.fromFile(path).getLines() | |
val T = lineIter.next.toInt | |
for (i <- 1 to T) { | |
implicit val trial = lineIter.next.toLong | |
val res = if(trial == 0L) "INSOMNIA" else findDigits(trial, fullSet) | |
println(s"Case #$i: $res") | |
} | |
def findDigits(current: Long, digitsToFind: Set[Char])(implicit N: Long): String = { | |
val nStr = current.toString | |
val newSet = digitsToFind -- nStr.toCharArray() | |
if (newSet.isEmpty) nStr | |
else findDigits(current + N, newSet) | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package main.scala | |
import scala.io.Source | |
object Pancakes extends App { | |
val path = "/Users/TristanO/Documents/projects/scalaFun/CodeJam/input.txt" | |
val lineIter = Source.fromFile(path).getLines() | |
val T = lineIter.next.toInt | |
for (i <- 1 to T) { | |
implicit val trial = lineIter.next.toList | |
val res = minFlips()(trial) | |
println(s"Case #$i: $res") | |
} | |
@scala.annotation.tailrec | |
def minFlips(flips: Int = 0)(implicit pancakes: List[Char]): Int = { | |
println(s"$flips --> $pancakes") | |
if(!pancakes.contains('-')) flips | |
else if(!pancakes.contains('+')) flips + 1 | |
else { | |
val firstDash = pancakes.indexOf('-') | |
val lastDash = pancakes.lastIndexOf('-') | |
val lastPlus = pancakes.lastIndexOf('+', firstDash) | |
val flipIdx = if(lastPlus != -1 && lastPlus + 1 == firstDash) firstDash else lastDash + 1 | |
minFlips(flips + 1)(returnPancakes(flipIdx)) | |
} | |
} | |
def returnPancakes(idx: Int)(implicit pancakes: List[Char]): List[Char] = { | |
val (flip, flop) = pancakes.splitAt(idx) | |
flip.reverse.map{ | |
_ match { | |
case '-' => '+' | |
case '+' => '-' | |
} | |
} ++ flop | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package main.scala | |
import scala.io.Source | |
object CoinJam extends App { | |
val path = "/Users/TristanO/Documents/projects/scalaFun/CodeJam/input.txt" | |
val lineIter = Source.fromFile(path).getLines() | |
// there will only ever be one test case according to the problem statement | |
val _ = lineIter.next.toInt | |
val Array(length, number) = lineIter.next.split(" ").map(_.toInt) | |
println("Case #1:") | |
val (minCoinJam, maxCoinJam) = findMinMaxPossibleJam(length) | |
val coinJams = findCoinJams(minCoinJam)(maxCoinJam) | |
def findMinMaxPossibleJam(length: Int): (CoinJam, CoinJam) = { | |
(CoinJam("1" + "0" * (length - 2) + "1"), CoinJam("1" * length)) | |
} | |
@scala.annotation.tailrec | |
def findCoinJams(current: CoinJam, | |
acc: Set[CoinJam] = Set())(implicit max: CoinJam): Set[CoinJam] = { | |
if (acc.size == number) acc | |
else if (current != max){ | |
if(current.allNotPrime._1) { | |
println(current) | |
findCoinJams(current.next, acc + current) | |
} | |
else { | |
findCoinJams(current.next, acc) | |
} | |
} | |
else { | |
// this can't happen as J is guaranteed! | |
acc | |
} | |
} | |
} | |
case class CoinJam(jam: String){ | |
def convertToDec(base: Int): Long = { | |
@scala.annotation.tailrec | |
def helper(digits: List[Char], acc: Long = 0L): Long = digits match { | |
case Nil => acc | |
case '0' :: tail => helper(tail, acc * base) | |
case '1' :: tail => helper(tail, acc * base + 1L) | |
case _ => acc // should not happen | |
} | |
helper(jam.toList) | |
} | |
lazy val next: CoinJam = CoinJam((numRepr.head + 2L).toBinaryString) | |
lazy val numRepr: List[Long] = (2 to 10).map(convertToDec).toList | |
lazy val allNotPrime: (Boolean, List[Int]) = { | |
@scala.annotation.tailrec | |
def helper(toVerif: List[Long], acc: List[Int] = Nil): (Boolean, List[Int]) = { | |
toVerif match { | |
case Nil => (true, acc) | |
case Factors(fact) :: tail => helper(tail, acc :+ fact) | |
case _ => (false, acc) | |
} | |
} | |
helper(numRepr) | |
} | |
override def toString: String = jam + " " + allNotPrime._2.mkString(" ") | |
object Factors { | |
val primes: Stream[Int] = 2 #:: Stream.from(3, 2).filter(i => primes.takeWhile(j => j * j <= i).forall(k => i % k > 0)) | |
def unapply(value: Long): Option[Int] = { | |
@scala.annotation.tailrec | |
def findFactor(iter: Int): Option[Int] = { | |
// if it's too much of a pain, we skip it! | |
if(iter > 500) None | |
else { | |
val factors = primes.drop(iter) | |
val head: Long = factors.head | |
if(math.sqrt(value).toLong > head) None | |
if(value % head == 0L) Some(head.toInt) | |
else findFactor(iter + 1) | |
} | |
} | |
findFactor(0) | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment