Created
February 9, 2016 20:32
-
-
Save mikehearn/4426cb4686a19881bd48 to your computer and use it in GitHub Desktop.
Kotlin version of the NYT Puzzles program
This file contains hidden or 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
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