Friday 18 September 2020

Magic Triangle - Solution

I first saw this puzzle in CSIRO’s Double Helix here.

The problem we are solving is described as:

Given a triangle with circle on each point and on each side:

I first saw this puzzle in CSIRO’s Double Helix here.

The Magic Triangle problem we are solving is described as:

You are given a triangle with circle on each point and on each side:

Magic Triangle

Magic Triangle

Then, using the numbers from 1 to 6, arrange them in a triangle with three numbers on each side. Swap them around until the sides all add up to the same number.

Finally, sum each side to 10.

Method

Let’s label the triangle: starting from any vertex label the nodes:

Labelled Magic Triangle

Labelled Magic Triangle

The method to solve this problem is broken into the following steps:

  • get all permutations of numbers 1 to 6 as a, b, c, d, e, f

  • filter permutation to satisfy conditions:

    • a + b + c == c + d + e == e + f + a

    • and final condition: a + b +c == 10

Using Haskell

All permutations of numbers 1 to 6:

This will give 6! = 720 permutations.

Filter on sides summing up to the same value:

Which gives all solutions where the sides are equal sums:

  [(3,2,5),(5,4,1),(1,6,3)]
  [(2,4,3),(3,5,1),(1,6,2)]
  [(1,5,3),(3,4,2),(2,6,1)]
  [(1,4,5),(5,2,3),(3,6,1)]
  [(5,3,4),(4,2,6),(6,1,5)]
  [(6,2,4),(4,3,5),(5,1,6)]
  [(4,5,2),(2,3,6),(6,1,4)]
  [(6,3,2),(2,5,4),(4,1,6)]
  [(2,3,6),(6,1,4),(4,5,2)]
  [(4,1,6),(6,3,2),(2,5,4)]
  [(3,4,2),(2,6,1),(1,5,3)]
  [(1,6,2),(2,4,3),(3,5,1)]
  [(5,4,1),(1,6,3),(3,2,5)]
  [(4,3,5),(5,1,6),(6,2,4)]
  [(6,1,5),(5,3,4),(4,2,6)]
  [(3,6,1),(1,4,5),(5,2,3)]
  [(5,2,3),(3,6,1),(1,4,5)]
  [(2,6,1),(1,5,3),(3,4,2)]
  [(3,5,1),(1,6,2),(2,4,3)]
  [(1,6,3),(3,2,5),(5,4,1)]
  [(5,1,6),(6,2,4),(4,3,5)]
  [(2,5,4),(4,1,6),(6,3,2)]
  [(6,1,4),(4,5,2),(2,3,6)]
  [(4,2,6),(6,1,5),(5,3,4)]

Filter on sides summing to 10:

Which gives our final list of solutions:

  [(3,2,5),(5,4,1),(1,6,3)]
  [(1,4,5),(5,2,3),(3,6,1)]
  [(5,4,1),(1,6,3),(3,2,5)]
  [(3,6,1),(1,4,5),(5,2,3)]
  [(5,2,3),(3,6,1),(1,4,5)]
  [(1,6,3),(3,2,5),(5,4,1)]

Note here that the solutions aren’t unique: there are repetitions if you consider rotations or node reversals. Can we filter these out to get the only unique solution?

Try ordering:

The idea here is that as the nodes are unique, we can order them. This yields our final solution:

  [(5,2,3),(3,6,1),(1,4,5)]

Using one other Haskell refinement we can write this as:

Solved Magic Triangle

Solved Magic Triangle

Check your answer on CSIRO page here.

Using Python

Python now has list comprehensions just like many other programming languages, so the solution is much the same. Also, use the built-in permutations function from itertools:

Which yields the same results as our previous solution in Haskell:

>>> [[(5, 2, 3), (3, 6, 1), (1, 4, 5)]]

Saturday 20 June 2020

Viral Maths Problems

Each year we are treated to another viral math problem. Can you solve (insert bad equation here)? The answer is rarely given, and the equation is poorly structured. So, lets unpack one such problem and explain why I believe they are so badly formed.

Example

The last one I saw online was the challenge:
Can you solve?
8 ÷ 2(2+2)
My first observation is the unusual use of ÷ (mathematicians prefer '/') and bad bracketing. Let us clean up the expression to clear up some ambiguity:
8 ÷ 2 × (2+2)

This makes it much easier to the next step of applying BODMAS.
The order of operations here are:
  1. Solve the Brackets, then
  2. From left to right apply division's and multiplications
  3. From left to right apply addition's and subtraction's
Here: division and multiplication have equal precedence as do addition and subtraction.
Applying these operations gives:

8 ÷ 2(2+2) = 8 ÷ 2 × (2 + 2)
                 =  8 ÷ 2 × 4
                 =  4 × 4
                 =  16
So, why is this a badly formed question? A goal of mathematics is to accurately and unambiguously provide solutions to problems. The real challenge is to answer the right problem. If the purpose of the problem was to provide a correct answer and not lead to argument on interpretation then the question could have been asked in a number of different ways:
Question What is (8 ÷ 2) × (2 + 2) ?
Answer (8 ÷ 2) × (2 + 2) = (4) × (4) = 4 × 4 = 16
Or, you could ask:
Question What is 8 ÷ (2 × (2 + 2)) ?
Answer 
8 ÷ (2 × (2 + 2)) = 8 ÷ (2 × 4) = 8 ÷ 8 = 1
Another variant of this question could be:
Question Explain the order of operations for 8 ÷ 2 × (2 + 2)  ?
Answer
Apply BODMAS and evaluate from left to right:
  1. First evaluate the terms inside the brackets: 8 ÷ 2 × (2 + 2) = 8 ÷ 2 × 4
  2. Then evaluation from left to right: 8 ÷ 2 × 4 = 4 × 4
  3. Giving the final operation: × 4 = 16
So, the problem could be much clearer about it's intent.
What was the point of the original challenge?
I feel that the problem as stated in so many online forums is more click-bait to generate an argument than as a pedagogical exercise.

Friday 28 February 2020

Git Pipelines

Git has become the de facto standard for version control. This has given rise to many vendors hosting Git repositories. Each vendor provides Git functionality such as branching, pull requests, project membership. Now there is growing competition to provide Continuous Integration / Continuous Delivery (CI/CD) services. It has become a very competitive market. One feature that extends version control beyond just hosting source repositories, is pipelines. Pipelines are an extensible suite of tools to build, test and deploy source code. Even data hosting sites like Kaggle now support pipelines.
This article provides a brief summary of some pipeline features from three popular Git hosting sites: GitLabBitbucket and GitHub.
This article was written in GitLab flavoured Markdown, and rendered to HTML using pandoc. This provides a version controlled project that can be used to show features for each Git repository.
The features being tested are:
  • use of Docker images to provide a consistent build environment
  • customise environment to install required tool)
  • use of stages to show how ti setup a tasks that make up a stage
  • archive of generated artefacts so we can save the rendered HTML document
The work-flow is:
  1. install GNU Make
  2. install pandoc
  3. render HTML from Markdown
  4. archive rendered HTML document for later download
Here are other source repositories that offer pipelines that you may also like to try:
The source code for this project that includes the pipeline code for each Git repository is available at: https://github.com/frankhjung/article-git-pipelines

GitLab

GitLab pipelines are a well integrated tool. CI / CD pipelines are easily accessed from the sidebar:
CI/CD on sidebar
CI/CD on sidebar
Viewing jobs gives you a pipeline run history:
Pipeline job history
Pipeline job history
The YAML configuration .gitlab-ci.yml looks like:
Where:
  • image - specifies a custom Docker image from Docker Hub
  • variables - define a variable to be used in all jobs
  • stages - declares the jobs to run
  • before_script - commands to run before all jobs
  • render - name of job associated with a stage. Jobs of the same stage are run in parallel
  • stage - associates a job with a stage
  • script - commands to run for job
  • artitacts - path to objects to archive, these can be downloaded if job completes successfully
What this pipeline configuration does is:
  • load a Alpine Docker image that includes pandoc
  • invoke the build stage which
    • initialises with alpine package update and install GNU make
    • runs the render job which makes the given target
    • on successful completion, the target HTML is archived for later download
GitLab is easy to configure and easy to navigate. There are many other pipeline features including scheduling and configuring jobs by branch. One feature that I have used on Maven / Java projects is caching a local .m2 directory. This speeds up the build as you don’t have a completely new environment for each build, but can leverage previous cached artefacts. GitLab also provides a clear cache button on the pipeline page.
GitLab also provides additional services that can be integrated with you project, for example: JIRA tracking, Kubernetes and Prometheus monitoring.

Bitbucket

The example is publicly available here. The configuration is similar to that from GitLab. The pipeline and settings are easily navigated to using the side-bar.
Pipeline job history
Pipeline job history
The pipeline configuration is similar. But there are important differences. The bitbucket-pipelines.yml configuration for this project looks like:
Here, the pipeline will be triggered automatically on commits to master branch. A Docker image can be defined at the level of the pipeline step. Variables can be defined and read from the Bitbucket settings page. This is useful for recording secrets that you don’t want to have exposed in your source code. However, internal script variables are set via the script language, which in this example is Bash. Finally, in order for the build artefacts to be preserved after the pipeline completes, you can publish to a downloads location. This requires that a secure variable be configured, as described here. If you don’t, the pipeline workspace is purged on completion.
Downloads
Downloads
Pipeline build performance is very good, where this entire step takes less than a minute to complete.
Build
Build
The free account limits you to 50 minutes per month with 1GB storage.
That you have to externally / manually configure repository settings has some benefits. The consequence though, is that there are settings that are not recorded by version control. This means there are external dependencies other than what is recorded by the pipeline configuration.
A feature of being able to customise the Docker image used at the step level is that your build and test steps can use different images. This is great if you want to trial your application on a production like image.
Although the free account is limited in time there are some nice features with good performance.

GitHub

When you create a GitHub repository, there is an option to include Azure Pipelines. However this is not integrated to GitHub directly, but is configured under Azure DevOps. Broadly, the steps to set-up a pipeline are:
  • sign up to Azure pipelines
  • create a project
  • add GitHub repository to project
  • configure pipeline job
Azure DevOps Pipelines
Azure DevOps Pipelines
Builds can be run and managed from the Azure DevOps dashboard. There appears no way to manually trigger a build from the GitHub repository. Though, if you commit it will happily trigger a build for you. But, again, you need to be on the Azure DevOps dashboard to monitor the pipeline steps. The interface could really be improved by adding a direct link in the sidebar to the pipelines like the other repositories.
The following YAML configuration uses an Azure provided Ubuntu 16.04 image. There are limited images, but they are maintained and kept installed packages are kept up to date. There are many pre-installed packages.
The azure-pipelines.yml pipeline configuration looks like:
If the package you need is not installed, then you can install it if available in the Ubuntu package repositories. The default user profile is not root, so installation requires sudo.
Azure DevOps Job History
Azure DevOps Job History
Finally, to be able to download the generated artefacts you need to invoke specific PublishBuildArtifacts task as described here.
Azure DevOps Download Artefacts
Azure DevOps Download Artefacts
Azure is fast as it uses images that Microsoft build and host. The above job to install pandoc and render this page as HTML takes only 1 minute.
I found the biggest negative to Azure Pipelines was the poor integration to the GitHub dashboard. Instead, you are strongly encouraged to manage pipelines using the Azure DevOps dashboard.

Summary

Git pipelines may not be suitable in all circumstances. There are however, clear advantages to using a hosted pipeline that ensures that your project build somewhere other than your laptop. It also removes the cost of building and maintaining custom CI infrastructure. The pipeline configuration also augments your projects documentation for build, test and deployment. It is an independent executable description for your project that explicitly lists dependencies. Hosted pipelines also ease the effort for provisioning and maintaining your own build infrastructure. This could be a great benefit to projects where time constraints limit ones ability to prepare an environment.

Acknowledgements