I recently came across some programming puzzles that Spotify have put out there for developers to test their skills on. There are 3 puzzles that range from easy to hard (or Reggae, Funk and Heavy metal as Spotify put it).
I had a go at the first challenge, titled ‘bestbefore‘ where your program should accept a date but without knowing whether the first, second or third parts are the day, month or year. Your challenge is to find the earliest legal date between 2000 and 2999.
The programs have to be written in C, C++, Java or Python. As my experience mainly lies in PHP I had to pick one of these other languages to code it in. One of my personal challenges this year is to learn Python so what better opportunity to apply it to a problem like this one.
Here is my solution to the ‘bestbefore’ problem. If you want to have a go at the challenges yourself, you might want to close your eyes now!
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 |
from datetime import datetime from calendar import timegm class BestBefore: in_date = '' parts = [] possible_dates = [] the_date = []; def __init__(self): self.in_date = self.getInput() self.splitInput() self.determineDateParts() self.determineFirstValidDate() def getInput(self): return raw_input() def splitInput(self): self.parts = self.in_date.split('/') def determineDateParts(self): for i in range(3): for j in range(3): if i != j: for k in range(3): if j != k and i != k: if (self.isValidDay(int(self.parts[i])) and self.isValidMonth(int(self.parts[j])) and self.isValidYear(int(self.parts[k]))): self.possible_dates.append([int(self.parts[i]), int(self.parts[j]), self.convertToFullYear(int(self.parts[k]))]) def determineFirstValidDate(self): dates = [] for i in self.possible_dates: try: d = datetime(i[2],i[1],i[0]) dates.append(timegm(d.timetuple())) except ValueError: dates.append(0) dates = sorted(dates) self.the_date = dates.pop(0) def isValidDay(self, day): if day >= 1 and day <= 31: return True else: return False def isValidMonth(self, month): if month >= 1 and month <= 12: return True else: return False def isValidYear(self, year): year = self.convertToFullYear(year) if year >= 2000 and year <= 2999: return True else: return False def convertToFullYear(self, year): if year < 100: year += 2000 return year def formatDate(self): if not self.the_date: return '%s %s' % (self.in_date, 'is illegal') else: return datetime.fromtimestamp(int(self.the_date)).strftime('%Y-%m-%d') def printDate(self): print "%s" % self.formatDate() obj = BestBefore() obj.printDate() |
I fully accept that this is not going to be the most beautiful Python code you’ve ever read nor a very elegant solution, but it seems to work and I’m very proud of my first decent length Python program…
Whoa, 78 lines? Hint: Think one big loop. Second hint: Look at itertools, specifically permutations.
mmm, permutations, that would have been useful. Difficult to know what to look for with Python. I don’t find the documentation as useful as PHPs’s.
Lots to learn I have…
Also, apologies for the code formatting. It seems that the plugin I’m using doesn’t always understand what a line break is
I know what you mean, I’ve stumbled around Python to be honest. Finding things as I go!