Last active
December 16, 2015 22:29
-
-
Save jimwhite/5507166 to your computer and use it in GitHub Desktop.
A Groovy and a Clojure solution for Google Code Jam practice Treasure [https://code.google.com/codejam/contest/2270488/dashboard#s=p3].
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
;; My first bit of Clojure. | |
;; https://code.google.com/codejam/contest/2270488/dashboard#s=p3 | |
(def test_chests '({:name 1 :opener 1 :contents ()} {:name 2 :opener 1 :contents (1 3)} {:name 3 :opener 2 :contents ()} {:name 4 :opener 3 :contents (2)})) | |
(defn remove-first [pred lst] | |
(if (pred (first lst)) (rest lst) (cons (first lst) (remove-first pred (rest lst))))) | |
;; Return sequence of chest names to open all the chests starting with the given list (multiset) of keys. | |
;; Return nil if there is no combination that opens all the chests. | |
(defn unlock_chests [keys chests] | |
(if (empty? chests) '() | |
(first | |
(for [this_chest (filter #((set keys) (:opener %1)) chests) | |
:let [open_the_rest | |
(unlock_chests | |
(concat (:contents this_chest) (remove-first #{(:opener this_chest)} keys)) | |
(remove-first #{this_chest} chests))] | |
:when open_the_rest] | |
(cons (:name this_chest) open_the_rest) | |
) | |
) | |
) | |
) | |
;; If there are no chests to open then the opening sequence is an empty list. | |
(println (unlock_chests [1] '())) | |
;; This should be '((2 1 4 3)). | |
(println (unlock_chests [1] test_chests)) | |
;; The answer for an unopenable set of chests should be nil. | |
(println (first (unlock_chests [2] test_chests))) | |
;; Here we see keys are a multiset and we're supposed to give lexicographically ordered first answer: (1 2 3). | |
(println (unlock_chests '(1 1 1) '({:name 1 :opener 1 :contents ()} {:name 2 :opener 1 :contents ()} {:name 3 :opener 1 :contents ()}))) |
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
// https://code.google.com/codejam/contest/2270488/dashboard#s=p3 | |
test_chests = [[name:1, opener:1, contains:[]], [name:2, opener:1, contains:[1, 3]], [name:3, opener:2, contains: []], [name:4, opener:3, contains: [2]]] | |
println unlock_all([1], test_chests) | |
def unlock_all(keys, chests) | |
{ | |
if (chests.isEmpty()) return [] | |
for (def this_chest in chests) { | |
def this_key = this_chest.opener | |
def this_key_count = keys.count(this_key) | |
if (this_key_count) { | |
// Can't use this shorter one-liner since the keys are a multiset. | |
// def remaining_keys = (keys - [this_key]) + this_chest.contains | |
def remaining_keys = (keys - this_key) + ([this_key] * (this_key_count - 1)) + this_chest.contains | |
def chest_unlock_seq = unlock_all(remaining_keys, chests - this_chest) | |
if (chest_unlock_seq != null) return [this_chest.name] + chest_unlock_seq | |
} | |
} | |
return null | |
} | |
run_test_cases(new BufferedReader(new StringReader("""\ | |
3 | |
1 4 | |
1 | |
1 0 | |
1 2 1 3 | |
2 0 | |
3 1 2 | |
3 3 | |
1 1 1 | |
1 0 | |
1 0 | |
1 0 | |
1 1 | |
2 | |
1 1 1 | |
"""))) | |
def run_test_cases(input) | |
{ | |
def cases = read_numbers(input)[0] | |
cases.times { case_i -> | |
def (num_keys, num_chests) = read_numbers(input) | |
def keys = read_numbers(input) | |
def chests = (1..num_chests).collect { chest_x -> | |
def chest_nums = read_numbers(input) | |
[name:chest_x, opener:chest_nums[0], contains: chest_nums.drop(2)] | |
} | |
def opening_seq = unlock_all(keys, chests) | |
println "Case #${case_i + 1}: ${(opening_seq == null) ? 'IMPOSSIBLE' : opening_seq.join(' ')}" | |
} | |
} | |
def read_numbers(input) | |
{ | |
input.readLine().split(/\s+/).collect { it as Integer } | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment