{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# Euler Problem 17\n",
    "\n",
    "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.\n",
    "\n",
    "If all the numbers from 1 to 1000 (one thousand) inclusive were written out in words, how many letters would be used?\n",
    "\n",
    "\n",
    "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."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "I can see us doing a semi-automated approach here or we write a nice function. We probably write a nice function because we are geeks."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 1,
   "metadata": {
    "collapsed": false
   },
   "outputs": [],
   "source": [
    "def single_digit_integer_to_spoken_language(n):\n",
    "    if n == 0:\n",
    "        return \"\"\n",
    "    assert(n > 0 and n < 10)\n",
    "    return {1: 'one', 2: 'two', 3: 'three', 4: 'four', 5: 'five',\n",
    "            6: 'six', 7: 'seven', 8: 'eight', 9: 'nine'}[n]\n",
    "\n",
    "def double_digit_integer_to_spoken_language(n):\n",
    "    assert(n > 9 and n < 100)\n",
    "    try:\n",
    "        return {\n",
    "            10: 'ten', 11: 'eleven', 12: 'twelve', 13: 'thirteen', \n",
    "            14: 'fourteen', 15: 'fifteen', 16: 'sixteen',\n",
    "            17: 'seventeen', 18: 'eighteen', 19: 'nineteen'}[n]\n",
    "    except KeyError:\n",
    "        pass\n",
    "    a, b = str(n)\n",
    "    a = {2: 'twenty', 3: 'thirty', 4: 'forty', 5: 'fifty',\n",
    "         6: 'sixty', 7: 'seventy', 8: 'eighty', 9: 'ninety'}[int(a)]\n",
    "    b = integer_to_spoken_language(int(b))\n",
    "    return a + '-' + b\n",
    "\n",
    "def triple_digit_integer_to_spoken_language(n):\n",
    "    a, b = str(n)[0], str(n)[1:]\n",
    "    a = single_digit_integer_to_spoken_language(int(a))\n",
    "    b = integer_to_spoken_language(int(b))\n",
    "    if not b:\n",
    "        return a + \" hundred\"\n",
    "    return a + \" hundred and \" + b\n",
    "\n",
    "def four_digit_integer_to_spoken_language(n):\n",
    "    a, b = str(n)[0], str(n)[1:]\n",
    "    a = single_digit_integer_to_spoken_language(int(a))\n",
    "    b = integer_to_spoken_language(int(b))  \n",
    "    return a + \" thousand \" + b\n",
    "\n",
    "def integer_to_spoken_language(n):\n",
    "    l = len(str(n))\n",
    "    if l == 1:\n",
    "        return single_digit_integer_to_spoken_language(n)\n",
    "    elif l == 2:\n",
    "        return double_digit_integer_to_spoken_language(n)\n",
    "    elif l == 3:\n",
    "        return triple_digit_integer_to_spoken_language(n)\n",
    "    elif l == 4:\n",
    "        return four_digit_integer_to_spoken_language(n)\n",
    "    else:\n",
    "        raise Exception(\"Length not supported.\")\n",
    "\n",
    "assert(integer_to_spoken_language(5) == 'five')\n",
    "assert(integer_to_spoken_language(19) == 'nineteen')\n",
    "assert(integer_to_spoken_language(21) == 'twenty-one')\n",
    "assert(integer_to_spoken_language(210) == 'two hundred and ten')\n",
    "assert(integer_to_spoken_language(3000) == 'three thousand ')\n",
    "assert(integer_to_spoken_language(8333) == 'eight thousand three hundred and thirty-three')"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Okay, I won't win a code golf contest but at least we can get the solution now."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "21124\n"
     ]
    }
   ],
   "source": [
    "l = len(\"\".join([integer_to_spoken_language(i) for i in range(1, 1001)]).replace(\" \", \"\").replace(\"-\", \"\"))\n",
    "assert(l == 21124)\n",
    "print(l)\n"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Made the classical fourty/forty error I have already done four years ago. Some things don't change. Also I still do not really like this problem. The Haskell solution is actually way easier to read this time."
   ]
  }
 ],
 "metadata": {
  "completion_date": "Sun, 31 Aug 2014, 21:20",
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.5.4"
  },
  "tags": [
   "count",
   "numbers",
   "tricky"
  ]
 },
 "nbformat": 4,
 "nbformat_minor": 0
}
