Git Product home page Git Product logo

Comments (21)

ErikSchierboom avatar ErikSchierboom commented on June 9, 2024

Exercise: pangram

Code

class Pangram {
    maybePan: string
    constructor(maybePan: string) {
        this.maybePan = maybePan;
    }

    isPangram(): boolean {
        let alpha = "abcdefghijklmnopqrstuvwxyz".split("")
        this.maybePan.split("").forEach((letter) => {
            let index = alpha.indexOf(letter.toLowerCase())
            if (index > -1) {
                alpha.splice(index, 1)
            }
        })
        return alpha.length === 0
    }
}

export default Pangram

Tags:

construct:assignment
construct:boolean
construct:class
construct:constructor
construct:field
construct:if
construct:implicit-conversion
construct:invocation
construct:lambda
construct:let
construct:method
construct:number
construct:parameter
construct:return
construct:string
construct:subtract
construct:variable
construct:visibility-modifiers
paradigm:functional
paradigm:imperative
paradigm:object-oriented
technique:higher-order-functions

from typescript.

ErikSchierboom avatar ErikSchierboom commented on June 9, 2024

Exercise: twelve-days

Code

class TwelveDays {
    static recite(start:number, end:number) {
        let days:string[] = ["first", "second", "third", "fourth", "fifth", "sixth", "seventh", "eighth", "ninth", "tenth", "eleventh", "twelfth"];
        let gifts:string[] = ["a Partridge in a Pear Tree.\n", "two Turtle Doves", "three French Hens", "four Calling Birds", "five Gold Rings", "six Geese-a-Laying", "seven Swans-a-Swimming", "eight Maids-a-Milking", "nine Ladies Dancing", "ten Lords-a-Leaping", "eleven Pipers Piping", "twelve Drummers Drumming"];

        let ret:string = "";
        for (let i=start-1; i<=end-1; i++) {
            ret += `On the ${days[i]} day of Christmas my true love gave to me: `;
            for (let j=i; j>=1; j--) {
                ret += gifts[j] + ", ";
            }
            if (i>0) { ret += "and "; }
            ret += gifts[0]
        }

        return ret;
    }
}

export default TwelveDays

Tags:

construct:assignment
construct:class
construct:for-loop
construct:if
construct:index-access
construct:initializer
construct:invocation
construct:lambda
construct:let
construct:method
construct:number
construct:parameter
construct:return
construct:string
construct:subtract
construct:template-string
construct:variable
construct:visibility-modifiers
paradigm:functional
paradigm:object-oriented
technique:higher-order-functions
technique:looping

from typescript.

ErikSchierboom avatar ErikSchierboom commented on June 9, 2024

Exercise: saddle-points

Code

interface SaddlePoint {
    row: number
    column: number
}

function saddlePoints(m: number[][]): SaddlePoint[] {
    const output: SaddlePoint[] = []
    const rows = m
    const columns = transposed(m)
    const rowMaxes = rows.map(maxIndex)

    for (let i = 0; i < rowMaxes.length; i++) {
        const j = rowMaxes[i]
        const n = m[i][j]
        if (isMin(columns, j, n)) {
            output.push({ row: i, column: j })
        }
    }

    return output
}

function maxIndex(l: number[]): number {
    let max = l[0]
    let idx = 0
    for (let i = 1; i < l.length; i++) {
        if (l[i] > max) {
            max = l[i]
            idx = i
        }
    }
    return idx
}

function transposed(m: number[][]): number[][] {
    const t: number[][] = []

    for (let j = 0; j < m.length; j++) {
        const row: number[] = []
        for (const a of m) {
            row.push(a[j])
        }
        t.push(row)
    }

    return t
}

function isMin(m: number[][], row: number, n: number): boolean {
    const min = Math.min(...m[row])
    return min === n
}

export default {
    saddlePoints,
}

Tags:

construct:assignment
construct:boolean
construct:const
construct:constructor
construct:for-loop
construct:function
construct:if
construct:implicit-conversion
construct:index-access
construct:interface
construct:invocation
construct:let
construct:method
construct:number
construct:object
construct:parameter
construct:property
construct:return
construct:spread
construct:variable
construct:visibility-modifiers
paradigm:imperative
paradigm:object-oriented
technique:looping

from typescript.

ErikSchierboom avatar ErikSchierboom commented on June 9, 2024

Exercise: luhn

Code

export default class Luhn {
    static valid(text: string): boolean {
        text = text.replace(/ /g, '')
        if (text.length <= 1 || !/^\d+$/g.test(text)) return false

        let sum = 0
        let isSecond = false
        for (let i = text.length - 1; i >= 0; i--) {
            if (isSecond) {
                const additive = 2 * Number(text.charAt(i))
                sum += (additive <= 9) ? additive : additive - 9
            }
            else sum += Number(text.charAt(i))
            isSecond = !isSecond
        }
        return sum % 10 === 0
    }
}

Tags:

construct:assignment
construct:boolean
construct:class
construct:const
construct:constructor
construct:for-loop
construct:if
construct:implicit-conversion
construct:index-access
construct:initializer
construct:logical-or
construct:method
construct:number
construct:parameter
construct:regular-expression
construct:return
construct:string
construct:subtract
construct:ternary
construct:throw
construct:variable
construct:visibility-modifiers
paradigm:imperative
paradigm:object-oriented
technique:boolean-logic
technique:exceptions
technique:looping
technique:regular-expression

from typescript.

ErikSchierboom avatar ErikSchierboom commented on June 9, 2024

Exercise: house

Code

interface VerseDetails {
  /**
   * The 'item' that this `Verse` introduced.
   */
  item: string
  /**
   * The action that this Verses `item` 'thats' upon the next Verses `item`.
   */
  that: string
}

export default class House {
  /**
   * Gets the details for the given `verse` from the `This is the House that Jack Built` nursery rhyme.
   *
   * @param {number} verse
   *
   * @return {VerseDetails}
   * @private
   */
  private static _getVerseDetails(verse: number): VerseDetails {
    return [
      { item: 'house that Jack built.', that: '' },
      { item: 'malt', that: 'lay in' },
      { item: 'rat', that: 'ate' },
      { item: 'cat', that: 'killed' },
      { item: 'dog', that: 'worried' },
      { item: 'cow with the crumpled horn', that: 'tossed' },
      { item: 'maiden all forlorn', that: 'milked' },
      { item: 'man all tattered and torn', that: 'kissed' },
      { item: 'priest all shaven and shorn', that: 'married' },
      { item: 'rooster that crowed in the morn', that: 'woke' },
      { item: 'farmer sowing his corn', that: 'kept' },
      { item: 'horse and the hound and the horn', that: 'belonged to' }
    ][verse - 1]
  }

  /**
   * Generates a verse to the `This is the House that Jack Built` nursery rhyme.
   *
   * @param {number} verse
   *
   * @return {Array<string>}
   */
  public static verse(verse: number): string[] {
    const details = Array(verse).fill(undefined).map((_, index) => this._getVerseDetails(index + 1))

    return details.map((verseDetails, index) => {
      if ((index + 1) === verse) {
        return `This is the ${verseDetails.item}`
      }

      return `that ${details[index + 1].that} the ${verseDetails.item}`
    }).reverse()
  }

  /**
   * Generates all the verses to the `This is the House that Jack Built` nursery rhyme,
   * between the given `from` & `to` range.
   *
   * @param {number} from
   * @param {number} to
   *
   * @return {string}
   */
  public static verses(from: number, to: number): string[] {
    const verses = []

    for (let i = from; i <= to; i++) {
      verses.push(this.verse(i), [''])
    }

    verses.pop()

    return verses.reduce((carry, array) => carry.concat(array), [])
  }
}

Tags:

construct:class
construct:constructor
construct:method
construct:parameter
construct:string
construct:throw
construct:visibility-modifiers
paradigm:object-oriented
technique:exceptions

from typescript.

ErikSchierboom avatar ErikSchierboom commented on June 9, 2024

Exercise: house

Code

const lyrics = [
  'that lay in the house that Jack built.',
  'that ate the malt',
  'that killed the rat',
  'that worried the cat',
  'that tossed the dog',
  'that milked the cow with the crumpled horn',
  'that kissed the maiden all forlorn',
  'that married the man all tattered and torn',
  'that woke the priest all shaven and shorn',
  'that kept the rooster that crowed in the morn',
  'that belonged to the farmer sowing his corn',
  'This is the horse and the hound and the horn'
]

const last = [
  'This is the house that Jack built.',
  'This is the malt',
  'This is the rat',
  'This is the cat',
  'This is the dog',
  'This is the cow with the crumpled horn',
  'This is the maiden all forlorn',
  'This is the man all tattered and torn',
  'This is the priest all shaven and shorn',
  'This is the rooster that crowed in the morn',
  'This is the farmer sowing his corn',
  'This is the horse and the hound and the horn'
]

export default class House {
  public static verse(line: number) {
    const rhyme = lyrics.slice(0, line).reverse()
    rhyme[0] = last[line - 1]
    return rhyme
  }

  public static verses(start: number, end: number) {
    const rhyme = []

    while (start <= end) {
      if (rhyme.length > 0) {
        rhyme.push('')
      }

      rhyme.push(...House.verse(start))
      start++
    }

    return rhyme
  }
}

Tags:

construct:assignment
construct:class
construct:const
construct:constructor
construct:export
construct:if
construct:index-access
construct:initializer
construct:method
construct:number
construct:parameter
construct:return
construct:string
construct:subtract
construct:throw
construct:variable
construct:visibility-modifiers
construct:while-loop
paradigm:imperative
paradigm:object-oriented
technique:exceptions
technique:looping

from typescript.

ErikSchierboom avatar ErikSchierboom commented on June 9, 2024

Exercise: nth-prime

Code

class Prime {
    nth(num: number): number {
        let currPrime = 1
        for(let i=1;i<num;i++) {
            currPrime = this.nextPrime(currPrime)
        }
        return currPrime;
    }

    nextPrime(currPrime: number = 1): number {
        let maybeNextPrime = currPrime + 1;
        if (this.prime(maybeNextPrime)) {
            return maybeNextPrime
        } else {
            return this.nextPrime(maybeNextPrime)
        }
    }

    prime(maybePrime: number): boolean {
        for(let i=2;i<maybePrime / 2; i++) {
            if (maybePrime % i === 0) return false
        }
        return true;
    }
}

export default Prime

Tags:

construct:add
construct:assignment
construct:boolean
construct:class
construct:constructor
construct:divide
construct:explicit-conversion
construct:for-loop
construct:if
construct:implicit-conversion
construct:invocation
construct:lambda
construct:logical-and
construct:method
construct:number
construct:optional-parameter
construct:parameter
construct:return
construct:ternary
construct:variable
construct:visibility-modifiers
paradigm:functional
paradigm:imperative
paradigm:object-oriented
technique:boolean-logic
technique:higher-order-functions
technique:looping
technique:recursion
technique:type-conversion

from typescript.

ErikSchierboom avatar ErikSchierboom commented on June 9, 2024

Exercise: matching-brackets

Code

const bracketPairs: { [key: string]: string } = {
  '{': '}',
  '[': ']',
  '(': ')'
}

export default class BracketPush {
  private readonly _wasStrPaired: boolean

  constructor(str: string) {
    this._wasStrPaired = this._isPaired(str)
  }

  /**
   * Checks if the given `char` is an opening bracket.
   *
   * Valid opening bracket characters are `{`, `[`, & `(`.
   *
   * @param {string} char
   *
   * @return {boolean}
   * @private
   *
   * @instance
   */
  private _isOpeningBracket(char: string): boolean {
    return ['{', '[', '('].includes(char)
  }

  /**
   * Checks if the given `char` is a closing bracket.
   *
   * Valid closing bracket characters are `}`, `]`, & `)`.
   *
   * @param {string} char
   *
   * @return {boolean}
   * @private
   *
   * @instance
   */
  private _isClosingBracket(char: string): boolean {
    return ['}', ']', ')'].includes(char)
  }

  /**
   * Checks if the given opening & closing brackets are a "pair".
   *
   * An opening & closing bracket are a pair when they're of the same bracket type.
   *
   * The three pairs of brackets are `{}`, `[]` & `()`.
   *
   * @param {string} openingBracket
   * @param {string} closingBracket
   *
   * @return {boolean}
   * @private
   *
   * @instance
   */
  private _isBracketPair(openingBracket: string, closingBracket: string): boolean {
    return bracketPairs[openingBracket] === closingBracket
  }

  /**
   * Checks if the given string is "paired".
   *
   * A string is considered "paired" when every opening bracket in the string has
   * a relative closing bracket.
   *
   * @example
   *    '[]' is paired
   *    '[[' is not paired
   *    '[{}]' is paired
   *    '[)(]' is not paired
   *
   * @param {string} str
   *
   * @return {boolean}
   * @private
   */
  private _isPaired(str: string): boolean {
    const chars = Array.from(str)
    const openingBrackets = []

    /*
      loop through each char
         - if a char is an opening bracket, add it to the record
         - if the char is a closing bracket...
          -> ... that does not match the last opening bracket ...
            - return false
          -> ... that does match the last opening bracket
            - pop bracket from record

      if at the end, there are no opening brackets left, the string is "paired".
     */
    for (const char of chars) {
      if (this._isOpeningBracket(char)) {
        openingBrackets.push(char)

        continue
      }

      if (this._isClosingBracket(char)) {
        const lastBracket = openingBrackets.pop()

        if (lastBracket && !this._isBracketPair(lastBracket, char)) {
          return false
        }
      }
    }

    return openingBrackets.length === 0
  }

  /**
   * Checks if the string this `BracketPush` was initialised with is considered "paired".
   *
   * A string is considered "paired" when every opening bracket in the string has
   * a relative closing bracket.
   *
   * @return {boolean}
   */
  isPaired(): boolean {
    return this._wasStrPaired
  }
}

Tags:

construct:assignment
construct:boolean
construct:class
construct:comment
construct:computed-access
construct:const
construct:constructor
construct:continue
construct:dictionary
construct:field
construct:for-of
construct:if
construct:implicit-conversion
construct:index-signature
construct:initializer
construct:invocation
construct:logical-and
construct:method
construct:method-overloading
construct:number
construct:parameter
construct:pop
construct:read-only
construct:return
construct:string
construct:variable
construct:visibility-modifiers
paradigm:imperative
paradigm:object-oriented
technique:boolean-logic
technique:looping
uses:Array.prototype.pop

from typescript.

ErikSchierboom avatar ErikSchierboom commented on June 9, 2024

Exercise: all-your-base

Code

export default class Converter {
    convert(n: number[], originBase: number, targetBase: number): number[] {
        this.validateBases(originBase, targetBase)
        this.validateNumber(n, originBase)
        return this.toDigits(this.fromDigits(n, originBase), targetBase)
    }

    toDigits(n: number, base: number): number[] {
        if (n === 0) {
            return [0]
        }
        const calculateDigits = (n: number, digits: number[] = []): number[] => {
            if (n <= 0) {
                return digits
            }
            return calculateDigits(Math.floor(n / base), [n % base, ...digits])
        }
        return calculateDigits(n)
    }

    fromDigits(digits: number[], base: number): number {
        return digits.reduce((acc, el) => base * acc + el, 0)
    }

    private validateNumber(n: number[], originBase: number) {
        if (n.length === 0) {
            throw new Error('Input has wrong format')
        }
        if (n.length > 1 && n[0] === 0) {
            throw new Error('Input has wrong format')
        }
        const isInvalidDigit = (x: number) => x >= originBase || x < 0
        if (n.filter(isInvalidDigit).length !== 0) {
            throw new Error('Input has wrong format')
        }
    }

    private validateBases(originBase: number, targetBase: number) {
        this.validateBase(originBase, 'Wrong input base')
        this.validateBase(targetBase, 'Wrong output base')
    }

    private validateBase(base: number, errorMessage: string) {
        if (base < 2 || Math.floor(base) !== Math.ceil(base)) {
            throw new Error(errorMessage)
        }
    }
}

Tags:

construct:add
construct:assignment
construct:boolean
construct:class
construct:const
construct:constructor
construct:divide
construct:error
construct:explicit-conversion
construct:field
construct:if
construct:implicit-conversion
construct:index-access
construct:invocation
construct:lambda
construct:logical-and
construct:logical-or
construct:method
construct:multiply
construct:number
construct:optional-parameter
construct:parameter
construct:return
construct:string
construct:throw
construct:variable
construct:visibility-modifiers
paradigm:functional
paradigm:imperative
paradigm:object-oriented
technique:boolean-logic
technique:exceptions
technique:higher-order-functions
technique:recursion

from typescript.

ErikSchierboom avatar ErikSchierboom commented on June 9, 2024

Exercise: allergies

Code

class Allergies {
    private readonly _allergiesCode: number
    private _allergies: {[key: string]: number} = {
        eggs: 1,
        peanuts: 2,
        shellfish: 4,
        strawberries: 8,
        tomatoes: 16,
        chocolate: 32,
        pollen: 64,
        cats: 128
    }

    constructor(allergiesCode: number) {
        this._allergiesCode = allergiesCode
    }

    allergicTo(name: string): boolean {
        const allergicCode = this._allergies[name]
        return (allergicCode & this._allergiesCode) > 0
    }

    list() {
        return Object
            .entries(this._allergies)
            .filter((value) => (value[1] & this._allergiesCode) === value[1] )
            .map((value) => value[0])
    }
}

export default Allergies

Tags:

construct:assignment
construct:bitwise-and
construct:boolean
construct:class
construct:const
construct:constructor
construct:field
construct:filter
construct:implicit-conversion
construct:index-signature
construct:initializer
construct:invocation
construct:lambda
construct:map
construct:method
construct:number
construct:object
construct:parameter
construct:property
construct:readme
construct:return
construct:string
construct:variable
construct:visibility-modifiers
paradigm:functional
paradigm:imperative
paradigm:object-oriented
technique:bit-manipulation
technique:bit-shifting
technique:higher-order-functions

from typescript.

ErikSchierboom avatar ErikSchierboom commented on June 9, 2024

Exercise: difference-of-squares

Code

export default class Squares {
    readonly squareOfSums: number;
    readonly sumOfSquares: number;
    readonly difference: number;

    constructor(n: number) {
        this.squareOfSums = Math.pow((n + 1) * n / 2, 2);
        this.sumOfSquares = n * (n + 1) * (2 * n + 1) / 6;
        this.difference = this.squareOfSums - this.sumOfSquares;
    }
}

Tags:

construct:add
construct:assignment
construct:class
construct:constructor
construct:divide
construct:field
construct:floating-point-number
construct:implicit-conversion
construct:method
construct:multiply
construct:number
construct:parameter
construct:read-only
construct:subtract
construct:variable
construct:visibility-modifiers
paradigm:imperative
paradigm:object-oriented

from typescript.

ErikSchierboom avatar ErikSchierboom commented on June 9, 2024

Exercise: hamming

Code

export default class Hamming {
  compute(a: string, b: string): number {
    if (a.length !== b.length) {
      throw new Error('DNA strands must be of equal length.');
    }
    let count = 0;
    for (let i = 0; i < a.length; i++) {
      if (a[i] !== b[i]) count++;
    }
    return count;
  }
}

Tags:

construct:class
construct:constructor
construct:for-loop
construct:if
construct:indexed-access
construct:method
construct:number
construct:parameter
construct:return
construct:string
construct:throw
construct:variable
construct:visibility-modifiers
paradigm:object-oriented
technique:exceptions
technique:looping

from typescript.

ErikSchierboom avatar ErikSchierboom commented on June 9, 2024

Exercise: scrabble-score

Code

export default (word: string | undefined) =>
    lettersOf(word)
        .map(scoreForLetter)
        .reduce((sum, score) => sum + score, 0)

const lettersOf = (word: string | undefined) =>
    (word || '')
        .toLowerCase()
        .split('')
        .filter((letter) => letter.match(/\w/))

const scoreForLetter = (letter: string) => {
    const [score] = scoringRules
        .filter((rule) => rule.appliesTo(letter))
        .map((rule) => rule.score)
    return score
}

const letters = (...applyingLetters: string[]) =>
    (letter: string) => applyingLetters.some((w) => w === letter)

const scoringRules = [
    {score: 1, appliesTo: letters('a', 'e', 'i', 'o', 'u', 'l', 'n', 'r', 's', 't')},
    {score: 2, appliesTo: letters('d', 'g')},
    {score: 3, appliesTo: letters('b', 'c', 'm', 'p')},
    {score: 4, appliesTo: letters('f', 'h', 'v', 'w', 'y')},
    {score: 5, appliesTo: letters('k')},
    {score: 8, appliesTo: letters('j', 'x')},
    {score: 10, appliesTo: letters('q', 'z')},
]

Tags:

construct:assignment
construct:array
construct:const
construct:constructor
construct:implicit-conversion
construct:indexed-access
construct:initializer
construct:invocation
construct:lambda
construct:logical-or
construct:map
construct:method
construct:number
construct:object
construct:overload
construct:parameter
construct:regular-expression
construct:return
construct:string
construct:template-string
construct:ternary
construct:tuple
construct:type-union
construct:variable
paradigm:functional
paradigm:imperative
paradigm:object-oriented
technique:boolean-logic
technique:higher-order-functions
technique:regular-expression
uses:RegExp

from typescript.

ErikSchierboom avatar ErikSchierboom commented on June 9, 2024

Exercise: scrabble-score

Code

export default function score(inputString: any) {
    var mapping = [{ regExpr: new RegExp("[AEIOULNRST]", "g"), score: 1}, 
                   { regExpr: new RegExp("[DG]", "g"), score: 2},
                   { regExpr: new RegExp("[BCMP]", "g"), score: 3},
                   { regExpr: new RegExp("[FHVWY]", "g"), score: 4},
                   { regExpr: new RegExp("[K]", "g"), score: 5},
                   { regExpr: new RegExp("[JX]", "g"), score: 8},
                   { regExpr: new RegExp("[QZ]", "g"), score: 10}];
    var value: number = 0;
    var occurences: number;
    if(inputString == undefined) inputString = "";
    inputString = inputString.toUpperCase();
    for(var i = 0; i < mapping.length; ++i){
        var matchesArray = inputString.match(mapping[i].regExpr);
        if (matchesArray == null ) occurences = 0;
        else occurences = matchesArray.length;
        value += occurences * mapping[i].score; 
    }
    return value;                
}

Tags:

construct:assignment
construct:constructor
construct:for-loop
construct:function
construct:if
construct:implicit-conversion
construct:index-access
construct:method
construct:multiply
construct:null
construct:nullability
construct:number
construct:object
construct:parameter
construct:return
construct:string
construct:throw
construct:typescript
construct:variable
construct:visibility-modifiers
paradigm:imperative
paradigm:object-oriented
technique:exceptions
technique:looping
uses:RegExp

from typescript.

ErikSchierboom avatar ErikSchierboom commented on June 9, 2024

Exercise: phone-number

Code

export default class {
    private _phoneNumber : string;
    constructor(phoneNumber : string) {
        this._phoneNumber = phoneNumber;
    }

    number() : string | undefined {
        const clean = this._phoneNumber.replace(/[\s\.\(\)\-]/g, "");
        const matches = /^(1?)([\d]{10})$/.exec(clean);
        return matches ? matches[2] : undefined;
    }
}

Tags:

construct:assignment
construct:class
construct:constructor
construct:field
construct:index-access
construct:method
construct:number
construct:parameter
construct:property
construct:regular-expression
construct:return
construct:string
construct:ternary
construct:throw
construct:undefined
construct:variable
construct:visibility-modifiers
paradigm:imperative
paradigm:object-oriented
technique:exceptions
technique:regular-expression

from typescript.

ErikSchierboom avatar ErikSchierboom commented on June 9, 2024

Exercise: rational-numbers

Code

export default class Rational {
    numer: number;
    denom: number;

    constructor(numer: number, denom: number) {
        let commonDivisor: number;

        if (numer === 0) {
            denom = 1;
            commonDivisor = 1;
        } else {
            commonDivisor = gcd(numer, denom);
        }

        if (denom < 0) {
            commonDivisor = -commonDivisor;
        }

        this.numer = numer / commonDivisor;
        this.denom = denom / commonDivisor;
    }

    add(other: Rational): Rational {
        const [a1, b1] = this.getParts();
        const [a2, b2] = other.getParts();

        return new Rational(a1 * b2 + a2 * b1, b1 * b2);
    }

    sub(other: Rational): Rational {
        const [a1, b1] = this.getParts();
        const [a2, b2] = other.getParts();

        return new Rational(a1 * b2 - a2 * b1, b1 * b2);
    }

    mul(other: Rational): Rational {
        const [a1, b1] = this.getParts();
        const [a2, b2] = other.getParts();

        return new Rational(a1 * a2, b1 * b2);
    }

    div(other: Rational): Rational {
        const [a1, b1] = this.getParts();
        const [a2, b2] = other.getParts();

        return new Rational(a1 * b2, a2 * b1);
    }

    abs(): Rational {
        const [a, b] = this.getParts();

        return new Rational(Math.abs(a), Math.abs(b));
    }

    exprational(power: number): Rational {
        const [a, b] = this.getParts();

        return new Rational(a ** power, b ** power);
    }

    expreal(base: number): number {
        const [a, b] = this.getParts();

        const r = Math.pow(base ** a, 1.0 / b);
        const roundR = Math.round(r);

        if (Math.abs(r - roundR) < 0.00001) {
            return roundR;
        } else {
            return r;
        }
    }

    reduce(): Rational {
        return this;
    }

    getParts(): [number, number] {
        return [this.numer, this.denom];
    }
}

const gcd = (a: number, b: number): number => {
    const absA = Math.abs(a);
    const absB = Math.abs(b);

    if (absA % absB === 0) {
        return absB;
    }

    if (absB % absA === 0) {
        return absA;
    }

    const divisorsA = reverseSort(divisors(absA));
    const divisorsB = reverseSort(divisors(absB));
    let indexA = 0;
    let indexB = 0;

    if (indexA < divisorsA.length && indexB < divisorsB.length) {
        let divisorB = divisorsB[0];

        while (indexA < divisorsA.length && indexB < divisorsB.length) {
            const divisorA = divisorsA[indexA];

            while (divisorA > divisorB && indexB < divisorsB.length) {
                divisorB = divisorsB[indexB];
                indexB++;
            }

            if (divisorA === divisorB) {
                return divisorA;
            }

            indexA++;
        }
    }

    return 1;
};

const reverseSort = (l: number[]) =>
    Array.from(l).sort((a: number, b: number) => b - a);

const divisors = (n: number): number[] => {
    const limit = Math.trunc(Math.sqrt(n));
    const result: number[] = [];

    for (let i = 2; i <= limit; i++) {
        if (n % i === 0) {
            result.push(i);
        }
    }

    return result;
};

Tags:

construct:add
construct:assignment
construct:boolean
construct:class
construct:const
construct:constructor
construct:divide
construct:double
construct:export
construct:field
construct:floating-point-number
construct:for-loop
construct:if
construct:implicit-conversion
construct:index-access
construct:initializer
construct:invocation
construct:lambda
construct:logical-and
construct:method
construct:multiply
construct:number
construct:parameter
construct:return
construct:string
construct:subtract
construct:tuple
construct:variable
construct:visibility-modifiers
construct:while-loop
paradigm:functional
paradigm:imperative
paradigm:object-oriented
technique:boolean-logic
technique:higher-order-functions
technique:looping
uses:Rational

from typescript.

ErikSchierboom avatar ErikSchierboom commented on June 9, 2024

Exercise: binary-search

Code

const isSorted = (array: number[]): boolean => {
    if (array.length === 0) {
        return true;
    } else {
        let previous = array[0];

        for (let i = 1; i < array.length; i++) {
            const v = array[i];

            if (v < previous) {
                return false;
            }

            previous = v;
        }

        return true;
    }
};

const search = (l: number[], v: number, low: number, high: number): number => {
    if (low >= high) {
        return -1;
    } else {
        const middleIndex = Math.trunc((high - low) / 2) + low;
        const middle = l[middleIndex];

        if (v === middle) {
            return middleIndex;
        } else if (v < middle) {
            return search(l, v, low, middleIndex);
        } else {
            return search(l, v, middleIndex + 1, high);
        }
    }
};

class BinarySearch {
    array: number[] | undefined;

    constructor(array: number[]) {
        if (isSorted(array)) {
            this.array = array;
        } else {
            this.array = undefined;
        }
    }

    indexOf(v: number): number {
        if (this.array) {
            return search(this.array, v, 0, this.array.length);
        } else {
            return -1;
        }
    }
}

export default BinarySearch;

Tags:

construct:add
construct:assignment
construct:boolean
construct:class
construct:const
construct:constructor
construct:divide
construct:explicit-conversion
construct:field
construct:for-loop
construct:if
construct:implicit-conversion
construct:index-access
construct:invocation
construct:lambda
construct:logical-or
construct:method
construct:number
construct:parameter
construct:return
construct:subtract
construct:ternary
construct:variable
construct:visibility-modifiers
paradigm:functional
paradigm:imperative
paradigm:object-oriented
technique:boolean-logic
technique:higher-order-functions
technique:looping
technique:recursion
technique:type-conversion

from typescript.

ErikSchierboom avatar ErikSchierboom commented on June 9, 2024

Exercise: diamond

Code

export default class Diamond {
    private readonly alphabets = ['A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z']
    makeDiamond(letter: string) {
        const index = this.alphabets.indexOf(letter)
        if (index === -1) {
            throw 'unexpected error'
        }
        const rangeAlphabets = this.alphabets.slice(0, index + 1)
        const width = (rangeAlphabets.length - 1) * 2 + 1
        const center = Math.floor(width / 2)
        const alphabetStrings = rangeAlphabets.map((alphabet, index) => {
            const stringArray = Array(width).fill(' ')
            stringArray[center + index] = alphabet
            stringArray[center - index] = alphabet
            return stringArray.join('')
        })
        const fullAlphabetStrings = alphabetStrings.concat(alphabetStrings.slice(0, alphabetStrings.length - 1).reverse())
        return fullAlphabetStrings.join('\n') + '\n'
    }
}

Tags:

construct:add
construct:assignment
construct:class
construct:const
construct:constructor
construct:divide
construct:field
construct:floating-point-number
construct:if
construct:implicit-conversion
construct:index-access
construct:initializer
construct:int
construct:integral-number
construct:invocation
construct:lambda
construct:method
construct:multiply
construct:number
construct:parameter
construct:read-only
construct:return
construct:string
construct:subtract
construct:throw
construct:variable
construct:visibility-modifiers
paradigm:functional
paradigm:imperative
paradigm:object-oriented
technique:exceptions
technique:higher-order-functions

from typescript.

ErikSchierboom avatar ErikSchierboom commented on June 9, 2024

Exercise: two-bucket

Code

interface Bucket {
  capacity: number;
  reference: string;
}

interface Path {
  moves: number;
  endState: State;
}

type PathGenerator = Generator<Path, void, undefined>;

type State = number[];

type StateTransition = (state: State) => State;

export class TwoBucket {
  buckets: Bucket[] = [];
  currentMoves = 0;
  goalBucket: string = '';
  otherBucket: number = 0;

  constructor(buckOne: number, buckTwo: number, goal: number, starterBuck: string) {
    this.setupBuckets([buckOne, buckTwo]);

    const initialState = this.buckets.map(() => 0);

    const exploredStates = [
      initialState,
      this.buckets.map(bucket => (bucket.reference == starterBuck ? 0 : bucket.capacity))
    ];

    const initialPath: Path = { moves: 0, endState: initialState };
    const actions = this.getPotentialMoves();
    const paths = this.findPaths([initialPath], exploredStates, actions);

    this.determineOutcome(paths, goal);
  }

  *findPaths(paths: Path[], exploredStates: State[], actions: StateTransition[]): PathGenerator {
    while (paths.length > 0) {
      paths = paths.reduce((paths: Path[], path) => {
        return paths.concat(
          actions
            .map((action): Path => ({ moves: path.moves + 1, endState: action(path.endState) }))
            .filter(
              newPath =>
                !exploredStates.some(
                  exploredState => JSON.stringify(exploredState) == JSON.stringify(newPath.endState)
                )
            )
        );
      }, []);
      yield* paths;
      exploredStates = exploredStates.concat(paths.map(path => path.endState));
    }
  }

  moves(): number {
    return this.currentMoves;
  }

  private setupBuckets(quantities: number[]): void {
    this.addBucket('one', quantities[0]);
    this.addBucket('two', quantities[1]);
  }

  private determineOutcome(paths: PathGenerator, goal: number): void {
    for (const path of paths) {
      if (path.endState.some(level => level == goal)) {
        this.goalBucket = this.buckets[path.endState.indexOf(goal)].reference;
        const otherBucket = path.endState.find((level: number) => level !== goal);
        if (otherBucket) {
          this.otherBucket = otherBucket;
        }
        this.currentMoves = path.moves;
        break;
      }
    }
  }

  private getPotentialMoves(): StateTransition[] {
    return this.buckets.reduce((acc: StateTransition[], bucket, index) => {
      acc.push(state => this.fill(index, state));
      acc.push(state => this.empty(index, state));

      this.buckets.forEach((innerBucket: Bucket, innerIndex: number) => {
        if (bucket == innerBucket) {
          return;
        }
        acc.push(state => this.pour(index, innerIndex, state));
      });
      return acc;
    }, []);
  }

  private addBucket(reference: string, capacity: number): void {
    this.buckets.push({
      capacity,
      reference
    });
  }

  private update(state: State, index: number, quantity: number): State {
    const newState = state.slice(0);
    newState[index] = quantity;
    return newState;
  }

  private fill(index: number, state: State): State {
    return this.update(state, index, this.buckets[index].capacity);
  }

  private pour(from: number, to: number, state: State): State {
    const availableInDestination = this.buckets[to].capacity - state[to];
    const fill = Math.min(availableInDestination, state[from]);

    return this.update(this.update(state, from, state[from] - fill), to, state[to] + fill);
  }

  private empty(index: number, state: State): State {
    return this.update(state, index, 0);
  }
}

Tags:

construct:add
construct:assignment
construct:boolean
construct:break
construct:class
construct:const
construct:constructor
construct:field
construct:for-loop
construct:if
construct:implicit-conversion
construct:index-access
construct:initializer
construct:invocation
construct:lambda
construct:logical-and
construct:map
construct:method
construct:number
construct:object
construct:optional-parameter
construct:parameter
construct:property
construct:return
construct:string
construct:subtract
construct:ternary
construct:throw
construct:type-alias
construct:variable
construct:visibility-modifiers
construct:while-loop
construct:yield
paradigm:functional
paradigm:imperative
paradigm:object-oriented
technique:boolean-logic
technique:exceptions
technique:higher-order-functions
technique:laziness
technique:looping

from typescript.

ErikSchierboom avatar ErikSchierboom commented on June 9, 2024

Exercise: resistor-color

Code

export const colorCode = (value: string) => {

    return COLORS.indexOf(value);

}

export const COLORS = [
    "black", "brown",
    "red", "orange",
    "yellow", "green",
    "blue", "violet",
    "grey", "white"];

Tags:

construct:assignment
construct:class
construct:export
construct:field
construct:import
construct:initializer
construct:method
construct:parameter
construct:property
construct:string
construct:throw
construct:variable
construct:visibility-modifiers
paradigm:object-oriented
technique:exceptions

from typescript.

ErikSchierboom avatar ErikSchierboom commented on June 9, 2024

This is an automated comment

Hello 👋 Next week we're going to start using the tagging work people are doing on these. If you've already completed the work, thank you! If you've not, but intend to this week, that's great! If you're not going to get round to doing it, and you've not yet posted a comment letting us know, could you please do so, so that we can find other people to do it. Thanks!

from typescript.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.