Latest news about Bitcoin and all cryptocurrencies. Your daily crypto news habit.
I just finished project euler #17. Iāll go through my thought process in solving it here, but would love feedback, especially if your solution was different than mine. Iām sure there are many more elegant and simplistic solutions.
The problem goes asĀ follows:
If the numbers 1 to 5 are written out in words: one, two, three, four, five, then there are 3 + 3 + 5 + 4 + 4 = 19 letters used inĀ total.
If all the numbers from 1 to 1000 (one thousand) inclusive were written out in words, how many letters would beĀ used?
NOTE: Do not count spaces or hyphens. For example, 342 (three hundred and forty-two) contains 23 letters and 115 (one hundred and fifteen) contains 20 letters. The use of āandā when writing out numbers is in compliance with BritishĀ usage.
My first thought was that I would need to loop over the numbers 1 to 1000 and convert each number into the written word corresponding to thatĀ number.
Naturally, I could just make an array containing every written word. But I didnāt want to have to write every number. Instead, I thought about doing something likeĀ this:
Without defining every letter, I could make an array of the numbers 1 through 9, and then another array of the letters āoneā throughĀ ānineā.
If, for example, the number is 547, then I could see if the first number of the given number set matches any numbers from the onesArr. Then I could do the same for the last number. Once it finds a match, Iāll simply grab the value of the onesComp array instead, but at the same index where I found the match in theĀ onesArr.
Although, this wouldnāt work for ātwentyā, āthirtyā, āfortyā etc. It also wouldnāt work with 10 through 19. So, I could make a couple of additional arrays, and do the same thing, depending on the length of the givenĀ number.
Something like this would allow me to have a number array for 1ā10, and a matching word array for āoneā-ātenā. Then the same thing for teens, and tens. The key for me, is having the index values match. So my ones array starts at 1 instead of 0, since we arenāt using zero, and my teens array does include a zero, since that starts at 10, and Iāll be looking for the 0 in the number 10, just like Iāll be looking for the 1 in 11 and the 2 in 12, etc. Then the tens array starts with 2 and twenty. At that point, the next obstacle would be to determine the length of the number. My thought there would be to loop over the array of 1 to 1000. For each item, I would turn the number into a string and then split the string, so it would give me an array of each number. Then, inside and if statement, I would use parseInt() to convert it back into a number and check it against the value of the compare array. That part would probably look something likeĀ this:
Hereās the finalĀ code:
let ones = ['one', 'two', 'three', 'four', 'five', 'six', 'seven', 'eight', 'nine'];let teens = ['ten', 'eleven', 'twelve', 'thirteen', 'fourteen', 'fifteen', 'sixteen', 'seventeen', 'eighteen', 'nineteen'];let tens = ['twenty', 'thrity', 'forty', 'fifty', 'sixty', 'seventy', 'eighty', 'ninety'];let thousands = ['thousand'];let compareOnes = [1,2,3,4,5,6,7,8,9];let compareTeens = [0,1,2,3,4,5,6,7,8,9];let compareTens = [2,3,4,5,6,7,8,9];
let numbers = [];for (var i = 1; i <= 1000; i++) { numbers.push(i);}
let currentCount = 0;
for (var i = 0; i < numbers.length; i++) { let numStr = numbers[i].toString(); let numStrArr = numStr.split(""); if(numStrArr.length == 1){ let digit1 = parseInt(numStrArr[0]); let index = compareOnes.indexOf(digit1); currentCount = currentCount + ones[index]; } if(numStrArr.length == 2 && numbers[i]>=20){ let digit1 = parseInt(numStrArr[0]); let digit2 = parseInt(numStrArr[1]); let index = compareTens.indexOf(digit1); let index2 = compareOnes.indexOf(digit2); currentCount = currentCount + tens[index] + ones[index2]; } if(numStrArr.length == 2 && numbers[i]<20){ let digit2 = parseInt(numStrArr[1]); let index2 = compareTeens.indexOf(digit2); currentCount = currentCount + teens[index2]; } if(numStrArr.length == 3 && numStrArr[1] == "0" && numStrArr[2] == "0"){ let digit1 = parseInt(numStrArr[0]); let digit2 = parseInt(numStrArr[1]); let digit3 = parseInt(numStrArr[2]); let index3 = compareOnes.indexOf(digit1); let index2 = compareTens.indexOf(digit2); let index = compareOnes.indexOf(digit3); currentCount = currentCount + ones[index3]+"hundred"; } if(numStrArr.length == 3 && numStrArr[1] == "0" && numStrArr[2] !== "0"){ let digit1 = parseInt(numStrArr[0]); let digit2 = parseInt(numStrArr[1]); let digit3 = parseInt(numStrArr[2]); let index3 = compareOnes.indexOf(digit1); let index2 = compareTens.indexOf(digit2); let index = compareOnes.indexOf(digit3); currentCount = currentCount + ones[index3]+"hundred"+"and"+tens[index2]+ones[index]; } if(numStrArr.length == 3 && numStrArr[1] == "1"){ let digit1 = parseInt(numStrArr[0]); let digit2 = parseInt(numStrArr[1]); let digit3 = parseInt(numStrArr[2]); let index3 = compareOnes.indexOf(digit1); let index2 = compareTeens.indexOf(digit3); currentCount = currentCount + ones[index3]+"hundred"+"and"+teens[index2]; } if(numStrArr.length == 3 && numStrArr[1] !== "0" && numStrArr[2] !== "0" && numStrArr[1] !== "1"){ let digit1 = parseInt(numStrArr[0]); let digit2 = parseInt(numStrArr[1]); let digit3 = parseInt(numStrArr[2]); let index3 = compareOnes.indexOf(digit1); let index2 = compareTens.indexOf(digit2); let index = compareOnes.indexOf(digit3); currentCount = currentCount + ones[index3]+"hundred"+"and"+tens[index2]+ones[index]; } if(numStrArr.length == 3 && numStrArr[1] !== "0" && numStrArr[2] == "0" && numStrArr[1] !== "1"){ let digit1 = parseInt(numStrArr[0]); let digit2 = parseInt(numStrArr[1]); let digit3 = parseInt(numStrArr[2]); let index3 = compareOnes.indexOf(digit1); let index2 = compareTens.indexOf(digit2); let index = compareOnes.indexOf(digit3); currentCount = currentCount + ones[index3]+"hundred"+"and"+tens[index2]; } if(numStrArr.length == 4){ currentCount = currentCount + "one"+"thousand"; }}let newCurrent = currentCount.replace(/undefined/g, "");console.log(newCurrent);console.log(newCurrent.length)
You may notice my bit of regex at the bottom there. I kept having undefined come up, and it was just added in there. I could have tried to figure out why, but it was obvious that all the other words I needed were still in there, so I just wrote a bit of regex to get rid of any undefined in the finalĀ string.
My Solution: 21124
Hereās what the final string looks likeā¦well, just the first 75Ā numbers:
onetwothreefourfivesixseveneightnineteneleventwelvethirteenfourteenfifteensixteenseventeeneighteennineteentwentytwentyonetwentytwotwentythreetwentyfourtwentyfivetwentysixtwentyseventwentyeighttwentyninethritythrityonethritytwothritythreethrityfourthrityfivethritysixthrityseventhrityeightthrityninefortyfortyonefortytwofortythreefortyfourfortyfivefortysixfortysevenfortyeightfortyninefiftyfiftyonefiftytwofiftythreefiftyfourfiftyfivefiftysixfiftysevenfiftyeightfiftyninesixtysixtyonesixtytwosixtythreesixtyfoursixtyfivesixtysixsixtysevensixtyeightsixtynineseventyseventyoneseventytwoseventythreeseventyfourseventyfive
projecteuler.net # 17 was originally published in Hacker Noon on Medium, where people are continuing the conversation by highlighting and responding to this story.
Disclaimer
The views and opinions expressed in this article are solely those of the authors and do not reflect the views of Bitcoin Insider. Every investment and trading move involves risk - this is especially true for cryptocurrencies given their volatility. We strongly advise our readers to conduct their own research when making a decision.