JavaScript Sudoku Backtracking Puzzle Solver

I have discussed using a backtracking algorithm to solve sudoku puzzles multiple times in previous posts. My first sudoku backtracking puzzle solver was programmed in Python with a Tkinter user interface. This worked well except the UI required the user to click a cell and enter a puzzle value into a popup window. I then implemented the same algorithm using an Excel VBA. This time the user entered each puzzle value directly into workbook cells but was about 10 times slower than the Python version. In this version I am using Javascript and a table within a web (this) page.

As a quick review the backtracking algorithm is a method for solving problems recursively by testing incremental solutions. If the solutions fails, then you “backtrack” the solution and attempt another solution. To solve a sudoku puzzle using the backtracking algorithm you place a value in the first empty puzzle square and test if that solution is valid (unique row, column, and 3×3 square value). If the value is not valid, then the next value is tried. If the test solution is valid, then the next empty square is filled with a value and tested until a valid solution is found. If you have tried all values without a valid solution, then you move back one “completed” square and try the next value. This continues until all empty squares have a value that meet the sudoku puzzle requirements.

The conversion from Python and Excel VBA to Javascript was straight forward. The only item I haven’t resolved is showing the solution progress live as with the Python and Excel VBA versions. This slight issue has a positive effect where the puzzle is solved more quickly without any UI updates. Also no fancy web table formatting was done.

Below is a blank sudoku puzzle. Click any table cell and place the known puzzle value. Once you have entered all the know puzzle values click “Solve Puzzle” to see the solution. A solution time is shown with the solved puzzle. You can clear the puzzle and enter new values by clicking “Clear Puzzle.” Enjoy!

Sudoku Puzzle Solver

Enter your puzzle values then click “Solve Puzzle”



Air Quality Index Fitbit App Released

Anyware, LLC Fitbit app for the display of relevant air quality data for ozone and 10 & 2.5 micron particles has been approved and published on the Fitbit Gallery.

This app helps you to know the air quality in your area before exercising outdoors. The app displays the current air quality index (AQI) using the official U.S. AQI, a color-coded index designed to communicate whether air quality is healthy or unhealthy for you. Data are provided by AirNow, which is a one-stop source for all air quality data. Using your location provided by your phone, the app finds the nearest reporting station and displays the AQI for ozone and particles 10 & 2.5 microns or less. Touch on a reported value to see the value description as provided by the Environmental Protection Agency.

To use this app, you must register and create an account at AirNow. AirNow will provide you a unique API key that is entered under the app settings on your phone. Enter the API key as provided by AirNow including all dashes. This app uses this API key to get the most relevant reported AQIs using your phone’s GPS and network connection. Instructions for obtaining an API key and configuring the app are found here.

The app only works in the U.S. and some locations in Canada and Mexico. The user needs to be within 250 miles of a reporting station used by AirNow.

Fitbit SunRise SunSet App Issue [Resolved August 20, 2022]

This published Fitbit app utilizes an API provided by sunrise-sunset.org to get the sunrise and sunset times for a given date and location. As of August 9. 2022, the sunrise-sunset API https call has an invalid certificate creating an issue. Fortunately a user notified me of this problem. Since the API certificate is invalid, returned data is throwing an error that wasn’t being properly handled in the code [Note: sunrise-sunset.org updated their certificate allowing the API to respond properly].

I am currently working on an update to the companion code to handle the unexpected error, which is discussed below. Even with this error handling, if the sunrise-sunset.org API certificate is not resolved, this will required a change in how the sunrise and sunset times are obtained. Currently my plan is to publish an app update by October 1, 2022 [Note: An app update to handle malformed JSON responses was published August 24, 2022, Version 1.1.0].

This issue with the unexpected error is found in the companion app (the code that runs on the Fitbit app on your phone). In the Fitbit architecture, messages are passed between your watch and the companion app (see this Fitbit guide for more information). The companion app provides the gateway to the Internet. The API call uses fetch() with the api calling string. The response should be a JSON string, which is parsed and the data sent back to the watch for display.

The solution to handle the unexpected error is simple. I added a “catch” statement to handle the error and pass an error indicator back to the watch. The companion code segment is show below. This code waits for a message from the watch to get sunrise and sunset data. The companion app builds the api string and then makes the api call using fetch(). The JSON string components are extracted and sent back to the watch for display. The catch sends back-100 lat and lon to indicate an error has occurred.

// Listen for messages from the device
// Message has the date we need, companion has everything else
messaging.peerSocket.onmessage = function(evt) {
  if (evt.data) {
    console.log("evt.data " + JSON.stringify(evt.data));
    if (messaging.peerSocket.readyState === messaging.peerSocket.OPEN) {
      // build api string
      var apiString = "https://api.sunrise-sunset.org/json?lat=" + lat + "&lng=" + lng + "&date=" + evt.data.getDate;
      console.log(apiString);
      
      // go to the web to get sun rise/set data that is returned in a json string
      fetch(apiString)
        .then(function(response) {return response.json();})
        .then(function(json) {
        console.log("Got JSON response from server:" + JSON.stringify(json));
        
        messaging.peerSocket.send({
          getDate: evt.data.getDate, lat: lat, lng: lng, rise: json.results.sunrise, set: json.results.sunset});
      })
      .catch(function(err) {
        console.error('Error during fetch ' + err.code);
        messaging.peerSocket.send({
          getDate: evt.data.getDate, lat: -100, lng: -100, rise: 0, set: 0}); // network data error occurred
      });
    }
  }
}

When the watch receives a message with the error indicators, the watch displays that an error has occurred but continues to allow the user to change dates and try again.

Calculating Moon Phase

Recently I published a Fitbit app that calculates the Moon phase and then displays the proper phase image and illumination value. The user can select a different date or simply increment the date using buttons. Some feedback I received was that the app was fast and they wanted to understand why?

First, the app performs all calculations on the watch. No phone resources are need No GPS. No Internet. The calculations are based on a dateNow date object (this object is settable by the user though the interface that is not part of this discussion).

The calculation is based on an article I found by SubsySTEMs while performing an Internet search. Their paper broke the Moon phase calculation into a series of steps, which was easy to follow and translated directly to JavaScript. The output of their calculation is the number of days since the last New Moon. From there the Moon phase is determined. There are eight Moon phases (in order from New):

  • New
  • Waning Crescent
  • Third Quarter
  • Waning Gibbous
  • Full
  • Waxing Gibbous
  • First Quarter
  • Waxing Crescent

Using the days since the last New Moon you can find the phase but beware, each phase isn’t just 1/8 of 29.53 days. Shown below is the JavaScript that implements the attached paper.

function calMoonPhase() {
  // calculate moon phase for date
  let month = dateNow.getMonth() + 1;
  let year = dateNow.getFullYear();
  if(month < 3) {
    year = year - 1;
    month = month + 12;
  }

  let a = Math.floor(year/100);
  let b = Math.floor(a/4);
  let c = 2 - a + b;
  let d = dateNow.getDate();
  let e = Math.floor(365.25*(year+4716));
  let f = Math.floor(30.6001 * (month + 1));
  let jd = c + d + e + f - 1524.5;
  let daysSinceNew = jd - 2451549.5;
  let newMoons = daysSinceNew / 29.53;

  <...Determine Moon phase...>
  <...Determine image to show...>
  <...Calculate illumination...>


}