Weekly Challenge 293
Each week Mohammad S. Anwar sends out The Weekly Challenge, a chance for all of us to come up with solutions to two weekly tasks. My solutions are written in Python first, and then converted to Perl. It's a great way for us all to practice some coding.
Task 1: Similar Dominos
Task
You are given a list of dominos, @dominos
.
Write a script to return the number of dominoes that are similar to any other domino.
$dominos[i] = [a, b]
and $dominos[j] = [c, d]
are same if either (a = c and b = d) or (a = d and b = c)
.
My solution
I'm not sure if it's a British/US English thing or something else, but I'm using Dominoes as the plural of Domino. Dominos what what you get when you are hungry.
For this task, I take integers from the command line and convert them to a list of lists (arrays of arrays in Perl). If this was an actual real-world project, I'd probably use a Dataclass, and have an equality operator.
I have a double loop. The outer loop - called i
- is from 0 to one less than the number of dominoes. The inner loop - called j
- is also the same. I skip the case when i
and j
are the same. If the dominoes at position i
and j
are the same (either same number or opposite numbers), I add one to count
and exit the inner loop.
def similar_dominoes(dominoes: list) -> int:
count = 0
for i in range(len(dominoes)):
for j in range(len(dominoes)):
if i == j:
continue
if (dominoes[i][0] == dominoes[j][0] and dominoes[i][1] == dominoes[j][1]) \
or (dominoes[i][0] == dominoes[j][1] and dominoes[i][1] == dominoes[j][0]):
count += 1
break
return count
Examples
$ ./ch-1.py 1 3 3 1 2 4 6 8
2
$ ./ch-1.py 1 2 2 1 1 1 1 2 2 2
3
Task 2: Boomerang
Task
You are given an array of points, (x, y)
.
Write a script to find out if the given points are a boomerang.
A boomerang is a set of three points that are all distinct and not in a straight line.
My solution
Like with the last task, I take integers from the command line and convert them to a list of lists (arrays of arrays in Perl).
I remember enough from high school math to know we can get the slope (gradient) of two points with the formula (x2 - x1) ÷ (y2 - y1)
. However if y1
and y2
are the same, we get a division by zero error.
Therefore I use the following checks:
- If all
y
values (second item in each list) are the same, returnFalse
as the points make a flat line. - If any
y
values are the same as the firsty
value, returnTrue
(as we know at least one y value is different). - Calculate the absolute slop between the first point and the other points using the above formula. Store this as a set. Sets don't store duplicate values.
- If the set only has one value, it's a straight line and return
False
. If there is more than one value, then it's a boomerang. I'm not here to determine if it is a good boomerang :)
def is_boomerang(points: list) -> bool:
if all(points[0][1] == points[i][1] for i in range(1, len(points))):
return False
if any(points[0][1] == points[i][1] for i in range(1, len(points))):
return True
degrees = set(abs((points[0][0] - points[i][0]) / (points[0][1] - points[i][1])) for i in range(1, len(points)))
return False if len(degrees) == 1 else True
Examples
$ ./ch-2.py 1 1 2 3 3 2
true
$ ./ch-2.py 1 1 2 2 3 3
false
$ ./ch-2.py 1 1 1 2 2 3
true
$ ./ch-2.py 1 1 1 2 1 3
false
$ ./ch-2.py 1 1 2 1 3 1
false
$ ./ch-2.py 0 0 2 3 4 5
true
Top comments (0)