Skip to content

Instantly share code, notes, and snippets.

@pelf
Created June 26, 2012 22:53
Show Gist options
  • Save pelf/2999894 to your computer and use it in GitHub Desktop.
Save pelf/2999894 to your computer and use it in GitHub Desktop.
Simple ruby scripts coded to help solve new scientist enigmas. They're not meant to be complete or even efficient solutions, only give a little boost in finding the answer as quickly as possible.
# radius: exact nr meters
# slabs: 1x1m
# cut 1/3 of slabs
# total nr slabs?
# ----
MAX_SLABS_RADIUS = 100
# check only a quarter of the circle, the rest is simetric
# try different radiuses
for radius in 1..MAX_SLABS_RADIUS
slabs = 0
cut = 0
# cycle through the slabs
for x in 0...radius
for y in 0...radius
# is slab inside, outside or cut?
# pitagoras ftw: closer corner
hyp = Math.sqrt(x*x + y*y)
if hyp < radius # it's not outside
slabs += 1
# it's either inside or cut
# pitagoras ftw: farther corner
hyp = Math.sqrt((x+1)**2 + (y+1)**2)
if hyp > radius # cut
cut += 1
end
end
end
end
if cut*1.0 == slabs/3.0
puts "radius: #{radius}, used #{slabs*4} slabs, cut #{cut*4}"
break
end
end
primes = Array.new(1000, true)
for i in 2...1000
next unless primes[i]
for j in 2...1000
prod = i*j
break if prod > 1000
primes[prod] = false
end
end
prime_nrs = []
for i in 0...1000
prime_nrs << i if primes[i] and i > 99
end
def encode(nr)
hash = {'0' => 'A', '1' => 'A', '2' => 'B', '3' => 'B','4' => 'C', '5' => 'C', '6' => 'D', '7' => 'D', '8' => 'E', '9' => 'E'}
nr = nr.to_s
enr = ''
for i in 0...nr.size do
enr << hash[nr[i,1]]
end
return enr
end
prime_nrs_e = prime_nrs.map{|p| encode(p)}
for i in 0...prime_nrs.size do
for j in i+1...prime_nrs.size do
if prime_nrs_e[i] == prime_nrs_e[j]
puts 'match'
puts "#{prime_nrs[i]} #{prime_nrs_e[i]}"
puts "#{prime_nrs[j]} #{prime_nrs_e[j]}"
end
end
end
puts '--------'
# squares
squares = []
for i in 1...99
sq = i**2
next if sq < 100
break if sq > 999
squares << sq
end
squares_e = squares.map{|s| encode(s)}
for i in 0...squares.size do
for j in i+1...squares.size do
if squares_e[i] == squares_e[j]
puts 'match'
puts "#{squares[i]} #{squares_e[i]}"
puts "#{squares[j]} #{squares_e[j]}"
end
end
end
# find primes in the first 1000 integers
primes = Array.new(1000,true)
for i in 2...1000
next unless primes[i]
for j in 2...1000
prod = i*j
break if prod > 1000
primes[prod] = false
end
end
prime_nrs = []
for i in 2...1000
prime_nrs << i if primes[i]
end
#puts prime_nrs.inspect
products = []
products_primes = {}
# find products of two primes with 2 digits
prime_nrs.each do |i|
prime_nrs.each do |j|
next if i == j # they need to be different
p = i*j
break if p > 200
if p > 9 # and have 2 digits
products << p
products_primes[p] = [i,j]
end
end
end
#puts products.sort.inspect
products.uniq!.sort!
# pair products and check their difference and sum for 'primeness'
products.each do |p1|
break if p1 > 99
products.each do |p2|
break if p2 > 99
dif = (p1-p2).abs
# is the difference a product of primes?
next unless products.include? dif
sum = p1+p2
# and the sum?
next unless products.include? sum
# prime factors must be distinct
break if (products_primes[p1]+products_primes[p2]+products_primes[dif]+products_primes[sum]).uniq.size < 8
puts "match: #{p1}, #{p2}, #{dif}, #{sum}"
puts (products_primes[p1]+products_primes[p2]+products_primes[dif]+products_primes[sum]).inspect
end
end
# check if if square is 'magic': 4x4 matrix
def magic?(square)
checksum = 34
# check rows
for i in 0...4 do
sum = 0
for j in 0...4 do
sum += square[i][j]
end
# check if sums are the same
if sum != checksum
return false
end
end
# check cols
for j in 0...4 do
sum = 0
for i in 0...4 do
sum += square[i][j]
end
# check if sums are the same
if sum != checksum
return false
end
end
# check diagonal
sum = 0
for i in 0...4 do
sum += square[i][i]
end
if sum != checksum
return false
end
return true
end
def init
return [[0,0,3,0],[5,0,0,0],[0,0,0,12],[0,14,15,0]]
end
def random_fill(square)
left = [1,2,4,6,7,8,9,10,11,12,13,16]
for i in 0...4 do
for j in 0...4 do
if square[i][j] == 0
square[i][j] = (left.delete_at rand*left.size)
end
end
end
return square
end
1000000000.times do
square = random_fill(init)
puts square.inspect if magic?(square)
end
def check(nr)
return false if nr < 100000 or nr > 999999
nrs = nr.to_s
# check 6 different digits
for i in 0...6
for j in i+1...6
return false if nrs[i] == nrs[j]
end
end
# check VPDs
begin
return false if nr % nrs[0,1].to_i != 0 # E
return false if nr % nrs[1,2].to_i != 0 # NI
return false if nr % nrs[2,2].to_i != 0 # IG
return false if nr % nrs[3,1].to_i != 0 # G
return false if nr % nrs[3,3].to_i != 0 # GMA
return false if nr % nrs[4,1].to_i != 0 # M
return false if nr % nrs[4,2].to_i != 0 # MA
return false if nr % nrs[5,1].to_i != 0 # A
rescue ZeroDivisionError => e
return false
end
# if we're here, yay!
return true
end
100000.upto(999999) do |nr|
puts nr if check(nr)
end
def check(nr)
return false if nr < 123456789 or nr > 987654321
nrs = nr.to_s
# check 9 different digits
for i in 0...9
for j in i+1...9
return false if nrs[i] == nrs[j]
end
end
both = false
# check neighbors
for i in 0...9
count = 0
# compare with previous
if i > 0
count += 1 if (nrs[i,1].to_i - nrs[i-1,1].to_i).abs == 1
end
# compare with next
if i < 8
count += 1 if (nrs[i,1].to_i - nrs[i+1,1].to_i).abs == 1
end
return false if count == 0
return false if both and count == 2
both = (count == 2)
end
# check divisible
count = 0
1.upto(12) do |d|
count += 1 if nr % d == 0
end
if count > 9
return true
else
return false
end
end
123456789.upto(987654321) do |nr|
puts nr if check(nr)
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment