RogerBW's Blog

The Weekly Challenge 293: Domino Boomerang 03 November 2024

I’ve been doing the Weekly Challenges. The latest involved checking dominoes and doing some floating-point operations. (Note that this ends today.)

Task 1: Similar Dominos

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 the same if either (a = c and b = d) or (a = d and b = c).

The obvious (to me) way of solving this is to use a hash function which will have the same value for both [y, x] and [x, y]. Perl:

sub dvalue($a) {
  if ($a->[0] < $a->[1]) {
    return $a->[0] * 64 + $a->[1];
  } else {
    return $a->[0] + $a->[1] * 64
  }
}

sub similardominoes($a) {

Count dominoes by hash value.

  my %c;
  map {$c{dvalue($_)}++} @{$a};

Then look through its values. Any bucket with more than one item in it contains dominoes that are similar to any other domino.

  my $t = 0;
  foreach my $v (values %c) {
    if ($v > 1) {
      $t += $v;
    }
  }
  return $t;
}

A counter class is useful once again in languages that have one.

Task 2: Boomerang

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.

Usual warnings apply with respect to floating-point equality, though the test cases all worked for me in all the languages.

Python:

def boomerang(a):

First, check for coincident points (always return false), and if that passes establish a set of deltas: p0 to p1, p0 to p2. (Yes, I'm doing two unrelated things in the outer loop. I think I may have picked up that habit in my very brief C days, when setting up even a straightforward loop meant mucking about with end conditions.)

  delta = []
  for ij in range(2):
    for ik in range(ij + 1, 3):
      if a[ij][0] == a[ik][0] and a[ij][1] == a[ik][1]:
        return False
    delta.append([a[ij + 1][0] - a[0][0], a[ij + 1][1] - a[0][1]])

If all three points have the same X value, return false.

  if delta[0][0] == 0 and delta[1][0] == 0:
    return False

Otherwise, if just one pair does, return true. (This won't spot the case where p1 and p2 are on the same vertical line distinct from p0, but that's OK; I'm only doing this special case so that my main algorithm won't divide by zero.)

  if delta[0][0] == 0 or delta[1][0] == 0:
    return True

Now we know that delta-X from p0 to p1 is not zero, so we can establish a slope for the line from p0 to p1.

  m = delta[0][1] / delta[0][0]

And a Y-offset. (Yeah, I still think in terms of y = mx + c not y = a + bx. Also I tend to use a as the input variable in these things.)

  c = a[0][1] - a[0][0] * m

Then it's a boomerang if p2 does not lie on that line.

  return a[2][1] != a[2][0] * m + c

Languages which distinguish floating-point obviously have a lot of type conversions in the last three lines.

Full code on github.

Add A Comment

Your Name
Your Email
Your Comment

Your submission will be ignored if any field is left blank, but your email address will not be displayed. Comments will be processed through markdown.

Search
Archive
Tags 1920s 1930s 1940s 1950s 1960s 1970s 1980s 1990s 2000s 2010s 3d printing action advent of code aeronautics aikakirja anecdote animation anime army astronomy audio audio tech base commerce battletech beer boardgaming book of the week bookmonth chain of command children chris chronicle church of no redeeming virtues cold war comedy computing contemporary cornish smuggler cosmic encounter coup covid-19 crime crystal cthulhu eternal cycling dead of winter doctor who documentary drama driving drone ecchi economics en garde espionage essen 2015 essen 2016 essen 2017 essen 2018 essen 2019 essen 2022 essen 2023 essen 2024 existential risk falklands war fandom fanfic fantasy feminism film firefly first world war flash point flight simulation food garmin drive gazebo genesys geocaching geodata gin gkp gurps gurps 101 gus harpoon historical history horror hugo 2014 hugo 2015 hugo 2016 hugo 2017 hugo 2018 hugo 2019 hugo 2020 hugo 2021 hugo 2022 hugo 2023 hugo 2024 hugo-nebula reread in brief avoid instrumented life javascript julian simpson julie enfield kickstarter kotlin learn to play leaving earth linux liquor lovecraftiana lua mecha men with beards mpd museum music mystery naval noir non-fiction one for the brow opera parody paul temple perl perl weekly challenge photography podcast politics postscript powers prediction privacy project woolsack pyracantha python quantum rail raku ranting raspberry pi reading reading boardgames social real life restaurant reviews romance rpg a day rpgs ruby rust scala science fiction scythe second world war security shipwreck simutrans smartphone south atlantic war squaddies stationery steampunk stuarts suburbia superheroes suspense television the resistance the weekly challenge thirsty meeples thriller tin soldier torg toys trailers travel type 26 type 31 type 45 vietnam war war wargaming weather wives and sweethearts writing about writing x-wing young adult
Special All book reviews, All film reviews
Produced by aikakirja v0.1