Welcome to collectivesolver - Programming & Software Q&A with code examples. A website with trusted programming answers. All programs are tested and work.

Contact: aviboots(AT)netvision.net.il

Semrush - keyword research tool

Turn ChatGPT, Claude, Gemini, And CoPilot Into Your Personal Assistant, Business Coach, Content Creator, And More

AFFILIATE MARKETING Your all-in-one performance engine Manage affiliates, creators, and customer referrals in one unified platform—turning every partnership into measurable growth
Secure & Reliable Web Hosting, Free Domain, Free SSL, 1-Click WordPress Install, Expert 24/7 Support

Boost your online presence with premium web hosting and servers

Disclosure: My content contains affiliate links.

42,707 questions

55,466 answers

573 users

How to generate a random 4×4 binary magic square (using only 0 and 1) in Ruby

1 Answer

0 votes
# ============================================================
# 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
#

 



answered Aug 5 by avibootz

Related questions

...