Prolog

Other Prolog solutions.
% Please visit https://exercism.io/tracks/prolog/installation
% for instructions on setting up prolog.
% Visit https://exercism.io/tracks/prolog/tests
% for help running the tests for prolog exercises.

% Replace the goal below with
% your implementation.

on_board(Coord) :-
  Coord >= 0, Coord < 8.

can_attack((X1, Y1), (X2, Y2)) :-
  X1 == X2;
  Y1 == Y2;
  abs(X2 - X1) =:= abs(Y2 - Y1).

create((X, Y)) :-
  on_board(X),
  on_board(Y).

attack(A, B) :-
  create(A),
  create(B),
  can_attack(A, B).

Roc

Other Roc solutions.
module [create, rank, file, queenCanAttack]

Square := { row : U8, column : U8 }

rank : Square -> U8
rank = \@Square { row } -> 8 - row

file : Square -> U8
file = \@Square { column } -> column + 'A'

create : Str -> Result Square [InvalidSquare]
create = \squareStr ->
    chars = Str.toUtf8 squareStr
    fileResult = List.get chars 0
    rankResult = List.get chars 1
    Result.map2 fileResult rankResult \fileChar, rankChar -> (fileChar, rankChar)
    |> Result.mapErr \OutOfBounds -> InvalidSquare
    |> Result.try \(fileChar, rankChar) ->
        column = fileChar - 'A'
        if rankChar < '1' || rankChar > '8' then
            Err InvalidSquare
        else if fileChar < 'A' || fileChar > 'H' then
            Err InvalidSquare
        else
            Ok (@Square { row: rankToRow rankChar, column })

queenCanAttack : Square, Square -> Bool
queenCanAttack = \@Square { row: row1, column: col1 }, @Square { row: row2, column: col2 } ->
    row1Signed = Num.toI32 row1
    row2Signed = Num.toI32 row2
    col1Signed = Num.toI32 col1
    col2Signed = Num.toI32 col2
    row1 == row2 || col1 == col2 || (Num.abs (row1Signed - row2Signed)) == (Num.abs (col1Signed - col2Signed))

rankToRow : U8 -> U8
rankToRow = \rankChar ->
    8 - (rankChar - '0')