//ProjectEulerTS/Problems/Problem37.ts //Matthew Ellison // Created: 07-01-21 //Modified: 07-14-21 //Find the sum of the only eleven primes that are both truncatable from left to right and right to left (2, 3, 5, and 7 are not counted). //Unless otherwise listed all non-standard includes are my own creation and available from https://bibucket.org/Mattrixwv/typescriptClasses /* Copyright (C) 2021 Matthew Ellison This program is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this program. If not, see . */ import { getSum } from "../../../Typescript/typescriptClasses/ArrayAlgorithms"; import { isPrime, sieveOfEratosthenes } from "../../../Typescript/typescriptClasses/NumberAlgorithms"; import { Unsolved } from "../Unsolved"; import { Problem } from "./Problem"; export class Problem37 extends Problem{ //Variables //Static variables private static LAST_PRIME_BEFORE_CHECK: number = 7; //The last prime before 11 since signle digit primes aren't checked //Instance variables private truncPrimes: number[]; private sum: number; //Functions //Constructor public constructor(){ super("Find the sum of the only eleven primes that are both truncatable from left to right and right to left (2, 3, 5, and 7 are not counted)."); this.truncPrimes = []; this.sum = 0; } //Operational functions //Solve the problems public solve(): void{ //If the porblem has already been solved do nothing and end the function if(this.solved){ return; } //Start the timer this.timer.start(); //Create the sieve and get the first prime number let sieve = sieveOfEratosthenes(); let tempPrime = sieve.next().value; let currentPrime: number = 0; if(typeof tempPrime == "number"){ currentPrime = tempPrime; } else{ throw new Unsolved("Sieve overflowed") } while(currentPrime < Problem37.LAST_PRIME_BEFORE_CHECK){ tempPrime = sieve.next().value; if(typeof tempPrime == "number"){ currentPrime = tempPrime; } else{ throw new Unsolved("Sieve overflowed") } } //Loop until truncPrimes contains 11 elements while(this.truncPrimes.length < 11){ let isTruncPrime: boolean = true; //Get the next prime tempPrime = sieve.next().value; if(typeof tempPrime == "number"){ currentPrime = tempPrime; } else{ throw new Unsolved("Sieve overflowed") } //Conver the prime to a string let primeString: string = currentPrime.toString(); //If the string contains an even digit move to the next prime for(let strLoc = 0;(strLoc < primeString.length) && (primeString[strLoc] == '2');++strLoc){ //Allow 2 to be the first digit if((strLoc == 0) && (primeString[strLoc] == '2')){ continue; } if((primeString[strLoc] == '0') || (primeString[strLoc] == '2') || (primeString[strLoc] == '4') || (primeString[strLoc] == '6') || (primeString[strLoc] == '8')){ isTruncPrime = false; break; } } //Start removing digits from the left and see if the number stays prime if(isTruncPrime){ for(let truncLoc = 1;(truncLoc < primeString.length) && (isTruncPrime);++truncLoc){ //Create a substring of the prime, removing the needed digits from the left let primeSubstring: string = primeString.substring(truncLoc); //Convert the string to an int and see if the number is still prime let newPrime: number = parseInt(primeSubstring); if(!isPrime(newPrime)){ isTruncPrime = false; } } } //Start removing digits from the right and see if the number stays prime if(isTruncPrime){ for(let truncLoc = 1;(truncLoc < primeString.length) && (isTruncPrime);++truncLoc){ //Create a substring of the prime, removing the needed digits from the right let primeSubstring: string = primeString.substring(0, primeString.length - truncLoc); //Convert the string to an int and see if the number is still prime let newPrime: number = parseInt(primeSubstring); if(!isPrime(newPrime)){ isTruncPrime = false; } } } //If the number remained prime through all operations add it to the vector if(isTruncPrime){ this.truncPrimes.push(currentPrime); } } //Get the sum of all elements in the truncPrimes list this.sum = getSum(this.truncPrimes); //Stop the timer this.timer.stop(); //Throw a flag to show the problem is solved this.solved = true; } //Reset the problem so it can be run again public reset(): void{ super.reset(); this.truncPrimes = []; this.sum = 0; } //Gets //Returns a string with the solution to the problem public getResult(): string{ this.solvedCheck("result"); return `The sum of all left and right truncatable primes is ${this.sum}`; } //Returns the list of primes that can be truncated public getTruncatablePrimes(): number[]{ this.solvedCheck("list of truncatable primes"); return this.truncPrimes; } //Returns the sum of all elements in truncPrimes public getSumOfTruncatablePrimes(): number{ this.solvedCheck("sum of truncatable primes"); return this.sum; } } /* Results: The sum of all left and right truncatable primes is 748317 It took an average of 104.007 milliseconds to run this problem through 100 iterations */