Arc Forumnew | comments | leaders | submitlogin
1 point by map 6096 days ago | link | parent

Ruby version of the wikipedia algorithm.

  class Array
    def rot
      push( shift )
    end
  end

  nqueens = proc{|n|
    odds, evens = (1..n).partition{|x| x % 2 > 0 }
    case n % 12
      when 2
        odds = [3,1] + odds[3..-1] + [5]
      when 3, 9
        odds.rot.rot
        evens.rot
      when 8
        d = -2
        odds.map!{|x| d *= -1; x + d}
    end
    p evens + odds
  }

  nqueens[8]


2 points by map 6095 days ago | link

Shorter:

  class Array
    def rot
      push( shift )
    end
  end

  proc{|n| p ((1..n).partition{|x|x%2>0}.inject{|o,e|
    e + case n % 12
      when 2
        [3,1]+o[3..-1]+[5]
      when 3,9
        o.rot.rot;e.rot;o
      when 8
        d=-2;o.map{|x| x + d*=-1} end})}[ 8 ]

-----

1 point by cchooper 6095 days ago | link

Getting shorter:

  (def rot ((x . y)) (join y `(,x)))

  (def nqueens (n)
    (withs (m (mod n 12) r (range 1 n) od (keep odd r) cod (cddr od) s '(1 3) ev (keep even r))
           (if (join (pos m '(3 9)) (rot ev) (join cod s))
               (join ev (case m 8 (apply join (map rev (pair od)))
                                2 (join (rev s) (rot cod))
                                od)))))
The things Arc is missing from Ruby are partition and testing against multiple objects in a case. With those it would become:

  (def rot ((x . y)) (join y `(,x)))

  (def nqueens (n)
    (withs ((od ev) (part odd (range 1 n)) cod (cddr od) s '(1 3))
           (join ev (case (mod n 12) 8    (apply join (map rev (pair od)))
                                     2    (join (rev s) (rot cod))
                                     3, 9 (do (zap (rot ev)) (join cod s))
                                     od))))

-----

1 point by map 6095 days ago | link

Oops. Both of my Ruby programs above lack a default for the case statement. E.g., the shorter program needs after the last "when":

      else
       o

-----