Skip to content

Instantly share code, notes, and snippets.

@arashbm
Last active August 29, 2015 14:12
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save arashbm/c6ee1d706df1463b2b5e to your computer and use it in GitHub Desktop.
Save arashbm/c6ee1d706df1463b2b5e to your computer and use it in GitHub Desktop.
Heram (Pyramid Scheme)

Heram Simulator

This is a quick attempt to participate in Jadi's contest. If this gist doesn't make any sense to you, just ignore it :)

Usage example: ruby heram.rb 1 2 6 6 70_000_000 4 for instructions, run without arguments (ruby heram) or just read the source!

human readable results will be printed on STDERR, Comma Separated Value (CSV) format will be printed to STDOUT, so you can ruby heram.rb 1 2 6 6 70_000_000 4 > results.csv and maybe xdg-open results.csv to plot it with your program of choice :)

With Gnuplot installed you can do something like this: ruby heram.rb 1 2 6 6 70_000_000 4 | gnuplot "plot.gp" > test.png && xdg-open test.png to generate a plot with Gnuplot file (plot.gp) provided here.

# This is an Oskolisp implementation :)
# Learn more [here](https://github.com/arashbm/oskolisp)
[
[:set, :evolve,
[:lambda,
[:list, :tree],
[:map, :tree,
[:lambda,
[:list, :i],
[:if, [:==, :i, 1],
[:list, 1, 1],
[:evolve, :i]
]
]
]
]
],
[:set, :ev,
[:lambda,
[:list, :tree, :n],
[:if, [:==, :n, 0],
:tree,
[:ev, [:evolve, :tree], [:-, :n, 1]]
]
]
],
[:set, :subordinates,
[:lambda,
[:list, :thing],
[:if, [:list?, :thing],
[:+, [:reduce, [:map, :thing, :subordinates], :+], 1],
1
]
]
],
[:p, [:subordinates, [:ev, [:list, 1], 16]]]
]
if ARGV.count < 6
puts "Usage: `ruby heram starting_people new_per_month stop_months benefit_min max_pop benefit_before_months`"
puts " starting_people: start simulation with how many people?"
puts " new_per_month: number of new people introduced per member per month"
puts " stop_months: number of months that each person stays active"
puts " benefit_min: minimum number of new people needed for a person to benefit"
puts " max_pop: population of country"
puts " benefit_before_months: how many months one should have at least benefit_min people to win?"
puts " example usage: `ruby heram.rb 1 2 6 6 70_000_000 4`"
exit 1
end
def evolve_tree(tree)
tree.map! do |i|
i == 1 ? Array.new($per_month, 1) : evolve_tree(i)
end
tree.size < ARGV[3].to_i ? tree.concat(Array.new($per_month, 1)) : tree
end
def ev(start, n)
n > 0 ? ev(evolve_tree(start), n-1) : start
end
people = {0 => ARGV[0].to_i}
$per_month = ARGV[1].to_i
benefit_min = ARGV[3].to_i
benefit_before_months = ARGV[5].to_i
month = 0
while people.values.reduce(:+) < ARGV[4].to_i
people = Hash[people.map{ |m, c| [m + 1, c] }]
people[0] = people.map{|k, v| k < ARGV[2].to_i ? v*$per_month : 0 }.reduce(:+)
month += 1
end
STDERR.puts "month: #{month}"
STDERR.puts "total: #{people.values.reduce(:+)}"
STDERR.puts "benefit: #{people.select{ |k, v| ev([1], k - benefit_before_months).flatten.reduce(:+) > benefit_min }.map(&:last).reduce(:+)}"
puts people.map { |i| i.join ", "}.join("\n")
set datafile separator ","
set terminal png
set title "Number of people by months activity"
set xlabel "Months active"
set ylabel "People"
plot "/dev/stdin" using 0:1
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment