monkeymusic 0.0.11 → 0.0.12

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,15 +1,15 @@
1
1
  ---
2
2
  !binary "U0hBMQ==":
3
3
  metadata.gz: !binary |-
4
- YzY1NTRjZTg4MjM3M2NmYWI5Y2FmZTEzNWE3YzY5NTQ1NjI3OGVkYg==
4
+ NTE5MDBiNmY2YzUxN2IxOGRjODJlY2RjZmY1NjJkM2IwMGEwNDgxYw==
5
5
  data.tar.gz: !binary |-
6
- MDRhYjgzOTQ2MWQ5NjdlOWU0NDAwN2IzOWRjNjI4MjVkNzNiNmMxOQ==
6
+ ODljNDQ5YzdjNjg3ZGNkOWQzOTYxZTk3MjRiY2JlYTYzNjliNzUzNg==
7
7
  !binary "U0hBNTEy":
8
8
  metadata.gz: !binary |-
9
- ODA1ZDI5ODJhOTAyNTc5MDA0ZTU2OTIzNWU3MDBiY2QyM2NmNzY3Y2E4Mjc4
10
- OTRkMjQ5ZDU0YTQ4NjA2MDVlNmM3MTIyMzRhNTdkYTZmOTA5NDhkOWMwOWUz
11
- ZmM5ZDBhZTY3OGRiZWI4YTk3MjIwMWUxZWMwNTU1MWVjYTRlMTk=
9
+ MmFiNzI1ZTEyZTVmMWFiZDIyYjhlMzk2MTYwNzdjNTUxZTUwYzJjZjMwNzJl
10
+ ZmU5ZmYwMmIxMWE2NDU3OGM5NWJiYzFiZGIzYmY2ZmIyYTEyMDdiMDdlYjQz
11
+ OWNhZDJlNThkMGJmODVlYTQ3ZDJjMTM0NGFiOTg2NWQ5ZGRmY2Q=
12
12
  data.tar.gz: !binary |-
13
- MGE2NzhmOTgzZmQ5MjUwNGQwZTQ4N2RkYmIxNWY1YmMzMjVmODg3YTdlOGRj
14
- MzZlMGI3ZjEyYmMyYzE0ZTZhMTQwM2NlODMxNWFkNzE5YTI4OWRmZWZmMWQ1
15
- NTIyNGQwNThiM2M2ZjBmYjQzOTQzNDAwNThiZDEyNjgyMzYwNzU=
13
+ YjhjYjUwN2IxYTM1YTk0M2ZkNzRjNTFjMjIxYzZlZDAwMTc4MGU1ZDE5MWE0
14
+ ZDczMTE4YjAxMjQ5ZDJmYmFhNzZmMmE2Yzc2NzViM2MwMmRlMDZkMDlhMWZh
15
+ MDRjYzA3OGJjMmFmNGRkYmUxODdkMWM1YTZiNTFjNjNiNjQyOTQ=
data/README.md ADDED
@@ -0,0 +1,401 @@
1
+ Monkey Music Challenge
2
+ ======================
3
+ {: .logo}
4
+
5
+ Introduction
6
+ ------------
7
+
8
+ The Spotify backend is consists of a multitude of individual services. One such service is the music recommendation service, which is responsible for finding and recommending new tracks to Spotify users, according to their music taste.
9
+
10
+ The music recommendation service has lately been getting some pretty negative feedback from users. The word out on Twitter is that even monkeys could find better music recommendations!
11
+
12
+ Therefore, upper management has made an informed decision that the next version of the music recommendation service shall be operated entirely by monkeys. As product manager for the music recommendation service, your job is to make sure that the monkeys do a good job.
13
+
14
+ You have therefore decided to write a computer program that helps monkeys find good track recommendations for Spotify users.
15
+
16
+ This is all entirely fictional of course.
17
+ {: .tip}
18
+
19
+ Task summary
20
+ ------------
21
+
22
+ The task consists of implementing a program to play the Monkey Music game. The goal of the game is to score points by gathering track recommendations and giving them to a Spotify user.
23
+
24
+ The game
25
+ --------
26
+
27
+ Every game of Monkey Music is broken up into a number of turns.
28
+
29
+ Every turn, your program will be executed and fed information about the current state of the level by reading from `stdin`. Your program responds by printing one command to `stdout`. The command decides what your monkey does during the current turn.
30
+
31
+ Fate decides the order in which monkeys execute their commands in a turn.
32
+ {: .tip}
33
+
34
+ Before every turn, execution of your program starts. After every turn, execution of your program stops.
35
+
36
+ Rules
37
+ -----
38
+
39
+ ### Scoring
40
+
41
+ Your monkey will pick up tracks and deliver them to a user.
42
+
43
+ When a track is delivered, you will recieve a score according to how well the track fits the music taste of the user. The player with the highest score at the end of the game will be the winner.
44
+
45
+ You should try to get as high a score as possible.
46
+ {. tip}
47
+
48
+ ### Turn limit
49
+
50
+ Every game is played for a limited amount of turns. This limit is different for different levels.
51
+
52
+ The game ends when the turn limit is reached.
53
+
54
+ ### Time limit
55
+
56
+ Every time your program is executed, the execution time will be measured. Every level has a total time limit, that your program should not exceed.
57
+
58
+ If your execution time reaches the time limit, your monkey will run out of energy and fall asleep for `5` turns. Afte sleeping for `5` turns, the remaining execution time of your program will be replenished.
59
+
60
+ ### Carrying capacity
61
+
62
+ The number of tracks your monkey can pick up and hold at any given time is called carrying capacity.
63
+
64
+ The carrying capacity of your monkey is different for every level.
65
+
66
+ Level layout
67
+ ------------
68
+
69
+ The level is a `n x m` grid of cells. It is sent to the standard input of your program.
70
+
71
+ Each cell contains one of the following things:
72
+
73
+ ### Monkeys
74
+
75
+ * ASCII: `M[id]`
76
+
77
+ You, and your competitors each have your own monkey to control.
78
+ Every monkey is identified by a unique numerical id.
79
+
80
+ ### Walls
81
+
82
+ * ASCII: `#`
83
+
84
+ Walls are inanimate objects that monkeys cannot pass through.
85
+
86
+ ### Tracks
87
+
88
+ * ASCII: `[URI]`
89
+
90
+ Tracks are identified by their unique Spotify URI. Every track URI starts with `spotify:track:`, followed by `22` alphanumerical characters.
91
+
92
+ Example: `spotify:track:5H85hOp2oMlhMh9JlkdJP2`.
93
+
94
+ Tracks can be picked up and carried around by monkeys.
95
+
96
+ ### The User
97
+
98
+ * ASCII: `U`
99
+
100
+ The user is where monkeys deliver their track recommendations. Monkeys are
101
+ scored for every track delivered to the user, according to how well the track fits the user's music taste.
102
+
103
+ ### Empty
104
+
105
+ * ASCII: `[SPACE]`
106
+
107
+ Nothing to do here.
108
+
109
+ A cell can only contain one thing at any time.
110
+ {: .tip}
111
+
112
+ User toplists
113
+ -------------
114
+
115
+ How well tracks match the music taste of a user is decided by the user's toplists.
116
+
117
+ Every Spotify user has a track toplist, an album toplist and an artist toplist. Every entry in a toplist is a comma-separated string of metadata.
118
+
119
+ The toplists are sent to the standard input of your program on the following formats:
120
+
121
+ ### Track toplist
122
+
123
+ First an integer `n`, followed by `n` lines of track metadata entries.
124
+
125
+ n
126
+ track,album,artist,year
127
+ track,album,artist,year
128
+ ...
129
+
130
+ ### Album toplist
131
+
132
+ First an integer `n`, followed by `n` lines of album metadata entries.
133
+
134
+ [n]
135
+ album,artist,year
136
+ album,artist,year
137
+ ...
138
+
139
+ ### Artist toplist
140
+
141
+ First an integer `n`, followed by `n` lines of artist metadata entries.
142
+
143
+ n
144
+ artist
145
+ artist
146
+ ...
147
+
148
+ ### Disliked artist toplist
149
+
150
+ You will also receive a list of artists that the user does not like.
151
+
152
+ First an integer `n`, followed by `n` lines of artist entries.
153
+
154
+ n
155
+ artist
156
+ artist
157
+ ...
158
+
159
+ Spotify does not actually keep toplists of disliked artists. ;)
160
+ {: .tip}
161
+
162
+ Score system
163
+ ------------
164
+
165
+ Each track is scored according to the user toplists by placing it into 1 out of 5 score tiers.
166
+
167
+ There are three positive tiers: `1`, `2` and `3`. There are two negative tiers, `-1` and `-2`
168
+
169
+ The following criteria decide which tier a track belongs to:
170
+
171
+ ### Tier -2: Disliked artist
172
+
173
+ The track artist is in the user's disliked artist toplist. To recommend one of
174
+ these tracks is an epic fail.
175
+
176
+ ### Tier -1: Played to death
177
+
178
+ The track is already in the user's track toplist. There is not much point
179
+ in recommending it.
180
+
181
+ ### Tier += 1: Favorite artist
182
+
183
+ The track artist is in the user's artist toplist.
184
+
185
+ ### Tier += 1: Favorite album
186
+
187
+ If track album in the user's album toplist.
188
+
189
+ ### Tier += 1: Favorite decade
190
+
191
+ The year of the track belongs to the user's top decade.
192
+
193
+ This is an interesting one. Every user has a top decade, which is the decade that is most prominent in the user's track toplist and album toplist.
194
+
195
+ ### Tally
196
+
197
+ Your track will be scored according to it's tier:
198
+
199
+ **Tier -2:** -16 points
200
+
201
+ **Tier -1:** -4 points
202
+
203
+ **Tier 1:** 4 points
204
+
205
+ **Tier 2:** 16 points
206
+
207
+ **Tier 3:** 64 points
208
+
209
+ Tier 3 tracks are obviously very valuable, so be on the lookout for these.
210
+ {: .tip}
211
+
212
+ Game progression
213
+ ----------------
214
+
215
+ ### Initialization phase
216
+
217
+ The game consists of two different phases.
218
+
219
+ The first phase is the initialization phase, it occurs once every game.
220
+
221
+ During the initialization phase, your program will be given information about the level that will be useful during the entire course of the game.
222
+
223
+ The information that can be read from `stdin` during the `init` phase is:
224
+
225
+ INIT\n
226
+ M[id]\n
227
+ [WIDTH]\n
228
+ [HEIGHT]\n
229
+ [TURN LIMIT]\n
230
+ [n]\n
231
+ [TRACK],[ALBUM],[ARTIST],[YEAR]\n
232
+ [n]\n
233
+ [ALBUM],[ARTIST],[YEAR]\n
234
+ [n]\n
235
+ [ARTIST]\n
236
+ [n]\n
237
+ [ARTIST]\n
238
+
239
+ * The string `"INIT"`
240
+ * The id of your monkey
241
+ * The `width` of the map
242
+ * The `height` of the map
243
+ * The `turn limit` of the game
244
+ * The number of entries in the user's track toplist
245
+ * The track toplist entries
246
+ * The number of entries in the user's album toplist
247
+ * The album toplist
248
+ * The number of entries in the user's artist toplist
249
+ * The artist toplist
250
+ * The number of entries in the user's disliked artist toplist
251
+ * The disliked artist toplist
252
+
253
+ After the initialization phase, execution of your program will stop until the next phase.
254
+
255
+ Make sure to keep the data from the initialization phase in a persistent cache!
256
+ {: .tip}
257
+
258
+ ### Turn phases
259
+
260
+ After the initialization phase, a number of turn phases will follow.
261
+
262
+ The total number of turn phases is decided by the turn limit of the level.
263
+
264
+ The information that can be read from `stdin` during a turn phase is:
265
+
266
+ TURN\n
267
+ M[ID]\n
268
+ [TURN NUMBER]\n
269
+ [REMAINING CAPACITY]\n
270
+ [REMAINING TIME]\n
271
+ [n]\n
272
+ [URI],[TRACK],[ALBUM],[ARTIST],[YEAR]\n
273
+ [LEVEL]\n
274
+
275
+ * The string `"TURN"`
276
+ * The id of your monkey
277
+ * The turn number
278
+ * The remaining carrying capacity of your monkey
279
+ * The remaining execution time of your program
280
+ * The number of available metadata lookup results
281
+ * Your metadata lookup results from the previous turn
282
+ * The current state of the level
283
+
284
+ After reading the turn information from `stdin`, your program will print a command for your monkey to `stdout`.
285
+
286
+ Monkey commands
287
+ ---------------
288
+
289
+ Commands are sent from the standard output of your program.
290
+ In each turn of the game, every monkey executes one command.
291
+
292
+ Commands which the monkeys can execute are:
293
+
294
+ [MOVE] | [METADATA LOOKUP] | B,[COMMAND],[COMMAND],[COMMAND]
295
+
296
+ ### Move
297
+
298
+ You can command the monkey to move in the four cardinal directions using
299
+ the commands:
300
+
301
+ W
302
+
303
+ Moves the monkey one cell to the left.
304
+
305
+ E
306
+
307
+ Moves the monkey one cell to the right.
308
+
309
+ N
310
+
311
+ Moves the monkey one cell up.
312
+
313
+ S
314
+
315
+ Moves the monkey one cell down.
316
+
317
+ Trying to move to an already occupied cell will casue the monkey to stand
318
+ still for the duration of the round.
319
+ {: .tip}
320
+
321
+ ### Metadata lookup
322
+
323
+ You can lookup the metadata of a track on the level by issuing a metadata
324
+ lookup command:
325
+
326
+ spotify:track:......................
327
+
328
+ You will recieve the result of the metadata lookup the following turn.
329
+
330
+ Your monkey must every turn choose between moving and looking up the metadata of a track!
331
+ {: .tip}
332
+
333
+ ### Boost
334
+
335
+ B,[COMMAND],[COMMAND],[COMMAND]
336
+
337
+ Once every game, the monkey can issue a boost command and then issue three other comma separated commands during the same turn.
338
+
339
+ You can only issue the boost command once every game. Choose wisely!
340
+ {: .tip}
341
+
342
+ The turn input after having issued this command:
343
+
344
+ B,W,spotify:track:5H85hOp2oMlhMh9JlkdJP2,spotify:track:5H85hOp2oMlhMh9JlkdJP2
345
+
346
+ could look like:
347
+
348
+ TURN
349
+ 10
350
+ M1
351
+ 1
352
+ 4529
353
+ 2
354
+ spotify:track:5H85hOp2oMlhMh9JlkdJP2,TODO,TODO,TODO,TODO
355
+ spotify:track:5H85hOp2oMlhMh9JlkdJP2,TODO,TODO,TODO,TODO
356
+
357
+ ### Picking up tracks
358
+
359
+ When standing next to a track and executing a move command toward the track, your monkey will remain in the same cell and pick up the track. If the carrying capacity of your monkey is maxed out, nothing will happen.
360
+
361
+ Once a track is picked up, there is no way to get rid of it but to deliver it.
362
+ {: .tip}
363
+
364
+ ### Delivering tracks
365
+
366
+ When standing next to the user and issuing a move command toward the track, your monkey will remain in the same cell and deliver all currently carried tracks to the user. You will then recieve score according to the score system.
367
+
368
+ Be careful about picking up negative tier tracks. You'll have to deliver them.
369
+ {: .tip}
370
+
371
+ Requirements
372
+ ------------
373
+
374
+ Monkey Music depends on Ruby 1.9.
375
+
376
+ If your OS does not provide it by default, you can always get it using RVM.
377
+
378
+ Installation
379
+ ------------
380
+
381
+ To install the challenge runtime:
382
+
383
+ > gem install monkeymusic
384
+
385
+ To get started quickly:
386
+
387
+ > monkeymusic demo
388
+
389
+ To see something on the screen:
390
+
391
+ > monkeymusic -p demo_player
392
+
393
+ You can probably learn a lot about the game from reading the `demo_player`.
394
+
395
+ Handing in
396
+ ----------
397
+
398
+ Your competition entry is to be handed in as a zip archive containing
399
+ everything needed to run your program.
400
+
401
+ When unpacked, your program should be runned through an executable file called `runme`.
data/bin/monkeymusic CHANGED
@@ -1,5 +1,5 @@
1
1
  #!/usr/bin/env ruby
2
2
  require File.dirname(__FILE__) + '/../lib/monkey_music'
3
3
 
4
- runner = MonkeyMusic::Runner.new(ARGV)
5
- runner.run
4
+ runner = MonkeyMusic::Runner.new
5
+ runner.run(MonkeyMusic::UI::Console)
@@ -0,0 +1,6 @@
1
+ #!/usr/bin/env ruby
2
+ require File.dirname(__FILE__) + '/../lib/monkey_music'
3
+ require File.dirname(__FILE__) + '/../lib/monkey_music/ui/browser'
4
+
5
+ runner = MonkeyMusic::Runner.new
6
+ runner.run(MonkeyMusic::UI::Browser)
data/levels/demo_level.rb CHANGED
@@ -4,11 +4,11 @@ time_limit 20000
4
4
 
5
5
  legend "1" => Monkey.player(1),
6
6
  "2" => Monkey.player(2),
7
- "X" => Track.worth(-2),
8
- "x" => Track.worth(-1),
9
- "l" => Track.worth(1),
10
- "t" => Track.worth(2),
11
- "T" => Track.worth(3),
7
+ "X" => Track.tier(-2),
8
+ "x" => Track.tier(-1),
9
+ "l" => Track.tier(1),
10
+ "t" => Track.tier(2),
11
+ "T" => Track.tier(3),
12
12
  "U" => User,
13
13
  "#" => Wall
14
14