Skip to content

Instantly share code, notes, and snippets.

@tom-lord
Last active August 29, 2015 14:16
Show Gist options
  • Save tom-lord/9dde8c0504b56fa3dd9e to your computer and use it in GitHub Desktop.
Save tom-lord/9dde8c0504b56fa3dd9e 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, SCORES = 20, [10, 7, 4, 1, 0]
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"
permutations_of_scores = [ [0]*(SCORES.length-1) + [PROBLEMS] ]
permutations_of_scores << next_permutation(permutations_of_scores.last.dup) while( permutations_of_scores.last != [PROBLEMS] + [0]*(SCORES.length-1) )
# 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