Skip to content

Instantly share code, notes, and snippets.

@DataKinds
Last active December 31, 2016 01:28
Show Gist options
  • Save DataKinds/5245fffde9114a5af6676f955999fb63 to your computer and use it in GitHub Desktop.
Save DataKinds/5245fffde9114a5af6676f955999fb63 to your computer and use it in GitHub Desktop.
Simulate the sending of chain mail that depends on generations
#a person will have, averagely, around double the specified value
#because when it's generated, everyone has to be friends with those
#who are friends with them
AMOUNT_OF_FRIENDS = 1
FRIEND_VARIANCE = 4
POPULATION = 7400 #7.4 billion in 1000's
def a(n)
if n <= 1
1
else
(1..(n-1)).reduce(:*)
end
end
class Person
attr_accessor :has_recieved_mail
attr_accessor :has_to_send_mail
attr_accessor :friends
def _gen_friend_connections(amount_of_people, amount_of_friends)
amount_of_friends.times do
@friends << rand(amount_of_people)
end
end
def initialize
@has_recieved_mail = false
@has_to_send_mail = false
@friends = []
end
end
def gen_world()
world = []
POPULATION.times do
world << Person.new
end
world.each_with_index do |p, pI|
variance = rand(FRIEND_VARIANCE)
sign = rand(2) == 0 ? -1 : 1
world[pI]._gen_friend_connections(POPULATION, AMOUNT_OF_FRIENDS + sign * variance)
end
world.each_with_index do |p, pI|
#check to make sure that friend is friends with
#someone who is friends with them
p.friends.each do |friend|
if !world[friend].friends.include?(pI)
world[friend].friends << pI
end
end
end
#make one guy have the chain mail
pI = rand(POPULATION)
world[pI].has_recieved_mail = true
world[pI].has_to_send_mail = true
return world
end
def sim_world(world, gen)
#make the mail be sent
world.each_with_index do |p, pI|
if p.has_to_send_mail
recipients = p.friends.sample gen
recipients.each do |friend|
if !world[friend].has_recieved_mail
world[friend].has_recieved_mail = true
world[friend].has_to_send_mail = true
end
end
world[pI].has_to_send_mail = false
end
end
return world
end
def gen_stats(world)
#new people, total people, untouched people
stats = [0, 0, 0]
world.each do |p|
if p.has_to_send_mail
stats[0] = stats[0] + 1
elsif p.has_recieved_mail
stats[1] = stats[1] + 1
else
stats[2] = stats[2] + 1
end
end
return stats
end
def print_gen(*args)
#puts " #{' '*(12 - gen.to_s.length)}#{gen} | #{' '*(12 - newPeople.to_s.length)}#{newPeople} | #{' '*(12 - totalPeople.to_s.length)}#{totalPeople} | #{' '*(12 - untouchedPeople.to_s.length)}#{untouchedPeople}"
s = ""
args.each do |n|
s << " #{' '*(14 - n.to_s.length)}#{n} |"
end
puts s
end
puts "Generating world of #{POPULATION} with #{AMOUNT_OF_FRIENDS*2} +- #{FRIEND_VARIANCE} friends each..."
world = gen_world
puts " Generation | New People | Total People | Untouched People "
puts ("-"*(`tput cols`.to_i))
1.step do |gen|
newPeople, totalPeople, untouchedPeople = *gen_stats(world)
print_gen(gen, newPeople, totalPeople, untouchedPeople)
world = sim_world(world, gen)
if newPeople == 0
break
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment