Test Them Puzzles

Follow along

brandenbyers.com/slides/test-them-puzzles

Puzzles

Puzzles are fun!

Learning to code is hard

Testing can feel cumbersome

Puzzle are nimble

Coding Puzzles

Coding Puzzles

Next to Last Item in a List

Return the next-to-last item from an array.

The Gas Station Problem

There is a truck driving clockwise on a circular route;
the truck has a gas tank with infinite capacity, initially empty.

Along the route are gas stations with varying amounts of gas available:
you are given a list of gas stations
with the amounts of gas they have available
and the amounts of gas required to drive to the next gas station.

You must find a gas station that,
for a trip starting from that gas station,
will be able to return to that gas station.

Convert Hindsight into Foresight...

Investigating the Torricelli point of a triangle

Let ABC be a triangle with all interior angles being less than 120 degrees.
Let X be any point inside the triangle and let XA = p, XC = q, and XB = r.

Fermat challenged Torricelli to find the position of X such that p + q + r was minimised.

Torricelli was able to prove that if equilateral triangles AOB, BNC and AMC are constructed on each side of triangle ABC, the circumscribed circles of AOB, BNC, and AMC will intersect at a single point, T, inside the triangle.
Moreover he proved that T, called the Torricelli/Fermat point, minimises p + q + r. Even more remarkable,
it can be shown that when the sum is minimised, AN = BM = CO = p + q + r and that AN, BM and CO also intersect at T.

If the sum is minimised and a, b, c, p, q and r are all positive integers we shall call triangle ABC a Torricelli triangle. For example, a = 399, b = 455, c = 511 is an example of a Torricelli triangle, with p + q + r = 784.

Find the sum of all distinct values of p + q + r ≤ 120000 for Torricelli triangles.

Simulate Real World Problems

Bite-size Chunks

Syntactic Wilderness

Wander and you might get lost

Why Puzzles?

Why write puzzles?

Programmer Practice

  • Athletes Train
  • Musicians Rehearse
  • Lawyers & Doctors Practice

Test-Driven Learning

Puzzles Are

universal

Aha!

Dopamine drip

rosettacode.org/wiki/towers_of_hanoi

Are you a

Parrot or a Crow?

Parrots

  • Inquisitive
  • Destructive exploration
  • Playful learners
  • Pull, tear, scratch, probe
  • Haphazardly dig for food

Crows

  • Curious
  • Explore from a distance
  • Methodical learners
  • Graceful tool users
  • Precisely prod for food

Code like a...

PARROT

  • Inquisitive
  • Destructive exploration
  • Playful learners
  • Pull, tear, scratch probe
  • Haphazardly dig for food

CROW

  • Curious
  • Explores from a distance
  • Methodical learners
  • Graceful tool users
  • Precisely prod for food

Flexibility in Problem Solving and Tool Use of Kea and New Caledonian Crows in a Multi Access Box Paradigm

Code Challenge Websites

How-to

Let's make some sausage!

var add = function (a, b) {
  return a + b;
};
expect(add(2, 2).to.equal(4));expect(add(2, '2').to.equal('22'));expect(add('con','cat').to.equal('concat'));

Assumptions

Bad!

var add = function (a, b) {
  if(typeof a + b === 'string') {
    return 'Go fish';
  }
  ...
};
expect(add('con','cat')).to.equal('Go fish');expect(add(2, 2)).to.be.a('number')
var add = function (a, b) {
  return parseInt(a) + parseInt(b);
};
expect(add(2, '2').to.equal(4));expect(add(2.22, 2.22).to.equal(4.44));
// AssertionError: expected 4 to equal 4.44

Chai.js

expect()

should()

assert()

expect('something').to.contain('thing');

expect('Hello World').to.be.a('string');

Draft Ideas

"Real-World"

Contrived

Inspired by Fiction

Fifty Shades of Repetition
Harry Potter and the Sorcerer's Puzzle
Ender's Puzzle

Libraries

Underscore

Lodash

Ramda

Moment

_.shuffle

test('shuffle', function() {
  deepEqual(_.shuffle([1]), [1], 'behaves correctly on size 1 arrays');
  var numbers = _.range(20);
  var shuffled = _.shuffle(numbers);
  notDeepEqual(numbers, shuffled, 'does change the order'); // Chance of false negative: 1 in ~2.4*10^18
  notStrictEqual(numbers, shuffled, 'original object is unmodified');
  deepEqual(numbers, _.sortBy(shuffled), 'contains the same members before and after shuffle');

  shuffled = _.shuffle({a: 1, b: 2, c: 3, d: 4});
  equal(shuffled.length, 4);
  deepEqual(shuffled.sort(), [1, 2, 3, 4], 'works on objects');
});

Frameworks

Angular, React, etc...

Docs and tests

Syntactic Sugar

Work Backwards

Solved software problem

Break it down

Use a bite-size chunk

rosettacode.org

Slasher Film

Return the surviving elements of an array
after chopping off n elements from the head.


                         slasher([1, 2, 3], 2);
expect(slasher([1,2,3],2)).to.equal([3]);expect(slasher([1,2,3],0)).to.equal([1,2,3]);expect(slasher([1,2,3],9)).to.equal([]);
            expect(slasher([1,2,3],2)).to.equal(['Three, you're lucky to still be.']);
          
            expect(slasher([1,2,3],0)).to.equal(['All numbers live another day.']);
          
            expect(slasher([1,2,3],9)).to.equal(['It is a sad day.']);
          
expect(slasher(['1,354','22','4900'],1)).to.equal(['Four thousand nine hundred and twenty-two; you are amongst the lucky few.']);

Return a string of the the English word equivalents
of the surviving elements (numbers) in an array
after chopping off n elements from the head.
The numbers must be listed from last to first.
The string should be finished with a phrase
that rhymes with the last number listed.

Rhyming Numbers Poem

You will be given an array of numbers.
Each number will be between 0 and 9.
These numbers may be integers or strings.
If a number is in a string, it may be a digit or word.
Return a nonsense poem,
where each line starts with a number from the array
followed by a phrase ending in a word that rhymes with that number.

Nine, you smell like wine
Five, chicken dumplings make me feel alive
Three, you be lost deep in the sea
Two, please stop sniffing glue
One, this poem is done

var rhymingNumberPoem = function(arr) {  // this is a poet but didn't know it  return str;
};
var shortArr = [9,5,3,1];
var longArr  = [9,5,3,1,5,4,3,5,6,3,2,3,4,7,5,2,3,4,7,10,23,4,2];
          
describe('Rhyming Number Poem', function() {  it('should return a string', function() {
    expect(rhymingNumberPoem(shortArr)).to.be.a('string');
  });  it('should return correct number of lines from short array', function() {
    expect(rhymingNumberPoem(shortArr).split('\n').length).to.equal(shortArr.length);
  });  it('should create a short rhyming poem', function() {
    expect(rhymeChecker(rhymingNumberPoem(shortArr))).to.equal(true);
  });  it('should create a long rhyming poem', function() {
    expect(rhymeChecker(rhymingNumberPoem(longArr))).to.equal(true);
  });});
var rhymeChecker = function(str) {
  var arr = str.split(/,|\./).join('').split("\n");
  if(str.length < 1 || arr[0].split(' ').length < 3) {
    return false;
  }
  var count = arr.reduce(function(a, b) {
    var words = b.split(' '),
        firstWord = words[0].toLowerCase(),
        lastWord = words[words.length - 1].toLowerCase();
    if(numberRhymes[firstWord].match(lastWord)) {
      return a + 1;
    }
    return a;
  }, 0);
  if(count < arr.length) {
    return false;
  }
  return true;
};

  zero: 'hero giro tiro nonzero subzero',
  one: 'won done run son none sun gun fun tion ton nun shun sion bun donne dun fon pun rien bn cen gon hun jun tonne tun ven yean naan spun fron seisin stun toucan anyone begun undone outdone outrun spline rerun redone everyone overrun overdone cretonne misdone twentyone'

brandenbyers.com/slides/test-them-puzzles/poem.js

github.com/brandenbyers/code-puzzles

npm install

mocha poem

Share your Puzzles

With the World!

Bonfires

freecodecamp/seed/challenges/basic-bonfires.json


    {
      "id": "a26cbbe9ad8655a977e1ceb5",
      "name": "Bonfire: Find the Longest Word in a String",
      "dashedName": "bonfire-find-the-longest-word-in-a-string",
      "difficulty": "1.04",
      "description": [
        "Return the length of the longest word in the provided sentence.",
      ],
      "challengeSeed": [
        "function findLongestWord(str) {",
        "  return str.length;",
        "}",
        "",
        "findLongestWord('The quick brown fox jumped over the lazy dog');"
      ],
      "tests": [
        "expect(findLongestWord('The quick brown fox jumped over the lazy dog')).to.be.a('Number');",
        "expect(findLongestWord('The quick brown fox jumped over the lazy dog')).to.equal(6);",
        "expect(findLongestWord('May the force be with you')).to.equal(5);",
        "expect(findLongestWord('Google do a barrel roll')).to.equal(6);",
        "expect(findLongestWord('What is the average airspeed velocity of an unladen swallow')).to.equal(8);"
      ],
      "MDNlinks": [
        "String.split()",
        "String.length"
      ]
    }

codewars.com/kata/new/javascript

Write Kickass Puzzles

  1. Devise a description
  2. Generate tests
  3. Double, triple, and quadrupal check for edge cases
  4. Solve and bathe in dopamine
  5. Share/repeat
Branden Head

@brandenbyers

Interactive Intelligence

Free Code Camp

Balance Boards

Goats

midwestjs.com/feedback