aboutsummaryrefslogtreecommitdiff
path: root/challenge-281/sgreen/python
diff options
context:
space:
mode:
Diffstat (limited to 'challenge-281/sgreen/python')
-rwxr-xr-xchallenge-281/sgreen/python/ch-1.py27
-rwxr-xr-xchallenge-281/sgreen/python/ch-2.py69
-rwxr-xr-xchallenge-281/sgreen/python/test.py20
3 files changed, 116 insertions, 0 deletions
diff --git a/challenge-281/sgreen/python/ch-1.py b/challenge-281/sgreen/python/ch-1.py
new file mode 100755
index 0000000000..293f65177e
--- /dev/null
+++ b/challenge-281/sgreen/python/ch-1.py
@@ -0,0 +1,27 @@
+#!/usr/bin/env python3
+
+import re
+import sys
+
+
+def check_color(coords: str) -> bool:
+ '''Determine if a coordinate on a chess board is light'''
+
+ # Check if the position is valid
+ if not re.search('^[a-h][1-8]$', coords):
+ raise ValueError('Not a valid chess coordinate!')
+
+ if coords[0] in ('a', 'c', 'e', 'g') and int(coords[1]) % 2 == 0:
+ return True
+ if coords[0] in ('b', 'd', 'f', 'h') and int(coords[1]) % 2 == 1:
+ return True
+ return False
+
+
+def main():
+ result = check_color(sys.argv[1])
+ print('true' if result else 'false')
+
+
+if __name__ == '__main__':
+ main()
diff --git a/challenge-281/sgreen/python/ch-2.py b/challenge-281/sgreen/python/ch-2.py
new file mode 100755
index 0000000000..76246733aa
--- /dev/null
+++ b/challenge-281/sgreen/python/ch-2.py
@@ -0,0 +1,69 @@
+#!/usr/bin/env python3
+
+import re
+import sys
+
+
+def convert_coord_to_list(coord: str) -> list:
+ letters = ' abcdefgh'
+ return (letters.index(coord[0]), int(coord[1]))
+
+
+def knights_move(start_coord: str, end_coord: str) -> int:
+ '''Calculate the least number of knight moves between two positions'''
+
+ # Check if the position is valid
+ for coord in (start_coord, end_coord):
+ if not re.search('^[a-h][1-8]$', coord):
+ raise ValueError(
+ f'The position {coord} is not a valid chess coordinate!')
+
+ # Direction the knight piece can move
+ deltas = ([2, 1], [2, -1], [-2, 1], [-2, -1],
+ [1, 2], [1, -2], [-1, 2], [-1, -2])
+
+ # Where we start
+ coords = [convert_coord_to_list(start_coord)]
+
+ # Where we want to end
+ target = convert_coord_to_list(end_coord)
+
+ # Count the required moves
+ moves = 1
+
+ # Co-ordinates we've already been to
+ seen = []
+
+ while True:
+ # The new coordinates after we've made the next move
+ new_coords = []
+
+ # For all existing places after the previous move
+ for coord in coords:
+ # Move the knight in all possible ways
+ for delta in deltas:
+ new_pos = (coord[0] + delta[0], coord[1] + delta[1])
+
+ # But exclude moves that take it off the board or we've already used
+ if not 0 < new_pos[0] < 9 or not 0 < new_pos[1] < 9 or new_pos in seen:
+ continue
+
+ if new_pos == target:
+ # We've hit the target position
+ return moves
+
+ new_coords.append(new_pos)
+ seen.append(new_pos)
+
+ # Looks like we'll need to move again!
+ coords = new_coords
+ moves += 1
+
+
+def main():
+ result = knights_move(sys.argv[1], sys.argv[2])
+ print(result)
+
+
+if __name__ == '__main__':
+ main()
diff --git a/challenge-281/sgreen/python/test.py b/challenge-281/sgreen/python/test.py
new file mode 100755
index 0000000000..a385705bf1
--- /dev/null
+++ b/challenge-281/sgreen/python/test.py
@@ -0,0 +1,20 @@
+#!/usr/bin/env python3
+
+import unittest
+ch_1 = __import__('ch-1')
+ch_2 = __import__('ch-2')
+
+
+class TestClass(unittest.TestCase):
+ def test_ch_1(self):
+ self.assertTrue(ch_1.check_color('d3'))
+ self.assertFalse(ch_1.check_color('g5'))
+ self.assertTrue(ch_1.check_color('e6'))
+
+ def test_ch_2(self):
+ self.assertEqual(ch_2.knights_move('g2', 'a8'), 4)
+ self.assertEqual(ch_2.knights_move('g2', 'h2'), 3)
+
+
+if __name__ == '__main__':
+ unittest.main()