Skip to content

Commit

Permalink
Merge branch 'main' into run-length-encoding
Browse files Browse the repository at this point in the history
  • Loading branch information
colinleach authored Nov 2, 2023
2 parents 5010199 + 7112808 commit de5d028
Show file tree
Hide file tree
Showing 11 changed files with 403 additions and 0 deletions.
9 changes: 9 additions & 0 deletions config.json
Original file line number Diff line number Diff line change
Expand Up @@ -303,6 +303,15 @@
"prerequisites": [],
"difficulty": 1,
"topics": null
},
{
"slug": "queen-attack",
"name": "Queen Attack",
"uuid": "1ca52419-bbe0-46fc-892a-56779f396b1c",
"practices": [],
"prerequisites": [],
"difficulty": 1,
"topics": null
}
]
},
Expand Down
25 changes: 25 additions & 0 deletions exercises/practice/queen-attack/.docs/instructions.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
# Instructions

Given the position of two queens on a chess board, indicate whether or not they are positioned so that they can attack each other.

In the game of chess, a queen can attack pieces which are on the same row, column, or diagonal.

A chessboard can be represented by an 8 by 8 array.

So if you are told the white queen is at `c5` (zero-indexed at column 2, row 3) and the black queen at `f2` (zero-indexed at column 5, row 6), then you know that the set-up is like so:

```text
a b c d e f g h
8 _ _ _ _ _ _ _ _ 8
7 _ _ _ _ _ _ _ _ 7
6 _ _ _ _ _ _ _ _ 6
5 _ _ W _ _ _ _ _ 5
4 _ _ _ _ _ _ _ _ 4
3 _ _ _ _ _ _ _ _ 3
2 _ _ _ _ _ B _ _ 2
1 _ _ _ _ _ _ _ _ 1
a b c d e f g h
```

You are also able to answer whether the queens can attack each other.
In this case, that answer would be yes, they can, because both pieces share a diagonal.
43 changes: 43 additions & 0 deletions exercises/practice/queen-attack/.meta/Example.cfc
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
/**
* Here is an example solution for the Queen Attack exercise
*/
component {

/**
* @param row : an integer 0-7
* @param col : an integer 0-7
*
* @returns an object that can be resolved into `row` and `col`, or `false` on error
*/
function create(row, col) {
if (row < 0) {
// "row not positive"
return false;
};
if (row > 7) {
// "row not on board"
return false;
};
if (col < 0) {
// "column not positive"
return false;
};
if (col > 7) {
// "column not on board"
return false;
};

return { row: row, col: col };
}

/**
* @returns a boolean
*/
function canAttack(queen1, queen2) {
sameRow = (queen1.row == queen2.row);
sameCol = (queen1.col == queen2.col);
sameDiagonal = abs(queen1.row - queen2.row) == abs(queen1.col - queen2.col);
return (sameRow || sameCol || sameDiagonal);
}

}
7 changes: 7 additions & 0 deletions exercises/practice/queen-attack/.meta/ExampleTest.cfc
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
component extends="QueenAttackTest" {

function beforeAll(){
SUT = createObject( 'Solution' );
}

}
17 changes: 17 additions & 0 deletions exercises/practice/queen-attack/.meta/config.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
{
"authors": ["colinleach"],
"files": {
"solution": [
"QueenAttack.cfc"
],
"test": [
"QueenAttackTest.cfc"
],
"example": [
".meta/Example.cfc"
]
},
"blurb": "Given the position of two queens on a chess board, indicate whether or not they are positioned so that they can attack each other.",
"source": "J Dalbey's Programming Practice problems",
"source_url": "https://users.csc.calpoly.edu/~jdalbey/103/Projects/ProgrammingPractice.html"
}
49 changes: 49 additions & 0 deletions exercises/practice/queen-attack/.meta/tests.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
# This is an auto-generated file.
#
# Regenerating this file via `configlet sync` will:
# - Recreate every `description` key/value pair
# - Recreate every `reimplements` key/value pair, where they exist in problem-specifications
# - Remove any `include = true` key/value pair (an omitted `include` key implies inclusion)
# - Preserve any other key/value pair
#
# As user-added comments (using the # character) will be removed when this file
# is regenerated, comments can be added via a `comment` key.

[3ac4f735-d36c-44c4-a3e2-316f79704203]
description = "Test creation of Queens with valid and invalid positions -> queen with a valid position"

[4e812d5d-b974-4e38-9a6b-8e0492bfa7be]
description = "Test creation of Queens with valid and invalid positions -> queen must have positive row"

[f07b7536-b66b-4f08-beb9-4d70d891d5c8]
description = "Test creation of Queens with valid and invalid positions -> queen must have row on board"

[15a10794-36d9-4907-ae6b-e5a0d4c54ebe]
description = "Test creation of Queens with valid and invalid positions -> queen must have positive column"

[6907762d-0e8a-4c38-87fb-12f2f65f0ce4]
description = "Test creation of Queens with valid and invalid positions -> queen must have column on board"

[33ae4113-d237-42ee-bac1-e1e699c0c007]
description = "Test the ability of one queen to attack another -> cannot attack"

[eaa65540-ea7c-4152-8c21-003c7a68c914]
description = "Test the ability of one queen to attack another -> can attack on same row"

[bae6f609-2c0e-4154-af71-af82b7c31cea]
description = "Test the ability of one queen to attack another -> can attack on same column"

[0e1b4139-b90d-4562-bd58-dfa04f1746c7]
description = "Test the ability of one queen to attack another -> can attack on first diagonal"

[ff9b7ed4-e4b6-401b-8d16-bc894d6d3dcd]
description = "Test the ability of one queen to attack another -> can attack on second diagonal"

[0a71e605-6e28-4cc2-aa47-d20a2e71037a]
description = "Test the ability of one queen to attack another -> can attack on third diagonal"

[0790b588-ae73-4f1f-a968-dd0b34f45f86]
description = "Test the ability of one queen to attack another -> can attack on fourth diagonal"

[543f8fd4-2597-4aad-8d77-cbdab63619f8]
description = "Test the ability of one queen to attack another -> cannot attack if falling diagonals are only the same when reflected across the longest falling diagonal"
17 changes: 17 additions & 0 deletions exercises/practice/queen-attack/QueenAttack.cfc
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
/**
* Your implementation of the Queen Attack exercise
*/
component {

/**
* @returns
*/
function create(row, col) {
// Implement me here
}

function canAttack(queen1, queen2) {
// Implement me here
}

}
88 changes: 88 additions & 0 deletions exercises/practice/queen-attack/QueenAttackTest.cfc
Original file line number Diff line number Diff line change
@@ -0,0 +1,88 @@
component extends="testbox.system.BaseSpec" {

function beforeAll(){
SUT = createObject( 'QueenAttack' );
}

function run(){

describe( "My QueenAttack class", function(){

// Test creation of Queens with valid and invalid positions

it( 'queen with a valid position', function(){
expect( SUT.create( row = 2, col = 2 ) ).notToBeEmpty();
});

it( 'queen must have positive row', function(){
expect( SUT.create( row = -2, col = 2 ) ).toBeFalse();
});

it( 'queen must have row on board', function(){
expect( SUT.create( row = 8, col = 4 ) ).toBeFalse();
});

it( 'queen must have positive column', function(){
expect( SUT.create( row = 2, col = -2 ) ).toBeFalse();
});
it( 'queen must have column on board', function(){
expect( SUT.create( row = 4, col = 8 ) ).toBeFalse();
});

// Test the ability of one queen to attack another

it( 'cannot attack', function(){
whiteQueen = SUT.create( row = 2, col = 4 );
blackQueen = SUT.create( row = 6, col = 6 );
expect( SUT.canAttack( whiteQueen, blackQueen) ).toBeFalse();
});

it( 'can attack on same row', function(){
whiteQueen = SUT.create( row = 2, col = 4 );
blackQueen = SUT.create( row = 2, col = 6 );
expect( SUT.canAttack( whiteQueen, blackQueen) ).toBeTrue();
});

it( 'can attack on same column', function(){
whiteQueen = SUT.create( row = 4, col = 5 );
blackQueen = SUT.create( row = 2, col = 5 );
expect( SUT.canAttack( whiteQueen, blackQueen) ).toBeTrue();
});

it( 'can attack on first diagonal', function(){
whiteQueen = SUT.create( row = 2, col = 2 );
blackQueen = SUT.create( row = 0, col = 4 );
expect( SUT.canAttack( whiteQueen, blackQueen) ).toBeTrue();
});

it( 'can attack on second diagonal', function(){
whiteQueen = SUT.create( row = 2, col = 2 );
blackQueen = SUT.create( row = 3, col = 1 );
expect( SUT.canAttack( whiteQueen, blackQueen) ).toBeTrue();
});

it( 'can attack on third diagonal', function(){
whiteQueen = SUT.create( row = 2, col = 2 );
blackQueen = SUT.create( row = 1, col = 1 );
expect( SUT.canAttack( whiteQueen, blackQueen) ).toBeTrue();
});

it( 'can attack on fourth diagonal', function(){
whiteQueen = SUT.create( row = 1, col = 7 );
blackQueen = SUT.create( row = 0, col = 6 );
expect( SUT.canAttack( whiteQueen, blackQueen) ).toBeTrue();
});

it( 'cannot attack if falling diagonals are only the same when reflected across the longest falling diagonal', function(){
whiteQueen = SUT.create( row = 4, col = 1 );
blackQueen = SUT.create( row = 2, col = 5 );
expect( SUT.canAttack( whiteQueen, blackQueen) ).toBeFalse();
});



});

}

}
103 changes: 103 additions & 0 deletions exercises/practice/queen-attack/TestRunner.cfc
Original file line number Diff line number Diff line change
@@ -0,0 +1,103 @@
/**
* I am a CommandBox task runner which you can use to test your implementation of this exercise against the
* provided test suite. To use me, open the CommandBox CLI and run this:
*
* CommandBox> task run TestRunner
*
* To start up a test watcher that will automatically rerun the test suite every time you save a file change, run this:
*
* CommandBox> task run TestRunner --watcher
*
*/
component {

/**
* @solution Runs the tests against the solution
* @watcher Start up a file watch that re-runs the tests on file changes. Use Ctrl-C to stop
*/
function run( boolean solution=false, boolean watcher=false ) {

ensureTestBox();

if( watcher ) {

// Tabula rasa
command( 'cls' ).run();

// Start watcher
watch()
.paths( '*.cfc' )
.inDirectory( getCWD() )
.withDelay( 500 )
.onChange( function() {

// Clear the screen
command( 'cls' )
.run();

// This is neccessary so changes to tests get picked up right away.
pagePoolClear();

runTests( solution );

} )
.start();

} else {
runTests( solution );
}

}

/**
* Make sure the TestBox framework is installed
*/
private function ensureTestBox() {
var excerciseRoot = getCWD();
var testBoxRoot = excerciseRoot & '/testbox';

if( !directoryExists( testBoxRoot ) ) {

print.boldYellowLine( 'Installing some missing dependencies for you!' ).toConsole();
command( 'install' )
.inWorkingDirectory( excerciseRoot )
.run();
}

// Bootstrap TestBox framework
filesystemUtil.createMapping( '/testbox', testBoxRoot );
}

/**
* Invoke TestBox to run the test suite
*/
private function runTests( boolean solution=false ) {

// Create TestBox and run the tests
testData = new testbox.system.TestBox()
.runRaw( directory = {
// Find all CFCs...
mapping = filesystemUtil.makePathRelative( getCWD() ),
// ... in this directory ...
recurse = false,
// ... whose name ends in "test"
filter = function( path ) {
return path.reFind( ( solution ? 'Solution' : '' ) & 'Test.cfc$' );
}
} )
.getMemento();

// Print out the results with ANSI formatting for the CLI
getInstance( 'CLIRenderer@testbox-commands' )
.render( print, testData, true );

print.toConsole();

// Set proper exit code
if( testData.totalFail || testData.totalError ) {
setExitCode( 1 );
}
}

}

8 changes: 8 additions & 0 deletions exercises/practice/queen-attack/box.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
{
"dependencies":{
"testbox":"^2.5.0+107"
},
"installPaths":{
"testbox":"testbox/"
}
}
Loading

0 comments on commit de5d028

Please sign in to comment.