with javascript_semantics
function swap(sequence s, integer x1, y1, x2, y2)
    {s[x1,y1],s[x2,y2]} = {s[x2,y2],s[x1,y1]}
    return s
end function

function se_magicsq(integer n)

    if n<6 or mod(n-2,4)!=0 then
        crash("illegal size (%d)",{n})
    end if

    sequence sq = repeat(repeat(0,n),n)
    integer magic_sum = n*(n*n+1)/2,
            sq_d_2 = n/2,
            q2 = power(sq_d_2,2),
            l = (n-2)/4,
            x1 = floor(sq_d_2/2)+1, x2,
            y1 = 1, y2,
            r = 1

    -- fill pattern a c
    --              d b
    -- main loop for creating magic square in section a
    -- the value for b,c and d is derived from a
    while true do
        if sq[x1,y1]=0 then
            x2 = x1+sq_d_2
            y2 = y1+sq_d_2
            sq[x1,y1] = r       -- a
            sq[x2,y2] = r+q2    -- b
            sq[x2,y1] = r+q2*2  -- c
            sq[x1,y2] = r+q2*3  -- d
            if mod(r,sq_d_2)=0 then
                y1 += 1
            else
                x1 += 1
                y1 -= 1
            end if
            r += 1
        end if
        if x1>sq_d_2 then
            x1 = 1
            while sq[x1,y1] <> 0 do
                x1 += 1
            end while
        end if
        if y1<1 then
            y1 = sq_d_2
            while sq[x1,y1] <> 0 do
                y1 -= 1
            end while
        end if
        if r>q2 then exit end if
    end while

    -- swap left side
    for y=1 to sq_d_2 do
        y2 = y+sq_d_2
        for x=1 to l do
            sq = swap(sq, x,y, x,y2)
        end for
    end for

    -- make indent
    y1 = floor(sq_d_2/2) +1
    y2 = y1+sq_d_2
    x1 = 1
    sq = swap(sq, x1,y1, x1,y2)
    x1 = l+1
    sq = swap(sq, x1,y1, x1,y2)

    -- swap right side
    for y=1 to sq_d_2 do
        y2 = y+sq_d_2
        for x=n-l+2 to n do
            sq = swap(sq, x,y, x,y2)
        end for
    end for

    -- check columms and rows
    for y=1 to n do
        r = 0
        l = 0
        for x=1 to n do
            r += sq[x,y]
            l += sq[y,x]
        end for
        if r<>magic_sum
        or l<>magic_sum then
            crash("error: value <> magic_sum")
        end if
    end for

    -- check diagonals
    r = 0
    l = 0
    for x=1 to n do
        r += sq[x,x]
        x2 = n-x+1
        l += sq[x2,x2]
    end for
    if r<>magic_sum
    or l<>magic_sum then
        crash("error: value <> magic_sum")
    end if

    return sq
end function

pp(se_magicsq(6),{pp_Nest,1,pp_IntFmt,"%3d",pp_StrFmt,3,pp_IntCh,false,pp_Pause,0})


import math
from sys import stdout

LOG_10 = 2.302585092994

# build odd magic square
def build_oms(s):
    if s % 2 == 0:
        s += 1
    q = [[0 for j in range(s)] for i in range(s)]
    p = 1
    i = s // 2
    j = 0
    while p <= (s * s):
        q[i][j] = p
        ti = i + 1
        if ti >= s: ti = 0
        tj = j - 1
        if tj < 0: tj = s - 1
        if q[ti][tj] != 0:
            ti = i
            tj = j + 1
        i = ti
        j = tj
        p = p + 1

    return q, s

# build singly even magic square
def build_sems(s):
    if s % 2 == 1:
        s += 1
    while s % 4 == 0:
        s += 2

    q = [[0 for j in range(s)] for i in range(s)]
    z = s // 2
    b = z * z
    c = 2 * b
    d = 3 * b
    o = build_oms(z)

    for j in range(0, z):
        for i in range(0, z):
            a = o[0][i][j]
            q[i][j] = a
            q[i + z][j + z] = a + b
            q[i + z][j] = a + c
            q[i][j + z] = a + d

    lc = z // 2
    rc = lc
    for j in range(0, z):
        for i in range(0, s):
            if i < lc or i > s - rc or (i == lc and j == lc):
                if not (i == 0 and j == lc):
                    t = q[i][j]
                    q[i][j] = q[i][j + z]
                    q[i][j + z] = t

    return q, s

def format_sqr(s, l):
    for i in range(0, l - len(s)):
        s = "0" + s
    return s + " "

def display(q):
    s = q[1]
    print(" - {0} x {1}\n".format(s, s))
    k = 1 + math.floor(math.log(s * s) / LOG_10)
    for j in range(0, s):
        for i in range(0, s):
            stdout.write(format_sqr("{0}".format(q[0][i][j]), k))
        print()
    print("Magic sum: {0}\n".format(s * ((s * s) + 1) // 2))

stdout.write("Singly Even Magic Square")
display(build_sems(6))


def odd_magic_square(n)
  n.times.map{|i| n.times.map{|j| n*((i+j+1+n/2)%n) + ((i+2*j-5)%n) + 1} }
end

def single_even_magic_square(n)
  raise ArgumentError, "must be even, but not divisible by 4." unless (n-2) % 4 == 0
  raise ArgumentError, "2x2 magic square not possible." if n == 2

  order = (n-2)/4
  odd_square = odd_magic_square(n/2)
  to_add = (0..3).map{|f| f*n*n/4}
  quarts = to_add.map{|f| odd_square.dup.map{|row|row.map{|el| el+f}} }

  sq = []
  quarts[0].zip(quarts[2]){|d1,d2| sq << [d1,d2].flatten}
  quarts[3].zip(quarts[1]){|d1,d2| sq << [d1,d2].flatten}

  sq = sq.transpose
  order.times{|i| sq[i].rotate!(n/2)}
  swap(sq[0][order], sq[0][-order-1])
  swap(sq[order][order], sq[order][-order-1])
  (order-1).times{|i| sq[-(i+1)].rotate!(n/2)}
  randomize(sq)
end

def swap(a,b)
  a,b = b,a
end

def randomize(square)
  square.shuffle.transpose.shuffle
end

def to_string(square)
  n = square.size
  fmt = "%#{(n*n).to_s.size + 1}d" * n
  square.inject(""){|str,row| str << fmt % row << "\n"}
end

puts to_string(single_even_magic_square(6))


F magicSquareDoublyEven(n)
   V bits = 1001'0110'0110'1001b
   V size = n * n
   V mult = n I/ 4

   V result = [[0] * n] * n
   V i = 0
   L(r) 0 .< n
      L(c) 0 .< n
         V bitPos = c I/ mult + (r I/ mult) * 4
         result[r][c] = I (bits [&] (1 << bitPos)) != 0 {i + 1} E size - i
         i++
   R result

V n = 8
L(row) magicSquareDoublyEven(n)
   L(x) row
      print(‘#2 ’.format(x), end' ‘’)
   print()
print("\nMagic constant: "((n * n + 1) * n I/ 2))


use std::env;

fn main() {
    let n: usize =
        match env::args().nth(1).and_then(|arg| arg.parse().ok()).ok_or(
            "Please specify the size of the magic square, as a positive multiple of 4 plus 2.",
        ) {
            Ok(arg) if arg % 2 == 1 || arg >= 6 && (arg - 2) % 4 == 0 => arg,
            Err(e) => panic!(e),
            _ => panic!("Argument must be a positive multiple of 4 plus 2."),
        };

    let (ms, mc) = magic_square_singly_even(n);
    println!("n: {}", n);
    println!("Magic constant: {}\n", mc);
    let width = (n * n).to_string().len() + 1;
    for row in ms {
        for elem in row {
            print!("{e:>w$}", e = elem, w = width);
        }
        println!();
    }
}

fn magic_square_singly_even(n: usize) -> (Vec<Vec<usize>>, usize) {
    let size = n * n;
    let half = n / 2;
    let sub_square_size = size / 4;
    let sub_square = magic_square_odd(half);
    let quadrant_factors = [0, 2, 3, 1];
    let cols_left = half / 2;
    let cols_right = cols_left - 1;

    let ms = (0..n)
        .map(|r| {
            (0..n)
                .map(|c| {
                    let localr = if (c < cols_left
                        || c >= n - cols_right
                        || c == cols_left && r % half == cols_left)
                        && !(c == 0 && r % half == cols_left)
                    {
                        if r >= half {
                            r - half
                        } else {
                            r + half
                        }
                    } else {
                        r
                    };
                    let quadrant = localr / half * 2 + c / half;
                    let v = sub_square[localr % half][c % half];
                    v + quadrant_factors[quadrant] * sub_square_size
                })
                .collect()
        })
        .collect::<Vec<Vec<_>>>();
    (ms, (n * n + 1) * n / 2)
}

fn magic_square_odd(n: usize) -> Vec<Vec<usize>> {
    (0..n)
        .map(|r| {
            (0..n)
                .map(|c| {
                    n * (((c + 1) + (r + 1) - 1 + (n >> 1)) % n)
                        + (((c + 1) + (2 * (r + 1)) - 2) % n)
                        + 1
                })
                .collect::<Vec<_>>()
        })
        .collect::<Vec<Vec<_>>>()
}


import "/fmt" for Fmt

var magicSquareOdd = Fn.new { |n|
    if (n < 3 || n%2 == 0) Fiber.abort("Base must be odd and > 2")
    var value = 1
    var gridSize = n * n
    var c = (n/2).floor
    var r = 0
    var result = List.filled(n, null)
    for (i in 0...n) result[i] = List.filled(n, 0)
    while (value <= gridSize) {
        result[r][c] = value
        if (r == 0) {
            if (c == n - 1) {
                r = r + 1
            } else {
                r = n - 1
                c = c + 1
            }
        } else if (c == n - 1) {
            r = r - 1
            c = 0
        } else if (result[r - 1][c + 1] == 0) {
            r = r - 1
            c = c + 1
        } else {
            r = r + 1
        }
        value = value + 1
    }
    return result
}

var magicSquareSinglyEven = Fn.new { |n|
    if (n < 6 || (n - 2) % 4 != 0) {
        Fiber.abort("Base must be a positive multiple of 4 plus 2")
    }
    var size = n * n
    var halfN = n / 2
    var subSquareSize = size / 4
    var subSquare = magicSquareOdd.call(halfN)
    var quadrantFactors = [0, 2, 3, 1]
    var result = List.filled(n, null)
    for (i in 0...n) result[i] = List.filled(n, 0)
    for (r in 0...n) {
        for (c in 0...n) {
            var quadrant = (r/halfN).floor * 2 + (c/halfN).floor
            result[r][c] = subSquare[r % halfN][c % halfN]
            result[r][c] = result[r][c] + quadrantFactors[quadrant] * subSquareSize
        }
    }
    var nColsLeft = (halfN/2).floor
    var nColsRight = nColsLeft - 1
    for (r in 0...halfN) {
        for (c in 0...n) {
            if (c < nColsLeft || c >= n - nColsRight || (c == nColsLeft && r == nColsLeft)) {
                if (c != 0 || r != nColsLeft) {
                    var tmp = result[r][c]
                    result[r][c] = result[r + halfN][c]
                    result[r + halfN][c] = tmp
                }
            }
        }
    }
    return result
}

var n = 6
for (ia in magicSquareSinglyEven.call(n)) {
    for (i in ia) Fmt.write("$2d  ", i)
    System.print()
}
System.print("\nMagic constant %((n * n + 1) * n / 2)")


*        Magic squares of doubly even order  01/03/2017
MAGICSDB CSECT
         USING  MAGICSDB,R13
         B      72(R15)            skip save area
         DC     17F'0'             save area
         STM    R14,R12,12(R13)
         ST     R13,4(R15)
         ST     R15,8(R13)
         LR     R13,R15            end of prolog
         SR     R8,R8              k=0
         LA     R6,0               i=0
       DO WHILE=(C,R6,LE,=A(N-1))  do i=0 to n-1
         MVC    PG,=CL80' '          clear buffer
         LA     R9,PG                pgi=0
         LA     R7,0                 j=0
       DO WHILE=(C,R7,LE,=A(N-1))    do j=0 to n-1
         LR     R4,R7                  j
         SRDA   R4,32                  >>r5
         D      R4,MULT                /mult
         LR     R2,R5                  r2=j/mult
         LR     R4,R6                  i
         SRDA   R4,32                  >>r5
         D      R4,MULT                /mult
         SLA    R5,2                   r5=(i/mult)*4
         AR     R2,R5                  bitpos=j/mult+(i/mult)*4
         STC    R2,XSLL+3              number_of_shift=bitpos
         L      R5,=F'1'               1
         EX     0,XSLL                 r5=1<<bitpos  (SLL R5,bitpos)
         L      R4,BITS                bits
         NR     R4,R5                  bits and (1<<bitpos)
       IF LTR,R4,NZ,R4 THEN            if (bits and (1<<bitpos))<>0
         LA     R10,1(R8)                x=k+1
       ELSE     ,                      else
         L      R10,SIZE                 size
         SR     R10,R8                   x=size-k
       ENDIF    ,                      endif
         XDECO  R10,XDEC               edit x
         MVC    0(4,R9),XDEC+8         output x
         LA     R9,4(R9)               pgi+=4
         LA     R8,1(R8)               k++
         LA     R7,1(R7)               j++
       ENDDO    ,                    enddo j
         XPRNT  PG,L'PG              print buffer
         LA     R6,1(R6)             i++
       ENDDO    ,                  enddo i
         MVC    PG,=CL80'magic constant='
         L      R1,=A((N*N+1)*N/2) magicnum=(n*n+1)*n/2
         XDECO  R1,XDEC            edit magicnum
         MVC    PG+15(4),XDEC+8    output magicnum
         XPRNT  PG,L'PG            print buffer
         L      R13,4(0,R13)       epilog
         LM     R14,R12,12(R13)
         XR     R15,R15            rc=0
         BR     R14                exit
XSLL     SLL    R5,0               shift left logical
N        EQU    8                  <= input value n
SIZE     DC     A(N*N)             size=n*n
MULT     DC     A(N/4)             mult=n/4  (multiple of 4)
BITS     DC     XL2'0000',BL2'1001011001101001'  pattern
PG       DS     CL80               buffer
XDEC     DS     CL12               temp for xdeco
         YREGS
         END    MAGICSDB


begin
	comment Magic squares of doubly even order - 10/02/2021;
    integer array pattern[1:4,1:4];
	integer n, r, c, s, m, i, b, t;
	n:=8;
	for r:=1 step 1 until 4 do
		for c:=1 step 1 until 4 do
			pattern[r,c]:=if
				((c=1 or c=4) and (r=1 or r=4)) or
				((c=2 or c=3) and (r=2 or r=3)) then 1 else 0;
	s:=n*n;  m:=n div 4;
	outstring(1,"magic square -- n ="); outinteger(1,n); outstring(1,"\n");
	i:=0;
	for r:=1 step 1 until n do begin
		for c:=1 step 1 until n do begin
			b:=pattern[(r-1) div m+1,(c-1) div m+1];
			if b=1 then t:=i+1 else t:=s-i;
			if t less 10 then outstring(1," ");
			outinteger(1,t);
			i:=i+1
		end;
		outstring(1,"\n")
	end;
	outstring(1,"magic constant ="); outinteger(1,(s+1)*n div 2)
end


BEGIN # Magic squares of doubly even order #
    PROC doubly even magic square = ( INT n )[,]INT:
         IF n MOD 4 /= 0 THEN
            # not a doubly even number #
            [ 1 : 0, 1 : 0 ]INT empty square;
            empty square
         ELSE
            # ok to create the square #
            [ 1 : 4, 1 : 4 ]INT pattern;
            FOR r TO 4 DO
                FOR c TO 4 DO
                    pattern[ r, c ] := IF ( ( c = 1 OR c = 4 ) AND ( r = 1 OR r = 4 ) )
                                       OR ( ( c = 2 OR c = 3 ) AND ( r = 2 OR r = 3 ) )
                                       THEN 1
                                       ELSE 0
                                       FI
                OD
            OD;
            [ 1 : n, 1 : n ]INT result;
            INT s  = n * n, m = n OVER 4;
            INT i := 0;
            FOR r TO n DO
                FOR c TO n DO
                    result[ r, c ] := IF pattern[ ( r - 1 ) OVER m + 1, ( c - 1 ) OVER m + 1 ] = 1
                                      THEN i + 1
                                      ELSE s - i
                                      FI;
                    i +:= 1
                OD
            OD;
            result
         FI # doubly eben magic square # ;
    # test doubly even magic square #
    FOR order FROM 8 BY 4 TO 12 DO
        # calculate the field width for the elements of the square #
        INT w := 1, v := order * order;
        WHILE ( v OVERAB 10 ) > 0 DO w +:= 1 OD;
        # construct the square #
        [,]INT square = doubly even magic square( order );
        print( ( "magic square -- n = ", whole( order, 0 ), newline ) );
        FOR r FROM 1 LWB square TO 1 UPB square DO
            FOR c FROM 2 LWB square TO 2 UPB square DO
                print( ( " ", whole( square[ r, c ], - w ) ) )
            OD;
            print( ( newline ) )
        OD;
        print( ( "magic constant = ", whole( ( ( ( order * order ) + 1 ) * order ) OVER 2, 0 ), newline ) )
    OD
END


class MagicSquareSinglyEven{
   fcn init(n){ var result=magicSquareSinglyEven(n) }
   fcn toString{
      sink,n:=Sink(String),result.len();  // num collumns
      fmt:="%2s ";
      foreach row in (result)
         { sink.write(row.apply('wrap(n){ fmt.fmt(n) }).concat(),"\n") }
      sink.write("\nMagic constant: %d".fmt((n*n + 1)*n/2));
      sink.close();
   }
   fcn magicSquareOdd(n){
      if (n<3 or n%2==0) throw(Exception.ValueError("base must be odd and > 2"));
      value,gridSize,c,r:=0, n*n, n/2, 0;
      result:=n.pump(List(),n.pump(List(),0).copy);  // array[n,n] of zero

      while((value+=1)<=gridSize){
	 result[r][c]=value;
	 if(r==0){
	    if(c==n-1) r+=1;
            else{ r=n-1; c+=1; }
	 }
	 else if(c==n-1){ r-=1; c=0; }
	 else if(result[r-1][c+1]==0){ r-=1; c+=1; }
	 else r+=1;
      }
      result;
   }
   fcn magicSquareSinglyEven(n){
      if (n<6 or (n-2)%4!=0)
	 throw(Exception.ValueError("base must be a positive multiple of 4 +2"));
      size,halfN,subSquareSize:=n*n,  n/2, size/4;

      subSquare:=magicSquareOdd(halfN);
      quadrantFactors:=T(0, 2, 3, 1);
      result:=n.pump(List(),n.pump(List(),0).copy);  // array[n,n] of zero

      foreach r,c in (n,n){
         quadrant:=(r/halfN)*2 + (c/halfN);
	 result[r][c]=subSquare[r%halfN][c%halfN];
	 result[r][c]+=quadrantFactors[quadrant]*subSquareSize;
      }
      nColsLeft,nColsRight:=halfN/2, nColsLeft-1;
      foreach r,c in (halfN,n){
         if ( c<nColsLeft or c>=(n-nColsRight) or
              (c==nColsLeft and r==nColsLeft) ){
	    if(c==0 and r==nColsLeft) continue;
	    tmp:=result[r][c];
	    result[r][c]=result[r+halfN][c];
	    result[r+halfN][c]=tmp;
	 }
      }
      result
   }
}


-- MAGIC SQUARE OF DOUBLY EVEN ORDER -----------------------------------------

-- magicSquare :: Int -> [[Int]]
on magicSquare(n)
    if n mod 4 > 0 then
        {}
    else
        set sqr to n * n

        set maybePowerOfTwo to asPowerOfTwo(sqr)
        if maybePowerOfTwo is not missing value then

            -- For powers of 2, the (append not) 'magic' series directly
            -- yields the truth table that we need
            set truthSeries to magicSeries(maybePowerOfTwo)
        else
            -- where n is not a power of 2, we can replicate a
            -- minimum truth table, horizontally and vertically

            script scale
                on |λ|(x)
                    replicate(n / 4, x)
                end |λ|
            end script

            set truthSeries to ¬
                flatten(scale's |λ|(map(scale, splitEvery(4, magicSeries(4)))))
        end if

        set limit to sqr + 1
        script inOrderOrReversed
            on |λ|(x, i)
                cond(x, i, limit - i)
            end |λ|
        end script

        -- Taken directly from an integer series  [1..sqr] where True
        -- and from the reverse of that series where False
        splitEvery(n, map(inOrderOrReversed, truthSeries))
    end if
end magicSquare

-- magicSeries :: Int -> [Bool]
on magicSeries(n)
    script boolToggle
        on |λ|(x)
            not x
        end |λ|
    end script

    if n ≤ 0 then
        {true}
    else
        set xs to magicSeries(n - 1)
        xs & map(boolToggle, xs)
    end if
end magicSeries

-- TEST ----------------------------------------------------------------------
on run

    formattedTable(magicSquare(8))

end run

-- formattedTable :: [[Int]] -> String
on formattedTable(lstTable)
    set n to length of lstTable
    set w to 2.5 * n
    "magic(" & n & ")" & linefeed & wikiTable(lstTable, ¬
        false, "text-align:center;width:" & ¬
        w & "em;height:" & w & "em;table-layout:fixed;")
end formattedTable

-- wikiTable :: [Text] -> Bool -> Text -> Text
on wikiTable(lstRows, blnHdr, strStyle)
    script fWikiRows
        on |λ|(lstRow, iRow)
            set strDelim to cond(blnHdr and (iRow = 0), "!", "|")
            set strDbl to strDelim & strDelim
            linefeed & "|-" & linefeed & strDelim & space & ¬
                intercalate(space & strDbl & space, lstRow)
        end |λ|
    end script

    linefeed & "{| class=\"wikitable\" " & ¬
        cond(strStyle ≠ "", "style=\"" & strStyle & "\"", "") & ¬
        intercalate("", ¬
            map(fWikiRows, lstRows)) & linefeed & "|}" & linefeed
end wikiTable

-- GENERIC FUNCTIONS ---------------------------------------------------------

-- asPowerOfTwo :: Int -> maybe Int
on asPowerOfTwo(n)
    if not isPowerOf(2, n) then
        missing value
    else
        set strCMD to ("echo 'l(" & n as string) & ")/l(2)' | bc -l"
        (do shell script strCMD) as integer
    end if
end asPowerOfTwo

-- concatMap :: (a -> [b]) -> [a] -> [b]
on concatMap(f, xs)
    script append
        on |λ|(a, b)
            a & b
        end |λ|
    end script

    foldl(append, {}, map(f, xs))
end concatMap

-- cond :: Bool -> a -> a -> a
on cond(bool, f, g)
    if bool then
        f
    else
        g
    end if
end cond

-- flatten :: Tree a -> [a]
on flatten(t)
    if class of t is list then
        concatMap(my flatten, t)
    else
        t
    end if
end flatten

-- foldl :: (a -> b -> a) -> a -> [b] -> a
on foldl(f, startValue, xs)
    tell mReturn(f)
        set v to startValue
        set lng to length of xs
        repeat with i from 1 to lng
            set v to |λ|(v, item i of xs, i, xs)
        end repeat
        return v
    end tell
end foldl

-- intercalate :: Text -> [Text] -> Text
on intercalate(strText, lstText)
    set {dlm, my text item delimiters} to {my text item delimiters, strText}
    set strJoined to lstText as text
    set my text item delimiters to dlm
    return strJoined
end intercalate

-- isPowerOf :: Int -> Int -> Bool
on isPowerOf(k, n)
    set v to k
    script remLeft
        on |λ|(x)
            x mod v is not 0
        end |λ|
    end script

    script integerDiv
        on |λ|(x)
            x div v
        end |λ|
    end script

    |until|(remLeft, integerDiv, n) = 1
end isPowerOf

-- map :: (a -> b) -> [a] -> [b]
on map(f, xs)
    tell mReturn(f)
        set lng to length of xs
        set lst to {}
        repeat with i from 1 to lng
            set end of lst to |λ|(item i of xs, i, xs)
        end repeat
        return lst
    end tell
end map

-- Lift 2nd class handler function into 1st class script wrapper
-- mReturn :: Handler -> Script
on mReturn(f)
    if class of f is script then
        f
    else
        script
            property |λ| : f
        end script
    end if
end mReturn

-- Egyptian multiplication - progressively doubling a list, appending
-- stages of doubling to an accumulator where needed for binary
-- assembly of a target length

-- replicate :: Int -> a -> [a]
on replicate(n, a)
    set out to {}
    if n < 1 then return out
    set dbl to {a}

    repeat while (n > 1)
        if (n mod 2) > 0 then set out to out & dbl
        set n to (n div 2)
        set dbl to (dbl & dbl)
    end repeat
    return out & dbl
end replicate

-- splitAt :: Int -> [a] -> ([a],[a])
on splitAt(n, xs)
    if n > 0 and n < length of xs then
        if class of xs is text then
            {items 1 thru n of xs as text, items (n + 1) thru -1 of xs as text}
        else
            {items 1 thru n of xs, items (n + 1) thru -1 of xs}
        end if
    else
        if n < 1 then
            {{}, xs}
        else
            {xs, {}}
        end if
    end if
end splitAt

-- splitEvery :: Int -> [a] -> [[a]]
on splitEvery(n, xs)
    if length of xs ≤ n then
        {xs}
    else
        set {gp, t} to splitAt(n, xs)
        {gp} & splitEvery(n, t)
    end if
end splitEvery

-- until :: (a -> Bool) -> (a -> a) -> a -> a
on |until|(p, f, x)
    set mp to mReturn(p)
    set v to x

    tell mReturn(f)
        repeat until mp's |λ|(v)
            set v to |λ|(v)
        end repeat
    end tell
    return v
end |until|


# Usage: GAWK -f MAGIC_SQUARES_OF_DOUBLY_EVEN_ORDER.AWK
BEGIN {
    n = 8
    msquare[0, 0] = 0
    if (magicsquaredoublyeven(msquare, n)) {
        for (i = 0; i < n; i++) {
            for (j = 0; j < n; j++) {
                printf("%2d ", msquare[i, j])
            }
            printf("\n")
        }
        printf("\nMagic constant: %d\n", (n * n + 1) * n / 2)
        exit 1
    } else {
        exit 0
    }
}
function magicsquaredoublyeven(msquare, n,    size, mult, r, c, i) {
    if (n < 4 || n % 4 != 0) {
        printf("Base must be a positive multiple of 4.\n")
        return 0
    }
    size = n * n
    mult = n / 4 # how many multiples of 4

    i = 0
    for (r = 0; r < n; r++) {
        for (c = 0; c < n; c++) {
            msquare[r, c] = countup(r, c, mult) ? i + 1 : size - i
            i++
        }
    }
    return 1
}
function countup(r, c, mult,    pattern, bitpos) {
    # Returns 1, if we are in a count-up zone (0 otherwise)
    pattern = "1001011001101001"
    bitpos =  int(c / mult) + int(r / mult) * 4 + 1
    return substr(pattern, bitpos, 1) + 0
}


#include<stdlib.h>
#include<ctype.h>
#include<stdio.h>

int** doublyEvenMagicSquare(int n) {
	if (n < 4 || n % 4 != 0)
		return NULL;

	int bits = 38505;
	int size = n * n;
	int mult = n / 4,i,r,c,bitPos;

	int** result = (int**)malloc(n*sizeof(int*));

	for(i=0;i<n;i++)
		result[i] = (int*)malloc(n*sizeof(int));

	for (r = 0, i = 0; r < n; r++) {
		for (c = 0; c < n; c++, i++) {
			bitPos = c / mult + (r / mult) * 4;
			result[r][c] = (bits & (1 << bitPos)) != 0 ? i + 1 : size - i;
		}
	}
	return result;
}

int numDigits(int n){
	int count = 1;

	while(n>=10){
		n /= 10;
		count++;
	}

	return count;
}

void printMagicSquare(int** square,int rows){
	int i,j,baseWidth = numDigits(rows*rows) + 3;

	printf("Doubly Magic Square of Order : %d and Magic Constant : %d\n\n",rows,(rows * rows + 1) * rows / 2);

	for(i=0;i<rows;i++){
		for(j=0;j<rows;j++){
			printf("%*s%d",baseWidth - numDigits(square[i][j]),"",square[i][j]);
		}
		printf("\n");
	}
}

int main(int argC,char* argV[])
{
	int n;

	if(argC!=2||isdigit(argV[1][0])==0)
		printf("Usage : %s <integer specifying rows in magic square>",argV[0]);
	else{
		n = atoi(argV[1]);
		printMagicSquare(doublyEvenMagicSquare(n),n);
	}
	return 0;
}


using System;

namespace MagicSquareDoublyEven
{
    class Program
    {
        static void Main(string[] args)
        {
            int n = 8;
            var result = MagicSquareDoublyEven(n);
            for (int i = 0; i < result.GetLength(0); i++)
            {
                for (int j = 0; j < result.GetLength(1); j++)
                    Console.Write("{0,2} ", result[i, j]);
                Console.WriteLine();
            }
            Console.WriteLine("\nMagic constant: {0} ", (n * n + 1) * n / 2);
            Console.ReadLine();
        }

        private static int[,] MagicSquareDoublyEven(int n)
        {
            if (n < 4 || n % 4 != 0)
                throw new ArgumentException("base must be a positive "
                        + "multiple of 4");

            // pattern of count-up vs count-down zones
            int bits = 0b1001_0110_0110_1001;
            int size = n * n;
            int mult = n / 4;  // how many multiples of 4

            int[,] result = new int[n, n];

            for (int r = 0, i = 0; r < n; r++)
            {
                for (int c = 0; c < n; c++, i++)
                {
                    int bitPos = c / mult + (r / mult) * 4;
                    result[r, c] = (bits & (1 << bitPos)) != 0 ? i + 1 : size - i;
                }
            }
            return result;
        }
    }
}


#include <iostream>
#include <sstream>
#include <iomanip>
using namespace std;

class magicSqr
{
public:
    magicSqr( int d ) {
        while( d % 4 > 0 ) { d++; }
        sz = d;
        sqr = new int[sz * sz];
        fillSqr();
    }
    ~magicSqr() { delete [] sqr; }

    void display() const {
        cout << "Doubly Even Magic Square: " << sz << " x " << sz << "\n";
        cout << "It's Magic Sum is: " << magicNumber() << "\n\n";
        ostringstream cvr; cvr << sz * sz;
        int l = cvr.str().size();

        for( int y = 0; y < sz; y++ ) {
            int yy = y * sz;
            for( int x = 0; x < sz; x++ ) {
                cout << setw( l + 2 ) << sqr[yy + x];
            }
            cout << "\n";
        }
        cout << "\n\n";
    }
private:
    void fillSqr() {
        static const bool tempAll[4][4] = {{ 1, 0, 0, 1 }, { 0, 1, 1, 0 }, { 0, 1, 1, 0 }, { 1, 0, 0, 1 } };
        int i = 0;
        for( int curRow = 0; curRow < sz; curRow++ ) {
            for( int curCol = 0; curCol < sz; curCol++ ) {
                sqr[curCol + sz * curRow] = tempAll[curRow % 4][curCol % 4] ? i + 1 : sz * sz - i;
                i++;
            }
        }
    }
    int magicNumber() const { return sz * ( ( sz * sz ) + 1 ) / 2; }

    int* sqr;
    int sz;
};

int main( int argc, char* argv[] ) {
    magicSqr s( 8 );
    s.display();
    return 0;
}


import std.stdio;

void main() {
    int n=8;
    foreach(row; magicSquareDoublyEven(n)) {
        foreach(col; row) {
            writef("%2s ", col);
        }
        writeln;
    }
    writeln("\nMagic constant: ", (n*n+1)*n/2);
}

int[][] magicSquareDoublyEven(int n) {
    import std.exception;
    enforce(n>=4 && n%4 == 0, "Base must be a positive multiple of 4");

    int bits = 0b1001_0110_0110_1001;
    int size = n * n;
    int mult = n / 4;  // how many multiples of 4

    int[][] result;
    result.length = n;
    foreach(i; 0..n) {
        result[i].length = n;
    }

    for (int r=0, i=0; r<n; r++) {
        for (int c=0; c<n; c++, i++) {
            int bitPos = c / mult + (r / mult) * 4;
            result[r][c] = (bits & (1 << bitPos)) != 0 ? i + 1 : size - i;
        }
    }

    return result;
}


import system'routines;
import extensions;
import extensions'routines;

MagicSquareDoublyEven(int n)
{
    if(n < 4 || n.mod(4) != 0)
        { InvalidArgumentException.new:"base must be a positive multiple of 4".raise() };

    int bits := 09669h;
    int size := n * n;
    int mult := n / 4;

    var result := IntMatrix.allocate(n,n);
    int i := 0;
    for (int r := 0, r < n, r += 1)
    {
        for(int c := 0, c < n, c += 1, i += 1)
        {
            int bitPos := c / mult + (r / mult) * 4;

            result[r][c] := ((bits && (1 $shl bitPos)) != 0).iif(i+1,size - i)
        }
    };

    ^ result
}

public program()
{
    int n := 8;

    console.printLine(MagicSquareDoublyEven(n));

    console.printLine().printLine("Magic constant: ",(n * n + 1) * n / 2)
}


defmodule Magic_square do
  def doubly_even(n) when rem(n,4)!=0, do: raise ArgumentError, "must be even, but not divisible by 4."
  def doubly_even(n) do
    n2 = n * n
    Enum.zip(1..n2, make_pattern(n))
    |> Enum.map(fn {i,p} -> if p, do: i, else: n2 - i + 1 end)
    |> Enum.chunk(n)
    |> to_string(n)
    |> IO.puts
  end

  defp make_pattern(n) do
    pattern = Enum.reduce(1..4, [true], fn _,acc ->
                acc ++ Enum.map(acc, &(!&1))
              end) |> Enum.chunk(4)
    for i <- 0..n-1, j <- 0..n-1, do: Enum.at(pattern, rem(i,4)) |> Enum.at(rem(j,4))
  end

  defp to_string(square, n) do
    format = String.duplicate("~#{length(to_char_list(n*n))}w ", n) <> "\n"
    Enum.map_join(square, fn row ->
      :io_lib.format(format, row)
    end)
  end
end

Magic_square.doubly_even(8)


USING: arrays combinators.short-circuit formatting fry
generalizations kernel math math.matrices prettyprint sequences
;
IN: rosetta-code.doubly-even-magic-squares

: top?    ( loc n -- ? ) [ second ] dip 1/4 * <  ;
: bottom? ( loc n -- ? ) [ second ] dip 3/4 * >= ;
: left?   ( loc n -- ? ) [ first  ] dip 1/4 * <  ;
: right?  ( loc n -- ? ) [ first  ] dip 3/4 * >= ;
: corner? ( loc n -- ? )
    {
        [ { [ top?    ] [ left?  ] } ]
        [ { [ top?    ] [ right? ] } ]
        [ { [ bottom? ] [ left?  ] } ]
        [ { [ bottom? ] [ right? ] } ]
    } [ 2&& ] map-compose 2|| ;

: center? ( loc n -- ? )
    { [ top? ] [ bottom? ] [ left? ] [ right? ] } [ not ]
    map-compose 2&& ;

: backward? ( loc n -- ? ) { [ corner? ] [ center? ] } 2|| ;
: forward   ( loc n -- m ) [ first2 ] dip * 1 + + ;
: backward  ( loc n -- m ) tuck forward [ sq ] dip - 1 + ;

: (doubly-even-magic-square) ( n -- matrix )
    [ dup 2array matrix-coordinates flip ] [ 3 dupn ] bi
    '[ dup _ backward? [ _ backward ] [ _ forward ] if ]
    matrix-map ;

ERROR: invalid-order order ;

: check-order ( n -- )
    dup { [ zero? not ] [ 4 mod zero? ] } 1&& [ drop ]
    [ invalid-order ] if ;

: doubly-even-magic-square ( n -- matrix )
    dup check-order (doubly-even-magic-square) ;

: main ( -- )
    { 4 8 12 } [
        dup doubly-even-magic-square dup
        [ "Order: %d\n" printf ]
        [ simple-table. ]
        [ first sum "Magic constant: %d\n\n" printf ] tri*
    ] each ;

MAIN: main


' version 18-03-2016
' compile with: fbc -s console
' doubly even magic square 4, 8, 12, 16...

Sub Err_msg(msg As String)
    Print msg
    Beep : Sleep 5000, 1 : Exit Sub
End Sub

Sub de_magicsq(n As UInteger, filename As String = "")

    ' filename <> "" then save square in a file
    ' filename can contain directory name
    ' if filename exist it will be overwriten, no error checking

    If n < 4 Then
        Err_msg( "Error: n is to small")
        Exit Sub
    End If

    If (n Mod 4) <> 0 Then
        Err_msg "Error: not possible to make doubly" + _
        " even magic square size " + Str(n)
        Exit Sub
    End If

    Dim As UInteger sq(1 To n, 1 To n)
    Dim As UInteger magic_sum = n * (n ^ 2 +1) \ 2
    Dim As UInteger q = n \ 4
    Dim As UInteger x, y, nr = 1
    Dim As String frmt = String(Len(Str(n * n)) +1, "#")

    ' set up the square
    For y = 1 To n
        For x = q +1 To n - q
            sq(x,y) = 1
        Next
    Next
    For x = 1 To n
        For y = q +1 To n - q
            sq(x, y) Xor= 1
        Next
    Next

    ' fill the square
    q = n * n +1
    For y = 1 To n
        For x = 1 To n
            If sq(x,y) = 0 Then
                sq(x,y) = q - nr
            Else
                sq(x,y) = nr
            End If
            nr += 1
        Next
    Next

    ' check columms and rows
    For y = 1 To n
        nr = 0 : q = 0
        For x = 1 To n
            nr += sq(x,y)
            q += sq(y,x)
        Next
        If nr <> magic_sum Or q <> magic_sum Then
            Err_msg "Error: value <> magic_sum"
            Exit Sub
        End If
    Next

    ' check diagonals
    nr = 0 : q = 0
    For x = 1 To n
        nr += sq(x, x)
        q += sq(n - x +1, n - x +1)
    Next
    If nr <> magic_sum Or q <> magic_sum Then
        Err_msg "Error: value <> magic_sum"
        Exit Sub
    End If

    ' printing square's on screen bigger when
    ' n > 19 results in a wrapping of the line
    Print "Single even magic square size: "; n; "*"; n
    Print "The magic sum = "; magic_sum
    Print
    For y = 1 To n
        For x = 1 To n
            Print Using frmt; sq(x, y);
        Next
        Print
    Next

    ' output magic square to a file with the name provided
    If filename <> "" Then
        nr = FreeFile
        Open filename For Output As #nr
        Print #nr, "Single even magic square size: "; n; "*"; n
        Print #nr, "The magic sum = "; magic_sum
        Print #nr,
        For y = 1 To n
            For x = 1 To n
                Print #nr, Using frmt; sq(x,y);
            Next
            Print #nr,
        Next
        Close #nr
    End If

End Sub

' ------=< MAIN >=------

de_magicsq(8, "magic8de.txt") : Print

' empty keyboard buffer
While Inkey <> "" : Wend
Print : Print "hit any key to end program"
Sleep
End


package main

import (
	"fmt"
	"log"
	"strings"
)

const dimensions int = 8

func setupMagicSquareData(d int) ([][]int, error) {
	var output [][]int
	if d < 4 || d%4 != 0 {
		return [][]int{}, fmt.Errorf("Square dimension must be a positive number which is divisible by 4")
	}
	var bits uint = 0x9669 // 0b1001011001101001
	size := d * d
	mult := d / 4
	for i, r := 0, 0; r < d; r++ {
		output = append(output, []int{})
		for c := 0; c < d; i, c = i+1, c+1 {
			bitPos := c/mult + (r/mult)*4
			if (bits & (1 << uint(bitPos))) != 0 {
				output[r] = append(output[r], i+1)
			} else {
				output[r] = append(output[r], size-i)
			}
		}
	}
	return output, nil
}

func arrayItoa(input []int) []string {
	var output []string
	for _, i := range input {
		output = append(output, fmt.Sprintf("%4d", i))
	}
	return output
}

func main() {
	data, err := setupMagicSquareData(dimensions)
	if err != nil {
		log.Fatal(err)
	}
	magicConstant := (dimensions * (dimensions*dimensions + 1)) / 2
	for _, row := range data {
		fmt.Println(strings.Join(arrayItoa(row), " "))
	}
	fmt.Printf("\nMagic Constant: %d\n", magicConstant)
}


import Data.List (transpose, unfoldr, intercalate)
import Data.List.Split (chunksOf)
import Data.Bool (bool)
import Control.Monad (forM_)

magicSquare :: Int -> [[Int]]
magicSquare n
  | rem n 4 > 0 = []
  | otherwise =
    chunksOf n $ zipWith (flip (bool =<< (-) limit)) series [1 .. sqr]
  where
    sqr = n * n
    limit = sqr + 1
    series
      | isPowerOf 2 n = magicSeries $ floor (logBase 2 (fromIntegral sqr))
      | otherwise =
        concat . concat . concat . scale $ scale <$> chunksOf 4 (magicSeries 4)
      where
        scale = replicate $ quot n 4

magicSeries :: Int -> [Bool]
magicSeries = (iterate ((++) <*> fmap not) [True] !!)

isPowerOf :: Int -> Int -> Bool
isPowerOf k n = until ((0 /=) . flip rem k) (`quot` k) n == 1

-- TEST AND DISPLAY FUNCTIONS --------------------------------------------------
checked :: [[Int]] -> (Int, Bool)
checked square =
  let diagonals =
        fmap (flip (zipWith (!!)) [0 ..]) . ((:) <*> (return . reverse))
      h:t =
        sum <$>
        square ++ -- rows
        transpose square ++ -- cols
        diagonals square -- diagonals
  in (h, all (h ==) t)

table :: String -> [[String]] -> [String]
table delim rows =
  let justifyRight c n s = drop (length s) (replicate n c ++ s)
  in intercalate delim <$>
     transpose
       ((fmap =<< justifyRight ' ' . maximum . fmap length) <$> transpose rows)

main :: IO ()
main =
  forM_ [4, 8, 16] $
  \n -> do
    let test = magicSquare n
    putStrLn $ unlines (table " " (fmap show <$> test))
    print $ checked test
    putStrLn []


public class MagicSquareDoublyEven {

    public static void main(String[] args) {
        int n = 8;
        for (int[] row : magicSquareDoublyEven(n)) {
            for (int x : row)
                System.out.printf("%2s ", x);
            System.out.println();
        }
        System.out.printf("\nMagic constant: %d ", (n * n + 1) * n / 2);
    }

    static int[][] magicSquareDoublyEven(final int n) {
        if (n < 4 || n % 4 != 0)
            throw new IllegalArgumentException("base must be a positive "
                    + "multiple of 4");

        // pattern of count-up vs count-down zones
        int bits = 0b1001_0110_0110_1001;
        int size = n * n;
        int mult = n / 4;  // how many multiples of 4

        int[][] result = new int[n][n];

        for (int r = 0, i = 0; r < n; r++) {
            for (int c = 0; c < n; c++, i++) {
                int bitPos = c / mult + (r / mult) * 4;
                result[r][c] = (bits & (1 << bitPos)) != 0 ? i + 1 : size - i;
            }
        }
        return result;
    }
}


(() => {
    'use strict';

    // doublyEvenMagicSquare :: Int -> [[Int]]
    const doublyEvenMagicSquare = n =>
        0 === n % 4 ? (() => {
            const
                sqr = n * n,
                power = Math.log2(sqr),
                scale = replicate(n / 4);
            return chunksOf(n)(
                map((x, i) => x ? 1 + i : sqr - i)(
                    isInt(power) ? truthSeries(power) : (
                        compose(
                            flatten,
                            scale,
                            map(scale),
                            chunksOf(4)
                        )(truthSeries(4))
                    )
                )
            );
        })() : undefined;

    // truthSeries :: Int -> [Bool]
    const truthSeries = n =>
        0 >= n ? (
            [true]
        ) : (() => {
            const xs = truthSeries(n - 1);
            return xs.concat(xs.map(x => !x));
        })();

    // TEST -----------------------------------------------
    const main = () =>
        // Magic squares of orders 4, 8 and 12, with
        // checks of row, column and diagonal sums.
        intercalate('\n\n')(
            map(n => {
                const
                    lines = doublyEvenMagicSquare(n),
                    sums = map(sum)(
                        lines.concat(
                            transpose(lines)
                            .concat(diagonals(lines))
                        )
                    ),
                    total = sums[0];
                return unlines([
                    "Order: " + str(n),
                    "Summing to: " + str(total),
                    "Row, column and diagonal sums checked: " +
                    str(all(eq(total))(sums)) + '\n',
                    unlines(map(compose(
                        intercalate('  '),
                        map(compose(justifyRight(3)(' '), str))
                    ))(lines))
                ]);
            })([4, 8, 12])
        );

    // GENERIC FUNCTIONS ----------------------------------

    // all :: (a -> Bool) -> [a] -> Bool
    const all = p =>
        // True if p(x) holds for every x in xs.
        xs => xs.every(p);

    // chunksOf :: Int -> [a] -> [[a]]
    const chunksOf = n => xs =>
        enumFromThenTo(0)(n)(
            xs.length - 1
        ).reduce(
            (a, i) => a.concat([xs.slice(i, (n + i))]),
            []
        );

    // compose (<<<) :: (b -> c) -> (a -> b) -> a -> c
    const compose = (...fs) =>
        x => fs.reduceRight((a, f) => f(a), x);

    // diagonals :: [[a]] -> [[a], [a]]
    const diagonals = rows =>
        // Two diagonal sequences,
        // from top left and bottom left
        // respectively, of a given matrix.
        map(flip(zipWith(index))(
            enumFromTo(0)(pred(
                0 < rows.length ? (
                    rows[0].length
                ) : 0
            ))
        ))([rows, reverse(rows)]);

    // enumFromThenTo :: Int -> Int -> Int -> [Int]
    const enumFromThenTo = x1 => x2 => y => {
        const d = x2 - x1;
        return Array.from({
            length: Math.floor(y - x2) / d + 2
        }, (_, i) => x1 + (d * i));
    };

    // enumFromTo :: Int -> Int -> [Int]
    const enumFromTo = m => n =>
        Array.from({
            length: 1 + n - m
        }, (_, i) => m + i);

    // eq (==) :: Eq a => a -> a -> Bool
    const eq = a => b => a === b;

    // flatten :: NestedList a -> [a]
    const flatten = nest => nest.flat(Infinity);

    // flip :: (a -> b -> c) -> b -> a -> c
    const flip = f =>
        x => y => f(y)(x);

    // index (!!) :: [a] -> Int -> a
    const index = xs => i => xs[i];

    // intercalate :: String -> [String] -> String
    const intercalate = s =>
        xs => xs.join(s);

    // isInt :: Int -> Bool
    const isInt = x => x === Math.floor(x);

    // justifyRight :: Int -> Char -> String -> String
    const justifyRight = n => cFiller => s =>
        n > s.length ? (
            s.padStart(n, cFiller)
        ) : s;

    // map :: (a -> b) -> [a] -> [b]
    const map = f => xs =>
        (Array.isArray(xs) ? (
            xs
        ) : xs.split('')).map(f);

    // pred :: Enum a => a -> a
    const pred = x => x - 1;

    // replicate :: Int -> a -> [a]
    const replicate = n => x =>
        Array.from({
            length: n
        }, () => x);

    // reverse :: [a] -> [a]
    const reverse = xs =>
        'string' !== typeof xs ? (
            xs.slice(0).reverse()
        ) : xs.split('').reverse().join('');

    // show :: a -> String
    const show = x => JSON.stringify(x);

    // str :: a -> String
    const str = x => x.toString();

    // sum :: [Num] -> Num
    const sum = xs => xs.reduce((a, x) => a + x, 0);

    // transpose :: [[a]] -> [[a]]
    const transpose = xs =>
        xs[0].map((_, iCol) => xs.map((row) => row[iCol]));

    // unlines :: [String] -> String
    const unlines = xs => xs.join('\n');

    // zipWith :: (a -> b -> c) -> [a] -> [b] -> [c]
    const zipWith = f => xs => ys =>
        xs.slice(
            0, Math.min(xs.length, ys.length)
        ).map((x, i) => f(x)(ys[i]));

    // MAIN ------------------------------------------------
    return main();
})();


def lpad($len):
  def l: tostring | ($len - length) as $l | (" " * $l)[:$l] + .;
  if type == "array" then map(l) else l end;

def magicSquareDoublyEven:
  if . < 4 or .%4 != 0 then "Base must be a positive multiple of 4" | error else . end
  | . as $n
  # pattern of count-up vs count-down zones
  | [1,0,0,1,0,1,1,0,0,1,1,0,1,0,0,1] as $bits
  | ($n * $n) as $size
  | ($n / 4 | floor) as $mult # how many multiples of 4
  | { i:0, result: null }
  | reduce range(0; $n) as $r (.;
      reduce range(0; $n) as $c (.;
         ( (($c/$mult)|floor) + (($r/$mult)|floor) * 4) as $bitPos
         | .result[$r][$c] =
	      (if ($bits[$bitPos] != 0) then .i + 1 else $size - .i end)
         | .i += 1 ) )
  | .result ;

# Input: the order
def task:
  . as $n
  | (.*.|tostring|length+1) as $width
  | (magicSquareDoublyEven[] | lpad($width) | join(" ")),
    "\nMagic constant for order \($n): \(($n*$n + 1) * $n / 2)\n\n" ;

8, 12 | task


using Printf

function magicsquaredoubleeven(order::Int)
    if order % 4 != 0; error("the order must be divisible by 4") end

    sqr = Matrix{Int}(order, order)
    mul = div(order, 4)
    ext = vcat(1:mul, order-mul+1:order)
    isext(i::Int, j::Int) = (i in ext) == (j in ext)
    boolsqr = collect(isext(i, j) for i in 1:order, j in 1:order)
    for i in linearindices(sqr)
        if boolsqr[i]; sqr[i] = i end
        if !boolsqr[end+1-i]; sqr[end+1-i] = i end
    end
    return sqr
end

for n in (4, 8, 12)
    magicconst = div(n ^ 3 + n, 2)
    sq = magicsquaredoubleeven(n)

    println("Order: $n; magic constant: $magicconst.\nSquare:")
    for r in 1:n, c in 1:n
        @printf("%4i", sq[r, c])
        if c == n; println() end
    end
    println()
end


// version 1.1.0

fun magicSquareDoublyEven(n: Int): Array<IntArray> {
    if ( n < 4 || n % 4 != 0)
        throw IllegalArgumentException("Base must be a positive multiple of 4")

    // pattern of count-up vs count-down zones
    val bits = 0b1001_0110_0110_1001
    val size = n * n
    val mult = n / 4  // how many multiples of 4
    val result = Array(n) { IntArray(n) }
    var i = 0
    for (r in 0 until n)
        for (c in 0 until n) {
            val bitPos = c / mult + r / mult * 4
            result[r][c] =  if (bits and (1 shl bitPos) != 0) i + 1 else size - i
            i++
        }
    return result
}

fun main(args: Array<String>) {
    val n = 8
    for (ia in magicSquareDoublyEven(n)) {
        for (i in ia) print("%2d  ".format(i))
        println()
    }
    println("\nMagic constant ${(n * n + 1) * n / 2}")
}


import bitops, sequtils, strutils

type Square = seq[seq[int]]

func magicSquareDoublyEven(n: int): Square =
  ## Build a magic square of doubly even order.

  assert n >= 4 and (n and 3) == 0, "base must be a positive multiple of 4."
  result = newSeqWith(n, newSeq[int](n))

  const bits = 0b1001_0110_0110_1001  # Pattern of count-up vs count-down zones.
  let size = n * n
  let mult = n div 4                  # How many multiples of 4.

  var i = 0
  for r in 0..<n:
    for c in 0..<n:
      let bitPos = c div mult + r div mult * 4
      result[r][c] = if bits.testBit(bitPos): i + 1 else: size - i
      inc i

func `$`(square: Square): string =
  ## Return the string representation of a magic square.
  let length = len($(square.len * square.len))
  for row in square:
    result.add row.mapIt(($it).align(length)).join(" ") & '\n'

when isMainModule:
  let n = 8
  echo magicSquareDoublyEven(n)
  echo "Magic constant = ", n * (n * n + 1) div 2


with javascript_semantics
constant t = {{1,1,0,0},
              {1,1,0,0},
              {0,0,1,1},
              {0,0,1,1}}

function magic_square(integer n)
    if n<4 or mod(n,4)!=0 then return false end if
    sequence square = repeat(repeat(0,n),n)
    integer i = 0
    for r=1 to n do
        for c=1 to n do
            square[r,c] = iff(t[mod(r,4)+1,mod(c,4)+1]?i+1:n*n-i)
            i += 1
        end for
    end for
    return square
end function

procedure check(sequence sq)
    integer n = length(sq)
    integer magic = n*(n*n+1)/2
    integer bd = 0, fd = 0
    for i=1 to length(sq) do
        if sum(sq[i])!=magic then ?9/0 end if
        if sum(columnize(sq,i))!=magic then ?9/0 end if
        bd += sq[i,i]
        fd += sq[n-i+1,n-i+1]
    end for
    if bd!=magic or fd!=magic then ?9/0 end if
end procedure

--for i=4 to 16 by 4 do
for i=8 to 8 by 4 do
    sequence square = magic_square(i)
    printf(1,"maqic square of order %d, sum: %d\n", {i,sum(square[i])})
    string fmt = sprintf("%%%dd",length(sprintf("%d",i*i)))
    pp(square,{pp_Nest,1,pp_IntFmt,fmt,pp_StrFmt,3,pp_IntCh,false,pp_Pause,0})
    check(square)
end for


Procedure.i MagicN(n.i)
  ProcedureReturn n*(n*n+1)/2
EndProcedure

Procedure.i MaxN(mx.i,n.i)
  If mx>n : ProcedureReturn mx : Else : ProcedureReturn n : EndIf
EndProcedure

Procedure.i MaxL(mx.i)
  Define.i i
  While mx
    mx/10 : i+1
  Wend
  ProcedureReturn i
EndProcedure

Procedure.b DblEvenMagicSquare(n.i)
  Define.i q=n/4, nr=1, x, y, max, spc
  Dim sq.i(n,n)

  For y=1 To n
    For x=q+1 To n-q
      sq(x,y)=1
    Next
  Next

  For x=1 To n
    For y=q+1 To n-q
      sq(x,y) ! 1
    Next
  Next

  q=n*n+1
  For y=1 To n
    For x=1 To n
      If sq(x,y)=0
        sq(x,y)=q-nr
      Else
        sq(x,y)=nr
      EndIf
      nr+1
      max=MaxN(max,sq(x,y))
    Next
  Next

  spc=MaxL(max)+1
  For y=n To 1 Step -1
    For x=n To 1 Step -1
      Print(RSet(Str(sq(x,y)),spc," "))
    Next
    PrintN("")
  Next

EndProcedure

OpenConsole("Magic-Square-Doubly-Even")
Define.i n

Repeat
  PrintN("Input [4,8,12..n] (0=Exit)")
  While (n<4) Or (n%4)
    Print(">") : n=Val(Input())
    If n=0 : End : EndIf
  Wend
  PrintN("The magic sum = "+Str(MagicN(n)))
  DblEvenMagicSquare(n)
  n=0
ForEver


def MagicSquareDoublyEven(order):
    sq = [range(1+n*order,order + (n*order)+1) for n in range(order) ]
    n1 = order/4
    for r in range(n1):
        r1 = sq[r][n1:-n1]
        r2 = sq[order -r - 1][n1:-n1]
        r1.reverse()
        r2.reverse()
        sq[r][n1:-n1] = r2
        sq[order -r - 1][n1:-n1] = r1
    for r in range(n1, order-n1):
        r1 = sq[r][:n1]
        r2 = sq[order -r - 1][order-n1:]
        r1.reverse()
        r2.reverse()
        sq[r][:n1] = r2
        sq[order -r - 1][order-n1:] = r1
    return sq

def printsq(s):
    n = len(s)
    bl = len(str(n**2))+1
    for i in range(n):
        print ''.join( [ ("%"+str(bl)+"s")%(str(x)) for x in s[i]] )
    print "\nMagic constant = %d"%sum(s[0])

printsq(MagicSquareDoublyEven(8))


/*REXX program constructs a  magic square  of doubly even sides (a size divisible by 4).*/
n= 8;   s= n%4;   L= n%2-s+1;    w= length(n**2) /*size; small sq;  low middle;  # width*/
@.= 0;            H= n%2+s                       /*array default;  high middle.         */
call gen                                         /*generate a grid in numerical order.  */
call diag                                        /*mark numbers on both diagonals.      */
call corn                                        /*  "     "    in small corner boxen.  */
call midd                                        /*  "     "    in  the middle    "     */
call swap                                        /*swap positive numbers with highest #.*/
call show                                        /*display the doubly even magic square.*/
call sum                                         /*   "     "  magic number for square. */
exit                                             /*stick a fork in it,  we're all done. */
/*──────────────────────────────────────────────────────────────────────────────────────*/
o:    parse arg ?;             return n-?+1      /*calculate the "other" (right) column.*/
@:    parse arg x,y;           return abs(@.x.y)
diag:      do r=1 for n;  @.r.[email protected](r,r); o=o(r);  @.r.[email protected](r,o);  end;              return
midd:      do r=L  to H;  do c=L  to H;  @.r.[email protected](r,c);           end;  end;        return
gen:  #=0; do r=1 for n;  do c=1  for n; #=#+1;   @.r.c=#;        end;  end;        return
show: #=0; do r=1 for n;  $=; do c=1  for n; $=$ right(@(r,c),w); end;  say $; end; return
sum:  #=0; do r=1 for n;  #=#[email protected](r,1);  end;  say;  say 'The magic number is: '   #; return
max#:      do a=n for n  by -1;  do b=n  for n  by -1;  if @.a.b>0  then return; end;  end
/*──────────────────────────────────────────────────────────────────────────────────────*/
swap:         do   r=1  for n
                do c=1  for n;  if @.r.c<0  then iterate;  call max#  /*find max number.*/
                parse value  [email protected].a.b  ([email protected].r.c)    with    @.r.c  @.a.b /*swap two values.*/
                end   /*c*/
              end     /*r*/;                       return
/*──────────────────────────────────────────────────────────────────────────────────────*/
corn:         do   r=1  for n;  if r>s & r<=n-s  then iterate   /*"corner boxen", size≡S*/
                do c=1  for n;  if c>s & c<=n-s  then iterate;  @.r.c= [email protected](r,c)  /*negate*/
                end   /*c*/
              end     /*r*/;                       return


def double_even_magic_square(n)
  raise ArgumentError, "Need multiple of four" if n%4 > 0
  block_size, max = n/4, n*n
  pre_pat = [true, false, false, true,
             false, true, true, false]
  pre_pat += pre_pat.reverse
  pattern = pre_pat.flat_map{|b| [b] * block_size} * block_size
  flat_ar = pattern.each_with_index.map{|yes, num| yes ? num+1 : max-num}
  flat_ar.each_slice(n).to_a
end

def to_string(square)
  n = square.size
  fmt = "%#{(n*n).to_s.size + 1}d" * n
  square.inject(""){|str,row| str << fmt % row << "\n"}
end

puts to_string(double_even_magic_square(8))


use std::env;

fn main() {
    let n: usize = match env::args()
        .nth(1)
        .and_then(|arg| arg.parse().ok())
        .ok_or("Please specify the size of the magic square, as a positive multiple of 4.")
    {
        Ok(arg) if arg >= 4 && arg % 4 == 0 => arg,
        Err(e) => panic!(e),
        _ => panic!("Argument must be a positive multiple of 4."),
    };

    let mc = (n * n + 1) * n / 2;
    println!("Magic constant: {}\n", mc);
    let bits = 0b1001_0110_0110_1001u32;
    let size = n * n;
    let width = size.to_string().len() + 1;
    let mult = n / 4;
    let mut i = 0;
    for r in 0..n {
        for c in 0..n {
            let bit_pos = c / mult + (r / mult) * 4;
            print!(
                "{e:>w$}",
                e = if bits & (1 << bit_pos) != 0 {
                    i + 1
                } else {
                    size - i
                },
                w = width
            );
            i += 1;
        }
        println!();
    }
}


object MagicSquareDoublyEven extends App {
  private val n = 8

  private def magicSquareDoublyEven(n: Int): Array[Array[Int]] = {
    require(n >= 4 || n % 4 == 0, "Base must be a positive multiple of 4.")

    // pattern of count-up vs count-down zones
    val (bits, mult, result, size) = (38505, n / 4, Array.ofDim[Int](n, n), n * n)
    var i = 0

    for (r <- result.indices; c <- result(0).indices) {
      def bitPos = c / mult + (r / mult) * 4

      result(r)(c) = if ((bits & (1 << bitPos)) != 0) i + 1 else size - i
      i += 1
    }
    result
  }

  magicSquareDoublyEven(n).foreach(row => println(row.map(x => f"$x%2s ").mkString))
  println(f"---%nMagic constant: ${(n * n + 1) * n / 2}%d")

}


func double_even_magic_square(n) {
    assert(n%4 == 0, "Need multiple of four")
    var (bsize, max) = (n/4, n*n)
    var pre_pat = [true, false, false, true,
                   false, true, true, false]
    pre_pat += pre_pat.flip
    var pattern = (pre_pat.map{|b| bsize.of(b)... } * bsize)
    pattern.map_kv{|k,v| v ? k+1 : max-k }.slices(n)
}

func format_matrix(a) {
    var fmt = "%#{a.len**2 -> len}s"
    a.map { .map { fmt % _ }.join(' ') }.join("\n")
}

say format_matrix(double_even_magic_square(8))


' Magic squares of doubly even order
n=8  'multiple of 4
pattern="1001011001101001"
size=n*n: w=len(size)
mult=n\4  'how many multiples of 4
wscript.echo "Magic square : " & n & " x " & n
i=0
For r=0 To n-1
	l=""
	For c=0 To n-1
		bit=Mid(pattern, c\mult+(r\mult)*4+1, 1)
		If bit="1" Then t=i+1 Else t=size-i
		l=l & Right(Space(w) & t, w) & " "
		i=i+1
	Next 'c
	wscript.echo l
Next 'r
wscript.echo "Magic constant=" & (n*n+1)*n/2


Module MagicSquares

    Function MagicSquareDoublyEven(n As Integer) As Integer(,)
        If n < 4 OrElse n Mod 4 <> 0 Then
            Throw New ArgumentException("base must be a positive multiple of 4")
        End If

        'pattern of count-up vs count-down zones
        Dim bits = Convert.ToInt32("1001011001101001", 2)
        Dim size = n * n
        Dim mult As Integer = n / 4 ' how many multiples of 4

        Dim result(n - 1, n - 1) As Integer

        Dim i = 0
        For r = 0 To n - 1
            For c = 0 To n - 1
                Dim bitPos As Integer = Math.Floor(c / mult) + Math.Floor(r / mult) * 4
                Dim test = (bits And (1 << bitPos)) <> 0
                If test Then
                    result(r, c) = i + 1
                Else
                    result(r, c) = size - i
                End If

                i = i + 1
            Next
            Console.WriteLine()
        Next

        Return result
    End Function

    Sub Main()
        Dim n = 8
        Dim result = MagicSquareDoublyEven(n)
        For i = 0 To result.GetLength(0) - 1
            For j = 0 To result.GetLength(1) - 1
                Console.Write("{0,2} ", result(i, j))
            Next
            Console.WriteLine()
        Next
        Console.WriteLine()
        Console.WriteLine("Magic constant: {0} ", (n * n + 1) * n / 2)

        Console.ReadLine()
    End Sub

End Module


import "/fmt" for Conv, Fmt

var magicSquareDoublyEven = Fn.new { |n|
    if (n < 4 || n%4 != 0) Fiber.abort("Base must be a positive multiple of 4")

    // pattern of count-up vs count-down zones
    var bits = Conv.atoi("1001011001101001", 2)
    var size = n * n
    var mult = (n/4).floor // how many multiples of 4
    var result = List.filled(n, null)
    for (i in 0...n) result[i] = List.filled(n, 0)
    var i = 0
    for (r in 0...n) {
        for (c in 0...n) {
            var bitPos = (c/mult).floor + (r/mult).floor * 4
            result[r][c] = ((bits & (1<<bitPos)) != 0) ? i + 1 : size - i
            i = i + 1
        }
    }
    return result
}

var n = 8
for (ia in magicSquareDoublyEven.call(n)) {
    for (i in ia) Fmt.write("$2d  ", i)
    System.print()
}
System.print("\nMagic constant %((n * n + 1) * n / 2)")


class MagicSquareDoublyEven{
   fcn init(n){ var result=magicSquareDoublyEven(n) }
   fcn toString{
      sink,n:=Sink(String),result.len();  // num collumns
      fmt:="%2s ";
      foreach row in (result)
         { sink.write(row.apply('wrap(n){ fmt.fmt(n) }).concat(),"\n") }
      sink.write("\nMagic constant: %d".fmt((n*n + 1)*n/2));
      sink.close();
   }
   fcn magicSquareDoublyEven(n){
      if (n<4 or n%4!=0 or n>16)
	 throw(Exception.ValueError("base must be a positive multiple of 4"));
      bits,size,mult:=0b1001011001101001, n*n, n/4;
      result:=n.pump(List(),n.pump(List(),0).copy);  // array[n,n] of zero

      foreach i in (size){
	 bitsPos:=(i%n)/mult + (i/(n*mult)*4);
	 value:=(bits.bitAnd((2).pow(bitsPos))) and i+1 or size-i;
	 result[i/n][i%n]=value;
      }
      result;
   }
}
MagicSquareDoublyEven(8).println();


V s = [‘It is certain’, ‘It is decidedly so’, ‘Without a doubt’, ‘Yes, definitely’,
 ‘You may rely on it’, ‘As I see it, yes’, ‘Most likely’, ‘Outlook good’,
 ‘Signs point to yes’, ‘Yes’, ‘Reply hazy, try again’, ‘Ask again later’,
 ‘Better not tell you now’, ‘Cannot predict now’, ‘Concentrate and ask again’,
 ‘Don't bet on it’, ‘My reply is no’, ‘My sources say no’, ‘Outlook not so good’,
 ‘Very doubtful’]

Set[String] qs

L
   V question = input(‘Ask your question:’)
   I question.empty
      L.break

   V answer = random:choice(s)

   I question C qs
      print(‘Your question has already been answered’)
   E
      qs.add(question)
      print(answer)


bdos:		equ	5	; CP/M calls
puts:		equ	9
gets: 		equ	10
		org	100h
		lxi	d,message	; Print message
		mvi	c,puts
		call	bdos
question:	lxi	d,prompt	; Ask for question
		mvi	c,puts
		call	bdos
		lxi	d,bufdef	; Read answer
		mvi	c,gets
		call	bdos
		lxi	d,newline	; Print newline
		mvi	c,puts
		call	bdos
		lxi	h,buf		; XOR the question w/ the RNG state
		mvi	b,20
xorouter:	lxi	d,xabcdat + 1
		mvi	c,3
xorinner:	ldax	d
		xra	m
		stax	d
		inx	d
		inx	h
		dcr	c
		jnz	xorinner
		dcr	b
		jnz	xorouter
getrnd:		call	xabcrand	; Generate random number <20
		ani	1fh
		cpi	20
		jnc	getrnd
		inr	a
		mov	b,a		; That is the number of the message
		lxi	h,responses	; Skip that many strings
		mvi	a,'$'
skipstring:	cmp	m
		inx	h
		jnz	skipstring
		dcr	b
		jnz	skipstring
		xchg			; Print the chosen string
		mvi	c,puts
		call	bdos
		jmp	question	; Get another question
		;; RNG to make it a little less predictable
xabcrand:       lxi     h,xabcdat
                inr     m       ; X++
                mov     a,m     ; X,
                inx     h       ;
                xra     m       ; ^ C,
                inx     h       ;
                xra     m       ; ^ A,
                mov     m,a     ; -> A
                inx     h
                add     m       ; + B,
                mov     m,a     ; -> B
                rar             ; >>1
                dcx     h
                xra     m       ; ^ A,
                dcx     h
                add     m       ; + C
                mov     m,a     ; -> C
                ret
		;; Strings
message:	db	'Magic 8 Ball$'
newline:	db	13,10,'$'
prompt:		db	13,10,13,10,'What is your question? '
		;; The possible responses
responses:	db	'$It is certain$It is decidedly so$Without a doubt$'
		db	'Yes, definitely$You may rely on it$As I see it, yes$'
		db	'Most likely$Outlook good$Signs point to yes$Yes$'
		db	'Reply hazy, try again$Ask again later$'
		db	'Better not tell you now$Cannot predict now$'
		db	'Concentrate and ask again$Don',39,'t bet on it$'
		db	'My reply is no$My sources say no$Outlook not so good$'
		db	'Very doubtful$'
		;; Variables
bufdef:		db	60,0		; 60 = 20*3
buf:		equ 	$		; question will be XOR'ed with the RNG state
xabcdat:	equ	buf + 60 	; Point RNG data into uninitialized memory,
					; to make it more exciting.


.model small
.stack 1024

.data
UserRam BYTE 256 DUP(0)
xorshift32_state_lo equ UserRam
xorshift32_state_hi equ UserRam+2

Ans0 byte "It is certain.",0
Ans1 byte "It is decidedly so.",0
Ans2 byte "Signs point to yes.",0
Ans3 byte "You can rely on it.",0
Ans4 byte "Most likely.",0
Ans5 byte "Cannot predict now.",0
Ans6 byte "Reply hazy, try again.",0
Ans7 byte "Outlook not so good.",0
Ans8 byte "My sources say no.",0
Ans9 byte "Very doubtful.",0
AnsA byte "Without a doubt.",0
AnsB byte "Outlook good.",0
AnsC byte "Ask again later.",0
AnsD byte "Better not tell you now.",0
AnsE byte "Don't count on it.",0
AnsF byte "Yes.",0

AnswerLookup word Ans0,Ans1,Ans2,Ans3,Ans4,Ans5,Ans6,Ans7
	     word Ans8,Ans9,AnsA,AnsB,AnsC,AnsD,AnsE,AnsF
.code

start:

	mov ax,@data
	mov ds,ax

	mov ax,@code
	mov es,ax

	CLD	;have LODSB,MOVSB,STOSB,etc. auto-increment

	mov ax,03h
	int 10h        ;sets video mode to MS-DOS text mode. Which the program is already in, so this just clears the screen.

	mov ah,2Ch
	int 21h         ;returns hour:minute in cx, second:100ths of second in dx
        mov word ptr [ds:xorshift32_state_lo],dx
        mov word ptr [ds:xorshift32_state_hi],cx

	call doXorshift32 ;uses the above memory locations as input. Do it three times just to mix it up some more
	call doXorshift32
	call doXorshift32

	mov ax,word ptr[ds:xorshift32_state_lo] ;get the random output from the RNG
	and al,0Fh
	;keep only the bottom nibble of al, there are only 16 possible messages.
	mov bx,offset AnswerLookup
	call XLATW
	;translates AX using a table of words as a lookup table.
	mov si,ax         ;use this looked-up value as the source index for our text.
	call PrintString  ;print to the screen

	mov ax,4C00h
	int 21h        ;return to DOS

XLATW:
;input: ds:bx = the table you wish to look up
;AL= the raw index into this table as if it were byte data.
;So don't left shift prior to calling this.
;AH is destroyed.
		SHL AL,1
		mov ah,al	;copy AL to AH
		XLAT		;returns low byte in al
		inc ah
		xchg al,ah	;XLAT only works with AL
		XLAT		;returns high byte in al (old ah)
		xchg al,ah
		;now the word is loaded into ax, big-endian.
		ret


PROC Main()
  DEFINE PTR="CARD"
  DEFINE COUNT="20"
  CHAR ARRAY s(256)
  PTR ARRAY a(COUNT)
  BYTE i

  a(0)="It is certain."
  a(1)="It is decidedly so."
  a(2)="Without a doubt."
  a(3)="Yes - definitely."
  a(4)="You may rely on it."
  a(5)="As I see it, yes."
  a(6)="Most likely."
  a(7)="Outlook good."
  a(8)="Yes."
  a(9)="Signs point to yes."
  a(10)="Reply hazy, try again."
  a(11)="Ask again later."
  a(12)="Better not tell you now."
  a(13)="Cannot predict now."
  a(14)="Concentrate and ask again."
  a(15)="Don't count on it."
  a(16)="My reply is no."
  a(17)="My sources say no."
  a(18)="Outlook not so good."
  a(19)="Very doubtful."

  DO
    PrintE("Enter your question or blank to exit:")
    InputS(s)
    IF s(0)=0 THEN
      EXIT
    FI
    i=Rand(COUNT)
    PrintE(a(i))
    PutE()
  OD
RETURN


with Ada.Text_IO;  use Ada.Text_IO;
with Ada.Strings; use Ada.Strings;
with Ada.Numerics.Discrete_Random;

procedure Main is

   --Creation of type with all the possible answers
   --
   type Possible_Answers_Type is (It_Is_Certain, It_Is_Decidedly_So, Without_A_Doubt,
				  Yes_Definitely, You_May_Rely_On_It, As_I_See_It, Yes_Most_Likely,
				  Outlook_Good, Signs_Point_To_Yes, Yes_Reply_Hazy,
				  Try_Again, Ask_Again_Later, Better_Not_Tell_You_Now,
				  Cannot_Predict_Now, Concentrate_And_Ask_Again,
				  Dont_Bet_On_It, My_Reply_Is_No, My_Sources_Say_No,
				  Outlook_Not_So_Good, Very_Doubtful);
   ---------------------------------------------------------------------

   -- Variable declaration
   Answer           : Possible_Answers_Type := Possible_Answers_Type'First;
   User_Question : String := " ";

   -----------------------------------------------------------------------------

   --Randomizer
   --
   package Random_Answer is new Ada.Numerics.Discrete_Random (Possible_Answers_Type);
   use Random_Answer;
   G : Generator;

begin

   Reset (G); -- Starts the generator in a unique state in each run

   --User get provides question
   Put_Line ("Welcome."); New_Line;

   Put_Line ("WARNING!!!  Please remember that there's no need to shake your device for this program to work, and shaking your device could damage it");
   New_Line;

   Put_Line ("What's your question? ");
   Get (Item => User_Question); New_Line;

   --Output Answer
   Answer := (Random (G)); --Assigns random answer to variable Answer

   Put (Answer'Image); --Prints Answer

end Main;


BEGIN
  []STRING answers = ("It is certain.", "It is decidedly so.",
                      "Without a doubt.", "Yes - definitely.", "You may rely on it.",
                      "As I see it, yes.", "Most likely.", "Outlook good.",
                      "Yes.", "Signs point to yes.", "Reply hazy, try again.",
                      "Ask again later.", "Better not tell you now.", "Cannot predict now.",
                      "Concentrate and ask again.", "Don't count on it.", "My reply is no.",
                      "My sources say no.", "Outlook not so good.", "Very doubtful.");
  DO
    REF STRING question := LOC STRING;
    print("Your question: ");
    read((question, new line));
    print((answers[ENTIER (random * UPB answers) + 1], new line))
  OD
END


 set the answers to {"It is certain", "It is decidedly so", "Without a doubt", "Yes, definitely", "You may rely on it", "As I see it, yes", "Most likely", "Outlook good", "Signs point to yes", "Yes", "Reply hazy, try again", "Ask again later", "Better not tell you now", "Cannot predict now", "Concentrate and ask again", "Don't bet on it", "My reply is no", "My sources say no", "Outlook not so good", "Very doubtful"}

display dialog some item of the answers


answers: [
    "It is certain" "It is decidedly so" "Without a doubt"
    "Yes, definitely" "You may rely on it" "As I see it, yes"
    "Most likely" "Outlook good" "Signs point to yes" "Yes"
    "Reply hazy, try again" "Ask again later"
    "Better not tell you now" "Cannot predict now"
    "Concentrate and ask again" "Don't bet on it"
    "My reply is no" "My sources say no" "Outlook not so good"
    "Very doubtful"
]

while ø [
    input "Ask a question: "
    print sample answers
]


answers := [
(join
"It is certain", "It is decidedly so", "Without a doubt","Yes, definitely",
"You may rely on it", "As I see it, yes","Most likely", "Outlook good",
"Signs point to yes", "Yes","Reply hazy, try again", "Ask again later",
"Better not tell you now", "Cannot predict now","Concentrate and ask again",
"Don't bet on it","My reply is no", "My sources say no", "Outlook not so good",
"Very doubtful"
)]
Ask:
InputBox, Question, Magic 8-Ball, Please ask your question or a blank line to quit.,,, 130
Random, rnd, 1, 20
if !question
	ExitApp
MsgBox % answers[rnd]
gosub, Ask
return


# syntax: GAWK -f MAGIC_8-BALL.AWK
BEGIN {
# Ten answers are affirmative, five are non-committal, and five are negative.
    arr[++i] = "It is certain"
    arr[++i] = "It is decidedly so"
    arr[++i] = "Without a doubt"
    arr[++i] = "Yes, definitely"
    arr[++i] = "You may rely on it"
    arr[++i] = "As I see it, yes"
    arr[++i] = "Most likely"
    arr[++i] = "Outlook good"
    arr[++i] = "Signs point to yes"
    arr[++i] = "Yes"
    arr[++i] = "Reply hazy, try again"
    arr[++i] = "Ask again later"
    arr[++i] = "Better not tell you now"
    arr[++i] = "Cannot predict now"
    arr[++i] = "Concentrate and ask again"
    arr[++i] = "Don't bet on it"
    arr[++i] = "My reply is no"
    arr[++i] = "My sources say no"
    arr[++i] = "Outlook not so good"
    arr[++i] = "Very doubtful"
    srand()
    printf("Please enter your question or a blank line to quit.\n")
    while (1) {
      printf("\n? ")
      getline ans
      if (ans ~ /^ *$/) {
        break
      }
      printf("%s\n",arr[int(rand()*i)+1])
    }
    exit(0)
}


dim answer$(20)
answer$[0] = "It is certain."
answer$[1] = "It is decidedly so."
answer$[2] = "Without a doubt."
answer$[3] = "Yes - definitely."
answer$[4] = "You may rely on it."
answer$[5] = "As I see it, yes."
answer$[6] = "Most likely."
answer$[7] = "Outlook good."
answer$[8] = "Yes."
answer$[9] = "Signs point to yes."
answer$[10] = "Reply hazy, try again."
answer$[11] = "Ask again later."
answer$[12] = "Better not tell you now."
answer$[13] = "Cannot predict now."
answer$[14] = "Concentrate and ask again."
answer$[15] = "Don't count on it."
answer$[16] = "My reply is no."
answer$[17] = "My sources say no."
answer$[18] = "Outlook not so good."
answer$[19] = "Very doubtful."

print "Q to quit."
while True
	input string "What would you like to know? ", question$
	if upper(question$) = "Q" then exit while
	print answer$[int(rand * answer$[?])]
	print
end while
end


#include <stdio.h>
#include <stdlib.h>
#include <time.h>

int main() {
    char *question = NULL;
    size_t len = 0;
    ssize_t read;
    const char* answers[20] = {
        "It is certain", "It is decidedly so", "Without a doubt",
        "Yes, definitely", "You may rely on it", "As I see it, yes",
        "Most likely", "Outlook good", "Signs point to yes", "Yes",
        "Reply hazy, try again", "Ask again later",
        "Better not tell you now", "Cannot predict now",
        "Concentrate and ask again", "Don't bet on it",
        "My reply is no", "My sources say no", "Outlook not so good",
        "Very doubtful"
    };
    srand(time(NULL));
    printf("Please enter your question or a blank line to quit.\n");
    while (1) {
        printf("\n? : ");
        read = getline(&question, &len, stdin);
        if (read < 2) break;
        printf("\n%s\n", answers[rand() % 20]);
    }
    if (question) free(question);
    return 0;
}


#include <array>
#include <cstdlib>
#include <ctime>
#include <iostream>
#include <string>

int main()
{
    constexpr std::array<const char*, 20> answers = {
        "It is certain.",
        "It is decidedly so.",
        "Without a doubt.",
        "Yes - definitely.",
        "You may rely on it.",
        "As I see it, yes.",
        "Most likely.",
        "Outlook good.",
        "Yes.",
        "Signs point to yes.",
        "Reply hazy, try again.",
        "Ask again later.",
        "Better not tell you now.",
        "Cannot predict now.",
        "Concentrate and ask again.",
        "Don't count on it.",
        "My reply is no.",
        "My sources say no.",
        "Outlook not so good.",
        "Very doubtful."
    };

    std::string input;
    std::srand(std::time(nullptr));
    while (true) {
        std::cout << "\n? : ";
        std::getline(std::cin, input);

        if (input.empty()) {
            break;
        }

        std::cout << answers[std::rand() % answers.size()] << '\n';
    }
}


using System;

namespace newProg
{

    class Program
    {
        static void Main(string[] args)
        {
            string[] answers =
            {
                "It is certain.",
                "It is decidedly so.",
                "Without a doubt.",
                "Yes – definitely.",
                "You may rely on it.",
                "As I see it, yes.",
                "Most likely.",
                "Outlook good.",
                "Yes.",
                "Signs point to yes.",
                "Reply hazy, try again.",
                "Ask again later",
                "Better not tell you now.",
                "Cannot predict now.",
                "Concentrate and ask again.",
                "Don't count on it.",
                "My reply is no.",
                "My sources say no.",
                "Outlook not so good.",
                "Very doubtful."
            };

            while (true)
            {
                Random rnd = new Random();
                int result = rnd.Next(0, 19);

                Console.WriteLine("Magic 8 Ball! Ask question and hit a key for the answer!");

                string inp = Console.ReadLine();

                Console.WriteLine(answers[result]);

            }
        }
    }
}


#!/var/cfengine/bin/cf-agent --no-lock
bundle agent __main__
{
  methods: "rosettacode_org:magic_8_ball";
}
body file control
{
      namespace => "rosettacode_org";
}
bundle agent magic_8_ball
{
  vars:
      "_responses"
        slist => {
                   "It is certain", "It is decidedly so", "Without a doubt",
                   "Yes definitely", "You may rely on it", "As I see it yes",
                   "Most likely", "Outlook good", "Signs point to yes", "Yes",
                   "Reply hazy try again", "Ask again later",
                   "Better not tell you now", "Cannot predict now",
                   "Concentrate and ask again", "Don't bet on it",
                   "My reply is no", "My sources say no", "Outlook not so good",
                   "Very doubtful",
        };
      "_selected_response"
        int => randomint( 0, length( _responses) ),
        unless => isvariable( "$(this.namespace):$(this.promiser)" );

      "_consideration_time"
        int => randomint( 3, 5),
        unless => isvariable( "$(this.namespace):$(this.promiser)" );

  commands:
      "/bin/sleep $(_consideration_time)"
        inform => "false",
        handle => "consider",
        depends_on => { "think" },
        comment => "This magic 8 ball takes a few seconds to consider the answer
                    after you bring your question to mind.";

  reports:
      "Think about your question ..."
        handle => "think";

      "Response: $(with)"
        with => nth( _responses, $(_selected_response) ),
        depends_on => { "consider" };
}


(def responses
  ["It is certain" "It is decidedly so" "Without a doubt"
  "Yes, definitely" "You may rely on it" "As I see it, yes"
  "Most likely" "Outlook good" "Signs point to yes" "Yes"
  "Reply hazy, try again" "Ask again later"
  "Better not tell you now" "Cannot predict now"
  "Concentrate and ask again" "Don't bet on it"
  "My reply is no" "My sources say no" "Outlook not so good"
  "Very doubtful"])

(do
  (println "Ask a question.  ")
  (read-line)
  (println (rand-nth responses)))


CMAKE_MINIMUM_REQUIRED(VERSION 3.6)

PROJECT(EightBall)

SET(CMAKE_DISABLE_SOURCE_CHANGES ON)
SET(CMAKE_DISABLE_IN_SOURCE_BUILD ON)

LIST(APPEND RESPONSES "It is certain." "It is decidedly so." "Without a doubt.")
LIST(APPEND RESPONSES "Yes - definitely." "You may rely on it.")
LIST(APPEND RESPONSES "As I see it yes." "Most likely." "Outlook good.")
LIST(APPEND RESPONSES "Yes." "Signs point to yes." "Reply hazy try again.")
LIST(APPEND RESPONSES "Ask again later." "Better not tell you now.")
LIST(APPEND RESPONSES "Cannot predict now." "Concentrate and ask again.")
LIST(APPEND RESPONSES "Don't count on it." "My reply is no.")
LIST(APPEND RESPONSES "My sources say no." "Outlook not so good." "Very doubtful.")

FUNCTION(RANDOM_RESPONSE)
    STRING(RANDOM LENGTH 1 ALPHABET 01 TENS)
    STRING(RANDOM LENGTH 1 ALPHABET 0123456789 UNITS)
    MATH(EXPR INDEX "${TENS}${UNITS}")
    LIST(GET RESPONSES ${INDEX} RESPONSE)
    MESSAGE(STATUS "Question: ${QUESTION}")
    MESSAGE(STATUS "Response: ${RESPONSE}")
ENDFUNCTION(RANDOM_RESPONSE)

OPTION(QUESTION "User's input question" "")

MESSAGE("===================== 8 Ball =====================")
IF(NOT QUESTION)
    MESSAGE(STATUS "Welcome to 8 ball! Please provide a question ")
    MESSAGE(STATUS "using the flag -DQUESTION=\"my question\"")
ELSE()
    RANDOM_RESPONSE()
ENDIF()
MESSAGE("==================================================")

ADD_CUSTOM_TARGET(${PROJECT_NAME} ALL)


10 dim f$(19):for i=0 to 19:read f$(i):next
20 print chr$(147);chr$(14)
30 print "Press any key to reveal your fortune."
40 print:print "Press Q to quit.":print
50 fo=int(rnd(1)*20):get k$:if k$="" then 50
60 if k$="q" then print "Good luck!":end
70 print "Your fortune reads:"
80 print spc(5);f$(fo):print
90 print "Again? (Y/N)"
100 get k$:if k$="" then 100
110 if k$="y" then goto 20
120 end
1000 data "It is certain.","It is decidedly so."
1010 data "Without a doubt.","Yes – definitely."
1020 data "You may rely on it.","As I see it, yes."
1030 data "Most likely.","Outlook good.","Yes."
1040 data "Signs point to yes.","Reply hazy, try again."
1050 data "Ask again later.","Better not tell you now."
1060 data "Cannot predict now.","Concentrate and ask again."
1070 data "Don't count on it.","My reply is no."
1080 data "My sources say no.","Outlook not so good."
1090 data "Very doubtful."


import std.random, std.stdio, std.string;

const string[] responses = ["It is certain", "It is decidedly so",
                            "Without a doubt", "Yes, definitely",
                            "You may rely on it", "As I see it, yes",
                            "Most likely", "Outlook good", "Signs point to yes",
                            "Yes", "Reply hazy, try again", "Ask again later",
                            "Better not tell you now", "Cannot predict now",
                            "Concentrate and ask again", "Don't bet on it",
                            "My reply is no", "My sources say no",
                            "Outlook not so good", "Very doubtful"];

void main()
{
    string question = "";
    auto rnd = Random(unpredictableSeed);
    int index = -1;

    writeln("Welcome to 8 ball! Please enter your question to ");
    write("find the answers you seek.");
    write("Type 'quit' to exit.", "\n\n");

    while(true)
    {
        write("Question: ");
        question = stdin.readln();
        if(strip(question) == "quit")
        {
            break;
        }
        write("Response: ");
        index = uniform(0, 20, rnd);
        write(responses[index], "\n\n");
    }
}


program Magic_8_ball;

{$APPTYPE CONSOLE}

uses
  System.SysUtils,
  windows;

// https://stackoverflow.com/questions/29794559/delphi-console-xe7-clearscreen
procedure ClearScreen;
var
  stdout: THandle;
  csbi: TConsoleScreenBufferInfo;
  ConsoleSize: DWORD;
  NumWritten: DWORD;
  Origin: TCoord;
begin
  stdout := GetStdHandle(STD_OUTPUT_HANDLE);
  Win32Check(stdout <> INVALID_HANDLE_VALUE);
  Win32Check(GetConsoleScreenBufferInfo(stdout, csbi));
  ConsoleSize := csbi.dwSize.X * csbi.dwSize.Y;
  Origin.X := 0;
  Origin.Y := 0;
  Win32Check(FillConsoleOutputCharacter(stdout, ' ', ConsoleSize, Origin, NumWritten));
  Win32Check(FillConsoleOutputAttribute(stdout, csbi.wAttributes, ConsoleSize,
    Origin, NumWritten));
  Win32Check(SetConsoleCursorPosition(stdout, Origin));
end;

const
  answers: array[0..19] of string = ('It is certain.', 'It is decidedly so.',
    'Without a doubt.', 'Yes – definitely.', 'You may rely on it.',
    'As I see it, yes.', 'Most likely.', 'Outlook good.', 'Yes.',
    'Signs point to yes.', 'Reply hazy, try again.', 'Ask again later',
    'Better not tell you now.', 'Cannot predict now.',
    'Concentrate and ask again.', 'Don''t count on it.', 'My reply is no.',
    'My sources say no.', 'Outlook not so good.', 'Very doubtful.');

begin
  Randomize;
  while True do
  begin
    writeln('Magic 8 Ball! Ask question and hit ENTER key for the answer!');
    readln;
    ClearScreen;
    writeln(answers[Random(length(answers))], #10#10#10);
    writeln('(Hit ENTER key to ask again)');
    readln;
    ClearScreen;
  end;
end.


USING: io kernel random sequences ;
IN: rosetta-code.magic-8-ball

CONSTANT: phrases {
    "It is certain" "It is decidedly so" "Without a doubt"
    "Yes, definitely" "You may rely on it" "As I see it, yes"
    "Most likely" "Outlook good" "Signs point to yes" "Yes"
    "Reply hazy, try again" "Ask again later"
    "Better not tell you now" "Cannot predict now"
    "Concentrate and ask again" "Don't bet on it"
    "My reply is no" "My sources say no" "Outlook not so good"
    "Very doubtful"
}

"Please enter your question or a blank line to quit." print

[ "? : " write flush readln empty? [ f ]
[ phrases random print t ] if ] loop


dim as string answer(0 to 19) = { "It is certain.", "It is decidedly so.", "Without a doubt.", "Yes – definitely.",_
                                  "You may rely on it.", "As I see it, yes.", "Most likely.", "Outlook good.",_
                                  "Yes.", "Signs point to yes.", "Reply hazy, try again.", "Ask again later.",_
                                  "Better not tell you now.", "Cannot predict now.", "Concentrate and ask again.", "Don't count on it.",_
                                  "My reply is no.", "My sources say no.", "Outlook not so good.", "Very doubtful." }

dim as string question
randomize timer

print "Q to quit."
do
    input "What would you like to know? ", question
    if ucase(question)="Q" then exit do
    print answer(int(rnd*20))
    print
loop


\ magic eight ball Rosetta Code
INCLUDE RANDOM.FS
DECIMAL
: CASE:  ( -- -7)   CREATE   ;
: ;CASE   ( n -- )  DOES>  SWAP CELLS +  @ EXECUTE ;

: VECTORS  0  DO  , LOOP ;

:NONAME   ." It is certain" ;
:NONAME   ." It is decidedly so" ;
:NONAME   ." Without a doubt" ;
:NONAME   ." Yes, definitely" ;
:NONAME   ." You may rely on it" ;
:NONAME   ." As I see it, yes." ;
:NONAME   ." Most likely" ;
:NONAME   ." Outlook good" ;
:NONAME   ." Signs point to yes." ;
:NONAME   ." Yes." ;
:NONAME   ." Reply hazy, try again" ;
:NONAME   ." Ask again later" ;
:NONAME   ." Better not tell you now" ;
:NONAME   ." Cannot predict now" ;
:NONAME   ." Concentrate and ask again" ;
:NONAME   ." Don't bet on it" ;
:NONAME   ." My reply is no"  ;
:NONAME   ." My sources say no" ;
:NONAME   ." Outlook not so good" ;
:NONAME   ." Very doubtful" ;

CASE: MAGIC8BALL  20 VECTORS  ;CASE

: GO
       CR ." Please enter your question or a blank line to quit."
       BEGIN   CR ." ? :" PAD 80 ACCEPT 0>
       WHILE   CR 19 RANDOM MAGIC8BALL  CR
       REPEAT ;


PROGRAM EIGHT_BALL
    CHARACTER(LEN=100) :: RESPONSE
    CHARACTER(LEN=100) :: QUESTION
    CHARACTER(LEN=100), DIMENSION(20) :: RESPONSES
    REAL :: R

    CALL RANDOM_SEED()

    RESPONSES(1) = "It is certain"
    RESPONSES(2) = "It is decidedly so"
    RESPONSES(3) = "Without a doubt"
    RESPONSES(4) = "Yes, definitely"
    RESPONSES(5) = "You may rely on it"
    RESPONSES(6) = "As I see it, yes"
    RESPONSES(7) = "Most likely"
    RESPONSES(8) = "Outlook good"
    RESPONSES(9) = "Signs point to yes"
    RESPONSES(10) = "Yes"
    RESPONSES(11) = "Reply hazy, try again"
    RESPONSES(12) = "Ask again later"
    RESPONSES(13) = "Better not tell you now"
    RESPONSES(14) = "Cannot predict now"
    RESPONSES(15) = "Concentrate and ask again"
    RESPONSES(16) = "Don't bet on it"
    RESPONSES(17) = "My reply is no"
    RESPONSES(18) = "My sources say no"
    RESPONSES(19) = "Outlook not so good"
    RESPONSES(20) = "Very doubtful"

    WRITE(*,*) "Welcome to 8 Ball! Ask a question to find the answers"
    WRITE(*,*) "you seek, type either 'quit' or 'q' to exit", NEW_LINE('A')

    DO WHILE(.TRUE.)
        PRINT*, "Ask your question: "
        READ(*,*) QUESTION
        IF(QUESTION == "q" .OR. QUESTION == "quit") THEN
            CALL EXIT(0)
        ENDIF
        CALL RANDOM_NUMBER(R)
        PRINT*, "Response: ", TRIM(RESPONSES(FLOOR(R*20))), NEW_LINE('A')
    ENDDO
END PROGRAM EIGHT_BALL


package main

import (
	"bufio"
	"bytes"
	"fmt"
	"log"
	"math/rand"
	"os"
	"time"
)

func main() {
	rand.Seed(time.Now().UnixNano())
	answers := [...]string{
		"It is certain", "It is decidedly so", "Without a doubt",
		"Yes, definitely", "You may rely on it", "As I see it, yes",
		"Most likely", "Outlook good", "Signs point to yes", "Yes",
		"Reply hazy, try again", "Ask again later",
		"Better not tell you now", "Cannot predict now",
		"Concentrate and ask again", "Don't bet on it",
		"My reply is no", "My sources say no", "Outlook not so good",
		"Very doubtful",
	}
	const prompt = "\n? : "
	fmt.Print("Please enter your question or a blank line to quit.\n" + prompt)
	sc := bufio.NewScanner(os.Stdin)
	for sc.Scan() {
		question := sc.Bytes()
		question = bytes.TrimSpace(question)
		if len(question) == 0 {
			break
		}
		answer := answers[rand.Intn(len(answers))]
		fmt.Printf("\n%s\n"+prompt, answer)
	}
	if err := sc.Err(); err != nil {
		log.Fatal(err)
	}
}


0 DATA "It is certain.", "It is decidedly so."
20 DATA "Without a doubt.", "Yes - definitely."
30 DATA "You may rely on it.", "As I see it, yes."
40 DATA "Most likely.", "Outlook good."
50 DATA "Yes.", "Signs point to yes."
60 DATA "Reply hazy, try again.", "Ask again later."
70 DATA "Better not tell you now.", "Cannot predict now."
80 DATA "Concentrate and ask again.", "Don't count on it."
90 DATA "My reply is no.", "My sources say no."
100 DATA "Outlook not so good.", "Very doubtful."
110 DIM M8BALL$(20)
120 FOR I=0 TO 19
130 READ M8BALL$(I)
140 NEXT I
150 RANDOMIZE TIMER
160 INPUT "What would you like to know? ", Q$
170 PRINT M8BALL$(INT(RND*20))
180 END


import           System.Random (getStdRandom, randomR)
import           Control.Monad (forever)

answers :: [String]
answers =
  [ "It is certain"
  , "It is decidedly so"
  , "Without a doubt"
  , "Yes, definitely"
  , "You may rely on it"
  , "As I see it, yes"
  , "Most likely"
  , "Outlook good"
  , "Signs point to yes"
  , "Yes"
  , "Reply hazy, try again"
  , "Ask again later"
  , "Better not tell you now"
  , "Cannot predict now"
  , "Concentrate and ask again"
  , "Don't bet on it"
  , "My reply is no"
  , "My sources say no"
  , "Outlook not so good"
  , "Very doubtful"]

main :: IO ()
main = do
  putStrLn "Hello. The Magic 8 Ball knows all. Type your question."
  forever $ do
    getLine
    n <- getStdRandom (randomR (0, pred $ length answers))
    putStrLn $ answers !! n


NB. translated from awk

prompt=: [: 1!:1 [: 1:  echo

ANSWERS=: [;._2'It is certain"It is decidedly so"Without a doubt"Yes, definitely"You may rely on it"As I see it, yes"Most likely"Outlook good"Signs point to yes"Yes"Reply hazy, try again"Ask again later"Better not tell you now"Cannot predict now"Concentrate and ask again"Don''t bet on it"My reply is no"My sources say no"Outlook not so good"Very doubtful"'

eight_ball=: ANSWERS&$: :(dyad define)
 while. 0 < # prompt 'Please enter your question or a blank line to quit.' do.
  echo ({~ [email protected]:#) x
 end.
)


import java.util.Random;
import java.util.Scanner;

public class MagicEightBall {

    public static void main(String[] args) {
        new MagicEightBall().run();
    }

    private static String[] ANSWERS = new String[] {"It is certain.", "It is decidedly so.", "Without a doubt.", "Yes - definitely.",
            "You may rely on it.", "As I see it, yes.", "Most likely.", "Outlook good.", "Yes.", "Signs point to yes.",
            "Reply hazy, try again.", "Ask again later.", "Better not tell you now.", "Cannot predict now.", "Concentrate and ask again.",
            "Don't count on it.", "My reply is no.", "My sources say no.", "Outlook not so good.", "Very doubtful. "};

    public void run() {
        Random random = new Random();
        System.out.printf("Hello.  The Magic 8 Ball knows all.  Type your question.%n%n");
        try ( Scanner in = new Scanner(System.in); ) {
            System.out.printf("?  ");
            while ( (in.nextLine()).length() > 0 ) {
                System.out.printf("8 Ball Response:  %s%n", ANSWERS[random.nextInt(ANSWERS.length)]);
                System.out.printf("?  ");
            }
        }
        System.out.printf("%n8 Ball Done.  Bye.");
    }
}


//console
var answers = [ "It is certain", "It is decidedly so", "Without a doubt",
        "Yes, definitely", "You may rely on it", "As I see it, yes",
        "Most likely", "Outlook good", "Signs point to yes", "Yes",
        "Reply hazy, try again", "Ask again later",
        "Better not tell you now", "Cannot predict now",
        "Concentrate and ask again", "Don't bet on it",
        "My reply is no", "My sources say no", "Outlook not so good",
        "Very doubtful"])

console.log("ASK ANY QUESTION TO THE MAGIC 8-BALL AND YOU SHALL RECEIVE AN ANSWER!")

for(;;){
  var answer = prompt("question:")
  console.log(answer)
console.log(answers[Math.floor(Math.random()*answers.length)]);
}


const responses = ["It is certain", "It is decidedly so", "Without a doubt",
    "Yes, definitely", "You may rely on it", "As I see it, yes", "Most likely",
    "Outlook good", "Signs point to yes", "Yes", "Reply hazy, try again",
    "Ask again later", "Better not tell you now", "Cannot predict now",
    "Concentrate and ask again", "Don't bet on it", "My reply is no",
    "My sources say no", "Outlook not so good", "Very doubtful"]

while true
    println("Ask a question (blank to exit):")
    if !occursin(r"[a-zA-Z]", readline(stdin))
        break
    end
    println(rand(responses))
end


// Version 1.2.40

import java.util.Random

fun main(args: Array<String>) {
    val answers = listOf(
        "It is certain", "It is decidedly so", "Without a doubt",
        "Yes, definitely", "You may rely on it", "As I see it, yes",
        "Most likely", "Outlook good", "Signs point to yes", "Yes",
        "Reply hazy, try again", "Ask again later",
        "Better not tell you now", "Cannot predict now",
        "Concentrate and ask again", "Don't bet on it",
        "My reply is no", "My sources say no", "Outlook not so good",
        "Very doubtful"
    )
    val rand = Random()
    println("Please enter your question or a blank line to quit.")
    while (true) {
        print("\n? : ")
        val question = readLine()!!
        if (question.trim() == "") return
        val answer = answers[rand.nextInt(20)]
        println("\n$answer")
    }
}


data "It is certain","It is decidedly so","Without a doubt","Yes - definitely",_
"You may rely on it","As I see it, yes","Most likely","Outlook good","Yes",_
"Signs point to yes","Reply hazy, try again","Ask again later","Better not tell you now",_
"Cannot predict now","Concentrate and ask again","Don't count on it","My reply is no",_
"My sources say no","Outlook not so good","Very doubtful"

dim c$(20)
for a = 1 to 20
    read b$
    c$(a) = b$
next a

[loop]
    input "Type your question: ";a$
    if a$="" then end
    d=int(rnd(1)*20)+1
    print "Answer: ";c$(d)
goto [loop]


10 mode 2:defint a-z:randomize time
20 input "Your question (hit Return to quit)";i$
30 if i$="" then print "Goodbye!":end
40 q=1+19*rnd
50 on q gosub 100, 110, 120, 130, 140, 150, 160, 170, 180, 190, 200, 210, 220, 230, 240, 250, 260, 270, 280, 290
60 goto 20
100 print "It is certain":return
110 print "It is decidedly so":return
120 print "Without a doubt":return
130 print "Yes, definitely":return
140 print "You may rely on it":return
150 print "As I see it, yes":return
160 print "Most likely":return
170 print "Outlook good":return
180 print "Signs point to yes":return
190 print "Yes":return
200 print "Reply hazy, try again":return
210 print "Ask again later":return
220 print "Better not tell you now":return
230 print "Cannot predict now":return
240 print "Concentrate and ask again":return
250 print "Don't bet on it":return
260 print "My reply is no":return
270 print "My sources say no":return
280 print "Outlook not so good":return
290 print "Very doubtful":return


math.randomseed(os.time())
answers = {
  "It is certain.", "It is decidedly so.", "Without a doubt.", "Yes, definitely.", "You may rely on it.",
  "As I see it, yes.", "Most likely.", "Outlook good.", "Signs point to yes.", "Yes.",
  "Reply hazy, try again.", "Ask again later.", "Better not tell you now.", "Cannot predict now.", "Concentrate and ask again.",
  "Don't bet on it.", "My reply is no.", "My sources say no.", "Outlook not so good.", "Very doubtful."
}
while true do
  io.write("Q:  ")
  question = io.read()
  print("A:  "..answers[math.random(#answers)])
end


Module Magic.8.Ball {
      answers=("It is certain", "It is decidedly so", "Without a doubt", "Yes, definitely", "You may rely on it", "As I see it, yes", "Most likely", "Outlook good", "Signs point to yes", "Yes", "Reply hazy, try again", "Ask again later",  "Better not tell you now", "Cannot predict now", "Concentrate and ask again", "Don't bet on it", "My reply is no", "My sources say no", "Outlook not so good", "Very doubtful")
      Print "Please enter your question or a blank line to quit."
      {
            Line Input A$
            Print
            A$=trim$(A$)
            If A$="" Then Exit
            Print Array$(answers, Random(0, 19))
            Loop
      }
}
Magic.8.Ball


answers = {"It is certain.", "It is decidedly so.",
   "Without a doubt.", "Yes - definitely.", "You may rely on it.",
   "As I see it, yes.", "Most likely.", "Outlook good.", "Yes.",
   "Signs point to yes.", "Reply hazy, try again.",
   "Ask again later.", "Better not tell you now.",
   "Cannot predict now.", "Concentrate and ask again.",
   "Don't count on it.", "My reply is no.", "My sources say no.",
   "Outlook not so good.", "Very doubtful."};
q = Input["Please enter your question"];
SeedRandom[Hash[q]];
Print[RandomChoice[answers]]


randomize   ; Seed the RNG with current timestamp.

(
    "It is certain" "It is decidedly so" "Without a doubt"
    "Yes, definitely" "You may rely on it" "As I see it, yes"
    "Most likely" "Outlook good" "Signs point to yes" "Yes"
    "Reply hazy, try again" "Ask again later"
    "Better not tell you now" "Cannot predict now"
    "Concentrate and ask again" "Don't bet on it"
    "My reply is no" "My sources say no" "Outlook not so good"
    "Very doubtful"
) =phrases

(phrases dup size pred random get puts!) :answer

(true) ("Ask a question" ask answer) while


answers = ["It is certain", "It is decidedly so", "Without a doubt",
        "Yes, definitely", "You may rely on it", "As I see it, yes",
        "Most likely", "Outlook good", "Signs point to yes", "Yes",
        "Reply hazy, try again", "Ask again later",
        "Better not tell you now", "Cannot predict now",
        "Concentrate and ask again", "Don't bet on it",
        "My reply is no", "My sources say no", "Outlook not so good",
        "Very doubtful"]
print "Ask your question and the Magic 8 Ball will give you the answer!"
input "What is your question?"
print answers[rnd * answers.len]


import random, strutils

const Answers = ["It is certain", "It is decidedly so", "Without a doubt",
                 "Yes, definitely", "You may rely on it", "As I see it, yes",
                 "Most likely", "Outlook good", "Signs point to yes", "Yes",
                 "Reply hazy, try again", "Ask again later",
                 "Better not tell you now", "Cannot predict now",
                 "Concentrate and ask again", "Don't bet on it",
                 "My reply is no", "My sources say no", "Outlook not so good",
                 "Very doubtful"]

proc exit() =
  echo "Bye."
  quit QuitSuccess

randomize()

try:
  while true:
    echo "Type your question or an empty line to quit."
    stdout.write "? "
    let question = stdin.readLine()
    if question.strip().len == 0: exit()
    echo Answers[rand(19)], ".\n"
except EOFError:
  exit()


/* REXX */
a=.array~of("It is certain", "It is decidedly so", "Without a doubt",,
            "Yes, definitely", "You may rely on it", "As I see it, yes",,
            "Most likely", "Outlook good", "Signs point to yes", "Yes",,
            "Reply hazy, try again", "Ask again later",,
            "Better not tell you now", "Cannot predict now",,
            "Concentrate and ask again", "Don't bet on it",,
            "My reply is no", "My sources say no", "Outlook not so good",,
            "Very doubtful")
Do Forever
  Say 'your question:'
  Parse Pull q
  If q='' Then Leave
  Say a[random(1,20)]
  Say ''
  End


@a = ('It is certain', 'It is decidedly so', 'Without a doubt', 'Yes, definitely',
 'You may rely on it', 'As I see it, yes', 'Most likely', 'Outlook good',
 'Signs point to yes', 'Yes', 'Reply hazy, try again', 'Ask again later',
 'Better not tell you now', 'Cannot predict now', 'Concentrate and ask again',
 "Don't bet on it", 'My reply is no', 'My sources say no', 'Outlook not so good',
 'Very doubtful');

while () {
    print 'Enter your question:';
    last unless <> =~ /\w/;
    print @a[int rand @a], "\n";
}