See the original problem on HackerRank.
Solutions
We can count the on time students. If the count is less than k, the professor is angry.
A possible optimization is to stop when k
positive elements are found, avoiding to iterate more elements. Finding a solution that combines efficiency with succinctness is another possible target.
Also, since this challenge is simple, you can work on it using other languages or approaches you are not comfortable with.
PHP
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
|
<?php
function angryProfessor($k, $a) {
$count = 0;
foreach ($a as $time) {
if ($time <= 0) {
$count++;
}
}
if ($count >= $k) {
return 'NO';
}
else {
return 'YES';
}
}
|
Javascript by Enrico Scantamburlo
1
|
const angryProfessor = (k, a) => a.filter(v => v < 1).length < k ? 'YES' : 'NO'
|
Ruby by Davide Pettenon
1
2
3
|
def angryProfessor(k, a)
a.select { |x| x <= 0 }.size < k ? 'YES' : 'NO'
end
|
Python by Beatrice Liberi
1
2
3
4
5
|
def angryProfessor(k, a):
if len(list(filter(lambda x: x <=0, a))) >= k :
return 'NO'
else:
return 'YES'
|
Haskell
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
|
import Data.List.Split
fromLines lines = (k, a)
where
_:k:a = read <$> concatMap words lines
countOnTime = length . filter (<= 0)
angryProfessor (k, a) = countOnTime a < k
output True = "YES"
output False = "NO"
main = do
_ <- getLine
testCases <- fmap fromLines . chunksOf 2 . lines <$> getContents
putStr . unlines $ output . angryProfessor <$> testCases
|
The algorithm can be optimized: just stop reading the array when at least k
students are on time.
1
|
angryProfessor (k, a) = k /= (length . take k $ filter (<= 0) a)
|
Rust
1
2
3
|
fn angry_professor(k: usize, a: &[i32]) -> bool {
k != a.iter().filter(|&&x| x <= 0).take(k).count()
}
|
Elixir by Tommaso Bertagnin
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
|
defmodule Solution do
[[_n_of_cases] | cases ] =
Enum.map(IO.stream(:stdio, :line), fn line ->
line
|> String.trim
|> String.split(" ", trim: true)
|> Enum.map(&String.to_integer/1)
end)
cases
|> Enum.chunk_every(2)
|> Enum.each(fn [[_n_students, min_attendance], entry_times] ->
arrived_on_time =
entry_times
|> Enum.filter(fn t -> t <= 0 end)
|> Enum.count()
professor_says =
if arrived_on_time >= min_attendance do "NO" else "YES" end
IO.write(professor_says <> "\n")
end)
end
|
C#
1
2
3
4
|
public static string angryProfessor(int k, List<int> a)
{
return a.Where(x => x <= 0).Take(k).Count() == k ? "NO" : "YES";
}
|
C++
1
2
3
4
|
string angryProfessor(int k, const vector<int>& times)
{
return count_if(begin(times), end(times), [](int i){return i<=0;}) >=k ? "NO" : "YES";
}
|
C++ with ranges:
1
2
3
4
5
6
|
string angryProfessor(int k, const vector<int>& times)
{
return distance(times
| views::filter([](int i){ return i<=0; })
| views::take(k)) == k ? "NO" : "YES";
}
|
A recursive solution
By Antonio D’Angelico:
1
2
3
4
5
6
7
8
9
10
11
12
|
string fun(int k, vector<int> a, int i)
{
if (i == (int)a.size())
return "YES";
if (k == 0)
return "NO";
if (a[i] <= 0)
return fun(k - 1, a, i + 1);
return fun(k, a, i + 1);
}
|