Skip to content

Instantly share code, notes, and snippets.

@tom-lord
Created March 9, 2015 15:41
Show Gist options
  • Save tom-lord/5c3a16ca50d9953756ff to your computer and use it in GitHub Desktop.
Save tom-lord/5c3a16ca50d9953756ff to your computer and use it in GitHub Desktop.
Prints all possible scores in a bouldering contest, given the number of problems and points system
PROBLEMS = 20
SCORES = [10, 7, 4, 1, 0]
def permutations_of_scores
result = [ [0]*(SCORES.length-1) + [PROBLEMS] ]
while( result.last != [PROBLEMS] + [0]*(SCORES.length-1) )
result << next_permutation(result.last.dup)
end
result
end
def next_permutation(perm)
# Take 1 from last non-zero
# Increment one to the left
# If furthest right was == 0, then move all but leftmost into it
need_to_shift_digits = perm[-1].zero?
last_nonzero_index = ->(p){p.size - 1 - p.reverse.find_index{|x| x > 0}}
incremented_index = last_nonzero_index.call(perm) - 1
perm[incremented_index+1] -= 1 # From last nonzero element
perm[incremented_index] += 1 # To the left, to the left
if need_to_shift_digits
(perm[last_nonzero_index.call(perm[0..-2])] -= 1; perm[-1] += 1) while last_nonzero_index.call(perm[0..-2]) != incremented_index
end
perm
end
# Table header
puts "#{SCORES.join(", ")} Total"
# Table results
permutations_of_scores.each { |p| puts "#{p.join(", ")}, #{p.each_with_index.map {|n, i| n*SCORES[i]}.inject(:+)}" }
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment