⌚Electricks Bond
⌚SB Watch 2
🚚 Free fedex shipping from 97 $
🌎 WORLDWIDE SHIPPING for 25 $
Search
Close this search box.

Atom Square

About

A magic square is a grid of numbers arranged such that the sum of the numbers in each row, column, and diagonal is the same.

As a magician, you can use a magic square for mentalism or as a mathematical magic trick. Ask a spectator to choose any number between 22 and 117, and then reveal the sum of the numbers in any row, column, or diagonal that contains that number.

This mini-app helps you create a magic square based on a chosen number. Simply enter the number provided by the spectator, and copy the resulting numbers displayed on the PeekSmith 3 screen.

				
					
// the number
let num = '';
// the array will contain the numbers of the 4x4 square
let square = newUint8Array(16);

function main() {
  ps.connect();
}

function formatNumber(n) {
  if (n < 10) return `\xA0${n}`;
  return `${n}`;
}

function buildSquare(n) {
  // we can calculate a magic square for numbers
  // between 22 and 117 when we would like to end with
  // max. two digit positive numbers
  if (n < 22 || n > 117) {
    ps.print(`${n}\nINVALID`);
    return;
  }
  let correction = (n - 22) / 6 | 0;
  if (n > 25) correction += rand(2);
  square[0] = 7 + correction;
  square[1] = 12 + correction;
  square[2] = 1 + correction;
  square[3] = n - 20 - correction * 3;
  square[4] = 2 + correction;
  square[5] = n - 21 - correction * 3;
  square[6] = 8 + correction;
  square[7] = 11 + correction;
  square[8] = n - 18 - correction * 3;
  square[9] = 3 + correction;
  square[10] = 10 + correction;
  square[11] = 5 + correction;
  square[12] = 9 + correction;
  square[13] = 6 + correction;
  square[14] = n - 19 - correction * 3;
  square[15] = 4 + correction;
  let vFlipped = rand(0, 2);
  let rotated = rand(0, 2);
  let startRow = vFlipped === 1 ? 3 : 0;
  let endRow = vFlipped === 1 ? -1 : 4;
  let step = vFlipped === 1 ? -1 : 1;
  let result = '';
  for (let row = startRow; row !== endRow; row += step) {
    for (let col = 0; col < 4; col++) {
      if (rotated === 0) {
        result += formatNumber(square[row * 4 + col]);
      } else { // col <==> row
        result += formatNumber(square[col * 4 + row]);
      }
      result += col < 3 ? ' ' : '\n';
    }
  }
  ps.print(result);
}

let layout = [
  '1', '2', '3',
  '4', '5', '6',
  '7', '8', '9',
  's', '0', '<'
];
function calc() {
  if (num === '') return;
  clearTimeout(timer);
  buildSquare(parseInt(num));
  num = '';
}

let timer;
function onButtonClick(buttonId) {
  let key = layout[buttonId];
  switch (key) {
    case 's':
      calc();
      return;
    case '<':
      num = strSub(num, 0, -1);
      break;
    default:
      if (strLen(num) < 3) num += key;
      break;
  }

  clearTimeout(timer);
  const processAfter = config.get('keyboard.submit.after');
  if (processAfter > 0) timer = setTimeout(() => {
    calc();
  }, processAfter);

  printNumberEntered();
}

function printNumberEntered() {
  let rest = '';
  for (let i = strLen(num); i < 3; i++) {
    rest += '_';
  }
  let text = `${num}${rest}\n`;
  ps.print(text);
}

function onEvent(e) {
  if (e.source === 'ps:ble' && e.type === 'connected') {
    ps.print('Atom\nSquare');
    setTimeout(printNumberEntered, 2000);
    return;
  }
  if (e.source === 'atom:button') {
    const buttonId = parseInt(e.value);
    if (e.type === 'click') {
      onButtonClick(buttonId);
    }
    if (strSub(e.type, 0, 5) === 'click' && strLen(e.type) === 6) {
        const clickCount = parseInt(strCharAt(e.type, 5));
        for (let i = 0; i < clickCount; i++) {
            onButtonClick(buttonId);
        }
    }
  }
}