• API
• FAQ
• Tools
• Archive
daily pastebin goal
68%
SHARE
TWEET

# Untitled

a guest May 17th, 2018 79 Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
1. # Rick's Winning Ticket!
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. #
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. #
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.

Top