daily pastebin goal
34%
SHARE
TWEET

Untitled

a guest May 17th, 2018 75 Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. # Rick's Winning Ticket!
  2. # Your favorite grandpa, Rick, is crazy about the lottery and even crazier about
  3. # how he picks his “lucky” numbers. And even though his “never fail” strategy has
  4. # yet to succeed, Grandpa Rick doesn't let that get him down.
  5. #
  6. # Every week he searches through the Sunday newspaper to find a string of digits
  7. # that might be potential lottery picks. But this week the newspaper has moved to
  8. # a new electronic format, and instead of a comfortable pile of papers, Grandpa
  9. # Rick receives a text file with the stories.
  10. #
  11. # Help your grandpa find his lotto picks. Given a large series of number strings,
  12. # return each that might be suitable for a lottery ticket pick. Note that a valid
  13. # lottery ticket must have 7 unique numbers between 1 and 59, digits must be used
  14. # in order, and every digit must be used.
  15. #
  16. # Example strings:
  17. # ["569815571556", "4938532894754", "01234567", "472844278465445"]
  18. #
  19. # Example output:
  20. # 01234567 -> 1 2 3 4 5 6 7
  21. #
  22. # Additionally:
  23. # 1) 6 and 06 both represent the number 6, however 006 would not be valid
  24. # 2) Return all valid picks per input sorted without duplicates for that input
  25. # 3) Please return both the original string, and the valid ticket created from it
  26. # 4) No output for invalid tickets.
  27.  
  28. # Testing command:
  29. # RicksNumberFinder.initialize(["abc", "1234567","569815571556","4938532894754","472844278465445","123045610","123451618","1234101112","12310111213","121415161718","1131415161718","59585756565453"])
  30.  
  31. class RicksNumberFinder
  32.  
  33.   # Receives an array of strings to find numbers from
  34.   def self.initialize(newspaper_arr)
  35.     hits_arr = [] # container array for positive hits
  36.     newspaper_arr.uniq.each do |word|
  37.       result = review_word(word)  # review string for suitability
  38.       hits_arr << result unless result.blank? # add to hits if not blank
  39.     end
  40.     print_output(hits_arr)
  41.   end
  42.  
  43.   # Checks to see if the number set is valid. First illegal numbers, then duplicate numbers
  44.   def self.check_validity(number_set)
  45.     return false unless number_set.select{|num| num.to_i > 59 || num.to_i == 0 }.count == 0
  46.     return false unless number_set.length == number_set.uniq.length
  47.   end
  48.  
  49.   # Choose calculation to find number of permutations possible for a string
  50.   def self.choose(n, k)
  51.     return 1 if k == 0
  52.     (n * choose(n - 1, k - 1)) / k
  53.   end
  54.  
  55.   # Creates a helper array that keeps tracks of the placement of double digit
  56.   # numbers. Example for three double digits: [0,1,2]
  57.   def self.initialize_dd_placements(doubles_allowed)
  58.     dd_placements = []
  59.     doubles_allowed.times do |counter|
  60.       dd_placements << counter
  61.     end
  62.     dd_placements
  63.   end
  64.  
  65.   # Populates the permutations array with all of the possible permutations
  66.   def self.populate_permutations_arr(test_string)
  67.     double_digits_count = test_string.length - 7 # count of how many double digits in this set of numbers
  68.     dd_placements = initialize_dd_placements(double_digits_count) # create the helper to keep track of double digit number placement
  69.  
  70.     permutations_arr = [] # create an array to hold all the permutations possible from the test_string
  71.     # choose method provides count of possible variations possible with this many double digits
  72.     choose(7, double_digits_count).times do
  73.       permutations_arr << [] # add array for every permutation possible
  74.     end
  75.     # Populate the permutations array with all possible permutations from this number string this uses the dd_placements array to
  76.     # simplify the logic. If the current counter location is present in the helper, then a double digit goes here.
  77.     permutations_arr.each do |permutation|
  78.       string_copy = test_string.dup
  79.       7.times do |counter|
  80.         if dd_placements.include? counter # this position is occupied by a double digit number
  81.           permutation[counter] = string_copy.slice!(0, 2).to_i
  82.         else # this position is occupied by a single digit number
  83.           permutation[counter] = string_copy.slice!(0, 1).to_i
  84.         end
  85.       end
  86.       helper = increment_dd_placements(dd_placements) # increment helper for the next possible permutation of double digit placements
  87.     end
  88.     permutations_arr # return permutations array
  89.   end
  90.  
  91.   # Print method
  92.   def self.print_output(hits)
  93.     hits.each do |hit_set|
  94.       hit_set[:results].each do |hit|
  95.         puts "#{hit_set[:test_string]} -> #{hit*" "}"
  96.       end
  97.     end
  98.   end
  99.  
  100.   # Reviews each string to see if it meets our criteria and gets results for those that do
  101.   def self.review_word(test_string)
  102.     return nil if test_string.length < 7 || test_string.length > 14 || !(test_string !~ /\D/) # Quick rejections
  103.     permutations_arr = populate_permutations_arr(test_string) # populates all possible permutations of double digit placements
  104.     permutations_arr.delete_if { |permutation| check_validity(permutation) == false } # remove invalid entries
  105.     return nil if permutations_arr.empty? # reject if no valid permutations found
  106.     permutations_arr.each do |permutation|
  107.       permutation.sort! # sort all of the permutations
  108.     end
  109.     {test_string: test_string, results: permutations_arr.uniq.sort}  # return hash with sorted unique entries
  110.   end
  111.  
  112.   # Increment the double digit helper to create the pattern for the next placement
  113.   # of double digit numbers.
  114.   # Ex: [0,1,2] => [0,1,3] | [0,1,6] => [0,2,6] | [0,5,6] => [1,5,6]
  115.   def self.increment_dd_placements(dd_placements)
  116.     pointer = dd_placements.count - 1
  117.     while pointer >= 0
  118.       if dd_placements[pointer] < (6 - (dd_placements.count - pointer - 1))
  119.         dd_placements[pointer] = dd_placements[pointer] + 1
  120.         break
  121.       elsif dd_placements[pointer] == 6
  122.         secondary_pointer = pointer - 1
  123.         new_max = 5
  124.         while dd_placements[secondary_pointer] == new_max
  125.           secondary_pointer = secondary_pointer - 1
  126.           new_max = new_max - 1
  127.         end
  128.         dd_placements[secondary_pointer] = dd_placements[secondary_pointer] + 1
  129.         (pointer - secondary_pointer).times do
  130.           secondary_pointer = secondary_pointer + 1
  131.           dd_placements[secondary_pointer] = dd_placements[secondary_pointer - 1] + 1
  132.         end
  133.         break
  134.       else
  135.         pointer = pointer - 1
  136.       end
  137.     end
  138.     dd_placements
  139.   end
  140.  
  141.  
  142. end
RAW Paste Data
We use cookies for various purposes including analytics. By continuing to use Pastebin, you agree to our use of cookies as described in the Cookies Policy. OK, I Understand
 
Top