-
Notifications
You must be signed in to change notification settings - Fork 2
/
Copy pathcodechallenge_114.py
148 lines (112 loc) · 4.67 KB
/
codechallenge_114.py
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
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
'''
Date: 05/03/2022
Problem description:
===================
This problem was asked by Pinterest.
The sequence [0, 1, ..., N] has been jumbled, and the only clue you have for its order
is an array representing whether each number is larger or smaller than the last.
Given this information, reconstruct an array that is consistent with it.
For example, given guide == [None, +, +, -, +], and jumbled_list = [1,4,2,3,0] ]you could return [1, 2, 3, 0, 4]
Algorithm:
==========
1. Validate input. And check for len(guide) == len(jumbled_array)
2. It helps if we pre-sort the jumbled list (not needed. as it turns out)
3. Traverse the guide and construct the list making sure the current element is logically valid with the previous element.
'''
from msilib.schema import Error
import unittest
#import HtmlTestRunner
from HtmlTestRunner import HTMLTestRunner
import os, time, sys
from unittest.runner import TextTestResult
def getSmallerElement(elem, lst):
# get the first element in the lst that is smaller tham elem.
# list.pop(index) will delete the element from lst too.
# pop() effects the passed-in param lst as well. How convinience!
for i,x in enumerate(lst):
if x < elem: return lst.pop(i)
def getLargerElement(elem, lst):
# get the first element in the lst that is bigger than elem.
# list.pop(index) will delete the element from lst too.
# pop() effects the passed-in param lst as well. How convinience!
for i,x in enumerate(lst):
if x > elem: return lst.pop(i)
#
# Solution for Algorithm #1
# return the reconstructed list
#
def reconstructList(guide, lst):
if len(guide) > len(lst):
raise ValueError("Reconstruction guide and jumbled list have different length.")
# pre-sort the jumbled list
#worklst = sorted(lst, reverse=False)
worklst = lst
# define the return list
newlst = []
# let's reassemble the list
for x in guide:
if x == 'None': # any object
newlst.append(worklst.pop(0))
elif x == '+':
# insert element with value greater than newlst[-1] into newlst
#print(len(worklst))
largerElem = getLargerElement(newlst[-1], worklst)
#print(len(worklst))
#print('newlst[-1]: ', newlst[-1], ' largerElem: ', largerElem)
newlst.append(largerElem)
elif x == '-':
# insert element with value lesser than newlst[-1] into newlst
smallerElem = getSmallerElement(newlst[-1], worklst)
#print('newlst[-1]: ', newlst[-1], ' smallerElem: ', smallerElem)
newlst.append(smallerElem)
else: #this should not happen
raise ValueError('Unknown guiding instruction!')
return newlst
#
# Unittest
#
class TestReconstructMessedupList(unittest.TestCase):
def setUp(self):
self.startTime = time.time()
def tearDown(self):
t = time.time() - self.startTime
print('%s: %.3f' % (self.id(), t))
def test_ReconstructList(self):
# guide = ['None', '+', '+', '-', '+']
# jlst = [1,4,2,3,0,5]
guide = ['None', '+', '+', '+', '-']
jlst = [1,2,4,3,0,9,5]
self.assertEqual(reconstructList(guide, jlst), [1, 2, 4, 9, 3])
jlst = [1,2,4]
self.assertRaises(ValueError, lambda: reconstructList(guide, jlst))
def main():
guide = ['None', '+', '+', '+', '-']
jlst = [1,2,4,3,0,9,5]
newList = reconstructList(guide, jlst)
print(newList)
if __name__ == '__main__':
if os.environ.get('UNITTEST_ONLY') != 'True':
main()
else:
try:
unittest.main(testRunner=HtmlTestRunner.HTMLTestRunner(output='test_reports'))
except Exception as e:
print(e)
unittest.main()
# unittest.main(testRunner=HtmlTestRunner.HTMLTestRunner(output='test_reports'))
# unittest.main(testRunner=HtmlTestRunner.HTMLTestRunner())
# unittest.main(testRunner=HtmlTestRunner.HTMLTestRunner(streams=sys.stdout, verbosity=1, title='unittest_codechallenge_114', description='test_reports'))
'''
Run-time Output:
===============
PS D:\devel\GIT\DailyCodingChallenge> pipenv run python .\codechallenge_114.py
Loading .env environment variables...
Running tests...
----------------------------------------------------------------------
test_ReconstructList (__main__.TestReconstructMessedupList) ... OK (0.000000)s
----------------------------------------------------------------------
Ran 1 test in 0:00:00
OK
Generating HTML reports...
test_reports\TestResults___main__.TestReconstructMessedupList_2022-05-03_17-37-24.html
'''