Problem 1 done
[ou-summer-of-code-2017.git] / 01-ticket-prices / ticket-pricing-solution.ipynb
1 {
2 "cells": [
3 {
4 "cell_type": "markdown",
5 "metadata": {},
6 "source": [
7 "# Ticket pricing\n",
8 "\n",
9 "You've been shopping around for a holiday package deal and its time to make your choice of which deal to go with. The file [01-holidays.txt](01-holidays.txt) contains a summary of your investigations. \n",
10 "\n",
11 "It's a simple text file, with one possible holiday package per line.\n",
12 "\n",
13 "Each line has four fields, separated by spaces. They are:\n",
14 "* The deal ID, from the price comparison website you found it.\n",
15 "* The holiday price, in whole pounds.\n",
16 "* The location of the holiday, always a single word.\n",
17 "* The number of nights you'd be staying. \n",
18 "\n",
19 "For example, the data file might look like this:\n",
20 "\n",
21 "```\n",
22 "db61bb906d 769 Morgantown 3\n",
23 "202c898b5f 1284 Morgantown 21\n",
24 "def36ffc7d 1514 Giessenmestia 21\n",
25 "389018bd07 1052 Estacada 21\n",
26 "a487c4270a 782 Geoje-Si 14\n",
27 "6caf2584a5 724 Stonington-Island 14\n",
28 "199608abc5 1209 Nordkapp 21\n",
29 "```"
30 ]
31 },
32 {
33 "cell_type": "markdown",
34 "metadata": {},
35 "source": [
36 "## Part 1\n",
37 "You have a budget of £1200. How many of the holidays can you afford?\n",
38 "\n",
39 "Given the example data above, you could afford four of the holidays: the 21 day trip to Morgantown and the trips to Giessenmestia and Nordkapp are all too expensive."
40 ]
41 },
42 {
43 "cell_type": "markdown",
44 "metadata": {},
45 "source": [
46 "### Solution"
47 ]
48 },
49 {
50 "cell_type": "code",
51 "execution_count": 7,
52 "metadata": {},
53 "outputs": [
54 {
55 "data": {
56 "text/plain": [
57 "[['5f12ce1b86', '1192', 'Sukhumi', '14'],\n",
58 " ['0279c8a91b', '1008', 'Estacada', '14'],\n",
59 " ['1faea40e9c', '1085', 'Tambon-Pa-Fa', '14']]"
60 ]
61 },
62 "execution_count": 7,
63 "metadata": {},
64 "output_type": "execute_result"
65 }
66 ],
67 "source": [
68 "holidays = []\n",
69 "with open('01-holidays.txt') as f:\n",
70 " for hol_line in f.readlines():\n",
71 " holidays.append(hol_line.split())\n",
72 " \n",
73 "holidays[:3]"
74 ]
75 },
76 {
77 "cell_type": "code",
78 "execution_count": 25,
79 "metadata": {},
80 "outputs": [
81 {
82 "data": {
83 "text/plain": [
84 "57"
85 ]
86 },
87 "execution_count": 25,
88 "metadata": {},
89 "output_type": "execute_result"
90 }
91 ],
92 "source": [
93 "affordable_holidays = []\n",
94 "for h in holidays:\n",
95 " if int(h[1]) <= 1200:\n",
96 " affordable_holidays.append(h)\n",
97 "\n",
98 "len(affordable_holidays)"
99 ]
100 },
101 {
102 "cell_type": "markdown",
103 "metadata": {},
104 "source": [
105 "### Smart-alec one-line solution"
106 ]
107 },
108 {
109 "cell_type": "code",
110 "execution_count": 6,
111 "metadata": {},
112 "outputs": [
113 {
114 "data": {
115 "text/plain": [
116 "57"
117 ]
118 },
119 "execution_count": 6,
120 "metadata": {},
121 "output_type": "execute_result"
122 }
123 ],
124 "source": [
125 "sum(1 for h in open('01-holidays.txt').readlines() if int(h.split()[1]) <= 1200)"
126 ]
127 },
128 {
129 "cell_type": "markdown",
130 "metadata": {},
131 "source": [
132 "# Part 2\n",
133 "You don't just want _a_ holiday. You want the _best_ holiday. What is the code of the holiday which would give you the best value?\n",
134 "\n",
135 "The \"value\" of a holiday is the duration per pound. Because some destinations are better than others, you'll want to scale the value for some locations. For instance, a night in Timbuktu is worth three times as much as a holiday in Bletchley.\n",
136 "\n",
137 "Assume all holidays have a relative value of 1, apart from these destinations.\n",
138 "\n",
139 "| Destination | Score |\n",
140 "|-------------|-------|\n",
141 "| Almaty | 2.0 |\n",
142 "| Brorfelde | 0.9 |\n",
143 "| Estacada | 0.4 |\n",
144 "| Jayuya | 0.6 |\n",
145 "| Karlukovo | 2.2 |\n",
146 "| Morgantown | 2.9 |\n",
147 "| Nordkapp | 1.5 |\n",
148 "| Nullarbor | 2.2 |\n",
149 "| Puente-Laguna-Garzonkuala-Penyu | 0.4 |\n",
150 "| Uzupis | 0.9 |\n",
151 "\n",
152 "## Example\n",
153 "\n",
154 "Given the holiday list above, the holiday to Geoje-Si (with the standard weighting of 1) has a value of $\\frac{14}{782} = 0.0179$ nights per pound. The best value holiday is the 21 day trip to Morgantown, with a value of $2.9 \\times \\frac{21}{1284} = 0.0474$ nights per pound. Unfortunately, it's unaffordable. \n",
155 "\n",
156 "The trip to Estacada looks promising, at $\\frac{21}{1052} = 0.0200$ nights per pound. Unfortunately, the weighting for Estacada is low, to the adjusted cost is $0.4 \\times \\frac{21}{1052} = 0.00798$ nights per pound.\n",
157 "\n",
158 "The best value affordable holiday is the trip to Stonnington Island, with $\\frac{14}{1284} = 0.0193$ nights per pound."
159 ]
160 },
161 {
162 "cell_type": "code",
163 "execution_count": 9,
164 "metadata": {
165 "collapsed": true
166 },
167 "outputs": [],
168 "source": [
169 "destination_values = {'Almaty': 2.0, 'Brorfelde': 0.9, 'Estacada': 0.4, 'Jayuya': 0.6, 'Karlukovo': 2.2, \n",
170 " 'Morgantown': 2.9,'Nordkapp': 1.5, 'Nullarbor': 2.2, \n",
171 " 'Puente-Laguna-Garzonkuala-Penyu': 0.4, 'Uzupis': 0.9}"
172 ]
173 },
174 {
175 "cell_type": "code",
176 "execution_count": 11,
177 "metadata": {},
178 "outputs": [],
179 "source": [
180 "def value_of_destination(name):\n",
181 " if name in destination_values:\n",
182 " return destination_values[name]\n",
183 " else:\n",
184 " return 1"
185 ]
186 },
187 {
188 "cell_type": "code",
189 "execution_count": 32,
190 "metadata": {},
191 "outputs": [],
192 "source": [
193 "def value_of_holiday(holiday):\n",
194 " hid, cost, destination, duration = tuple(holiday)\n",
195 " value = value_of_destination(destination) * float(duration) / int(cost)\n",
196 " return value"
197 ]
198 },
199 {
200 "cell_type": "code",
201 "execution_count": 36,
202 "metadata": {},
203 "outputs": [
204 {
205 "data": {
206 "text/plain": [
207 "'dc16c9b87f'"
208 ]
209 },
210 "execution_count": 36,
211 "metadata": {},
212 "output_type": "execute_result"
213 }
214 ],
215 "source": [
216 "best_holiday = ''\n",
217 "best_value = 0\n",
218 "\n",
219 "for h in affordable_holidays:\n",
220 " if value_of_holiday(h) > best_value:\n",
221 " best_value = value_of_holiday(h)\n",
222 " best_holiday = h[0]\n",
223 " \n",
224 "best_holiday"
225 ]
226 },
227 {
228 "cell_type": "markdown",
229 "metadata": {},
230 "source": [
231 "## Smart-alec solution"
232 ]
233 },
234 {
235 "cell_type": "code",
236 "execution_count": 34,
237 "metadata": {},
238 "outputs": [
239 {
240 "data": {
241 "text/plain": [
242 "'dc16c9b87f'"
243 ]
244 },
245 "execution_count": 34,
246 "metadata": {},
247 "output_type": "execute_result"
248 }
249 ],
250 "source": [
251 "max(affordable_holidays, key=value_of_holiday)[0]"
252 ]
253 },
254 {
255 "cell_type": "code",
256 "execution_count": null,
257 "metadata": {
258 "collapsed": true
259 },
260 "outputs": [],
261 "source": []
262 }
263 ],
264 "metadata": {
265 "kernelspec": {
266 "display_name": "Python 3",
267 "language": "python",
268 "name": "python3"
269 },
270 "language_info": {
271 "codemirror_mode": {
272 "name": "ipython",
273 "version": 3
274 },
275 "file_extension": ".py",
276 "mimetype": "text/x-python",
277 "name": "python",
278 "nbconvert_exporter": "python",
279 "pygments_lexer": "ipython3",
280 "version": "3.5.2+"
281 }
282 },
283 "nbformat": 4,
284 "nbformat_minor": 2
285 }