05/6/19

Posting Schedule Sprint/Summer 2019

This page has 85 HackerRank Tasks posted as of May 2019. After looking over my HR profile, I noticed that I had solved a total of 200 Tasks there. In other words, I have not posted the majority of them 🙂

I have also run out of Tasks marked as Easy. I still have around 60 Medium ones that need solving.

It is unlikely, that I can just clean all of that up in a single session. I have therefore created a posting rhythm that should allow me to get all that code up here within a reasonable time frame.

I will be posting five posts every week until the end of September. Four of those will be Tasks that I have solved in the past, and only minor cleanups are required. Additionally, I will be posting one new Medium or harder Task every week.


If you enjoyed this post, then make sure you subscribe to my Newsletter and/or Feed.

Facebooktwittergoogle_plusredditpinterestlinkedin
06/12/19

HackerRank ‘Repeated String’ Solution

Short Problem Definition:

Lilah has a string, s, of lowercase English letters that she repeated infinitely many times. Given an integer, n, find and print the number of letters a in the first n letters of Lilah’s infinite string.

For example, if the string s = ‘abcac’ and n = 10, the substring we consider is abcacabcac, the first 10 characters of her infinite string. There are 4 occurrences of a in the substring.

Link

Repeated String

Complexity:

time complexity is O(N)

space complexity is O(1)

Execution:

As with most simple problems, there are many ways to write the code that can achieve the correct result. I picked the one that seems the simplest and most Pythonesque.

Solution:
#!/bin/python

import math
import os
import random
import re
import sys

# Complete the repeatedString function below.
def repeatedString(s, n):
    n_per_string = s.count('a')
    n_per_substring = s[0:n%len(s)].count('a')
    return n_per_string * (n/len(s)) + n_per_substring

if __name__ == '__main__':
    fptr = open(os.environ['OUTPUT_PATH'], 'w')
    s = raw_input()
    n = int(raw_input())
    result = repeatedString(s, n)
    fptr.write(str(result) + '\n')
    fptr.close()

If you enjoyed this post, then make sure you subscribe to my Newsletter and/or Feed.

Facebooktwittergoogle_plusredditpinterestlinkedin
06/11/19

HackerRank ‘Climbing The Leatherboard’ Solution

Short Problem Definition:

Alice is playing an arcade game and wants to climb to the top of the leaderboard and wants to track her ranking. The game uses Dense Ranking, so its leaderboard works like this:

  • The player with the highest score is ranked number 1 on the leaderboard.
  • Players who have equal scores receive the same ranking number, and the next player(s) receive the immediately following ranking number
Link

Climbing The Leaderboard

Complexity:

time complexity is O(N*log(N))

space complexity is O(1)

Execution:

I am not a fan of the Dense Rank. Standard Competition ranking makes much more sense.

1) In the Dense Rank, duplicates have no impact on the ranking, so they can be safely removed.

2) The array should be sorted. Since the value range is fairly small (10^5), counting sort would improve the theoretical O-notation to O(N).

3) Take advantage of built-in Python functionality. Bisect right finds an insertion point after potential duplicates, giving us the correct Dense Rank.

Solution:
#!/bin/python

import math
import os
import random
import re
import sys
import bisect

# Complete the climbingLeaderboard function below.
def climbingLeaderboard(scores, alice):
    res = []
    s = sorted(list(set(scores)))
    l = len(s)
    for v in alice:
         res.append(l - bisect.bisect_right(s, v) +1)
            
    return res

if __name__ == '__main__':
    fptr = open(os.environ['OUTPUT_PATH'], 'w')
    scores_count = int(raw_input())
    scores = map(int, raw_input().rstrip().split())
    alice_count = int(raw_input())
    alice = map(int, raw_input().rstrip().split())
    result = climbingLeaderboard(scores, alice)
    fptr.write('\n'.join(map(str, result)))
    fptr.write('\n')
    fptr.close()


If you enjoyed this post, then make sure you subscribe to my Newsletter and/or Feed.

Facebooktwittergoogle_plusredditpinterestlinkedin
06/10/19

The Various Flavors of Two-Phase Commits — Explained

Internally, NuoDB uses the two-phase commit protocol to manage the durability of user data. NuoDB also supports the X/Open XA protocol for synchronizing global transactions across multiple data stores. XA is also sometimes referred to as two-phase commit. The fundamental principles in both protocols are similar but serve different purposes. Let us explore the difference between these two protocols.

A SINGLE TRANSACTION ACROSS TWO RESOURCES

Let us explore a simple use case. A simple application takes messages from one data source (outgoing_messages) and writes them to a new data source (incoming_messages). This is a fairly common use case if you read messages from a message queue such as Apache ActiveMQ and you write them to a database (such as NuoDB). The following code snippet shows this example in the corresponding SQL form.

SQL> SELECT * FROM outgoing_messages;
 
 ID     MSG    
 --- --------- 
 
  1  message 1 
 
SQL> START TRANSACTION;
SQL> SELECT * FROM outgoing_messages;
 
 ID     MSG    
 --- --------- 
 
  1  message 1 
 
SQL> DELETE FROM outgoing_messages WHERE id=1;
SQL> INSERT INTO incoming_messages(id, msg) VALUES(1, 'message 1');
SQL> commit;

When executed in a single relational database, the two statements (insert and delete) are expected to behave according to the ACID guarantees. They either both succeed or they both fail. Throughout this article, we focus on the A(tomic) guarantee of ACID.

XA abstracts away the statements and transaction lifetime for scenarios where the tables live in different data stores. The following example is a simplified version of an ActiveMQ consumer that receives a message and writes it to NuoDB. Due to space constraints in this article, the code does not contain any setup or failure handling.

​javax.jms.MessageConsumer consumer=xasession.createConsumer(queue);
        MessageListener listener = NEW MessageListener() {
            @Override
            public void onMessage(Message msg) {
                TextMessage msg1=(TextMessage)msg;
 
                NuoXADataSource nuodbDs = NEW NuoXADataSource();
                XAConnection nuodbXAconn = nuodbDs.getXAConnection(DBA_USER, DBA_PASSWORD);
 
                XAResource mqRes = xasession.getXAResource();
                XAResource nuoRes = nuodbXAconn.getXAResource();
 
                nuodbStmt.executeUpdate(String.format("insert into incoming_messages(id, msg) values(1, '%s')", msg1.getText()));
 
                mqRes.END(xid, XAResource.TMSUCCESS);
                nuoRes.END(xid, XAResource.TMSUCCESS);
 
                mqRes.PREPARE(xid);
                nuoRes.PREPARE(xid);
 
                mqRes.commit(xid, FALSE);
                nuoRes.commit(xid, FALSE);
            }
        };
Continue reading
If you enjoyed this post, then make sure you subscribe to my Newsletter and/or Feed.

Facebooktwittergoogle_plusredditpinterestlinkedin
06/6/19

HackerRank ‘Almost Sorted’ Solution

Short Problem Definition:

Given an array of integers, determine whether the array can be sorted in ascending order using only one of the following operations one time.

  1. Swap two elements.
  2. Reverse one sub-segment.

Determine whether one, both or neither of the operations will complete the task. If both work, choose swap. For instance, given an array [2, 3, 5, 4] either swap the 4 and 5; or reverse them to sort the array. Choose swap.

Link

Almost Sorted

Complexity:

time complexity is O(N)

space complexity is O(1)

Execution:

I wrote this code 4 years ago and I already have no clue what it does. It is linear time and it works even today.

Today, I would have broken this logic down into smaller functions with clear purpose.

If you have solved this in a readable way, please share!

Solution:
#!/usr/bin/py
def getReverseAction(arr):
    is_sorted = True
    
    low_idx = 0
    high_idx = len(arr)-1
    
    while (low_idx < high_idx and arr[low_idx] < arr[low_idx+1]):
        low_idx += 1
   
    if low_idx == high_idx:
        print "yes"
        return

    while (high_idx > 0 and arr[high_idx] > arr[high_idx-1]):
        high_idx -= 1

     
    #print "low", low_idx, arr[low_idx]
    #print "high", high_idx, arr[high_idx]
    
    if low_idx == 0 or arr[high_idx] > arr[low_idx -1]:
        #print "high index swapable"
        if arr[high_idx] < arr[low_idx +1] or low_idx+1 == high_idx:
            #print "high index swapable"
            if high_idx == len(arr)-1 or arr[low_idx] < arr[high_idx+1]:
                #print "low index swapable"
                if arr[low_idx] > arr[high_idx -1] or low_idx == high_idx-1:
                    #print "low index swapable"
                    low_idx_runner = low_idx+1
                    while (low_idx_runner < high_idx and arr[low_idx_runner] < arr[low_idx_runner+1]):
                        low_idx_runner += 1
                    if low_idx_runner == high_idx-1 or low_idx == high_idx-1:    
                        print "yes"
                        print "swap", low_idx+1, high_idx+1
                        return
    
    low_idx_runner = low_idx+1
    while (low_idx_runner < high_idx and arr[low_idx_runner] > arr[low_idx_runner+1]):
        low_idx_runner += 1
    
    if low_idx_runner == high_idx:
        if low_idx == 0 or arr[high_idx] > arr[low_idx -1]:
            if high_idx == len(arr)-1 or arr[low_idx] < arr[high_idx+1]:
                print "yes"
                print "reverse", low_idx+1, high_idx+1
                return
    
    print "no"
    
        
if __name__ == '__main__':
    n = input()
    arr = map(int, raw_input().split())
    getReverseAction(arr)    

If you enjoyed this post, then make sure you subscribe to my Newsletter and/or Feed.

Facebooktwittergoogle_plusredditpinterestlinkedin
06/5/19

HackerRank ‘Picking Numbers’ Solution

Short Problem Definition:

Given an array of integers, find and print the maximum number of integers you can select from the array such that the absolute difference between any two of the chosen integers is less than or equal to 1. For example, if your array is a = [1, 1, 2, 2, 4, 4, 5, 5, 5], you can create two subarrays meeting the criterion:  [1 ,1 ,2 ,2] and [4, 4, 5, 5, 5]. The maximum length subarray has 5 elements.

Link

Picking Numbers

Complexity:

time complexity is O(N*log(N))

space complexity is O(N)

Execution:

There is a simple solution. Sort the array and iterate over it, counting pairs. But I don’t like it.

The solution proposed here never sorts the array. Depending on the O-complexity of a map implementation, it could be O(N) or O(NlogN).

The idea is to check the +/-1 neighbors of each value as you iterate over them.

Solution:
from collections import defaultdict

def pickingNumbers(a):
    d = defaultdict(int)
    r_val = 0
    for val in a:
        d[val] += 1
        r_val = max(r_val, d[val]+d[val+1], d[val]+d[val-1])

    return r_val

If you enjoyed this post, then make sure you subscribe to my Newsletter and/or Feed.

Facebooktwittergoogle_plusredditpinterestlinkedin
06/4/19

HackerRank ‘Cats And A Mouse’ Solution

Short Problem Definition:

Two cats and a mouse are at various positions on a line. You will be given their starting positions. Your task is to determine which cat will reach the mouse first, assuming the mouse doesn’t move and the cats travel at equal speed. If the cats arrive at the same time, the mouse will be allowed to move and it will escape while they fight.

Link

Cats And A Mouse

Complexity:

time complexity is O(1)

space complexity is O(1)

Execution:

This feels like a very simplistic version of Codility Fish. Just implement the specification.

Solution:
#!/bin/python

import sys

q = int(raw_input().strip())
for a0 in xrange(q):
    x,y,z = raw_input().strip().split(' ')
    x,y,z = [int(x),int(y),int(z)]
    catA = abs(x-z)
    catB = abs(y-z)
    if (catA < catB):
        print "Cat A"
    elif (catB < catA):
        print "Cat B"
    else:
        print "Mouse C"

If you enjoyed this post, then make sure you subscribe to my Newsletter and/or Feed.

Facebooktwittergoogle_plusredditpinterestlinkedin
06/3/19

HackerRank ‘Electronics Shop’ Solution

Short Problem Definition:

Monica wants to buy a keyboard and a USB drive from her favorite electronics store. The store has several models of each. Monica wants to spend as much as possible for the 2 items, given her budget.

Given the price lists for the store’s keyboards and USB drives, and Monica’s budget, find and print the amount of money Monica will spend. If she doesn’t have enough money to both a keyboard and a USB drive, print -1 instead. She will buy only the two required items.

Link

Electronics Shop

Complexity:

time complexity is O(N*M)

space complexity is O(1)

Execution:

This is one of the problem specifications that feel like there has to be a better solution. The solution presented here is naive and is O(N*M). Given that this is categorized as easy, I assumed that I can get away with this simple solution.

One could sort one of the arrays and use binary search to find the ideal match, this would result in O(N*log(N)).

Solution:
#!/bin/python

def getMoneySpent(keyboards, drives, s):
    spend = -1
    for dr in drives:
        for kb in keyboards:
            cnt = dr+kb
            if cnt <= s and cnt > spend:
                spend = cnt
    return spend
            
s,n,m = raw_input().strip().split(' ')
s,n,m = [int(s),int(n),int(m)]

keyboards = map(int, raw_input().strip().split(' '))
drives = map(int, raw_input().strip().split(' '))

moneySpent = getMoneySpent(keyboards, drives, s)
print(moneySpent)

If you enjoyed this post, then make sure you subscribe to my Newsletter and/or Feed.

Facebooktwittergoogle_plusredditpinterestlinkedin
06/2/19

HackerRank ‘Counting Valleys’ Solution

Short Problem Definition:

Gary is an avid hiker. He tracks his hikes meticulously, paying close attention to small details like topography. During his last hike he took exactly n steps. For every step he took, he noted if it was an uphill, U, or a downhill, D step. Gary’s hikes start and end at sea level and each step up or down represents a 1 unit change in altitude.

Link

Counting Valleys

Complexity:

time complexity is O(N)

space complexity is O(1)

Execution:

All is required is a simple counter.

I find this problem specification oddly satisfying since I am currently finishing off my list of 48 4000 footers in New Hampshire, US.

Solution:
#!/bin/python

n = input()
s = raw_input()

level = 0
valleys = 0
for direction in s:
    if direction == "U":
        level += 1
        if level == 0:
            valleys += 1
    else:
        level -= 1
        
print valleys

If you enjoyed this post, then make sure you subscribe to my Newsletter and/or Feed.

Facebooktwittergoogle_plusredditpinterestlinkedin
06/2/19

HackerRank ‘Drawing Book’ Solution

Short Problem Definition:

Brie’s Drawing teacher asks her class to open their books to a page number. Brie can either start turning pages from the front of the book or from the back of the book. She always turns pages one at a time. When she opens the book, page 1 is always on the right side.

Link

Drawing Book

Complexity:

time complexity is O(1)

space complexity is O(1)

Execution:

Integral division here again. No padding required.

Solution:
#!/bin/python

import sys

def solve(n, p):
    last_letter = n // 2
    goal_letter = p // 2
    return min(goal_letter, last_letter-goal_letter)

n = int(raw_input().strip())
p = int(raw_input().strip())
result = solve(n, p)
print(result)

If you enjoyed this post, then make sure you subscribe to my Newsletter and/or Feed.

Facebooktwittergoogle_plusredditpinterestlinkedin
06/2/19

HackerRank ‘Sock Merchant’ Solution

Short Problem Definition:

John works at a clothing store. He has a large pile of socks that he must pair by color for sale. Given an array of integers representing the color of each sock, determine how many pairs of socks with matching colors there are.

Link

Sock Merchant

Complexity:

time complexity is O(N)

space complexity is O(N)

Execution:

Group the same color together. Look out for the integer division // that discards the odd socks.

Solution:
#!/bin/python

import sys
from collections import defaultdict

n = int(raw_input().strip())
c = map(int,raw_input().strip().split(' '))

d = defaultdict(int)
for k in c:
    d[k] += 1
    
cnt = 0
for ele in d.values():
    cnt += ele//2
    
print cnt

If you enjoyed this post, then make sure you subscribe to my Newsletter and/or Feed.

Facebooktwittergoogle_plusredditpinterestlinkedin