Here's a little puzzler for you! Given the twelve signs of the zodiac, write some code to print out a list of all the valid keys / pairs such that:
- The keys have the form: zodiac.firstsign.secondsign (all lowercase)
- The values have the form Firstsign and Secondsign (correct case on the sign names)
- firstsign and secondsign are in alphabetical order
- There are no duplicates
The result will have lines like:
- [zodiac.aquarius.aquarius Aquarius and Aquarius]
- [zodiac.aquarius.pisces Aquarius and Pisces]
- ...
- [zodiac.aries.pisces Aries and Pisces]
- [zodiac.aries.aries Aries and Aries]
- [zodiac.aries.taurus Aries and Taurus]
- ...
Here's the solution I came up with in Clojure:
(def z ["Aquarius" "Pisces" "Aries" "Taurus" "Gemini" "Cancer" "Leo" "Virgo" "Libra" "Scorpio" "Sagittarius" "Capricorn"])
(defn zkey[a b] [(str "zodiac." (.toLowerCase a) "." (.toLowerCase b)) (str a " and " b)])
(defn accept[a b] (<= (.compareTo a b) 0))
(defn zkeys[s] (map (partial zkey s) (filter (partial accept s) z)))
(map println (mapcat zkeys z))
The zkey function creates the key / value strings from a pair of signs. The accept function is a predicate that returns true if and only if sign a is alphabetically no greater than sign b. The zkeys function returns the set of key / value pairs for a given sign (against the full list of signs). Finally the last line applies zkeys across the full list of signs and prints the result - mapcat just flattens the results one level to make it easier to read.
If you think you have a better solution (in any language), feel free to post it as a comment!

7 responses so far ↓
1 Marlon // Nov 22, 2010 at 3:46 PM
z = %w(Aquarius Pisces Aries Taurus Gemini Cancer Leo Virgo Libra Scorpio Sagittarius Capricorn)
z.map {|sign| z.map {|sign2| [sign, sign2].sort.join(".")}}.flatten.uniq.each {|combo| puts "zodiac.#{combo.downcase} #{combo.gsub('.',' and ')}"}
2 hsanjeewa // Nov 22, 2010 at 4:12 PM
(doseq [[fst snd] (for [z1 z z2 z :when (>= 0 (compare z1 z2))] [z1 z2])]
(println (lower-case (str "zodiac." fst "." snd)) fst " and " snd))
3 Barney Boisvert // Nov 22, 2010 at 4:26 PM
z = ['Aquarius', 'Pisces', 'Aries', 'Taurus', 'Gemini', 'Cancer', 'Leo', 'Virgo', 'Libra', 'Scorpio', 'Sagittarius', 'Capricorn']
map = [:]
z.sort().each { a ->
z.sort().findAll {
it >= a
}.each { b ->
map["zodiac.${a.toLowerCase()}.${b.toLowerCase()}"] = "$a and $b"
}
}
println map
4 brandon // Nov 22, 2010 at 5:08 PM
(defn combos []
(for [x z
y z
:when (accept x y)]
(zkey x y)))
(clojure.pprint/pprint (combos))
5 Michael Kohl // Nov 23, 2010 at 2:43 AM
z = %w(Aquarius Pisces Aries Taurus Gemini Cancer Leo Virgo Libra Scorpio Sagittarius Capricorn)
z.combination(2).each { |combo| p ["zodiac.#{combo.join('.').downcase} #{combo[0].capitalize} and #{combo[1].capitalize}"] }
6 brandon // Nov 23, 2010 at 4:42 AM
: )
7 Sean Corfield // Nov 23, 2010 at 10:19 PM
Leave a Comment