Add tasks for all the new languages

This commit is contained in:
Tina Müller 2016-12-05 23:44:36 +01:00
parent 9dc3c2bb62
commit bba7bfd280
13208 changed files with 134745 additions and 0 deletions

View file

@ -0,0 +1,20 @@
(def nqueens (n (o queens))
(if (< len.queens n)
(let row (if queens (+ 1 queens.0.0) 0)
(each col (range 0 (- n 1))
(let new-queens (cons (list row col) queens)
(if (no conflicts.new-queens)
(nqueens n new-queens)))))
(prn queens)))
; check if the first queen in 'queens' lies on the same column or diagonal as
; any of the others
(def conflicts (queens)
(let (curr . rest) queens
(or (let curr-column curr.1
(some curr-column (map [_ 1] rest))) ; columns
(some [diagonal-match curr _] rest))))
(def diagonal-match (curr other)
(is (abs (- curr.0 other.0))
(abs (- curr.1 other.1))))

View file

@ -0,0 +1,84 @@
!------------------------------------------------
! QUEENS.R : solve queens problem on a NxN board
!------------------------------------------------
PROGRAM QUEENS
DIM COL%[15]
BEGIN
MAXSIZE%=15
PRINT(TAB(25);" --- PROBLEMA DELLE REGINE --- ")
PRINT
PRINT("Board dimension ";)
INPUT(N%)
PRINT
IF (N%<1 OR N%>MAXSIZE%)
THEN
PRINT("Illegal dimension!!")
ELSE
FOR CURCOLNBR%=1 TO N%
COL%[CURCOLNBR%]=0
END FOR
CURCOLNBR%=1
WHILE CURCOLNBR%>0 DO
PLACEDAQUEEN%=FALSE
I%=COL%[CURCOLNBR%]+1
WHILE (I%<=N%) AND NOT PLACEDAQUEEN% DO
PLACEDAQUEEN%=TRUE
J%=1
WHILE PLACEDAQUEEN% AND (J%<CURCOLNBR%) DO
PLACEDAQUEEN%=COL%[J%]<>I%
J%=J%+1
END WHILE
IF PLACEDAQUEEN%
THEN
DIAGNBR%=I%+CURCOLNBR%
J%=1
WHILE PLACEDAQUEEN% AND (J%<CURCOLNBR%) DO
PLACEDAQUEEN%=(COL%[J%]+J%)<>DIAGNBR%
J%=J%+1
END WHILE
ELSE
END IF
IF PLACEDAQUEEN%
THEN
DIAGNBR%=I%-CURCOLNBR%
J%=1
WHILE PLACEDAQUEEN% AND (J%<CURCOLNBR%) DO
PLACEDAQUEEN%=(COL%[J%]-J%)<>DIAGNBR%
J%=J%+1
END WHILE
ELSE
END IF
IF NOT PLACEDAQUEEN%
THEN
I%=I%+1
ELSE
COL%[CURCOLNBR%]=I%
END IF
END WHILE
IF NOT PLACEDAQUEEN%
THEN
COL%[CURCOLNBR%]=0
CURCOLNBR%=CURCOLNBR%-1
ELSE
IF CURCOLNBR%=N%
THEN
NSOL%=NSOL%+1
PRINT("Soluzione";NSOL%;":";)
FOR I%=1 TO N%
PRINT(COL%[I%];)
END FOR
PRINT
ELSE
CURCOLNBR%=CURCOLNBR%+1
END IF
END IF
END WHILE
PRINT("Search completed")
REPEAT
GET(CH$)
UNTIL CH$<>""
END IF
END PROGRAM

View file

@ -0,0 +1,57 @@
;; square num is i + j*N
(define-syntax-rule (sq i j) (+ i (* j N)))
;; compute diag number for each square
(define (do-diag1 i0 j0 dnum into: dnum1 N) ;; ++i and ++j diags
(for [(i (in-range i0 N)) (j (in-range j0 N))]
;;(writeln i j 'diag1 dnum)
(vector-set! dnum1 (sq i j) dnum)))
(define (do-diag2 i0 j0 dnum into: dnum2 N) ;; --i and ++j diags
(for [(i (in-range i0 -1 -1)) (j (in-range j0 N))]
;; (writeln i j 'diag2 dnum)
(vector-set! dnum2 (sq i j) dnum)))
(define (init-diags dnum1 dnum2 N)
(define dnum 0)
(for ((j N)) (do-diag1 0 j dnum dnum1 N) (++ dnum))
(for ((i (in-range 1 N)))
(do-diag1 i 0 dnum dnum1 N) (++ dnum))
(set! dnum 0)
(for ((j N)) (do-diag2 (1- N) j dnum dnum2 N) (++ dnum))
(for ((i (1- N))) (do-diag2 i 0 dnum dnum2 N) (++ dnum)))
;; end boring diags part
(define (q-search i N col diag1 diag2 dnum1 dnum2 &hits (ns))
(cond
[(= i N) (set-box! &hits (1+ (unbox &hits))) ] ;; (writeln 'HIT col)
[else
(for ((j N))
(set! ns (sq i j))
#:continue (or [col j] [diag1 [dnum1 ns]] [diag2 [dnum2 ns]])
(vector-set! col j i) ;; move
(vector-set! diag1 [dnum1 ns] #t) ;; flag busy diagonal
(vector-set! diag2 [dnum2 ns] #t)
(q-search (1+ i) N col diag1 diag2 dnum1 dnum2 &hits)
(vector-set! col j #f) ;; unmove
(vector-set! diag1 [dnum1 ns] #f)
(vector-set! diag2 [dnum2 ns] #f))
]))
(define (q-count (N 8))
(define dnum1 (make-vector (* N N)))
(define dnum2 (make-vector (* N N )))
(init-diags dnum1 dnum2 N)
(define diag1 (make-vector (* 2 N) #f)) ; busy diag's
(define diag2 (make-vector (* 2 N) #f))
(define col (make-vector N #f))
(define &hits (box 0))
(q-search 0 N col diag1 diag2 dnum1 dnum2 &hits)
(unbox &hits))
(define (task up-to-n)
(for ((i up-to-n)) (writeln i ' ♕ (q-count i) 'solutions)))

View file

@ -0,0 +1,25 @@
const boardSize = 8
proc underAttack(col, queens): bool =
if col in queens: return true
for i, x in queens:
if abs(col - x) == queens.len - i:
return true
return false
proc solve(n): auto =
result = newSeq[seq[int]]()
result.add(@[])
var newSolutions = newSeq[seq[int]]()
for row in 1..n:
for solution in result:
for i in 1..boardSize:
if not underAttack(i, solution):
newSolutions.add(solution & i)
swap result, newSolutions
newSolutions.setLen(0)
for answer in solve(boardSize):
for i, x in answer:
if i > 0: stdout.write ", "
stdout.write "(",i,", ",x,")"

View file

@ -0,0 +1,54 @@
let print_table = function (pos) {
pos.foreach(function (_, i) {
stdout.printf(" %c", 'a' + i);
});
stdout.write("\n");
pos.foreach(function (col, row) {
stdout.printf("%d", row + 1);
stdout.printf("%s #\n", range(col).reduce("", function (s, t) {
return s .. " ";
}));
});
stdout.write("\n\n");
};
let threatens = function (row_a, col_a, row_b, col_b) {
return row_a == row_b
or col_a == col_b
or abs(row_a - row_b) == abs(col_a - col_b);
};
let good = function(pos, end_idx) {
return pos.all(function (col_a, row_a) {
return range(row_a + 1, end_idx).all(function (row_b) {
let col_b = pos[row_b];
return not threatens(row_a, col_a, row_b, col_b);
});
});
};
// Returns number of solutions
let n_queens = function (pos, index) {
if index >= pos.length {
if good(pos, index) {
print_table(pos);
return 1;
}
return 0;
}
if not good(pos, index) {
return 0;
}
return pos.map(function (_, col) {
pos[index] = col;
return n_queens(pos, index + 1);
}).reduce(0, function (a, b) { return a + b; });
};
stdout.printf("%d solutions\n", n_queens(range(8), 0));

View file

@ -0,0 +1,25 @@
def single_solution_queens(n):
def q: "♛";
def init(k): reduce range(0;k) as $i ([]; . + ["."]);
def matrix(k): init(k) as $row | reduce range(0;k) as $i ([]; . + [$row]);
def place(stream; i; j):
# jq indexing is based on offsets but we are using the 1-based formulae:
reduce stream as $s (.; setpath([-1+($s|i), -1+($s|j)]; q) );
def even(k):
if ((k-2) % 6) != 0 then
place( range(1; 1+(k/2)); .; 2*. )
| place( range(1; 1+(k/2)); (k/2) + .; 2*. -1 )
else place( range(1; 1+(k/2)); .; 1 + ((2*. + (k/2) - 3) % k))
| place( range(1; 1+(n/2)); n + 1 - .; n - ((2*. + (n/2) - 3) % n))
end;
matrix(n) # the chess board
| if (n % 2) == 0 then even(n)
else even(n-1) | .[n-1][n-1] = q
end;
# Example:
def pp: reduce .[] as $row
(""; reduce $row[] as $x (.; . + $x) + "\n");
single_solution_queens(8) | pp

View file

@ -0,0 +1,8 @@
...♛....
.....♛..
.......♛
.♛......
......♛.
♛.......
..♛.....
....♛...

View file

@ -0,0 +1,13 @@
# permutations of 0 .. (n-1)
def permutations(n):
# Given a single array, generate a stream by inserting n at different positions:
def insert(m;n):
if m >= 0 then (.[0:m] + [n] + .[m:]), insert(m-1;n) else empty end;
if n==0 then []
elif n == 1 then [1]
else
permutations(n-1) | insert(n-1; n)
end;
def count(g): reduce g as $i (0; .+1);

View file

@ -0,0 +1,16 @@
def queens(n):
def sums:
. as $board
| [ range(0;length) | . + $board[.]]
| unique | length;
def differences:
. as $board
| [ range(0;length) | . - $board[.]]
| unique | length;
def allowable:
length as $n
| sums == $n and differences == $n;
count( permutations(n) | select(allowable) );

View file

@ -0,0 +1 @@
queens(8)