Skip to content

Instantly share code, notes, and snippets.

@alekst
Created January 29, 2014 15:36
Show Gist options
  • Save alekst/8690448 to your computer and use it in GitHub Desktop.
Save alekst/8690448 to your computer and use it in GitHub Desktop.
class Numeric # converts numbers into letters
Alph = ("A".."Z").to_a
def alph
s, q = "", self
(q, r = (q - 1).divmod(26)) && s.prepend(Alph[r]) until q.zero?
s
end
end
class Deck < Array
def initialize
@deck = Array.new(54) { |i| i+=1 }
end
def show
p @deck
end
def flatten
@deck = @deck.flatten.compact
end
def move_one_up
# 2. Move the A joker down one card.
# If the joker is at the bottom of the deck, move it to just below the first card.
position = @deck.index(53)
@deck.insert(position + 1, @deck.delete_at(position))
@deck
end
def move_two_down
#3. Move the B joker down two cards.
# If the joker is the bottom card, move it just below the second card.
# If the joker is the just above the bottom card, move it below the top card.
position = @deck.index(54)
if position < 52 #default behavior
@deck.insert(position + 2, @deck.delete_at(position))
elsif position == 53 #If the joker is the bottom card, move it just below the second card.
@deck.insert(2, @deck.delete_at(position))
else #If the joker is the just above the bottom card, move it below the top card.
@deck.insert(1, @deck.delete_at(position))
end
end
def do_triple
#4. Perform a triple cut around the two jokers.
# All cards above the top joker move to below the bottom joker and vice versa.
# The jokers and the cards between them do not move.
position_joker_B = @deck.index(54)
position_joker_A = @deck.index(53)
if position_joker_B < position_joker_A # checking to see if joker B preceeds joker A
top_cards = @deck.slice(0..position_joker_B - 1)
unless @deck.last == 53
bottom_cards = @deck.slice(position_joker_A - 1..@deck.length)
end
inbetweeners = @deck.slice(position_joker_B..position_joker_A)
else
top_cards = @deck.slice(0..position_joker_A - 1)
unless @deck.last == 54
bottom_cards = @deck.slice(position_joker_A - 1..@deck.length)
end
inbetweeners = @deck.slice(position_joker_A..position_joker_B)
end
new_deck = []
new_deck << bottom_cards
new_deck << inbetweeners
new_deck << top_cards
@deck = new_deck
flatten
end
def do_value_cut
# 5. Perform a count cut using the value of the bottom card.
# Cut the bottom card's value in cards off the top of the deck
# and reinsert them just above the bottom card.
removed_cards = @deck.slice!(0, @deck.last)
@deck = @deck.insert(-2, removed_cards)
flatten
end
def find_letter
# 6.Find the output letter. Convert the top card to it's value
# and count down that many cards from the top of the deck,
# with the top card itself being card number one. Look at
# the card immediately after your count and convert it to a letter.
# This is the next letter in the keystream. If the output card is a joker,
# no letter is generated this sequence. This step does not alter the deck.
top_card_value = @deck[0]
p "top card value is #{top_card_value}"
number_to_convert = @deck[top_card_value]
p "number to covert is #{number_to_convert}"
if number_to_convert > 52
puts "the number is scrapped because it is a joker"
return
end
converted_number = number_to_convert % 26
if number_to_convert % 26 == 0
converted_number = 26
end
converted_number.alph
end
end
class Message
def initialize(message)
@message = message
end
def strip
@message = @message.gsub(/[^0-9a-z]/i, '').upcase
end
def length
@message.length
end
def show
puts @message
end
end
deck = Deck.new
keystream = Array.new
message = Message.new("Code in Ruby, live longer!")
message.strip
message.show
(1..5).each do |i|
deck.move_one_up
#deck.show
deck.move_two_down
#deck.show
deck.do_triple
#deck.show
deck.do_value_cut
#deck.show
keystream << deck.find_letter
end
p keystream
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment