Code Says https://codesays.com C code. C code run. Run code run... please! Thu, 30 Nov 2017 07:36:42 +0000 en-US hourly 1 https://wordpress.org/?v=4.8.3 Solution to Rectangle-Builder-Greater-Area by codility https://codesays.com/2016/solution-to-rectangle-builder-greater-area-by-codility/ https://codesays.com/2016/solution-to-rectangle-builder-greater-area-by-codility/#respond Sun, 20 Nov 2016 21:58:45 +0000 https://codesays.com/?p=1908 Question: https://codility.com/demo/take-sample-test/rectangle_builder_greater_area/

Question Name: Rectangle-Builder-Greater-Area or RectangleBuilderGreaterArea

This key is the binary search.

```def solution(A, X):
fence_count = {}
for fence in A:
fence_count[fence] = fence_count.get(fence, 0) + 1

num_of_pens = 0
usable_fences = []
for fence in fence_count:
if fence_count[fence] < 2:
# Less than one pair. We cannot use it.
continue
elif fence_count[fence] < 4:
usable_fences.append(fence)
else:
usable_fences.append(fence)
# We consider the square pen here.
if fence * fence >= X:
num_of_pens += 1

# We consider the non-square pen here.
usable_fences.sort()
candidate_size = len(usable_fences)
for i in xrange(candidate_size):
# Use binary search to find the first fence pair, that
# could be used with current pair to form a pen.
begin = i + 1
end = candidate_size - 1
while begin <= end:
mid = (begin + end) // 2
if usable_fences[mid] * usable_fences[i] >= X:
end = mid - 1
else:
begin = mid + 1

# Now the usable_fences[end + 1] is the first qualified
# fence.
combination_num = candidate_size - (end + 1)
num_of_pens += combination_num
if num_of_pens > 1000000000:
return -1

return num_of_pens```

]]>
https://codesays.com/2016/solution-to-rectangle-builder-greater-area-by-codility/feed/ 0
Solution to Dwarfs-Rafting by codility https://codesays.com/2016/solution-to-dwarfs-rafting-by-codility/ https://codesays.com/2016/solution-to-dwarfs-rafting-by-codility/#comments Sun, 20 Nov 2016 04:18:03 +0000 https://codesays.com/?p=1905 Question: https://codility.com/demo/take-sample-test/dwarfs_rafting/

Question Name: Dwarfs-Rafting or DwarfsRafting

Need some simple mathematical knowledge. The code is unnecessarily long. A 2-d array is better to write much shorter code. However, I keep the long version for better readability.

```def solution(N, S, T):
quadrant_left_front = (N // 2) * (N // 2)
quadrant_left_back = (N // 2) * (N // 2)
quadrant_right_front = (N // 2) * (N // 2)
quadrant_right_back = (N // 2) * (N // 2)
boundary = N // 2

# Compute how many slots are available in each quadrant.
for barrel in S.split():
row = int(barrel[:-1]) - 1
column = ord(barrel[-1]) - ord("A")

if row < boundary:
# The barrel is in the front.
if column < boundary:
# The barrel is in the left.
else:
# The barrel is in the right.
else:
# The barrel is in the back.
if column < boundary:
# The barrel is in the left.
else:
# The barrel is in the right.

# lf is short for left front, etc.
# To keep balance, we need:
#   1. weight_lf + weight_lb = weight_rf + weight_rb
#   2. weight_lf + weight_rf = weight_rf + weight_rb
# Solve the equations and we can get the answer:
#   1. weight_lf = weight_rb
#   2. And weight_rf = weight_lb

# Minus the seats, which are already occupied by dwarfs.
for dwarf in T.split():
row = int(dwarf[:-1]) - 1
column = ord(dwarf[-1]) - ord("A")

if row < boundary:
# The dwarf is in the front.
if column < boundary:
# The dwarf is in the left.
allowance_lf -= 1
if allowance_lf < 0:    return -1
else:
# The dwarf is in the right.
allowance_rf -= 1
if allowance_rf < 0:    return -1
else:
# The dwarf is in the back.
if column < boundary:
# The dwarf is in the left.
allowance_lb -= 1
if allowance_lb < 0:    return -1
else:
# The dwarf is in the right.
allowance_rb -= 1
if allowance_rb < 0:    return -1

return allowance_lf + allowance_rb + allowance_lb + allowance_rf```

]]>
https://codesays.com/2016/solution-to-dwarfs-rafting-by-codility/feed/ 1
Solution to Slalom-Skiing by codility https://codesays.com/2016/solution-to-slalom-skiing-by-codility/ https://codesays.com/2016/solution-to-slalom-skiing-by-codility/#respond Sun, 23 Oct 2016 05:20:10 +0000 https://codesays.com/?p=1896 Read More »]]> Question: https://codility.com/programmers/lessons/90-tasks_from_indeed_prime_2015_challenge/slalom_skiing/

Question Name: Slalom-Skiing or SlalomSkiing

This is a wonderful variant of longest increasing subsequence. Because the longest increasing subsequence is a very classic question withe O(NlogN) solution, the key point to solve this question is to covert its original form to the classic question. We would like to extend it with two mirror universe.

```+--------+--------+--------+
|        |        |        |
|        |        |        |
|Original| mirror | mirror |
|        |   #1   |   #2   |
| Points |        |        |
|        |        |        |
|        |        |        |
|        |        |        |
+--------+--------+--------+```

The original question is convert into: find the longest increasing subsequence in the new extended multiverse. Here is an example of extended multiverse:

```Original universe:
+------+
|X     |
|  X   |
|    X |
|  X   |
|    X |
+------+

Extended multiverse:
+------+------+------+
|X     |     X|X     |
|  X   |   X  |  X   |
|    X | X    |    X |
|  X   |   X  |  X   |
|    X | X    |    X |
+------+------+------+```

For each point P, it has three instances: the instance in the original world as P0, one in the mirror world as P1, and the last in the double-mirror world as P2. We process P2 firstly, then P1, and finally P0, so that to avoid the self-link sequence. In other words, we do not want that P2 is connected from P0 or P1, because they are essentially the same point.
The relationship between the original qualified subsequence (change direction at most two times) and the new longest increasing subsequence is 1:N mapping. Actually every subsequence in the original question has multiple equivalent subsequence in the new multiverse. Oppositely, every subsequence in the new multiverse has one equivalent in the original world.

```def LongestIncreasingSubsequence(seq):
''' The classic dynamic programming solution for longest increasing
subsequence. More details could be found:
https://en.wikipedia.org/wiki/Longest_increasing_subsequence
http://www.geeksforgeeks.org/dynamic-programming-set-3-longest-increasing-subsequence/
http://stackoverflow.com/questions/3992697/longest-increasing-subsequence
'''
# smallest_end_value[i] = j means, for all i-length increasing
# subsequence, the minmum value of their last elements is j.
smallest_end_value = [None] * (len(seq) + 1)
# The first element (with index 0) is a filler and never used.
smallest_end_value[0] = -1
# The length of the longest increasing subsequence.
lic_length = 0

for i in range(len(seq)):
# Binary search: we want the index j such that:
#     smallest_end_value[j-1] < seq[i]
#     AND
#     (  smallest_end_value[j] > seq[i]
#        OR
#        smallest_end_value[j] == None
#     )
# Here, the result "lower" is the index j.
lower = 0
upper = lic_length
while lower <= upper:
mid = (upper + lower) // 2
if seq[i] < smallest_end_value[mid]:
upper = mid - 1
elif seq[i] > smallest_end_value[mid]:
lower = mid + 1
else:
raise "Should never happen: " + \
"the elements of A are all distinct"

if smallest_end_value[lower] == None:
smallest_end_value[lower] = seq[i]
lic_length += 1
else:
smallest_end_value[lower] = \
min(smallest_end_value[lower], seq[i])

return lic_length

def solution(A):
# We are solving this question by creating two mirrors.
bound = max(A) + 1
multiverse = []
for point in A:
# The point in the double-mirror universe.
multiverse.append(bound * 2 + point)
# The point in the mirror universe.
multiverse.append(bound * 2 - point)
# The point in the original universe.
multiverse.append(point)

return LongestIncreasingSubsequence(multiverse)```

]]>
https://codesays.com/2016/solution-to-slalom-skiing-by-codility/feed/ 0
Solution to Flood-Depth by codility https://codesays.com/2016/solution-to-flood-depth-by-codility/ https://codesays.com/2016/solution-to-flood-depth-by-codility/#comments Mon, 26 Sep 2016 05:04:05 +0000 https://codesays.com/?p=1890 Question: https://codility.com/demo/take-sample-test/flood_depth/

Question Name: Flood-Depth or FloodDepth

This is a variant of Trapping Rain Water by LeetCode. The undergoing concept is the same. However, the implementation is a bit different.

```from collections import namedtuple

def solution(A):
if len(A) < 3:
return 0

# The blocks in the stack is in strictly height descending order.
# For the first block in the stack, its max_depth is maximum water
# depth of its (exclusive) left area.
# The other blocks' max_depth is the maximum water depth between its
# previous block in the stack and itself, both exclusive.
Block = namedtuple("Block", ["height", "max_depth"])
stack = [Block(A[0],0)]

for height in A[1:]:
if height == stack[-1].height:
# These two adjacent blocks have the same height. They act
# totally the same in building any water container.
continue
elif height < stack[-1].height:
stack.append(Block(height, 0))
else:
max_depth = 0

# Let the current iterating block be C, the previous two
# blocks in the stack be A and B. And their positions are
# demoed as:
#             C
# A           C
# A ... B ... C
# while the blocks between A and B are omitted. So do the
# blocks between B and C.
#
# The additional_depth consider the blocks A, B, and C only,
# and igonres all the omitted blocks, such as:
#       C
# A     C
# A  B  C   (no block is between A and B, or B and C)
#
# HOWEVER, the additional_depth is not always the maximum
# water depth between A and C, because there may be some
# water between A and B, or B and C, as exists in the omitted
# maximum water depth between A and C, both exclusive.
while len(stack) > 1 and height > stack[-1].height:
additional_depth = min(stack[-2].height, height) - \
stack[-1].height
max_depth = max(max_depth, stack[-1].max_depth) + \
stack.pop()

# Combine leftward same-or-less-height blocks. These dropped
# blocks are never going to be part of the remaining water
# container.
while len(stack) > 0 and height >= stack[-1].height:
max_depth = max(max_depth, stack[-1].max_depth)
stack.pop()

stack.append(Block(height, max_depth))

overall_max_depth = 0
for block in stack:
if block.max_depth > overall_max_depth:
overall_max_depth = block.max_depth

return overall_max_depth```

]]>
https://codesays.com/2016/solution-to-flood-depth-by-codility/feed/ 2

The solution could be more Pythonic with some additional space.

```def solution(S):
longest = -1
num_of_letters = 0
num_of_digits = 0
num_of_others = 0

for letter in S:
if letter.isalpha():
num_of_letters += 1
elif letter.isdigit():
num_of_digits += 1
elif letter == " ":
# Check whether it's a valid password.
if num_of_others == 0 and \
num_of_letters % 2 == 0 and \
num_of_digits % 2 == 1:
if longest < num_of_letters + num_of_digits:
longest = num_of_letters + num_of_digits

# Reset the counters for the next word.
num_of_letters = 0
num_of_digits = 0
num_of_others = 0
else:
num_of_others += 1

# Check whether the last word is a valid password.
if num_of_others == 0 and \
num_of_letters % 2 == 0 and \
num_of_digits % 2 == 1:
if longest < num_of_letters + num_of_digits:
longest = num_of_letters + num_of_digits

return longest```

]]>
Solution to Sql-Sum by codility https://codesays.com/2016/solution-to-sql-sum-by-codility/ https://codesays.com/2016/solution-to-sql-sum-by-codility/#respond Thu, 22 Sep 2016 07:03:56 +0000 https://codesays.com/?p=1883 Question: https://codility.com/demo/take-sample-test/sql_sum/

Question Name: Sql-Sum or SqlSum

This question is too easy to be a serious training lesson. Most likely, it’s a live test for SQL challenges on Codility.com. The following solution works in both PostgreSQL and SQLite.

`SELECT SUM(v) FROM elements`

]]>
https://codesays.com/2016/solution-to-sql-sum-by-codility/feed/ 0
Solution to Contains Duplicate by LeetCode https://codesays.com/2016/solution-to-contains-duplicate-by-leetcode/ https://codesays.com/2016/solution-to-contains-duplicate-by-leetcode/#respond Sun, 21 Aug 2016 05:08:47 +0000 https://codesays.com/?p=1878 Read More »]]> Question: https://leetcode.com/problems/contains-duplicate/

Question Name: Contains Duplicate

In general, I found two solutions. The first solution is using hash set:

```class Solution(object):
def containsDuplicate(self, nums):
"""
:type nums: List[int]
:rtype: bool
"""
deduplicated = set(nums)
return len(deduplicated) != len(nums)```

The second solution is using sorting. We could sort the input and check each pair of adjacent items. Or we could early terminate the sorting if we found two same numbers.

```class Solution_I(object):
def containsDuplicate(self, nums):
"""
:type nums: List[int]
:rtype: bool
"""
nums.sort()
for index in xrange(len(nums) - 1):
if nums[index] == nums[index + 1]:
return True
return False

################################################

def compare(num1, num2):
if num1 < num2:
return -1
elif num1 > num2:
return 1
else:
raise Exception("Duplicate is found.")
return 0

class Solution_II(object):
def containsDuplicate(self, nums):
"""
:type nums: List[int]
:rtype: bool
"""
try:
nums.sort(cmp = compare)
except Exception:
return True
else:
return False```

]]>
https://codesays.com/2016/solution-to-contains-duplicate-by-leetcode/feed/ 0
Solution to Combination Sum III by LeetCode https://codesays.com/2016/solution-to-combination-sum-iii-by-leetcode/ https://codesays.com/2016/solution-to-combination-sum-iii-by-leetcode/#comments Tue, 16 Aug 2016 05:47:02 +0000 https://codesays.com/?p=1875 Question: https://leetcode.com/problems/combination-sum-iii/

Question Name: Combination Sum III

This is a typical recursion problem. Find out the base case and recursive cases, and that’s the right solution.

```class Solution(object):
def _combinationSum3Helper(self, remaining, candidates, next_value,
partial_sum, target):
"""
:type remaining: int. It's the count of additional numbers could be
used.
:type candidates: list[bool]. candidates[i] is True, if the number i is\
used.
:type next_value: int. It's the next number to consider.
:type partial_sum: int. The sum of used candidates so far.
:type target : int. It's the target sum.
:rtype: List[List[int]]
"""
result = []
if remaining == 0:
if partial_sum == target:
# Found one combination.
combination = []
for i in xrange(1, next_value):
if candidates[i] == True:
combination.append(i)
result.append(combination)
return result
else:
# This combination is not valid.
return result
elif partial_sum + next_value > target or next_value > 9:
# It's impossbile to have any valid combination with current
# prefix.
return result
else:
# It does not take the next_value.
result.extend(self._combinationSum3Helper(
remaining, candidates, next_value + 1, partial_sum, target))

# It does take the next_value.
candidates[next_value] = True
result.extend(self._combinationSum3Helper(
remaining - 1, candidates, next_value + 1,
partial_sum + next_value, target))
candidates[next_value] = False
return result

def combinationSum3(self, k, n):
"""
:type k: int
:type n: int
:rtype: List[List[int]]
"""
candidates = [False for _ in xrange(10)]    # 0 is never used.
return self._combinationSum3Helper(k, candidates, 1, 0, n)```

]]>
https://codesays.com/2016/solution-to-combination-sum-iii-by-leetcode/feed/ 7
Solution to Kth Largest Element in an Array by LeetCode https://codesays.com/2016/solution-to-kth-largest-element-in-an-array-by-leetcode/ https://codesays.com/2016/solution-to-kth-largest-element-in-an-array-by-leetcode/#respond Sat, 11 Jun 2016 05:17:46 +0000 https://codesays.com/?p=1868 Question: https://leetcode.com/problems/kth-largest-element-in-an-array/

Question Name: Kth Largest Element in an Array

This is exactly the quick-select.

```class Solution(object):
def _quickSortHelper(self, nums, begin, end):
"""
:type nums: List[int]
:type begin: int
:type end: int
:rtype: int (the index of nums[begin] after quick-select)
"""
next_smaller_pos = begin + 1
next_bigger_pos = end

while next_smaller_pos <= next_bigger_pos:
if nums[next_smaller_pos] <= nums[begin]:
next_smaller_pos += 1
elif nums[begin] <= nums[next_bigger_pos]:
next_bigger_pos -= 1
else:
nums[next_smaller_pos] ^= nums[next_bigger_pos]
nums[next_bigger_pos]  ^= nums[next_smaller_pos]
nums[next_smaller_pos] ^= nums[next_bigger_pos]
next_smaller_pos += 1

nums[begin], nums[next_bigger_pos] = nums[next_bigger_pos], nums[begin]

return next_bigger_pos

def findKthLargest(self, nums, k):
"""
:type nums: List[int]
:type k: int
:rtype: int
"""
k = len(nums) - k
begin, end = 0, len(nums) - 1
while True:
position = self._quickSortHelper(nums, begin, end)
if position == k:       return nums[k]
elif position < k:      begin = position + 1
else:                   end = position - 1

# Should never be here.
return 0```

]]>
https://codesays.com/2016/solution-to-kth-largest-element-in-an-array-by-leetcode/feed/ 0
Solution to Shortest Palindrome by LeetCode https://codesays.com/2016/solution-to-shortest-palindrome-by-leetcode/ https://codesays.com/2016/solution-to-shortest-palindrome-by-leetcode/#comments Thu, 09 Jun 2016 06:06:24 +0000 https://codesays.com/?p=1866 Read More »]]> Question: https://leetcode.com/problems/shortest-palindrome/

Question Name: Shortest Palindrome

This is a variant of Longest Palindromic Substring. The key point is to convert the original question as following:
1. Shortest Palindrome by adding any characters in the head.  Therefore the original string “original” is going to be “***original”. Because the inserted characters could be ANY thing, we can guarantee that the added sub-string is a mirror of the tailing sub-string. So the question turns out to be:
2. Convert the original string to a palindrome by removing characters at the end of it. Furthermore, it’s equal to:
3. In the original string, what’s the longest Palindrome sub-string, which starts at the index 0.

```class Solution(object):
def shortestPalindrome(self, s):
"""
:type s: str
:rtype: str
"""
newS = "#"+"#".join(s)+"#"
palHalfLenCenteringHere = [1] * len(newS)

center, right = 0,1
for index in xrange(1, len(newS)):
if index < right and index + palHalfLenCenteringHere[2*center-index] < right:
# No way to extend the right. Thus the center is not changed.
palHalfLenCenteringHere[index] = palHalfLenCenteringHere[2*center-index]
else:
# We MIGHT extend the right. And we DO change the center here.
# IF we did NOT extend the right, the new center and old one have completely
# the SAME effect on the next steps/rounds.
center = index
if index < right:
# Use some pre-computed information
palHalfLenCenteringHere[index] = right - center
else:
# Actually scanning from scratch
palHalfLenCenteringHere[index] = 1
right += 1

# Try to extend the right
while right < len(newS) and 2*center-right >= 0 and \
newS[right] == newS[2*center-right]:
right += 1
palHalfLenCenteringHere[index] += 1

# Find the longest palindromic substring, which starts at the beginning.
# We travel from the middle point to the begin point. Therefore the first
# qualified sub-string is the longest one.
for center in xrange(len(newS)//2, -1, -1):
# Check whether this palindromic substring starts at index 0.
if center - palHalfLenCenteringHere[center] + 1 == 0:
halfLen = palHalfLenCenteringHere[center]
result = newS[center + halfLen:][::-1] + newS
return result.replace("#", "")

# Should never be here.
return None```

]]>
https://codesays.com/2016/solution-to-shortest-palindrome-by-leetcode/feed/ 2