Table of Contents

Introduction

This article explains how to model a logic grid puzzle in the JavaScript programming language. Logic grid puzzles, also known as logic puzzles or logic problems can be found in magazines by Dell Magazines and Penny Press. The Mystery Master website at http://www.mysterymaster.com is devoted to writing software that can solve logic puzzles. Think "Skynet", but without the intent of eliminating mankind. This article will focus on the logic puzzle "Five Houses". Earlier versions of this two-star puzzle have been called "Einstein's Riddle" or the "Zebra Puzzle". This version of the puzzle appeared in a column by the very cerebral Marilyn vos Savant. Please look at this logic puzzle before continuing. You should have a basic knowledge of JavaScript, know some of the newer constructs, and understand how classes work in JavaScript.

JavaScript

JavaScript is the client-side language of the web. I don't think it is the best language, but there have been improvements over the years. I wish it was strongly-typed, had better scoping rules (public, private, etc.), but I guess I could use TypeScript. It can't do some of the nice things I can do in C# like initialize an object when I instantiate it. It doesn't have the null-coalescing operator??. It is also very fragile - your IDE and/or browser may not pick up your mistakes. But enough complaining... Here are some of the things I do like.

The "use strict"; option.

Define a constant with the const keyword.

Avoid the hoisting of variables with the let keyword.

The addEventListener method so the method the event calls can be local.

The ability to return closures - functions that refer to local variables. See the sections on Smart Links and Smart Rules for more on closures.

The ability to store/retrieve information in local storage.

What is a Logic Puzzle

A logic puzzle is a story of mystery. But you are not only its reader, you are it's most important character - the detective! And as with any detective worth their spyglass, you must solve the mystery. Most logic puzzles have properties such as its title, author, and number of stars. One star means the puzzle is easy, and five stars means it is very difficult. Each puzzle also has a humorous image. While these properties are important, they won't help you solve a logic puzzle. What does help are the clues of the puzzle. The clues are usually given in a numbered list, but sometimes they can also be in the introduction. The properties, introduction, and list of clues are the text of the logic puzzle.

Note: If you wanted to solve a logic puzzle on your own, you have the following tools at your disposal: the Chart and the Grids. Both of these forms will be discussed in a future article.

To model a logic puzzle, the text of the logic puzzle must be parsed into specific types of data. Everything that is essential to solving a logic puzzle must be captured by this data. There is one important thing to remember as you go forward:

All of the relationships between the nouns in a logic puzzle must be expressed as either facts or rules.

Please read the text of the puzzle with the following questions in mind.

What are the relationships between the nouns? These are expressed by the verbs and links.

What are the facts? These combine the nouns, verbs, and links into static statements.

What are the rules? These are conditional statements. Not all puzzles have rules, including this one.

We need data structures to store each type of data, and when we talk data structures in a world of OOP, we're talking classes. And what should we name a class that stores all of the data for a logic puzzle? Why Puzzle of course!

Puzzle

The Puzzle class is the parent class of every puzzle module. This class performs many duties. It has methods to load data into an array for each type of object. It has a method to validate the data. And it needs to make that data available to the classes that view and solve the puzzle.

Puzzle Module

The puzzle module stores all of the data and functions necessary to solve it. In order to do this, this class must inherit from the base class Puzzle. Below is the puzzle module for the logic puzzle "Five Houses". Please note that since all of the relationships in this puzzle can be represented by facts, there are no rules.

Prototypal Inheritance

You can see that the name of the puzzle module class is FiveHouses. So how does our child class inherit the powers of the Puzzle class? The last three lines of every puzzle module performs "inheritance" for a prototype-based language. Note: the variable puzzle was defined earlier as a global.

Sets the FiveHouses class to inherit from the base class Puzzle. Unfortunately, the constructor for the child class FiveHouses is now set to the constructor of the parent class Puzzle.

Sets the constructor for FiveHouses to its own constructor.

Instantiates (creates) an object of class FiveHouses, which inherits from Puzzle, and invokes its own constructor.

I currently do not use the class and constructor keywords introduced in ECMAScript 2015. So when I say constructor, I really mean the function FiveHouses that I treat as a class. Let's discuss each section you may see in a puzzle module.

Properties

Properties are the metadata of a logic puzzle. The only properties we care about are the puzzle's name and title. This information is set via the Puzzle members myName and myTitle. I use these names instead of the more generic name and title to avoid naming collisions.

Nouns

The nouns in a logic puzzle must be organized into categories. These categories are called noun types. A puzzle must have at least two noun types. The noun types for our example puzzle are: House, Color, Nationality, Hobby, Pet, and Drink. Note that the names of the noun types are singular, not plural. For this puzzle, there are five nouns for each type. Below is a table of the nouns, where the column header is the noun type. Please keep in mind that each noun type must have the same number of nouns, and there must be at least two nouns per noun type.

Nouns

#

House

Color

Nationality

Hobby

Pet

Drink

1

1st

Red

Englishman

Stamps

Dogs

Coffee

2

2nd

Green

Spaniard

Antiques

Snails

Tea

3

3rd

White

Ukrainian

Singing

Fox

Milk

4

4th

Yellow

Norwegian

Gardening

Horse

Juice

5

5th

Blue

Japanese

Cooking

Zebra

Water

The first column (#) in this table shows the one-based number of the noun. Usually, the order of the nouns within a noun type is not important, but there is one major exception:

If a link references a noun type, then the nouns for that type must be in a logical order.

Placeholders

While most logic puzzles will give you all of the nouns in the puzzle, some very difficult puzzles may not give you all of the values of the nouns. This means the values must be calculated by one or more rules. Nouns where the initial value is unknown are called placeholders. Usually these values are numeric, such as the number of people who attended a talk in "Astrophysics Conference", or the age of a salesperson in "Dandy Salespeople".

Verbs

There are always three verbs in a logic puzzle. The three verbs are: the negative (false) verb, the possible (unknown) verb, and the positive (true) verb. Each verb has a brief text phrase for its name, and a character for its code. Our example logic puzzle has the following verbs.

Verbs

#

Type

Name

Code

-1

Negative

is not

X

0

Possible

may be

1

Positive

is

O

Here is a brief description of each verb.

The negative verb has the name "is not", and its code is the 'X' character.

The possible verb has the name "may be", and its code is the blank character.

The positive verb has the name "is", and its code is the 'O' character.

The tense for the names of the verbs can be present, past, or future, and only affects the negative and positive verbs. As a general rule, the names of the negative and positive verbs should come from the clues. Here is an example.

The negative verb can be "is not", "was not", or "will not be".

The positive verb can be "is", "was", or "will be".

The characters you see in the Grids form are given by the character for each verb. Before you begin solving a logic puzzle, each cell in the grids contains the possible verb, usually represented by a blank character. To solve a logic puzzle, each cell that contains the possible verb must be replaced by either the negative verb ('X'), or the positive verb ('O'). When all of the cells have been properly filled in, then you have the solution to the logic puzzle.

Adding Verbs

The three nouns are always defined for each puzzle module. These three global variables are: IsNot, Maybe, and Is. Since the predefined attributes for these verbs are acceptable, this section is not needed for our puzzle module.

Note: I know I should avoid globals, but I also want to avoid having to prefix each class member with "this". So this is my compromise.

Links

All of the relationships between two nouns in a puzzle must be expressed as verbs and links. When you examine the clues in a puzzle and the relationship is not obvious, this means the link is "with". For example, the first clue in our example puzzle states: "The Englishman lives in the red house." This clue can be expressed as a fact, where the first noun is "The Englishman", the verb is positive, and the link is "with". Anytime a clue states that one noun is or is not with another noun, just use the default link "with". In other words, the phrase "lives in" really means "with". The data for this fact could be interpreted as: fact(englishman, is, with, red).

For our example puzzle, there are three links: "with", "directly to the right of", and "next to". All of the links use the noun type House. To understand these links, draw a picture of the five houses in this puzzle. You want a picture of five numbered houses in a row, where the 1st house is on the far left, and the 5th house is on the far right. Assume each house is initially colorless.

1st

2nd

3rd

4th

5th

With

The first clue in our logic puzzle states: "The Englishman lives in the red house." If a clue states that one noun is or is not with another noun, then the default link "with" is used. In less-than-stellar English, the first clue tells us "The Englishman is with the red house." The "with" link is a one-to-one relationship because it means that a noun is with itself. This link is automatically defined for you, and it defaults to the first noun type of the puzzle. For our puzzle, here are the only statements that are true:

House 1 is with house 1

House 2 is with house 2

House 3 is with house 3

House 4 is with house 4

House 5 is with house 5

I highly recommend that if a noun type is referenced by the links, then it should be the first noun type you define. With that in mind, I should point out that a logic puzzle may have some links that reference one noun type, and other links that reference another noun type. For example "Small Town Motels" has seven links that reference three different noun types. Now that's a hard logic puzzle! In cases like this, have the most logical noun type be first.

Directly To The Right Of

The second link given by the clues is "directly to the right of". This link is in clue 5 "The green house is directly to the right of the white one." Going back to our picture, this means only the following statements are true.

House 2 is directly to the right of house 1

House 3 is directly to the right of house 2

House 4 is directly to the right of house 3

House 5 is directly to the right of house 4

This type of link has a "one-to-one" relationship because exactly one house is directly to the right of another house.

Next To

The third link given by the clues is "next to". This link is in clues 10, 12, and 14. While some houses are only next to one house, other houses are between two houses. Therefore, this link is not "one-to-one". Can you determine all of the statements that are true for this link?

Comparisons

The "directly to the right of" link is a "more than" comparison because we want to see if noun A is higher than noun B. This comparison is done using the one-based number of the noun. To reduce the number of links in a logic puzzle, use either "more than" or "less than" comparisons, but not both. For example, if a fact stated "A is less than B", you can also say "B is more than A", and vice versa. Below are the links for our example puzzle. The first table displays the links. Here is a brief description for each column.

# is the zero-based number of the link.

Noun Type is the noun type referenced by the link.

Name is the name of the link.

1:1 tells use if the link is one-to-one (checked) or not (unchecked).

The subsequent tables display the link grid for each link. This type of grid visually informs us the relationship between noun A (left-most column of row headers) and noun B (top-most row of column headers). If the intersecting cell has a 'O', then the relationship between noun A and noun B is true. If the intersecting cell has a 'X', then the relationship between noun A and noun B is false.

Note: The function assigned to each link via the f member is given by a method in the SmartLink static class. See the section on Smart Links for more information. If you cannot find what you want in the SmartLink class, you will need to "roll your own".

Facts

The facts are the static relationships between two nouns. An example is "A is next to B." A fact has the following form.

"Noun 1 Verb Link Noun 2.", where (1) the verb is positive or negative, and (2) the verb and link is the relationship between the two nouns.

The first clue in our example puzzle can be expressed directly as a fact: "The Englishman lives in the red house." In fact (pun intended), what makes this puzzle unique is that each clue is a fact. Here are the facts for this puzzle.

Facts

#

X

Hits

Name

1

✓

0

The Englishman is in the red house (clue 1).

2

✓

0

The Spaniard's pet is dogs (clue 2).

3

✓

0

Coffee is drunk in the green house (clue 3).

4

✓

0

The Ukrainian's favorite drink is tea (clue 4).

5

✓

0

The green house is directly to the right of the white house (clue 5).

6

✓

0

The man who's hobby is stamps owns snails (clue 6).

7

✓

0

The man who's hobby is antiques is in the yellow house (clue 7).

8

✓

0

The man in the 3rd house drinks milk (clue 8).

9

✓

0

The Norwegian is in the 1st house (clue 9).

10

✓

0

The man who's hobby is singing is next to the man with the fox (clue 10).

11

✓

0

The man who's hobby is gardening drinks juice (clue 11).

12

✓

0

The man who's hobby is antiques is next to the man with the horse (clue 12).

13

✓

0

The Japanese man's hobby is cooking (clue 13).

14

✓

0

The Norwegian is next to the blue house (clue 14).

Here is a brief description for each column.

# is the one-based number of the fact.

X tells you if the fact is enabled (checked) or disabled (unchecked).

Hits is the number of times a fact is referenced.

Name is the text of the fact.

Types of Facts

The types of facts are given below. While the first type of fact yields only one mark, the other types of facts usually produce more than one mark.

Type 1

A type 1 fact has the default link "with". Only a type 1 fact has "with" as the link. It is the easiest to process, and the easiest to notice when a mark contradicts it. Most of the facts in our example puzzle "Five Houses" are type 1 facts.

I must point out that both nouns in a type 1 fact cannot have the same noun type. Why? Because in any logic grid puzzle, two nouns of the same noun type can never be together! If you had the fact with two first names such as "Abe is with Bob", this would be a violation. And if you had the fact "Abe is not with Bob", this would simply be redundant.

Type 2

A type 2 fact has exactly one noun where its noun type matches the noun type of the link. It is slightly harder to process, and is harder to catch when a mark contradicts it. This puzzle, along with most puzzles, does not have this type of fact.

A logic puzzle that does have facts of type 2 is "Lucky Streets". In this puzzle, fact 15 states "She found the quarter earlier than Friday." This means the quarter was not found on Friday or Saturday. The quarter has the noun type "Coin", while the link "earlier than" and Friday both have the noun type "Day". In this puzzle, facts 16 and 17 are type 2 facts as well.

Again, I must point out that both nouns in a type 2 fact cannot have the same noun type. Why? Because this is like saying "Thursday is earlier than Friday." While this may be factually true, this is already defined within the link "earlier than".

Type 3

A type 3 fact has the same noun type for both nouns, but this noun type is different from the noun type of the link. A fact of type 3 from our example puzzle is fact 5: "The green house is directly to the right of the white one." The green house and the white house have the noun type "Color", and the link "directly to the right of" has the noun type "House".

Type 4

A type 4 fact is where the noun types for both nouns and the link are all different. From our example puzzle, facts 10, 12, and 14 are facts of type 4. Let's examine fact 10: "The man who sings lives next to the man with the fox." The man who sings has the noun type "Hobby". The link "next to" has the noun type "House". And the man with the fox has the noun type "Pet".

An important issue concerning logic puzzles has to do with whether two objects given in a clue are distinct, and therefore cannot be paired. For type 1 facts, the answer is explicitly given. For the other types of facts, usually the link will let you know whether this is true or not. If a fact states: "Abe is in a room next to the room the cat is in", then you know that Abe can never be in the same room as the cat.

But if the fact states: "Abe is in a room that is not next to the room the cat is in", it may be possible that Abe is in the same room as the cat. My suggestion is that if the clue does not say otherwise, assume that the two nouns given in the clue are distinct.

Note: As you can see in this fact, the variables Is and With do not need to be prefixed by the this keyword because they are globals. I wish "this" was not an issue.

This method appears very straightforward. But I must tell you this method has overloads where you can enter more than one fact at a time. So let's discuss what those overloads are in another article.

Validating Facts

Before the Mystery Master solves a logic puzzle, it first validates the logic puzzle by looking for various logic errors. The Puzzle method that validates the puzzle is appropriately named validate. Here are some reasons a fact is invalid.

The fact's verb is the possible verb ("maybe"). It must be either the positive verb ("is") or the negative verb ("is not").

Both nouns in the fact are the same. The nouns in a fact must be different.

The fact's link is "with", but both nouns have the same type. This is like saying "Bob is not Abe", or "Abe is Bob". For logic grid puzzles, two nouns of the same type are never together anyway.

The fact's link is not "with", but both nouns have the same type as the link. For example "The 2nd person in line is ahead of the 4th person in line.", may make sense, but this is a relationship, not a fact! This statement is exactly what the "ahead of" link is suppose to define.

Rules

A rule is a conditional relationship between two or more nouns such as "If A is next to B, then C is not next to D." Rules are needed when facts cannot represent the clues in a logic puzzle. Since our example puzzle does not have rules, below is the puzzle module for the puzzle "All Tired Out".

Rules, along with links, require programming. The function f for each rule is provided by a method in the SmartRule static class. See the section on Smart Rules for more information. A rule usually does something based on the marks, and returns a status code. The status code is either negative for a violation, or zero for success. A rule may perform one or more of the following tasks.

Enforce Violations

A violation occurs when a mark contradicts the clues of a puzzle. A mark that violates the clues is called a contradiction. This should only happen when assumptions are made. A violation means the program should undo the last assumption, and make another one. If an assumption was not made, this is a fatal logic error, and the program will stop solving the puzzle. In the puzzle "All Tired Out", if a mark created the situation where Grace was first and a woman was second, this mark would contradict the clues. When a rule encounters this, it must inform the program of the violation.

Trigger Marks

A rule that examines the current mark to enter additional marks is called a trigger. The status of a trigger is the status of the submitted mark. If there are no problems with the mark, the status is zero. If there is a problem with the mark, the status is negative, and is returned immediately. If the mark entered by a trigger is rejected, this is the same as a rule violation. If the trigger was successful, the current rule can continue, and additional rules can be invoked.

For the logic puzzle "All Tired Out", a rule must look for a situation such as "If no man can be 2nd in line, then Grace cannot be 1st in line." When this situation is found, the rule enters 'X' for 1st and Grace. In general, rule violations should be handled first, followed by triggers.

Updating Placeholders

Some logic puzzles may not give you all of the values of the nouns. This means the values must be calculated by a rule. Nouns where the initial value is unknown are called placeholders. Usually these values are numeric, such as the number of people who attended a talk in "Astrophysics Conference", or the age of a salesperson in "Dandy Salespeople". Rules that update placeholders can be quite complex.

To summarize, rules are laws that are specific to a logic puzzle. The laws for solving a logic puzzle will be discussed in a future article.

Solution

This is the encoded solution to the logic puzzle, but is optional. If you know the solution, you can encode it here. See if you can "decode" this.

Helper

The Helper static class defines global variables and helpful methods. This class is referenced by several of my classes. Though global variables and methods are discouraged, below are some of the globals defined in this module.

Q is the double quote character as a string.

NL is the new line character given by the escaped sequence "\n".

print(msg) is a method that prints the given message to the browser's console window.

Note: The files head.php and WebWorker.js will be discussed in a future article.

Conclusion

I hope you enjoyed reading this article. My motivation for writing this article is that you will try to model a logic puzzle on your own. Then together we can find better ways to model and/or solve logic puzzles. Thank you.

Share

About the Author

My name is Michael Benson, and I am the zookeeper of the Mystery Master website at http://www.mysterymaster.com.
My favorite languages are C#, Java, and JavaScript.
When I'm not at my computer, I am travelling far more than I like to places far more exciting than I can handle.