Programming Puzzles & Code Golf Stack Exchange is a question and answer site for programming puzzle enthusiasts and code golfers. Join them; it only takes a minute:

Sign up
Here's how it works:
  1. Anybody can ask a question
  2. Anybody can answer
  3. The best answers are voted up and rise to the top

A simple pedometer can be modeled by a pendulum with two switches on opposite sides—one at x=0 and one at x=l. When the pendulum contacts the far switch, the ambulator can be assumed to have taken half a step. When it contacts the near switch, the step is completed.

Given a list of integers representing positions of the pendulum, determine the number of full steps recorded on the pedometer.

Input

  • An integer l>0, the length of the track.

  • A list of integers representing the positions of the pedometer's pendulum at each time.

Output

The number of full steps measured. A step is taken when the pendulum contacts the far switch (x>=l) and then the near switch (x<=0).

Test cases

8, [8, 3, 0, 1, 0, 2, 2, 9, 4, 7]
1

The pendulum immediately makes contact with the far switch at x=8 at t=0. Then it touches the near switch at t=2 and t=4, completing one step. After that, it touches the far switch again at x=9 at t=8, but it never touches the near switch again.

1, [1, 5, -1, -4, -1, 1, -2, 8, 0, -4]
3

15, [10, -7, -13, 19, 0, 22, 8, 9, -6, 21, -14, 12, -5, -12, 5, -3, 5, -15, 0, 2, 11, -11, 12, 5, 16, 14, 27, -5, 13, 0, -7, -2, 11, -8, 27, 15, -10, -10, 4, 21, 29, 21, 2, 5, -7, 15, -7, -14, 13, 27]
7

7, [5, 4, 0]
0

7, [5, 8, 6, 1, 2] 
0   
share|improve this question
1  
What about 7, [5, 4, 0]? Is that 0 or 1? That is - do you assume that a swing is always "full-length"? Or 7, [5, 8, 6, 1, 2]? Is that 0 or 1? – Not that Charles Mar 8 at 20:31
1  
@NotthatCharles Added. – lirtosiast Mar 8 at 20:34
    
I assume a step always is: contact at far end, then near end. That is: near end, then far end is not a full step. So input 8, [0 8 0 8] should give 1, not 2. Am I correct? – Luis Mendo Mar 8 at 23:55
    
@DonMuesli Yes. – lirtosiast Mar 9 at 0:31

CJam, 27 24 bytes

l~:Xfe<0fe>_[XT]:Y--Y/,(

Input format is the list of pendulum positions followed by l on a single line.

Test it here.

Explanation

l~     e# Read and evaluate input.
:X     e# Store track length in X.
fe<    e# Clamp each position to X from above.
0f>    e# Clamp each position to 0 from below.
_      e# Duplicate.
[XT]   e# Push the array [X 0].
:Y     e# Store it in Y.
-      e# Set subtraction from the clamped input list. This gives all the
       e# intermediate values.
-      e# Another set subtraction. Remove intermediate values from input list.
Y/     e# Split remaining list around occurrences of ...X 0...
,(     e# Count them and decrement. This is the number of times the pendulum
       e# moved from X to 0.
share|improve this answer

MATL, 22 bytes

>~2G0>~-XzY'nw1)0<-H/k

This uses current version (14.0.0) of the language/compiler.

Inputs are in the same order and format as in the challenge, separated by a newline.

Try it online!

Explanation

>~     % take the two inputs implicitly. Generate an array that contains true 
       % where the second input (array of positions) is >= the first input (l)
2G     % push second input (positions) again
0      % push a 0
>~     % true where the second input (array of positions) is <= 0
-      % subtract: array of 1, -1 or 0
Xz     % discard the 0 values
Y'     % run-length encoding: push values and number of repetitions
n      % length of the latter array: number of half-steps, perhaps plus 1
w1)    % swap. Get first element
0<     % true if that element is -1. We need to discard one half-step then
-      % subtract
H/k    % divide by 2 and round down
share|improve this answer

Javascript ES6 57 bytes

(t,a)=>a.map(a=>a<t?a>0?'':0:1).join``.split`10`.length-1

Thanks @NotThatCharles for -4

share|improve this answer
1  
Why not split on /10/? – Not that Charles Mar 8 at 21:29
    
@NotthatCharles I was so sure that didn't work, just tried it and it's great! - thanks – Charlie Wynn Mar 8 at 21:33
4  
One Charles to another ;) – Not that Charles Mar 8 at 21:34

Perl, 28 bytes

Includes +1 for -p

Run with the input as one long line of space separated integers on STDIN, the first number is the length:

perl -p steps.pl <<< "8 8 3 0 1 0 2 2 9 4 7"

steps.pl:

s; ;$'>=$_..$'<1;eg;$_=y;E;

Uses the perl flip-flop operator and counts the number of times it returns to false

share|improve this answer

Pyth, 18 bytes

/.:@J,Q0m@S+Jd1E2J

Test suite

Explanation:

/.:@J,Q0m@S+Jd1E2J
                      Implicit: Q is the length of the track.
    J,Q0              Set J to [Q, 0]
        m      E      Map over the list
           +Jd        Add the current element to J
          S           Sort
         @    1       Take the middle element.
                      This is the current element, 
                      clamped above by Q and below by 0.
   @J                 Filter for presence in J.
 .:             2     Form 2 element substrings
/                J    Count occurrences of J.
share|improve this answer

Ruby, 42

->i,a{r=!0
a.count{|v|r^r=v>=i||r&&v>0}/2}

r starts as false. We toggle r at each end of the track, and add it to our count. Then, halve the count (rounding down) to get the number of steps.

share|improve this answer

Retina, 34

-1*

^(1*)((?>.*?\1.*? \D))*.*
$#2

Try it online! or try it with decimal input.

Takes input in unary, negative unary numbers are treated as -111... and zero is the empty string. Counts the number of times that the first number appears followed by a zero. Uses an atomic group to guarantee that the matches are minimal (sadly atomic groups are non-capturing so it has to be wrapped in another group...).

share|improve this answer

Python 3, 82

Saved 2 bytes thanks to DSM.

Not super golfed yet.

def f(x,s):
 c=l=0
 for a in s:
  if a>=x:l=x
  elif a<1:c+=l==x;l*=l!=x
 return c

Test cases:

assert f(8, [8, 3, 0, 1, 0, 2, 2, 9, 4, 7]) == 1
assert f(1, [1, 5, -1, -4, -1, 1, -2, 8, 0, -4]) == 3
assert f(15, [10, -7, -13, 19, 0, 22, 8, 9, -6, 21, -14, 12, -5, -12, 5, -3, 5, -15, 0, 2, 11, -11, 12, 5, 16, 14, 27, -5, 13, 0, -7, -2, 11, -8, 27, 15, -10, -10, 4, 21, 29, 21, 2, 5, -7, 15, -7, -14, 13, 27]) == 7
share|improve this answer

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.