loading...

Daily Challenge #16 - Number of People on the Bus

thepracticaldev profile image dev.to staff ・1 min read

Today's challenge comes from aryan-firouzian on Codewars. You are to figure out how many people are on the bus given the following scenario:

There is a bus moving in the city, and it takes and drop some people at each bus stop.

You are provided with a list (or array) of integer arrays (or tuples). Each integer array has two items which represent the number of people that get on the bus (The first item) and the number of people that get off the bus (The second item) at a bus stop.

Your task is to return number of people who are still left on the bus after the last bus station (after the last array).

Good luck, and happy coding!


Thank you to CodeWars, who has licensed redistribution of this challenge under the 2-Clause BSD License!

Want to propose a challenge for a future post? Email yo+challenge@dev.to with your suggestions!

Posted on by:

thepracticaldev profile

dev.to staff

@thepracticaldev

The hardworking team behind dev.to ❤️

Discussion

pic
Editor guide
 

JS:

result = arr.reduce((a, [wentOn, wentOff]) => {
    return a + wentOn - wentOff;
});
 

Nice one, although you're missing the second argument to reduce which specifies the initial value for a.

 

According to the MDN Web Docs, that argument is optional.

 

Rust Solution

This also checks to make sure that more people don't get off the stop than were on + got on that stop. This assumes no passengers were on the bus initially.

pub fn riders_left(bus_stops: &[(u32, u32)]) -> Result<u32, &str> {
    bus_stops.iter().fold(Ok(0), |sum, (on, off)| {
        let new_sum = sum? + on;

        if off > &new_sum {
            Err("Somehow more people left the bus than got on")
        } else {
            Ok(new_sum - off)
        }
    })
}

#[cfg(test)]
mod tests {
    use crate::*;

    #[test]
    fn it_returns_zero_for_an_empty_array() {
        assert_eq!(riders_left(&[]), Ok(0))
    }

    #[test]
    fn it_for_a_semi_complicated_array_example() {
        assert_eq!(riders_left(&[(10, 0), (5, 9), (6, 6), (2, 6)]), Ok(2));
    }

    #[test]
    fn it_for_a_semi_complicated_vec_example() {
        assert_eq!(riders_left(&vec![(10, 0), (5, 9), (6, 6), (2, 6)]), Ok(2));
    }

    #[test]
    fn it_for_a_broken_example() {
        assert_eq!(
            riders_left(&vec![(10, 0), (5, 9), (6, 6), (2, 12)]),
            Err("Somehow more people left the bus than got on")
        );
    }
}

 

PHP 7.4:

$bus = fn(array $stops, int $riders = 0): int => array_reduce($stops, fn(int $count, array $data): int => ($count + $data[0]) - $data[1], $riders);

var_dump($bus([[1, 0], [2, 1], [5, 3], [4, 2]])); //=> int(6)
 
#! /usr/bin/perl
use warnings;
use strict;
use feature qw{ say };

use List::Util qw{ sum };

sub bus { sum(map $_->[0] - $_->[1], @_) }

use Test::More tests => 1;
my @people = ([10, 0], [5, 3], [12, 1], [1, 3], [0, 3], [1, 7]);
is bus(@people), 12;

BTW, it seems today's post didn't make it into the series.
Update: It's been fixed.

 

Ruby 2.6

require "minitest/autorun"

class BusStopSimulator
  def self.call bus_stops
    bus_stops.map { |stop| stop.reduce(:-) }.sum
  end
end

class BusStopSimulatorTest < MiniTest::Test
  def test_four_bus_stops
    assert_equal 7, BusStopSimulator.call([[8,4],[1,0],[2,5],[6,1]])
  end
end
 

Elixir:

defmodule Bus do
  @spec passengers([{non_neg_integer, non_neg_integer}]) :: non_neg_integer
  def passengers(list) do
    list
    |> Enum.map(fn {went_on, went_off} -> went_on - went_off end)
    |> Enum.sum()
  end
end
 

CSS (kind of):

For the list of of integer arrays, we can use an actual HTML list with <li> that contain CSS variables with the number of people going up (--up) and down (--down) the bus. Then using CSS counters we can keep a count of the people who are on the bus at each moment.

Live demo on CodePen.

 

Didn't see anyone else try it in C, so here's my solution in C:

#include "stdio.h"
#include "stdlib.h"

unsigned int bus( unsigned int ( *data )[2], size_t n ) {
    unsigned int sum = 0;

    for ( size_t i = 0; i < n; ++i ) {
        sum += ( data[i][0] - data[i][1] );
    }

    return sum;
}

int main( int argc, char const *argv[] ) {
    // Read in data, somehow
    printf( "Passengers remaining after last stop: %u\n",
      bus( ( unsigned int[][2] ){{1, 0}, {2, 1}, {5, 3}, {4, 2}}, 4 ) );
    // 6
    return 0;
}
 

Python:

bus_array = [(10,0), (2,1), (1,11)]
passengers_left = sum([entered - left for entered, left in bus_array])
 

JS

const stops = [
 [10, 0],
 [5, 3],
 [4, 4],
 [3, 8],
 [0, 2],
]

const inBus = stops.reduce(
(n, [gotIn, gotOut]) => n + gotIn - gotOut,
0
)
 

R

# Read in data, somehow. Likely into a data.frame
bus_data <- data.frame(on = c(1, 2, 5, 4), off = c(0, 1, 3, 2))
sum(bus_data$on - bus_data$off)
# [1] 6
 

Here is the simple solution with Python:

def number(bus_stops):
    people = 0
    for items in bus_stops:
        people += items[0]
        people -= items[1]

    return people
 

Haskell

passengers :: [(Int, Int)] -> Int
passengers xs = sum $ map (\x -> fst x - snd x) xs

main = print $ passengers [(1, 0), (2, 1), (5, 3), (4, 2)]
 

Smalltalk --- because it seems nobody did it yet:

result := arr sum: [ :aStop | aStop first - aStop second ]
 

Haskell:

type BusStop = (Int, Int)

getChange :: BusStop -> Int
getChange stop = fst stop - snd stop

peopleOnBus :: [BusStop] -> Int
peopleOnBus = sum . map getChange
 

My solution in js

const totalPeopleInBus = (arr) => arr.reduce((total, [enter, exit]) => total + enter - exit, 0);