# ============================================================
# Generate a random 4×4 magic square containing only 0 and 1.
#
# A valid square must satisfy:
# • All rows sum to the same target value.
# • All columns sum to that same target value.
# • Both diagonals also match that target value.
#
# The program:
# 1. Precomputes all 4‑bit binary rows.
# 2. Groups rows by their sum.
# 3. Generates *all* valid magic squares.
# 4. Picks one at random.
# ============================================================
# Generate all binary rows of length 4
def binary_rows
(0..15).map { |n| "%04b" % n }.map { |s| s.chars.map(&:to_i) }
end
# Group rows by their sum
ROWS_BY_SUM = binary_rows.group_by(&:sum)
# Generate all magic squares
def generate_all_magic_squares
results = []
(0..4).each do |target|
candidate_rows = ROWS_BY_SUM[target]
square = []
col_sums = [0, 0, 0, 0]
build = lambda do |row_index|
if row_index == 4
main_diag = square[0][0] + square[1][1] + square[2][2] + square[3][3]
anti_diag = square[0][3] + square[1][2] + square[2][1] + square[3][0]
if main_diag == target && anti_diag == target
results << square.map(&:dup)
end
return
end
candidate_rows.each do |row|
feasible = true
4.times do |c|
if col_sums[c] + row[c] > target
feasible = false
break
end
end
next unless feasible
square << row
old_cols = col_sums.dup
4.times { |c| col_sums[c] += row[c] }
build.call(row_index + 1)
square.pop
col_sums.replace(old_cols)
end
end
build.call(0)
end
results
end
# Pick a random magic square
all_squares = generate_all_magic_squares
random_square = all_squares.sample
puts "Random 4×4 binary magic square:"
random_square.each { |row| puts row.join(" ") }
# run:
#
# Random 4×4 binary magic square:
# 1 0 0 1
# 0 1 1 0
# 1 0 0 1
# 0 1 1 0
#