function double(a: number): number {
  return 2 * a;
}

function halve(a: number): number {
  return Math.floor(a / 2);
}

function isEven(a: number): bool {
  return a % 2 == 0;
}

function showEthiopianMultiplication(x: number, y: number): void {
  var tot = 0;
  while (x >= 1) {
    process.stdout.write(x.toString().padStart(9, ' ') + " ");
    if (!isEven(x)) {
      tot += y;
      process.stdout.write(y.toString().padStart(9, ' '));
    }
    console.log();
    x = halve(x);
    y = double(y);
  }
  console.log("=" + " ".repeat(9) + tot.toString().padStart(9, ' '));
}

showEthiopianMultiplication(17, 34);
---
function primeFactorsCount(n: number): number {
  n = Math.abs(n);
  var count = 0;
  if (n >= 2)
    for (factor = 2; factor <= n; factor++)
      while n % factor == 0) {
        count++;
        n /= factor;
      }
  return count;
}

const readline = require('readline').createInterface({
  input: process.stdin, output: process.stdout
});

readline.question('Enter an integer: ', sn => {
  var n = parseInt(sn);
  console.log(primeFactorsCount(n) == 2 ?
    "It is a semiprime." : "It is not a semiprime.");
  readline.close();
});
---
function sumOfDigitBase(n: number, bas: number): number {
  var digit = 0, sum = 0;
  while (n > 0)
  {
    var tmp = Math.floor(n / bas);
    digit = n - bas * tmp;
    n = tmp;
    sum += digit;
  }
  return sum;
}

console.log(`    1 sums to ${sumOfDigitBase(1, 10)}`);
console.log(` 1234 sums to ${sumOfDigitBase(1234, 10)}`);
console.log(` 0xfe sums to ${sumOfDigitBase(0xfe, 16)}`);
console.log(`0xf0e sums to ${sumOfDigitBase(0xf0e, 16)}`);
maxint = Number.MAX_SAFE_INTEGER;
console.log(`${maxint} (Number.MAX_SAFE_INTEGER) sums to ${sumOfDigitBase(maxint, 10)}`);
---
interface Door {
  id: number;
  open: boolean;
}

function doors(): Door[] {
  var Doors: Door[] = [];

  for (let i = 1; i <= 100; i++) {
    Doors.push({id: i, open: false});
  }

  for (let secuence of Doors) {
    for (let door of Doors) {
      if (door.id % secuence.id == 0) {
        door.open = !door.open;
      }
    }
  }

  return Doors.filter(a => a.open);
}
---
const weightsSymbols: [number, string][] =
  [[1000, 'M'], [900, 'CM'], [500, 'D'], [400, 'CD'], [100, 'C'], [90, 'XC'],
  [50, 'L'], [40, 'XL'], [10, 'X'], [9, 'IX'], [5, 'V'], [4, 'IV'], [1, 'I']];

function toRoman(n: number): string {
  var roman = "";
  for (i = 0; i <= 12 && n > 0; i++) {
    var w = weightsSymbols[i][0];
    while (n >= w) {
      roman += weightsSymbols[i][1];
      n -= w;
    }
  }
  return roman;
}

console.log(toRoman(1990));
console.log(toRoman(2022));
console.log(toRoman(3888));
---
const isLongYear = (year: number): boolean => {
  const jan1: Date = new Date(year, 0, 1);
  const dec31: Date = new Date(year, 11, 31);
  return (4 == jan1.getDay() || 4 == dec31.getDay())
}

for (let y: number = 1995; y <= 2045; y++) {
  if (isLongYear(y)) {
    console.log(y)
  }
}
---
function identity(n) {
    if (n < 1) return "Not defined";
    else if (n == 1) return 1;
    else {
        var idMatrix:number[][];
        for (var i: number = 0; i < n; i++) {
            for (var j: number = 0; j < n; j++) {
                if (i != j) idMatrix[i][j] = 0;
                else idMatrix[i][j] = 1;
            }
        }
        return idMatrix;
    }
}
---
function rootAndPers(n: number, bas: number): [number, number] {
  var pers = 0;
  while (n >= bas)
  {
    var s = 0;
    do
    {
      s += n % bas;
      n = Math.floor(n / bas);
    } while (n > 0);
    pers++;
    n = s;
  }
  return [n, pers];
}

for (var a of [1, 14, 267, 8128, 39390, 588225, 627615]) {
  var rp = rootAndPers(a, 10);
  console.log(a.toString().padStart(7, ' ') +
    rp[1].toString().padStart(6, ' ') + rp[0].toString().padStart(6, ' '));
}
---
import { maze,display } from "./maze"
const X = 10
const Y = 10

let canvas = document.createElement('canvas')
document.body.appendChild(canvas)
let m = maze(X,Y)
display(canvas,m)
---
function gcd(a: number, b: number) {
  a = Math.abs(a);
  b = Math.abs(b);

  if (b > a) {
    let temp = a;
    a = b;
    b = temp;
  }

  while (true) {
    a %= b;
    if (a === 0) { return b; }
    b %= a;
    if (b === 0) { return a; }
  }
}
---
function mapRange(
	a: number[],
	b: number[],
	s: number
): number {
	return b[0] + (s-a[0]) * (b[1]-b[0]) / (a[1]-a[0]);
}

const a = [0, 10];
const b = [-1, 0];

for (let s = 0; s < 11; s++) {
	console.log(`${s} -> ${mapRange(a, b, s)}`);
}
---
var f = 2008;
var t = 2121;
console.log(`Sunday Christmases ${f} - ${t}`);
for (y = f; y <= t; y++) {
  var x = (y * 365) + Math.floor(y / 4) - Math.floor(y / 100) + Math.floor(y / 400) - 6;
  if (x % 7 == 0)
    process.stdout.write(`${y}\t`);
}
process.stdout.write("\n");
---
function levenshtein(a: string, b: string): number {
    const m: number = a.length,
      n: number = b.length;
    let t: number[] = [...Array(n + 1).keys()],
      u: number[] = [];
    for (let i: number = 0; i < m; i++) {
      u = [i + 1];
      for (let j: number = 0; j < n; j++) {
        u[j + 1] = a[i] === b[j] ? t[j] : Math.min(t[j], t[j + 1], u[j]) + 1;
      }
      t = u;
    }
    return u[n] ?? n;
  }
---
function s(n:number): number {
    return [...Array(n).keys()].map(k => 1 / (1+k)**2).reduce((a, b) => a + b);
}

console.log( s(1000) )
---
function isPrime(n: number): boolean {
    if (n < 2) return false;
    if (n < 4) return true;
    if (n % 2 == 0 || n % 3 == 0) return false;
    for (let i = 5; i <= n ** 0.5; i += 6) {
        if (n % i == 0 || n % (i+2) == 0) return false;
    }
    return true;
}

function sumDigits(x: number): number {
    let sum = 0;
    while (x > 0) {
      sum = sum + (x % 10);
      x = Math.floor(x / 10);
    }
    return sum;
}

const additivePrimes: number[] = [];

for (let i = 2; i < 10**7; i++) {
    if (isPrime(i) && isPrime(sumDigits(i))) {
        additivePrimes.push(i);
    }
}

console.log(additivePrimes);
console.log(`Found ${additivePrimes.length} values`);
---
function josephus(n: number, k: number): number {
  if (!n) {
    return 1;
  }

  return ((josephus(n - 1, k) + k - 1) % n) + 1;
}
---
type AnyWriteableObject={write:((textToOutput:string)=>any)};

function calcPi(pipe:AnyWriteableObject) {
    let q = 1n, r=0n, t=1n, k=1n, n=3n, l=3n;
    while (true) {
        if (q * 4n + r - t < n* t) {
            pipe.write(n.toString());
            let nr = (r - n * t) * 10n;
            n  = (q * 3n + r) * 10n / t - n * 10n ;
            q  = q * 10n;
            r  = nr;
        } else {
            let nr = (q * 2n + r) * l;
            let nn = (q * k * 7n + 2n + r * l) / (t * l);
            q = q * k;
            t = t * l;
            l = l + 2n;
            k = k + 1n;
            n  = nn;
            r  = nr;
        }
    }
}

calcPi(process.stdout);
---
console.log(`POLICE SANITATION FIRE`);
let f: number;
for (var p = 2; p <= 7; p += 2) {
  for (var s = 1; s <= 7; s++) {
    if (s != p) {
      f = (12 - p) - s;
      if ((f > 0) && (f <= 7) && (f != s) && (f != p))
        console.log(`   ${p}       ${s}       ${f}`);
    }
  }
}
---
function suffix(n: number): string {
  var nMod10: number = n % 10;
  var nMod100: number = n % 100;
  if (nMod10 == 1 && nMod100 != 11)
    return "st";
  else if (nMod10 == 2 && nMod100 != 12)
    return "nd";
  else if (nMod10 == 3 && nMod100 != 13)
    return "rd";
  else
    return "th";
}

function printImages(loLim: number, hiLim: number) {
  for (i = loLim; i <= hiLim; i++)
    process.stdout.write(`${i}` + suffix(i) + " ");
  process.stdout.write("\n");
}

printImages(   0,   25);
printImages( 250,  265);
printImages(1000, 1025);
---
var n = 12;
console.clear();
for (j = 1; j < n; j++)
  process.stdout.write(j.toString().padStart(3, ' ') + " ");
console.log(n.toString().padStart(3, ' '));
console.log("----".repeat(n) + "+");
for (i = 1; i <= n; i++) {
  for (j = 1; j <= n; j++)
    process.stdout.write(j < i ?
      "    " : (i * j).toString().padStart(3, ' ') + " ");
  console.log("| " + i.toString().padStart(2, ' '));
}
---
function leoNums(
	n: number,
	L0: number = 1,
	L1: number = 1,
	add: number = 1
): number[] {
	const lNums: number[] = [L0, L1];
	while (lNums.length < n) {
		lNums.push(lNums[lNums.length - 1] + lNums[lNums.length - 2] + add);
	}
	return lNums
}

console.log(leoNums(25))
console.log(leoNums(25, 0, 1, 0))
---
function beerSong(){
    function nbottles(howMany:number){
        return `${howMany?howMany:'no'} bottle${howMany!=1?'s':''}`;
    }
    let song=[];
    let beer = 99;
    while (beer > 0) {
        song.push(`
            ${nbottles(beer)} of beer on the wall,
            ${nbottles(beer)} of beer!
            Take one down, pass it around
            ${nbottles(--beer)} of beer on the wall
        `);
    }
    return song.join('');
}

console.log(beerSong());
---
function mean(numbersArr)
{
    let arrLen = numbersArr.length;
    if (arrLen > 0) {
        let sum: number = 0;
        for (let i of numbersArr) {
            sum += i;
        }
        return sum/arrLen;
    }
    else return "Not defined";
}

alert( mean( [1,2,3,4,5] ) );
alert( mean( [] ) );
---
function compose<T, U, V> (fn1: (input: T) => U, fn2: (input: U) => V){
    return function(value: T) {
        return fn2(fn1(value))
    }
}

function size (s: string): number { return s.length; }

function isEven(x: number): boolean { return x % 2 === 0; }

const evenSize = compose(size, isEven);

console.log(evenSize("ABCD"))
console.log(evenSize("ABC"))
---
function gcd(m: number, n: number): number {
  var tmp: number;
  while (m != 0) {
    tmp = m;
    m = n % m;
    n = tmp;
  }
  return n;
}

function lcm(m: number, n: number): number {
    return Math.floor(m / gcd(m, n)) * n;
}

console.log(`LCM(35, 21) = ${lcm(35, 21)}`);
---
var arr1: string[] = ['a', 'b', 'c'];
var arr2: string[] = ['A', 'B', 'C'];
var arr3: number[] = [1, 2, 3];
for (var i = 0; i <= 2; i++)
  console.log(`${arr1[i]}${arr2[i]}${arr3[i]}`);
---
function modInv(e: number, t: number): number {
  var d = 0;
  if (e < t) {
    var count = 1;
    var bal = e;
    do {
      var step = Math.floor((t - bal) / e) + 1;
      bal += step * e;
      count += step;
      bal -= t;
    } while (bal != 1);
    d = count;
  }
  return d;
}

console.log(`${modInv(42, 2017)}`);
---
function encode(v: number): number {
  return v ^ (v >> 1);
}

function decode(v: number): number {
  var result = 0;
  while (v > 0) {
    result ^= v;
    v >>= 1;
  }
  return result;
}

console.log("decimal  binary   gray    decoded");
for (var i = 0; i <= 31; i++) {
  var g = encode(i);
  var d = decode(g);
  process.stdout.write(
    "  " + i.toString().padStart(2, " ") +
    "     " + i.toString(2).padStart(5, "0") +
    "   " + g.toString(2).padStart(5, "0") +
    "   " + d.toString(2).padStart(5, "0") +
    "  " + d.toString().padStart(2, " "));
  console.log();
}
---
function isKPrime(n: number, k: number): bool {
  var f = 0;
  for (var i = 2; i <= n; i++)
    while (n % i == 0) {
      if (f == k)
        return false;
      ++f;
      n = Math.floor(n / i);
    }
  return f == k;
}

for (var k = 1; k <= 5; k++) {
  process.stdout.write(`k = ${k}:`);
  var i = 2, c = 0;
  while (c < 10) {
    if (isKPrime(i, k)) {
      process.stdout.write(" " + i.toString().padStart(3, ' '));
      ++c;
    }
    ++i;
  }
  console.log();
}
---
function replace(input: string, key: number) : string {
   return input.replace(/([a-z])/g,
      ($1) => String.fromCharCode(($1.charCodeAt(0) + key + 26 - 97) % 26 + 97)
      ).replace(/([A-Z])/g,
      ($1) => String.fromCharCode(($1.charCodeAt(0) + key + 26 - 65) % 26 + 65));
}

var str = 'The five boxing wizards jump quickly';
var encoded = replace(str, 3);
var decoded = replace(encoded, -3);

console.log('Enciphered: ' + encoded);
console.log('Deciphered: ' + decoded);
---
function sum(array: Array<number>): number {
    return array.reduce((a, b) => a + b)
}

function square(x : number) :number {
    return x * x
}

function mean(array: Array<number>): number {
    return sum(array) / array.length
}

function averageSquareDiff(a: number, predictions: Array<number>): number {
    return mean(predictions.map(x => square(x - a)))
}

function diversityTheorem(truth: number, predictions: Array<number>): Object {
    const average: number = mean(predictions)
    return {
        "average-error": averageSquareDiff(truth, predictions),
        "crowd-error": square(truth - average),
        "diversity": averageSquareDiff(average, predictions)
    }
}

console.log(diversityTheorem(49, [48,47,51]))
console.log(diversityTheorem(49, [48,47,51,42]))
---
function pascal(n: number): void {
  var ld: number[] = new Array(40);
  var nw: number[] = new Array(40);
  for (var row = 0; row < n; row++) {
    nw[0] = 1;
    for (var i = 1; i <= row; i++)
      nw[i] = ld[i - 1] + ld[i];
    process.stdout.write(" ".repeat((n - row - 1) * 2));
    for (var i = 0; i <= row; i++) {
      if (nw[i] < 100)
        process.stdout.write(" ");
      process.stdout.write(nw[i].toString());
      if (nw[i] < 10)
        process.stdout.write(" ");
      process.stdout.write(" ");
    }
    nw[row + 1] = 0;
    var tmp = ld;
    ld = nw;
    nw = tmp;
    console.log();
  }
}

pascal(13);
---
var c: number[] = [1];
console.log(`${0}\t${c[0]}`);
for (n = 0; n < 15; n++) {
  c[n + 1] = 0;
  for (i = 0; i <= n; i++)
    c[n + 1] = c[n + 1] + c[i] * c[n - i];
  console.log(`${n + 1}\t${c[n + 1]}`);
}
---
#!/usr/bin/env node

import EventEmitter from 'events';

function stdinLineByLine() {
  const stdin = new EventEmitter();
  let buff = '';
  let lines;

  process.stdin
    .on('data', (data) => {
      buff += data;
      lines = buff.split(/\r\n|\n/);
      buff = lines.pop();
      lines.forEach((line) => stdin.emit('line', line));
    })
    .on('end', () => {
      if (buff.length > 0) stdin.emit('line', buff);
    });

  return stdin;
}

const stdin = stdinLineByLine();
stdin.on('line', console.log);
---
for (let i: number = 0; i < 5; ++i) {
    let line: string = ""
    for(let j: number = 0; j <= i; ++j) {
        line += "*"
    }
    console.log(line)
}