Skip to content

Instantly share code, notes, and snippets.

View tom-lord's full-sized avatar
🔥
🚒

Tom Lord tom-lord

🔥
🚒
View GitHub Profile
@tom-lord
tom-lord / boulder_scores.rb
Created March 9, 2015 15:41
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
@tom-lord
tom-lord / boulder_scores_stupidly_compact.rb
Last active August 29, 2015 14:16
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
@tom-lord
tom-lord / boulder_scores_3_lines.rb
Last active August 29, 2015 14:16
Now this is just silly...
PROBLEMS, SCORES = 6, [10, 7, 4, 1, 0] # Takes ~2 minutes for 20 problems and 5 scores :P
puts "#{SCORES.join(", ")}, Total"
puts (0..(PROBLEMS+1)**SCORES.length).lazy.map{|x| x.to_s(PROBLEMS+1).rjust(SCORES.length, '0').split("").map{|y| y.to_i(PROBLEMS+1)} }.reject{|x| x.inject(:+) != PROBLEMS}.map { |p| "#{p.join(", ")}, #{p.each_with_index.map {|n, i| n*SCORES[i]}.inject(:+)}" }.to_a
# Here is a "spaced out" version, you you can actually read it!
#
#puts (0..(PROBLEMS+1)**SCORES.length)
# .lazy # An optimisation, to prevent 1000000s of arrays being held in memory!
# .map{|x|
# x.to_s(PROBLEMS+1) # Convert to string, of base 7 (or whatever - i.e. this will still work for PROBLEMS=20)
@tom-lord
tom-lord / Regular expression in 4 symbols
Created March 19, 2015 22:33
A few examples of how regular expressions can all be decomposed into the same 4 symbols
/a+/ == /a|a*/
/a?/ == /ε|a/
/a{2,4}/ == /aa|aaa|aaaa/
/a{3,} == /aaaa*/
/[a-d]*/ == /(a|b|c|d)*/
/\d\n?/ == /(0|1|2|3|4|5|6|7|8|9)(ε|\n)
# Note: My use of the == operator here is not to be taken too literally...
# In ruby, Regexp equality is not based purely on what strings they match!
# http://ruby-doc.org/core-2.2.1/Regexp.html#method-i-3D-3D
@tom-lord
tom-lord / Reguar expression quantifiers
Created March 19, 2015 22:39
All regular expression quantifiers (repeaters) are very similar...
/a/ == /a{1}/
/a?/ == /a{0,1}/
/a*/ == /a{0,}/
/a+/ == /a{1,}/
@tom-lord
tom-lord / Irregular expressions
Created March 19, 2015 22:47
Examples of regex patterns that are not truly "regular"
/\bword\b/ # How does "\b" know whether it lies on a word boundary?
/line1\n^line2/ # How does "^" know whether it lies at the start of a line?
/irregular (?=expression)/ # Or in general, how can any "look-ahead"/"look-behind" be regular?
@tom-lord
tom-lord / Fundamental structure of regexps
Created March 19, 2015 22:57
All regular expressions can be broken down into their individual components, as something like this...
/(this|that)+/
== /(this|that){1,}/
== /(t{1}h{1}i{1}s{1}|t{1}h{1}a{1}t{1}){1,}/
@tom-lord
tom-lord / Missy Elliott example
Created March 28, 2015 15:09
The Missy Elliott example, copied from my ruby gem (https://github.com/tom-lord/missy_elliott)
MissyElliott.encode("Example") # => "\xAE\xF0\xBC\xA4\xF8\xE4\xAC"
#"Example"
#--> ["E", "x", "a", "m", "p", "l", "e"]
#--> [69, 120, 97, 109, 112, 108, 101]
#--> ["01000101", "01111000", "01100001", "01101101", "01110000", "01101100", "01100101"]
# Shift yo bits down
#--> ["10001010", "11110000", "11000010", "11011010", "11100000", "11011000", "11001010"]
# Flip it
#--> ["01110101", "00001111", "00111101", "00100101", "00011111", "00100111", "00110101"]
@tom-lord
tom-lord / Missy Elliott is reciprocal!
Created March 28, 2015 15:26
The Missy Elliott encoding algorithm is the inverse of itself!
MissyElliott.encode("How is this even possible?!")
# => "\xF6\x84\x88\xFD\xB4\x98\xFD\xE8\xF4\xB4\x98\xFD\xAC\xC8\xAC\xC4\xFD\xF8\x84\x98\x98\xB4\xDC\xE4\xAC\x81\xBD"
MissyElliott.encode("\xF6\x84\x88\xFD\xB4\x98\xFD\xE8\xF4\xB4\x98\xFD\xAC\xC8\xAC\xC4\xFD\xF8\x84\x98\x98\xB4\xDC\xE4\xAC\x81\xBD")
# => "How is this even possible?!"
MissyElliott.decode("How is this even possible?!")
# => "\xF6\x84\x88\xFD\xB4\x98\xFD\xE8\xF4\xB4\x98\xFD\xAC\xC8\xAC\xC4\xFD\xF8\x84\x98\x98\xB4\xDC\xE4\xAC\x81\xBD"
MissyElliott.decode("\xF6\x84\x88\xFD\xB4\x98\xFD\xE8\xF4\xB4\x98\xFD\xAC\xC8\xAC\xC4\xFD\xF8\x84\x98\x98\xB4\xDC\xE4\xAC\x81\xBD")
@tom-lord
tom-lord / Missy Elliott's perfect oscillations
Created March 28, 2015 20:58
What's not to love about them?
127, 63, 95, 31, 111, 47, 79, 15, 119, 55, 87, 23, 103, 39, 71, 7, 123, 59, 91, 27, 107, 43, 75, 11, 115, 51, 83, 19, 99, 35, 67, 3, 125, 61, 93, 29, 109, 45, 77, 13, 117, 53, 85, 21, 101, 37, 69, 5, 121, 57, 89, 25, 105, 41, 73, 9, 113, 49, 81, 17, 97, 33, 65, 1, 126, 62, 94, 30, 110, 46, 78, 14, 118, 54, 86, 22, 102, 38, 70, 6, 122, 58, 90, 26, 106, 42, 74, 10, 114, 50, 82, 18, 98, 34, 66, 2, 124, 60, 92, 28, 108, 44, 76, 12, 116, 52, 84, 20, 100, 36, 68, 4, 120, 56, 88, 24, 104, 40, 72, 8, 112, 48, 80, 16, 96, 32, 64, 0