1
+
2
+ def k_to_flipper_int (k ):
3
+ flipper_int = 0
4
+ for i in range (k ):
5
+ flipper_int += 2 ** i
6
+ # print ("K = ", k, ", flipper_int = ", flipper_int)
7
+ return flipper_int
8
+
9
+
10
+ def string_to_pancakes_int (string , to_int = True ):
11
+ binary_string = ""
12
+ for char in string :
13
+ if char == "+" :
14
+ binary_string += "0"
15
+ elif char == "-" :
16
+ binary_string += "1"
17
+ else :
18
+ return "Error"
19
+ # print("String: ", string)
20
+ if to_int == True :
21
+ num = binary_string_to_int (binary_string )
22
+ # print("Pancake Int: ", num)
23
+ return num
24
+ else :
25
+ # print("Binary string: ", binary_string)
26
+ return binary_string
27
+
28
+ def binary_string_to_int (string ):
29
+ # print("Binary string: ", string)
30
+ binary_string_length = len (string )
31
+ num = 0
32
+ for i in range (1 , binary_string_length + 1 ):
33
+ digit = string [- i ]
34
+ if digit == "1" :
35
+ num += 2 ** (i - 1 )
36
+ elif string [- i ] == "0" :
37
+ pass
38
+ else :
39
+ return "Error"
40
+ # print("Pancake Sequence Int: ", num)
41
+ return num
42
+
43
+ def largest_power_of_two_smaller_than (n ):
44
+ # TODO:
45
+ # print("Largest power of two smaller than ", n, ":")
46
+ power = - 1
47
+ while n > 0 :
48
+ n = divmod (n , 2 )[0 ]
49
+ power += 1
50
+ if power < 0 :
51
+ return "Error: n <= 0"
52
+ power_of_two = 2 ** power
53
+ # print(power_of_two)
54
+ return power_of_two
55
+
56
+
57
+ def pancake_flipper (pancakes_string , k ):
58
+ flipper_int = k_to_flipper_int (k )
59
+ number_of_flips = 0
60
+ pancakes_int = string_to_pancakes_int (pancakes_string )
61
+ if pancakes_int % flipper_int == 0 :
62
+ # It is possible
63
+ while pancakes_int != 0 :
64
+ pancakes_int -= largest_power_of_two_smaller_than (pancakes_int )
65
+ number_of_flips += 1
66
+ # print ("Number of flips: ", number_of_flips)
67
+ return number_of_flips
68
+ else :
69
+ # print("Impossible")
70
+ return "Impossible"
71
+
72
+ # k_to_flipper_int(5)
73
+ # k_to_flipper_int(10)
74
+
75
+ def v2_pancake_flipper (pancakes_string , k ):
76
+ """O(n2) greedy algorithm.
77
+ Happy side up = 0, empty side up = 1."""
78
+ binary_list = list (string_to_pancakes_int (pancakes_string , to_int = False ))
79
+ flips = 0
80
+ # for each distinct possible flip
81
+ for i in range (len (binary_list ) - (k - 1 )):
82
+ # set active as leftmost pancake in flip
83
+ active = binary_list [i ]
84
+ # if active is empty side up, flip
85
+ if active == '1' :
86
+ # flip this pancake
87
+ binary_list [i ] = '0'
88
+ # Flip the next (k-1) pancakes
89
+ for j in range (1 ,k ):
90
+ binary_list [i + j ] = str (abs (int (binary_list [i + j ]) - 1 ))
91
+ # print updated pancake list
92
+ # print(binary_list)
93
+ flips += 1
94
+ # After all necessary flips completed
95
+ # if there are still empty side up pancakes, print 'IMPOSSIBLE'
96
+ for i in range (1 , k ):
97
+ # print("binary_list[-", i, "]: ", binary_list[-i])
98
+ if binary_list [- i ] == "1" :
99
+ # print("IMPOSSIBLE")
100
+ return "IMPOSSIBLE"
101
+ # print("Flips: ", flips)
102
+ return flips
103
+
104
+ def v3_pancake_flipper (pancakes_string , k ):
105
+ """O(n) greedy algorithm with memo-isation."""
106
+ binary_list = list (string_to_pancakes_int (pancakes_string , to_int = False ))
107
+ flips = 0
108
+ flip_count = 0
109
+ n = len (pancakes_string )
110
+ unflip_at = [0 ] * n
111
+ # for each leftmost pancake
112
+ for i in range (n ):
113
+ active = binary_list [i ]
114
+ if unflip_at [i ] == 1 :
115
+ flip_count -= 1
116
+ # if active is empty side up
117
+ if (active == '1' and flip_count % 2 == 0 ) \
118
+ or (active == '0' and flip_count % 2 == 1 ):
119
+ # if there is still room to flip, flip
120
+ if i < (n - (k - 1 )):
121
+ print ("Flip " , i )
122
+ # flip this pancake
123
+ flips += 1
124
+ flip_count += 1
125
+ if (i + k ) <= n - 1 :
126
+ unflip_at [i + k ] += 1
127
+ # if we can't flip, return 'IMPOSSIBLE'
128
+ else :
129
+ print (flip_count , active )
130
+ print ("IMPOSSIBLE: -" , i )
131
+ return "IMPOSSIBLE"
132
+ # print("Flips: ", flips)
133
+ return flips
134
+
135
+ # Test cases:
136
+ print (v3_pancake_flipper ("---+-++-" , 3 ))
137
+ print (v2_pancake_flipper ("---+-++-" , 3 ))
138
+ print (pancake_flipper ("---+-++-" , 3 ))
139
+ """
140
+ import time
141
+
142
+ start = time.time()
143
+ long_string = "++--++--+++++++--+-+++----+++++++-+---+--+-++--+-" * 19
144
+ v2_pancake_flipper(long_string, 8)
145
+ end = time.time()
146
+ print("Time taken: ", end - start "seconds")
147
+ """
148
+
149
+ """ For Code Jam
150
+ # input() reads a string with a line of input, stripping the '\n ' (newline) at the end.
151
+ # This is all you need for most Google Code Jam problems.
152
+ t = int(input()) # read a line with a single integer
153
+ for i in range(1, t + 1):
154
+ pancake_string, k = [s for s in input().split(" ")] # read a list of integers, 2 in this case
155
+ # print("n, k: ", n, k)
156
+ k = int(k)
157
+ flips = v2_pancake_flipper(pancake_string, k)
158
+ print("Case #{}: {}".format(i, flips))
159
+ # check out .format's specification for more formatting options
160
+ """
0 commit comments