coding challenge screenshot
This is from Facebook/Meta Careers page practice problems
here is my current solution so far 2/32 test cases passed, has anyone been able to get 32/32?
from typing import List
# Write any import statements here
def getMinCodeEntryTime(N: int, M: int, C: List[int]) -> int:
# Write your code here
dial_1 = 1
dial_2 = 1
count = 0
code = C
if len(code) > 0:
for number in code:
print("before: dial_1, dial_2: ", dial_1, dial_2)
fwd_1 = abs(number - dial_1)
rev_1 = N - abs(number - dial_1)
fwd_2 = abs(number - dial_2)
rev_2 = N - abs(number - dial_2)
# Dial 1 calc: fwd vs rev
if fwd_1 > rev_1:
count_1 = rev_1
else:
count_1 = fwd_1
# Dial 2 calc: fwd vs rev
if fwd_2 > rev_2:
count_2 = rev_2
else:
count_2 = fwd_2
# Dial 1 vs Dial 2 movement decision
if count_1 > count_2:
dial_2 = number
count += count_2
else:
dial_1 = number
count += count_1
print("after: dial_1, dial_2: ", dial_1, dial_2, "+/-", count)
return count
Your algorithm is greedy. You always move the closest deal to the next number. Sometimes, you have to make a suboptimal move to get the best overall answer. (There are times greedy algorithms are optimal, but not here.)
Try writing a recursive function:best(n, other) gives you the number of moves to solve steps numbers Cn+1 to the end, assuming the two dials are at Cn and other. This will be a nice recursive function. Now rewrite the recursion in terms of dynamic programming.
Please don't expect anyone to write the code for you.
Related
I'm a beginner with Python. I have a 2-d array called infected that stores values that correspond with the index. This bit of code is messy, but basically what I'm trying to do is simulate an infectious disease spreading over a number of days (T). The individual is infectious for infTime many days and then goes into recovery where they are immune for immTime days. There's also a probability value for whether a node will be infected and a value for how many nodes they will be connected to.
My problem is that I'm also trying to track the number of individuals currently susceptible, infected, or immune, but something is going wrong in the elif statement that is marked "# Messing up in this loop". Currently, the program is running through the statement more times than it should, which is throwing off the variables. If I switch the conditions in the elif statement, the program doesn't go through it and will stay at a very low number of infected individuals the entire time. I'm really stuck and I can't find any reason why it's not working how I want it to.
Code:
# Loop through T days, checking for infected individuals and connecting them to beta num of nodes, possibly infecting
infTime = 5 # Time spent infected before becoming immune
immTime = 20 # Time spent immune before becoming susceptible again
numSus = N - count
day = 0
while day < T:
for a in range(len(infected)):
nextnode = random.randint(0, N-1)
if((infected[a][0] == 1) and (infected[a][3] < infTime)):
num = infected[a][1]
for b in range(num-1):
if((a != nextnode) and (infected[nextnode][0] == 0)):
infected[a][3] += 1
chance = round((random.uniform(0, 1)), 2)
if(infected[nextnode][2] > chance):
infected[nextnode][0] = 1
G.add_edge(a, nextnode)
count += 1
numInf += 1
numSus -= 1
elif((a != nextnode) and (infected[nextnode][0] == 1)):
G.add_edge(a, nextnode)
elif((infected[a][0] == 1) and (infected[a][3] == infTime)): # Messing up in this loop
infected[a][3] = 0
infected[a][4] = 1
numImm += 1
numInf -= 1
G.add_edge(a, nextnode)
elif((infected[a][0] == 0) and (1 < infected[a][4] < immTime)):
infected[a][4] += 1
elif((infected[a][0] == 0) and (infected[a][4] == immTime)):
infected[a][4] = 0
numImm -= 1
numSus =+ 1
day += 1
print("Number of infected on day ", day, ": ", count)
I came across the LeetCode problem 2100. Find Good Days to Rob the Bank:
You and a gang of thieves are planning on robbing a bank. You are given a 0-indexed integer array security, where security[i] is the number of guards on duty on the ith day. The days are numbered starting from 0. You are also given an integer time.
The ith day is a good day to rob the bank if:
There are at least time days before and after the ith day,
The number of guards at the bank for the time days before i are non-increasing, and
The number of guards at the bank for the time days after i are non-decreasing.
More formally, this means day i is a good day to rob the bank if and only if security[i - time] >= security[i - time + 1] >= ... >= security[i] <= ... <= security[i + time - 1] <= security[i + time].
Return a list of all days (0-indexed) that are good days to rob the bank. The order that the days are returned in does not matter.
The solution, that I created seems fine to me. Not sure, where I am going wrong with some test cases failing.
class Solution(object):
def goodDaysToRobBank(self, security, time):
"""
:type security: List[int]
:type time: int
:rtype: List[int]
"""
total_guards = len(security)
if time == 0:
return [i for i in range(total_guards)]
left = [1]*total_guards
right = [1]*total_guards
l_pattern_found = False
r_pattern_found = False
for i in range(1, total_guards):
if security[i-1] >= security[i]:
left[i] = left[i-1] + 1
l_pattern_found = True
for i in range(total_guards-2, -1, -1):
if security[i+1] >= security[i]:
right[i] = right[i+1] + 1
r_pattern_found = True
if not l_pattern_found or not r_pattern_found:
return []
days = []
for i in range(time, total_guards-time):
if left[i-1] >= time and right[i+1] >= time:
days.append(i)
return days
Here is what I have done:
Compute the left prefix for the condition mentioned
Compute the right prefix for the condition mentioned
Find the days in the range [time, n-time]
This is failing for the test case as follows:
security = [1,2,5,4,1,0,2,4,5,3,1,2,4,3,2,4,8]
time = 2
The expected output is: [5,10,14] and my output is [4,5,6,10,14]
What is it that I am doing wrong?
The main issue is in this line:
if left[i-1] >= time and right[i+1] >= time:
Here the value of left[i-1] does not guarantee that the current value at security[i] is not greater than security[i-1]. To ensure that, you would need to look at left[i] instead of left[i-1]. For the same reason you should be looking at right[i] instead of right[i+1]. But that means you need to reduce all counts by 1, and initialise your left and right lists with zeroes:
left = [0]*total_guards
right = [0]*total_guards
With those corrections it will work.
I'm having trouble implementing the problem in python as follows. I understand the original Tower of Hanoi problem which is that one can move $N$ disks to say the 3rd disk, and there are algorithms to do so but I am unable to figure out how to list out each of the individual disks at each stage. The problem is as follows:
I figured that I could use a binomial tree representation shown as follows:
So far the rough skeleton code I thought of would look something along the lines of
def recursion(m,n,T):
pos = list(range(1,m))
index = 0
values = list(range(1,n))
tree = []
if pos[index+1] > pos[index]:
pos[index + 1] -= pos[index+1]
pos[index + 2] += pos[index+1]
tree.append(pos)
if pos[index+1] < pos[index]:
pos[index+1] += pos[index]
pos[index] -= pos[index]
tree.append(pos)
else:
recursion()
return tree
I would greatly appreciate some help with this
You didn't pass no. of disks to your function, and this number must be decreased at every next call you make to the function. And there is a condition to break further recursion. Here is the modified form
# n = no. of rods
def recurse(n , from_rod, to_rod, aux_rod):
if n == 1:
print "Move disk 1 from rod", from_rod, "to rod",to_rod
return
recurse(n-1, from_rod, aux_rod, to_rod)
print "Move disk", n, "from rod", from, "to rod", to
recurse(n-1, aux_rod, to_rod, from_rod)
n = 5
recurse(n, 'A', 'B', 'C')
This is very similar to ksai solution except this is for python 3 and I removed the extra print and return statement
def move(disk , from_rod, to_rod, aux_rod):
if disk >= 1:
move(disk-1, from_rod, aux_rod, to_rod)
print ("Move disk", disk, "from rod", from_rod, "to rod", to_rod)
move(disk-1, aux_rod, to_rod, from_rod)
n = 3
move(n, 'A', 'B', 'C')
output:
I have recently started learning programming, just completed a course on edX. I was trying to solve this problem on HackerRank and it is running out of time in each case. What am I doing wrong?
n,k = input().strip().split(' ')
n,k = [int(n),int(k)]
x = [int(x_temp) for x_temp in input().strip().split(' ')]
x.sort()
def transmitter(aList=[], target=0):
'''
accepts a list of house location, and a target location for the transmitter
returns the optimal number of transmitters required to cover all the houses
'''
List = aList[:]
start = target - k
end = target + k + 1
for i in range(start, end):
if i in List:
List.remove(i)
if not List:
return 1
m = max(List)
for e in List:
if transmitter(List, e) < m:
m = transmitter(List, e)
return 1 + m
m = max(x)
for e in x:
if transmitter(x, e) < m:
m = transmitter(x, e)
print(m)
I am pretty new to this. Sorry for making any obvious mistakes, or for posting this here in case this is not the suitable site. In that case, it will be really helpful if you can recommend a site where I can ask such question.
the screenshot of the question
I'm pretty sure a greedy algorithm solves this problem optimally in just O(N) time. There's not need for any recursion. Just place each transmitter in turn as far to the right as you can without leaving any houses to its left uncovered. Stop when the last house is covered.
Here's how I'd code that:
def hackerland(houses, k): # houses should be sorted list of locations
first = None # location of first uncovered house
last = 0 # last location covered by a previous transmitter
prev = None
count = 0 # transmitters = []
for x in houses:
if first is not None and x > first + k:
first = None
count += 1 # transmitters.append(prev)
last = prev + k
if last is not None and x > last:
last = None
first = x
prev = x
if first is not None:
count += 1 # transmitters.append(prev)
return count # return transmitters
I've included comments that show how this code could be easily modified to return a list of the transmitter locations, rather than just a count of how many are needed.
It is not necessary to take a recursive approach. In fact, you can just work forward, iterate over the houses, placing transmitters when the previously placed one does not reach far enough to cover the current house, etc.
It is a bit more complicated than that, but not much. See this code:
# input
n,k = input().strip().split(' ')
n,k = [int(n),int(k)]
x = [int(x_temp) for x_temp in input().strip().split(' ')]
# eliminate duplicate house x-xoordinates, they don't influence the result
houses = list(set(x))
houses.sort()
# add extreme far dummy house (will make the loop easier)
houses.append(100000)
reachedX = 0 # coordinate until where the previously placed transmitter reaches
unreachedX = -1 # coordinate that the next one needs to cover (to the left)
lastHouseId = -1 # index where previous transmitter was placed
transmitters = [] # coordinates of the placed transmitters
for houseId, houseX in enumerate(houses):
if reachedX > unreachedX: # we might still be in range of last transmitter
if houseX > reachedX: # we just went out of reach
unreachedX = houseX # this house must be covered by next one
elif houseX - k > unreachedX: # transmitter here wouldn't reach far enough back
lastHouseId = houseId - 1 # place it on previous house
reachedX = houses[lastHouseId] + k
transmitters.append(houses[lastHouseId])
print(transmitters)
print(len(transmitters))
What is an iterative implementation of the ruler function?
This website asserts that "The ruler function can be generated non-recursively" but never shows an example.
A recursive implementation (from the same webpage) in Python looks like this:
def ruler(k):
for i in range(1, k+1):
yield i
for x in ruler(i-1): yield x
For each number n, ruler(n) is equal to 1 + (number of trailing 0s in binary n).
I think (this untested) it can be implented efficiently as
def ruler(n):
return (x ^ (x - 1)).bit_length()
because in binary the tailing digits look like
...mno1000 # x
...mno0111 # x - 1
...0001111 # x XOR (x - 1)
then you want the number of 1s, which .bit_length() gives you.
I may be missing something here, but based on the description of the ruler function...
def ruler(k):
pow = 1
while ((2*k) % (2**pow)) == 0:
pow += 1
return pow-1
for x in range(1, 10):
print ruler(x)
1
2
1
3
1
2
1
4
1
Dunno, maybe I'm not understanding the question.
A look-up table and bit-twiddling lets you solve this efficiently.
ruler = dict((1<<i, i+1) for i in xrange(63))
for i in xrange(1, 20):
print ruler[i & ~(i-1)],
Using what Hugh Bothwell said, you can do the following (for n > 0):
def ruler(n):
return len(bin(n).split('1')[-1]) + 1
I was trying this prob & use some old methods. Please check it once. I have not set it up totally. But apparently it's working. Few of unfinished broken codes are there.
Apology in advance.
#!/usr/bin/env python
import os
def ruler():
print("Initiating ruler function...")
num = int(input("Enter the value to Eval:: "))
expNumrange = 1234567890
if num%2 == 0:
for i in range(num):
print(expNumrange,end='----')
else:
rem = num%2
remLen = len(str(abs(rem)))
expNumrangelen = len(str(abs(expNumrange)))
finval = len(str(abs(expNumrange - remLen)))
setVal = expNumrange - finval
#rem2 = (str(expNumrange) - str(remLen))
for i in range(num):
print(expNumrange, end=(str(setVal) + '--'))
if __name__ == '__main__':
ruler()
Now, please check output.
For "8"
1234567890----1234567890----1234567890----1234567890----1234567890----1234567890----1234567890----1234567890----
For "5"
12345678901234567880--12345678901234567880--12345678901234567880--12345678901234567880--12345678901234567880--