Skip to content

Instantly share code, notes, and snippets.

@mikehearn
Created February 9, 2016 20:32
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
Star You must be signed in to star a gist
Save mikehearn/4426cb4686a19881bd48 to your computer and use it in GitHub Desktop.
Kotlin version of the NYT Puzzles program
import java.io.File
import kotlin.system.measureTimeMillis
fun main(args: Array<String>) {
val name = if (args.size > 1) args[0] else "/usr/share/dict/words"
val time = measureTimeMillis {
repeat(200) {
go(name)
}
}
println("Took ${time / 1000.0} seconds")
}
private fun go(name: String) {
val sevens = IntArray(1 shl 16)
val words = IntArray(1 shl 16)
var sevensCursor = 0
var wordsCursor = 0
var word = 0
var len = 0
var ones = 0
File(name).bufferedReader().use {
while (true) {
val char = it.read()
if (char == -1) break
if (char == '\n'.toInt()) {
if (len >= 5 && ones <= 7) {
if (ones == 7)
sevens[sevensCursor++] = word
else
words[wordsCursor++] = word
}
word = 0
len = 0
ones = 0
} else if (ones != 8 && char.toChar() in 'a'..'z') {
len++
word = word or (1 shl (25 - (char - 'a'.toInt())))
ones = Integer.bitCount(word)
} else {
ones = 8
}
}
}
sevens.sort(0, sevensCursor)
val counts = IntArray(sevensCursor)
var count = -1
var prev = 0
for (si in 0..sevensCursor) {
val seven = sevens[si]
if (prev != seven) {
prev = seven
sevens[++count] = prev
}
counts[count] += 3
}
var outputsSoFar = 0
val bits = IntArray(7)
val scores = IntArray(7)
val out = CharArray(8)
for (c in count downTo 0) {
val seven = sevens[c]
var rest = seven
// Explode each bit of 'seven' to an entry in 'bits
for (place in 6 downTo 0) {
bits[place] = Integer.numberOfTrailingZeros(rest)
scores[place] = counts[c]
rest = rest and (rest - 1)
}
for (wi in 0..wordsCursor) {
val w = words[wi]
if (w and seven.inv() == 0) {
// inv() is bitwise inversion, ie ~seven
for (place in 0..scores.size - 1)
scores[place] += (w ushr bits[place]) and 1
}
}
var any = false
for (place in 0..scores.size - 1) {
val points = scores[place]
val a = if (points in 26..32) {
any = true
'A'
} else 'a'
out[place] = a + (25 - bits[place])
}
if (any) {
out[7] = '\n'
print(out)
outputsSoFar++
}
}
println("found $outputsSoFar")
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment