#!/usr/bin/env ruby1.8 # copyright (C) Y. Guillot, 2012 # license: WtfPLv2 # a script to bruteforce the words from the sophos crossword challenge for 01/01/2012 def hash(s) #var x = (Word.charCodeAt(0) * 719) % 1138; #var Hash = 837; #for (i = 1; i <= Word.length; i++) # Hash = (Hash * i + 5 + (Word.charCodeAt(i - 1) - 64) * x) % 98503; s = s.unpack('C*') x = (s[0] * 719) % 1138 h = 837 i = 1 s.each { |c| h = (h*i + 5 + (c-64)*x) % 98503 i += 1 } h end Clue = [ "Numeric representation with variable exponent (8,5)", "A protocol that keeps track of you between packets (8)", "Edgser Dijkstra considered it harmful (4)", "Top guitarist on hacker T-shirts (7)", "Mini-theorem used in proving a proposition (5)", "Solaris utility for tracking system calls (5)", "A number that is the sum of its factors (7)", "A function that adapts one library call to another (4)", "Loops with a fixed number of iterations (8)", "Dijkstra's bête noire implemented using function calls at the end of functions (4,9)", "Old-school x86 table lookup instruction (4)", "Let rip with one's true feelings in an online forum (6)", "What NOT does to your data (3-4)", "Programming that avoids waterfalls (5)", "Hardware copy-protection thingummybob (6)", "A Pascal module (4)", "Your WiFi card emits it (3)", "What a fanbuoy keeps in a custom-fit neoprene sleeve (3)", "Friday afternoon geek-squad office weapon (4,3)", "Something of which you get N in a survey (6)", "Oracle keyword to invoke a failover operation (7)", "Spc xplrtn whzz bttr knwn fr hs dt cmprssn wrk (5)", "Where free gives back what malloc borrowed (4)", "1980s sci-fi movie with unspeakably bad 2010 sequel (4)"] AnswerHash = [ 58375, 48014, 59092, 19577, 44287, 36606, 80598, 25885, 80159, 5126, 35186, 19649, 64194, 63412, 19177, 12403, 63971, 67148, 11076, 35218, 40288, 52478, 73566, 83433] AHH = AnswerHash.inject({}) { |h, i| h.update i => true } def bf(hint, cache=nil, cachenr=0) if not cache cache = [] while i = hint.index('.') cache << i hint[i] = ?A end end if i = cache[cachenr] (?A..?Z).each { |l| hint[i] = l bf(hint, cache, cachenr+1) } else puts hint if AHH[hash(hint)] end end if ARGV[1] nr = ARGV[1].to_i puts Clue[nr] AHH.replace AnswerHash[nr] => true end if ARGV[0] bf ARGV[0].dup else abort "usage: ruby1.8 #{__FILE__} FO.BA.BAZ []" end