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 steps. For every step he took, he noted if it was an uphill, , or a downhill, step. Gary's hikes start and end at sea level and each step up or down represents a unit change in altitude. We define the following terms:
A mountain is a sequence of consecutive steps above sea level, starting with a step up from sea level and ending with a step down to sea level.
A valley is a sequence of consecutive steps below sea level, starting with a step down from sea level and ending with a step up to sea level.
Given Gary's sequence of up and down steps during his last hike, find and print the number of valleys he walked through.
For example, if Gary's path is , he first enters a valley units deep. Then he climbs out an up onto a mountain units high. Finally, he returns to sea level and ends his hike.
Function Description
Complete the countingValleys function in the editor below. It must return an integer that denotes the number of valleys Gary traversed.
I have tried writing this code in python and it runs well but cannot figure out a code logically
#n is the number of steps and s is the sequence of steps taken
def countingValleys(n, s):
level=valley=0
for i in range(n):
if(s[i]=='U'):
level+=1
if(level==0):
valley+=1
else:
level-=1
return valley
Results are fine
Questions: Can someone explain me the logic starting from if(level==0). If we increase the level by one unit when the person moves uphill, shouldn't we increase valley by 1 then. Why should valley increase by one when level is zero. Confused about the logic- can someone please help me understand this
If the step is uphill if(s[i]=='U')
And the level is 0 if(level==0)
Then it is a valley valley+=1
The function works by counting the valleys when you come out of them, and it tells that you come out of them because you reach the sea level giving an uphill step.
Its simple,
What the code means is, if you have encountered an up symbol it means you have climbed. Now if you have climbed from plane or mountain your level would be greater than 0. But if you have climbed from a valley to level then only your level would become 0.
basically if level<0 it means you are still in valley, level>0 means you are in mountain, level 0 means you are in sea level.
So if you have encountered a up symbol denoting climb action and then your level is 0 that means you have climbed up a valley that's all.
We can assign values to uphill and downhill as uphill=1, downhill=-1 and sea level=0 and as valley can be defined as when we reached the sea level from downhill, i.e from a negative value to zero
so if we are at a negative level and moving to sea level by adding the next step we can increment the valley.
Find the code snippet below
def returnCode(step):
if step=='U':
return 1;
return -1;
def countingValleys(steps, path):
# Write your code here
level=valley=0
for element in path:
code = returnCode(element)
if level< 0 and level+code == 0:
valley=valley+1
level = level+code
return valley
Does
level=0 valley=0
make any difference, they both are similar level=valley=0
The logic is simple you just have to count if the no if "U"-uphill assigned as '1' and number of 'D'-Downhills assigned as '-1' and on adding the both count one should get '0' as in [DDDUUU] which will increment valley by '1'.
When level=0 Gary has reached sea level meaning he has covered a valley
In Javascript
function countingValleys(steps, path){
let altitude = 0;
let valleys = 0;
for(let i = 0; i < steps; i++){
altitude = (path[i] == 'U') ? altitude + 1 : altitude - 1;
if(altitude == 0 && path[i] == 'U'){
valleys++;
}
}
return valleys;
}
console.log(countingValleys(8, "UDDDUDUU"));
in php
function countingValleys($steps, $path) {
// Write your code here
$valley = 0;
$altitude = 0;
for($i=0; $i < $steps; $i++){
$altitude = ($path[$i] == "U") ? $altitude + 1 : $altitude -1;
if($altitude == 0 && $path[$i] == "U"){
$valley += 1;
}
}
return $valley;
}
countingValleys(8, "UDDDUDUU")
Solution in Golang
The function is expected to return an INTEGER.
The function accepts following parameters:
INTEGER steps
STRING path
*/
func countingValleys(steps int32, path string) int32 {
// Write your code here
//level 0 is sea
//level>0 is mountain
//level< 0 valley
// check the steps if its U do level+1
//if step is D do a level-1
level :=0
valley :=0
step := []rune(path)
for i:=0; i< int(steps);i++{
if string(step[i]) =="U"{
level= level+1
}else if string(step[i])=="D"{
level= level-1
}
if string(step[i])=="U" && level == 0{
valley++
}
}
return int32(valley)
}
Counting valley hacker solution in php
function countingValleys($steps, $path) {
$valley = 0;
$sealevel = 0;
$newPath = str_split($path);
$c = count($newPath);
if ($steps == $c && $c >= 2) {
for($i = 0; $i < $c; $i++) {
if ($newPath[$i] == "D") {
$sealevel -= 1;
} else {
$sealevel += 1;
}
if ($sealevel == 0 && $newPath[$i] == "U") {
$valley += 1;
}
}
return $valley;
}
}
Track the altitude. Any time you return back to sea-level and you came from below, you know you've found a valley. Keep count of these finding.
Time-complexity: O(steps)
Space-complexity: O(steps)
Java 8
public static int countingValleys(int steps, String path)
{
int altitude = 0; // 0 = sea-level
int countedValleys = 0;
//Loop through path evaluating each change in altitude
for(char altChange: path.toCharArray())
{
//'U' increases altitude. Otherwise, decrease altitude ('D')
altitude = altChange == 'U' ? altitude + 1 : altitude - 1;
//If you've reached sea-level and you came from below, you've found a valley
if(altitude == 0 && altChange == 'U')
countedValleys++;
}
//Return count of found valleys
return countedValleys;
}
Javascript Solution:
function countingValleys(steps, path) {
var altitude = 0;
var numberOfValleys = 0;
path.split('').forEach(step => {
if(step === 'U'){
altitude ++;
if(altitude === 0){
numberOfValleys++;
}
}else{
altitude--
}
})
return numberOfValleys;
}
#JavaScript(Nodejs) solution
function countingValleys(steps, path) {
// Write your code here
let a = Array.from(path);
let valleys=0;
let pos=0;
let prevpos=0;
for(let i=0;i<a.length;i++){
if(a[i]==='U'){
prevpos=pos++;
if(pos===0){
valleys++;
}
}
else
{
prevpos = pos--;
}
}
return valleys;
}
you can try this code with go
func countingValleys(steps int32, path string) int32 {
// Write your code here
var lv int;
var count int32;
var lembah bool;
for i := 0; i< int(steps); i++{
if path[i]== 'U' {lv ++;}else if path[i]== 'D'{lv--}
if lv<0 {lembah = true}
if lembah {
if(lv>=0){
count ++;
lembah = false;
}
}
}
return count;
}
I had a coding challenge as one of the process for recruitment into a company. In that coding challenge, one of the question was to inverse an expression.
For Example,
Input : 14-3*2/5
Output : 5/2*3-14
I used stack to put each number say 14 or 3 and expressions and then popped it out again to form the output.
Input format is : num op num op num op num
So we need not worry about input being -2.
num can be between -10^16 to 10^16. I was dealing with strings completely, so even if the number exceeds the 10^16 limit, my algorithm wouldn't have any problem.
My algorithm passed 7 test cases and failed in 2 of them.
I couldn't figure it out what the corner case would be. I couldn't see the test cases as well. Any idea what that might be. I know there isn't enough information, but unfortunately I too don't have them.
// Complete the reverse function below.
static String reverse(String expression) {
expression = expression.trim();
if(expression == ""){
return "";
}
Stack<String> stack = new Stack<String>();
String num = "";
for(int i=0; i<expression.length(); i++){
char c = expression.charAt(i);
if(c==' '){
continue;
}
if(c == '+' || c == '-' || c == '*' || c == '/'){
if(num != "") {
stack.push(num);
}
num = "";
stack.push(Character.toString(c));
} else{
num += c;
}
}
if(num != "") {
stack.push(num);
}
String revExp = "";
while(! stack.empty()){
revExp = revExp + stack.pop();
}
return revExp;
}
This is a question not about how LongAdder works, it's about an intriguing implementation detail that I can't figure out.
Here is the code from Striped64 (I've cut out some parts and left the relevant parts for the question):
final void longAccumulate(long x, LongBinaryOperator fn,
boolean wasUncontended) {
int h;
if ((h = getProbe()) == 0) {
ThreadLocalRandom.current(); // force initialization
h = getProbe();
wasUncontended = true;
}
boolean collide = false; // True if last slot nonempty
for (;;) {
Cell[] as; Cell a; int n; long v;
if ((as = cells) != null && (n = as.length) > 0) {
if ((a = as[(n - 1) & h]) == null) {
//logic to insert the Cell in the array
}
// CAS already known to fail
else if (!wasUncontended) {
wasUncontended = true; // Continue after rehash
}
else if (a.cas(v = a.value, ((fn == null) ? v + x : fn.applyAsLong(v, x)))){
break;
}
A lot of things from code are clear to me, except for the :
// CAS already known to fail
else if (!wasUncontended) {
wasUncontended = true; // Continue after rehash
}
Where does this certainty that the following CAS will fail?
This is really confusing for me at least, because this check only makes sense for a single case : when some Thread enters the longAccumulate method for the n-th time (n > 1) and the busy spin is at it's first cycle.
It's like this code is saying : if you (some Thread) have been here before and you have some contention on a particular Cell slot, don't try to CAS your value to the already existing one, but instead rehash the probe.
I honestly hope I will make some sense for someone.
It's not that it will fail, it's more that it has failed. The call to this method is done by the LongAdder add method.
public void add(long x) {
Cell[] as; long b, v; int m; Cell a;
if ((as = cells) != null || !casBase(b = base, b + x)) {
boolean uncontended = true;
if (as == null || (m = as.length - 1) < 0 ||
(a = as[getProbe() & m]) == null ||
!(uncontended = a.cas(v = a.value, v + x)))
longAccumulate(x, null, uncontended);
}
}
The first set of conditionals is related to existence of the long Cells. If the necessary cell doesn't exist, then it will try to accumulate uncontended (as there was no attempt to add) by atomically adding the necessary cell and then adding.
If the cell does exist, try to add (v + x). If the add failed then there was some form of contention, in that case try to do the accumulating optimistically/atomically (spin until successful)
So why does it have
wasUncontended = true; // Continue after rehash
My best guess is that with heavy contention, it will try to give the running thread time to catch up and will force a retry of the existing cells.
I currently working on an intro assignment for a computer architecture course and i was asked to accomplish some string modifications. My question is not how to do it, but what should i be researching to be able to do it? Is there any functions that will make this easier, for example .reverse() is java.
What i need to accomplish is getting string input from the user, reverse the letters (while reversing numbers keep them where they are), add spaces whenever there is a vowel, and alternate the caps.
Example:
Input: AbC_DeF12
Output: f E d _ c B a 2 1
This is code i ripped from the lecture: http://pastebin.com/2E1UtGdD I put it in pastebin to avoid clutter. Anything used in this is fair game. (this code does have limitiations though, it only support ~9 characters and the looping doesn't work at the end of strings)
I would look at it like this.
Generate a function on paper of how you want to achieve this. This is notes and only a starting point.
Loop from 0 to string length.
if(byte >= 'A' || byte <= 'Z') then byte -= 'A' - 'a'; /* convert to lower case */
if(byte >= 'a' || byte <= 'z') then byte += 'A' - 'a'; /* convert to upper case */
/* Switch the letters only. */
a = 0; b = string length
Loop i from a to b. if((input >= 'A' && input <='Z') || (input >= 'a' && input <='z')) p = i
Loop j from b to a. if((input >= 'A' && input <='Z') || (input >= 'a' && input <='z')) q = j
c = input[i]; input[i] = input[j]; input[j] = c;
/* Regenerate the string and add spaces. */
loop i, 0 to string length
if(input[i] == 'A' 'a' 'E' 'e' ...) string2[j] = ' '; j++; string2[j] = input[i]; j++;
i++
After that if you don't know 8086 I would look at examples online of how to do each individual part. The most important bit is generating the code in your head and on paper on how it is going to work.
Reverse characters of each word in a sentence. For eg:
My name is alex
changes to
yM eman si xela
I thought of the normal O(n) time algorithm of using two pointer to point to either end of the word and reverse it.
But in the below site
http://www.businessinsider.com/8-mind-bending-interview-questions-that-google-asks-its-engineers-2012-7?op=1
(Refer to ans of ques 2)
it is give that converting it to linked list and repetitively applying reversal of linked list for individual word is better. I found the following solution for the same program on Hackerearth:
http://learn.hackerearth.com/question/317/reverse-characters-of-each-word-in-a-sentence/
This solution takes O(n) time and O(n) space. The solution I suggested takes O(n) time O(1) space. How is the second one better?
Following is the code from Hackerearth:
public node stringReverseChars(node ll){
if(ll == null || ll.next == null)
return ll;
node tmp = ll;
node head = null, prev = null;
while(tmp != null){
while(tmp != null && tmp.data == ' '){
if(head == null)
head = tmp;
prev = tmp;
tmp = tmp.next;
}
if(tmp == null)
break;
node curr = tmp;
while(tmp.next != null && tmp.next.data != ' '){
tmp = tmp.next;
}
node np = tmp.next;
tmp.next = null;
node rev = reverseLL(curr);
if(prev != null)
prev.next = rev;
prev = curr;
curr.next = np;
if(head == null)
head = rev;
tmp = np;
}
return head;
}
I'm pretty skeptical that those other approaches are better. They have worse memory usage (Θ(n) versus O(1)) and worse locality of reference (they use linked lists rather than arrays). I don't see anything wrong with your solution; in fact, I think it's the standard way to do this.
Hope this helps!