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,209 @@
! **********************************************************************
! * *
! * IL GIRO DEL CAVALLO - come collocare un cavallo su di una *
! * scacchiera n*n passando una sola volta *
! * per ogni casella. *
! * *
! **********************************************************************
! ----------------------------------------------------------------------
! Inizializzazione dei parametri
! ----------------------------------------------------------------------
PROGRAM KNIGHT
!$INTEGER
!$KEY
DIM H[25,25],A[8],B[8],P0[8],P1[8]
!$INCLUDE="PC.LIB"
PROCEDURE INIT_SCACCHIERA
! **********************************************************************
! * Routine di inizializzazione scacchiera *
! **********************************************************************
FOR I1=1 TO 8 DO
U=X+A[I1] V=Y+B[I1]
IF (U>0 AND U<=N) AND (V>0 AND V<=N) THEN
H[U,V]=H[U,V]-1
END IF
END FOR
END PROCEDURE
PROCEDURE MOSTRA_SCACCHIERA
! *********************************************************************
! * Routine di visualizzazione della scacchiera *
! *********************************************************************
LOCATE(5,1) COLOR(0,7) PRINT(" Mossa num.";NMOS) COLOR(7,0)
L2=N
FOR I2=1 TO N DO
PRINT
FOR L1=1 TO N DO
IF H[L1,L2]>0 THEN COLOR(15,0) END IF
WRITE("####";H[L1,L2];)
COLOR(7,0)
END FOR
L2=L2-1
END FOR
END PROCEDURE
PROCEDURE AGGIORNA_SCACCHIERA
! *********************************************************************
! * Routine di Aggiornamento Scacchiera *
! *********************************************************************
B=1
FOR I1=1 TO 8 DO
U=X+A[I1] V=Y+B[I1]
IF (U>0 AND U<=N) AND (V>0 AND V<=N) THEN
IF H[U,V]<=0 THEN
H[U,V]=H[U,V]+1 B=0
END IF
END IF
END FOR
IF B=1 THEN Q1=0 END IF
END PROCEDURE
PROCEDURE MOSSA_MAX_PESO
! *********************************************************************
! * Cerca la prossima mossa con il massimo peso *
! *********************************************************************
M1=0 RO=1
FOR W=1 TO 8 DO
U=Z1+A[W] V=Z2+B[W]
IF (U>0 AND U<=N) AND (V>0 AND V<=N) THEN
IF H[U,V]<=0 AND H[U,V]<=M1 THEN
IF H[U,V]=M1 THEN
RO=RO+1 P0[RO]=W
ELSE
M1=H[U,V] Q1=1 T1=U T2=V RO=1 P0[1]=W
END IF
END IF
END IF
END FOR
END PROCEDURE
PROCEDURE MOSSA_MIN_PESO
! *********************************************************************
! * Cerca la prossima mossa con il minimo peso *
! *********************************************************************
M1=-9 RO=1
FOR W=1 TO 8 DO
U=Z1+A[W] V=Z2+B[W]
IF (U>0 AND U<=N) AND (V>0 AND V<=N) THEN
IF H[U,V]<=0 AND H[U,V]>=M1 THEN
IF H[U,V]=M1 THEN
RO=RO+1 P0[RO]=W
ELSE
M1=H[U,V] Q1=1 T1=U T2=V RO=1 P0[1]=W
END IF
END IF
END IF
END FOR
END PROCEDURE
BEGIN
A[1]=1 A[2]=2 A[3]=2 A[4]=1
A[5]=-1 A[6]=-2 A[7]=-2 A[8]=-1
B[1]=2 B[2]=1 B[3]=-1 B[4]=-2
B[5]=-2 B[6]=-1 B[7]=1 B[8]=2
CLS
PRINT(" *** LA GALOPPATA DEL CAVALIERE ***")
PRINT
PRINT("Inserire la dimensione della scacchiera (max. 25)";)
INPUT(N)
PRINT("Inserire la caselle di partenza (x,y) ";)
INPUT(X1,Y1)
NMOS=1 A1=1 N1=N*N ESCAPE=FALSE
! ----------------------------------------------------------------------
! Set della scacchiera
! ----------------------------------------------------------------------
WHILE NOT ESCAPE DO
FOR I=1 TO N DO
FOR J=1 TO N DO
H[I,J]=0
END FOR
END FOR
FOR I=1 TO N DO
FOR J=1 TO N DO
X=I Y=J
INIT_SCACCHIERA
END FOR
END FOR
! ----------------------------------------------------------------------
! Effettua la prima mossa
! ----------------------------------------------------------------------
X=X1 Y=Y1 H[X,Y]=1 L=2
AGGIORNA_SCACCHIERA
Q1=1 Q2=1
! -----------------------------------------------------------------------
! Trova la prossima mossa
! -----------------------------------------------------------------------
WHILE Q1<>0 AND Q2<>0 DO
Q1=0 Z1=X Z2=Y
MOSSA_MIN_PESO
IF RO<=1 THEN
C1=T1 C2=T2
ELSE
! ------------------------------------------------------------------------
! Esamina tutti i vincoli
! ------------------------------------------------------------------------
FOR K=1 TO RO DO
P1[K]=P0[K]
END FOR
R1=RO
IF A1=1 THEN M2=-9 ELSE M2=0 END IF
FOR K=1 TO R1 DO
F1=P1[K] Z1=X+A[F1] Z2=Y+B[F1]
IF A1=1 THEN
MOSSA_MAX_PESO
IF M1<=M2 THEN
!$NULL
ELSE
M2=M1 C1=Z1 C2=Z2
END IF
ELSE
MOSSA_MIN_PESO
IF M1>=M2 THEN
!$NULL
ELSE
M2=M1 C1=Z1 C2=Z2
END IF
END IF
END FOR
! ------------------------------------------------------------------------
! Prossima mossa trovata:aggiorna la scacchiera
! ------------------------------------------------------------------------
END IF
IF Q1<>0 THEN
X=C1 Y=C2 H[X,Y]=L
AGGIORNA_SCACCHIERA
IF L=N1 THEN Q2=0 END IF
END IF
L=L+1
MOSTRA_SCACCHIERA
NMOS=NMOS+1
END WHILE
! ------------------------------------------------------------------------
! La ricerca è terminata: visualizza i risultati
! ------------------------------------------------------------------------
PRINT PRINT
IF Q2<>1 THEN
PRINT("*** Trovata la soluzione! ***")
MOSTRA_SCACCHIERA
ESCAPE=TRUE
ELSE
IF A1=0 THEN
PRINT("Nessuna soluzione.")
ESCAPE=TRUE
ELSE
BEEP
A1=0
END IF
END IF
END WHILE
REPEAT
GET(A$)
UNTIL A$<>""
END PROGRAM

View file

@ -0,0 +1,68 @@
(require 'plot)
(define *knight-moves*
'((2 . 1)(2 . -1 ) (1 . -2) (-1 . -2 )(-2 . -1) (-2 . 1) (-1 . 2) (1 . 2)))
(define *hit-squares* null)
(define *legal-moves* null)
(define *tries* 0)
(define (square x y n ) (+ y (* x n)))
(define (dim n) (1- (* n n))) ; n^2 - 1
;; check legal knight move from sq
;; return null or (list destination-square)
(define (legal-disp n sq k-move)
(let ((x (+ (quotient sq n) (first k-move)))
(y (+ (modulo sq n) (rest k-move))))
(if (and (>= x 0) (< x n) (>= y 0) (< y n))
(list (square x y n)) null)))
;; list of legal destination squares from sq
(define (legal-moves sq k-moves n )
(if (null? k-moves) null
(append (legal-moves sq (rest k-moves) n) (legal-disp n sq (first k-moves)))))
;; square freedom = number of destination squares not already reached
(define (freedom sq)
(for/sum ((dest (vector-ref *legal-moves* sq)))
(if (vector-ref *hit-squares* dest) 0 1)))
;; The chess adage" A knight on the rim is dim" is false here :
;; choose to move to square with smallest freedom : Warnsdorf's rule
(define (square-sort a b)
(< (freedom a) (freedom b)))
;; knight tour engine
(define (play sq step starter last-one wants-open)
(set! *tries* (1+ *tries*))
(vector-set! *hit-squares* sq step) ;; flag used square
(if (= step last-one) (throw 'HIT last-one)) ;; stop on first path found
(when (or wants-open ;; cut search iff closed path
(and (< step last-one) (> (freedom starter) 0))) ;; this ensures a closed path
(for ((target (list-sort square-sort (vector-ref *legal-moves* sq))))
(unless (vector-ref *hit-squares* target)
(play target (1+ step) starter last-one wants-open))))
(vector-set! *hit-squares* sq #f)) ;; unflag used square
(define (show-steps n wants-open)
(string-delimiter "")
(if wants-open
(printf "♘-tour: %d tries." *tries*)
(printf "♞-closed-tour: %d tries." *tries*))
(for ((x n))
(writeln)
(for((y n))
(write (string-pad-right (vector-ref *hit-squares* (square x y n)) 4)))))
(define (k-tour (n 8) (starter 0) (wants-open #t))
(set! *hit-squares* (make-vector (* n n) #f))
;; build vector of legal moves for squares 0..n^2-1
(set! *legal-moves*
(build-vector (* n n) (lambda(sq) (legal-moves sq *knight-moves* n))))
(set! *tries* 0) ; counter
(try
(play starter 0 starter (dim n) wants-open)
(catch (hit mess) (show-steps n wants-open))))

View file

@ -0,0 +1,33 @@
(k-tour 8 0 #f)
♞-closed-tour: 66 tries.
0 47 14 31 62 27 12 29
15 32 63 54 13 30 57 26
48 1 46 61 56 59 28 11
33 16 55 50 53 44 25 58
2 49 42 45 60 51 10 39
17 34 19 52 43 40 7 24
20 3 36 41 22 5 38 9
35 18 21 4 37 8 23 6
(k-tour 20 57)
♘-tour: 400 tries.
31 34 29 104 209 36 215 300 211 38 213 354 343 40 345 386 383 42 1 388
28 103 32 35 216 299 210 37 214 335 342 39 346 385 382 41 390 387 396 43
33 30 105 208 201 308 301 336 323 212 353 340 355 344 391 384 395 0 389 2
102 27 202 219 298 217 322 309 334 341 356 347 358 351 376 381 378 399 44 397
203 106 207 200 307 228 311 302 337 324 339 352 373 364 379 392 375 394 3 368
26 101 220 229 218 297 304 321 310 333 348 357 350 359 374 377 380 367 398 45
107 204 199 206 227 306 231 312 303 338 325 330 363 372 365 328 393 254 369 4
100 25 122 221 230 233 296 305 320 313 332 349 326 329 360 371 366 251 46 253
121 108 205 198 145 226 237 232 295 286 319 314 331 362 327 316 255 370 5 178
24 99 144 123 222 129 234 279 236 281 294 289 318 315 256 361 250 179 252 47
109 120 111 130 197 146 225 238 285 278 287 272 293 290 317 180 257 162 177 6
98 23 124 143 128 223 276 235 280 239 282 291 288 265 270 249 176 181 48 161
115 110 119 112 131 196 147 224 277 284 273 266 271 292 245 258 163 174 7 58
22 97 114 125 142 127 140 275 194 267 240 283 264 269 248 175 182 59 160 49
87 116 95 118 113 132 195 148 187 274 263 268 191 244 259 246 173 164 57 8
96 21 88 133 126 141 150 139 262 193 190 241 260 247 172 183 60 159 50 65
77 86 117 94 89 138 135 188 149 186 261 192 171 184 243 156 165 64 9 56
20 81 78 85 134 93 90 151 136 189 170 185 242 155 166 61 158 53 66 51
79 76 83 18 91 74 137 16 169 72 153 14 167 70 157 12 63 68 55 10
82 19 80 75 84 17 92 73 152 15 168 71 154 13 62 69 54 11 52 67

View file

@ -0,0 +1,9 @@
(define (step-color x y n last-one)
(letrec ((sq (square (floor x) (floor y) n))
(step (vector-ref *hit-squares* sq) n n))
(cond ((= 0 step) (rgb 1 0 0)) ;; red starter
((= last-one step) (rgb 0 1 0)) ;; green end
(else (gray (// step n n))))))
(define ( k-plot n)
(plot-rgb (lambda (x y) (step-color x y n (dim n))) (- n epsilon) (- n epsilon)))

View file

@ -0,0 +1,133 @@
import List exposing (concatMap, foldl, head,member,filter,length,minimum,concat,map,map2,tail)
import List.Extra exposing (minimumBy, andThen)
import String exposing (join)
import Html as H
import Html.Attributes as HA
import Html.App exposing (program)
import Time exposing (Time,every, second)
import Svg exposing (rect, line, svg, g)
import Svg.Events exposing (onClick)
import Svg.Attributes exposing (version, viewBox, x, y, x1, y1, x2, y2, fill, style, width, height)
w = 450
h = 450
rowCount=20
colCount=20
dt = 0.03
type alias Cell = (Int, Int)
type alias Model =
{ path : List Cell
, board : List Cell
}
type Msg = NoOp | Tick Time | SetStart Cell
init : (Model,Cmd Msg)
init =
let board = [0..rowCount-1] `andThen` \r ->
[0..colCount-1] `andThen` \c ->
[(r, c)]
path = []
in (Model path board, Cmd.none)
view : Model -> H.Html Msg
view model =
let
showChecker row col =
rect [ x <| toString col
, y <| toString row
, width "1"
, height "1"
, fill <| if (row + col) % 2 == 0 then "blue" else "grey"
, onClick <| SetStart (row, col)
]
[]
showMove (row0,col0) (row1,col1) =
line [ x1 <| toString ((toFloat col0) + 0.5)
, y1 <| toString ((toFloat row0) + 0.5)
, x2 <| toString ((toFloat col1) + 0.5)
, y2 <| toString ((toFloat row1) + 0.5)
, style "stroke:yellow;stroke-width:0.05"
]
[]
render model =
let checkers = model.board `andThen` \(r,c) ->
[showChecker r c]
moves = case List.tail model.path of
Nothing -> []
Just tl -> List.map2 showMove model.path tl
in checkers ++ moves
unvisited = length model.board - length model.path
center = HA.style [ ( "text-align", "center") ]
in
H.div
[]
[ H.h2 [center] [H.text "Knight's Tour"]
, H.h2 [center] [H.text <| "Unvisited count : " ++ toString unvisited ]
, H.h2 [center] [H.text "(pick a square)"]
, H.div
[center]
[ svg
[ version "1.1"
, width (toString w)
, height (toString h)
, viewBox (join " "
[ toString 0
, toString 0
, toString colCount
, toString rowCount ])
]
[ g [] <| render model]
]
]
nextMoves : Model -> Cell -> List Cell
nextMoves model (stRow,stCol) =
let c = [ 1, 2, -1, -2]
km = c `andThen` \cRow ->
c `andThen` \cCol ->
if abs(cRow) == abs(cCol) then [] else [(cRow,cCol)]
jumps = List.map (\(kmRow,kmCol) -> (kmRow + stRow, kmCol + stCol)) km
in List.filter (\j -> List.member j model.board && not (List.member j model.path) ) jumps
bestMove : Model -> Maybe Cell
bestMove model =
case List.head (model.path) of
Nothing -> Nothing
Just mph -> minimumBy (List.length << nextMoves model) (nextMoves model mph)
update : Msg -> Model -> (Model, Cmd Msg)
update msg model =
let mo = case msg of
SetStart start ->
{model | path = [start]}
Tick t ->
case model.path of
[] -> model
_ -> case bestMove model of
Nothing -> model
Just best -> {model | path = best::model.path }
NoOp -> model
in (mo, Cmd.none)
subscriptions : Model -> Sub Msg
subscriptions _ =
Time.every (dt * second) Tick
main =
program
{ init = init
, view = view
, update = update
, subscriptions = subscriptions
}

View file

@ -0,0 +1,86 @@
constant size = 8
constant nchars = length(sprintf(" %d",size*size))
constant fmt = sprintf(" %%%dd",nchars-1)
constant blank = repeat(' ',nchars)
-- to simplify output, each square is nchars
sequence board = repeat(repeat(' ',size*nchars),size)
-- keep current counts, immediately backtrack if any hit 0
-- (in line with the above, we only use every nth entry)
sequence warnsdorffs = repeat(repeat(0,size*nchars),size)
constant ROW = 1, COL = 2
constant moves = {{-1,-2},{-2,-1},{-2,1},{-1,2},{1,2},{2,1},{2,-1},{1,-2}}
function onboard(integer row, integer col)
return row>=1 and row<=size and col>=nchars and col<=nchars*size
end function
procedure init_warnsdorffs()
integer nrow,ncol
for row=1 to size do
for col=nchars to nchars*size by nchars do
for move=1 to length(moves) do
nrow = row+moves[move][ROW]
ncol = col+moves[move][COL]*nchars
if onboard(nrow,ncol) then
warnsdorffs[row][col] += 1
end if
end for
end for
end for
end procedure
atom t0 = time()
integer tries = 0
atom t1 = time()+1
function solve(integer row, integer col, integer n)
integer nrow, ncol
if time()>t1 then
?{row,floor(col/nchars),n,tries}
puts(1,join(board,"\n"))
t1 = time()+1
-- if wait_key()='!' then ?9/0 end if
end if
tries+= 1
if n>size*size then return 1 end if
sequence wmoves = {}
for move=1 to length(moves) do
nrow = row+moves[move][ROW]
ncol = col+moves[move][COL]*nchars
if onboard(nrow,ncol)
and board[nrow][ncol]=' ' then
wmoves = append(wmoves,{warnsdorffs[nrow][ncol],nrow,ncol})
end if
end for
wmoves = sort(wmoves)
-- avoid creating orphans
if length(wmoves)<2 or wmoves[2][1]>1 then
for m=1 to length(wmoves) do
{?,nrow,ncol} = wmoves[m]
warnsdorffs[nrow][ncol] -= 1
end for
for m=1 to length(wmoves) do
{?,nrow,ncol} = wmoves[m]
board[nrow][ncol-nchars+1..ncol] = sprintf(fmt,n)
if solve(nrow,ncol,n+1) then return 1 end if
board[nrow][ncol-nchars+1..ncol] = blank
end for
for m=1 to length(wmoves) do
{?,nrow,ncol} = wmoves[m]
warnsdorffs[nrow][ncol] += 1
end for
end if
return 0
end function
init_warnsdorffs()
board[1][nchars] = '1'
if solve(1,nchars,2) then
puts(1,join(board,"\n"))
printf(1,"\nsolution found in %d tries (%3.2fs)\n",{tries,time()-t0})
else
puts(1,"no solutions found\n")
end if
{} = wait_key()

View file

@ -0,0 +1,61 @@
var board = []
var I = 8
var J = 8
var F = (I*J > 99 ? '%3d' : '%2d')
var (i, j) = (I.irand, J.irand)
func from_algebraic(square) {
if (var match = square.match(/^([a-z])([0-9])\z/)) {
return(I - Num(match[1]), match[0].ord - 'a'.ord)
}
die "Invalid block square: #{square}"
}
func possible_moves(i,j) {
gather {
for ni,nj in [
[i-2,j-1], [i-2,j+1], [i-1,j-2], [i-1,j+2],
[i+1,j-2], [i+1,j+2], [i+2,j-1], [i+2,j+1],
] {
if ((ni ~~ ^I) && (nj ~~ ^J) && !board[ni][nj]) {
take([ni, nj])
}
}
}
}
func to_algebraic(i,j) {
('a'.ord + j).chr + Str(I - i)
}
if (ARGV[0]) {
(i, j) = from_algebraic(ARGV[0])
}
var moves = []
for move in (1 .. I*J) {
moves << to_algebraic(i, j)
board[i][j] = move
var min = [9]
for target in possible_moves(i, j) {
var (ni, nj) = target...
var nxt = possible_moves(ni, nj).len
if (nxt < min[0]) {
min = [nxt, ni, nj]
}
}
(i, j) = min[1,2]
}
say (moves/4 -> map { .join(', ') }.join("\n") + "\n")
for i in ^I {
for j in ^J {
(i%2 == j%2) && print "\e[7m"
F.printf(board[i][j])
print "\e[0m"
}
print "\n"
}