7
\$\begingroup\$

Related as it requires you to measure the time between the first and last input. But here you're required to count how many inputs in a period of time.

I was assigned a task to stand by a gate and count how many students enter it. The problem is that my memory is not as good as it was when I first started this job. I need some kind of program to help me count how many students enter the gate until my shift is over.

Task

Given an integer t that represents the number of seconds until my shift is over. Tell me how many times I pressed the button during that time.

Rules

  • The button press can be any convenient user input, such as pressing the Return key;
  • You can assume that t will allways be in range [1; 60];
  • You can assume that the number of students will be less than 231;
  • When the time is up, you must output within 1 second;
  • Your program does not need to end, as long as the only output to stdout is at the end of the shift;
  • If your input method (such as Enter-key) repeats if held, you can choose to count it just once, or several times. Either way, you must still be able to handle separate inputs.
\$\endgroup\$
  • \$\begingroup\$ Hey, when you say output, is returning a value OK? \$\endgroup\$ – Timtech Jul 31 '17 at 18:32
  • \$\begingroup\$ @Timtech sure, you can \$\endgroup\$ – Felipe Nardi Batista Jul 31 '17 at 18:33
  • 5
    \$\begingroup\$ I highly doubt you can press 2^31 times in 60 seconds! \$\endgroup\$ – Mr. Xcoder Jul 31 '17 at 18:49
  • 2
    \$\begingroup\$ Why are people closing this question? It's defined well enough. \$\endgroup\$ – Timtech Jul 31 '17 at 19:12
  • \$\begingroup\$ Do we have to output to stdout or are other acceptable methods OK for this challenge? \$\endgroup\$ – Engineer Toast Jul 31 '17 at 20:10

12 Answers 12

6
\$\begingroup\$

TI-Basic, 22 bytes

Fairly simple. Sets a time Ans seconds in the future which we call T which is when the loop stops. While the loop is going, we check for if a key is pressed. It's been a while since I had the fgitw :)

startTmr+Ans->T
0
While T≠startTmr
Ans+not(not(getKey
End
\$\endgroup\$
  • \$\begingroup\$ Pro tip: None of the inputs repeat when you hold them down, except for Del and the arrow keys. So, you can try it both ways if you want. \$\endgroup\$ – Timtech Jul 31 '17 at 18:35
  • \$\begingroup\$ Note that startTmr is only available on TI-84+/SE. \$\endgroup\$ – Nnnes Jul 31 '17 at 18:36
  • \$\begingroup\$ is there a way to test it without the calculator? \$\endgroup\$ – Felipe Nardi Batista Aug 2 '17 at 14:25
  • \$\begingroup\$ @FelipeNardiBatista If you have any TI84 series ROM you can use it with cemetech.net/projects/jstified \$\endgroup\$ – Timtech Aug 2 '17 at 15:40
  • \$\begingroup\$ Are we allowed to just return in Ans now, without displaying? \$\endgroup\$ – lirtosiast Aug 25 '17 at 0:19
3
\$\begingroup\$

Ruby, 38 42 bytes

Uses the global variable $., which counts how many times the standard input function gets has successfully been completed. As such, it will only give accurate results the first time it is called per program run.

Input via command-line argument, such as ruby gatekeeper.rb 40

Thread.new{loop{gets}}
sleep eval$*[0]
p$.
\$\endgroup\$
  • \$\begingroup\$ As per meta, function submissions have to be reusable. \$\endgroup\$ – LyricLy Aug 1 '17 at 2:10
  • \$\begingroup\$ @LyricLy fair enough. Fixed. \$\endgroup\$ – Value Ink Aug 1 '17 at 2:37
3
\$\begingroup\$

AHK, 110 bytes

1*=-1000
c=0
Loop,255
Hotkey,% Format("vk{:x}",A_Index),s,On
SetTimer,q,%1%
Return
s:
c++
Return
q:
MsgBox,%c%

This is not as short as other submissions, but it distinguishes itself by allowing you to use practically any key as a counter. This includes mouse clicks and control keys like Ctrl, Shift, etc. unless you use special keys that can never be blocked such Ctrl+Alt+Del on Windows.

Two important notes:

  • The key presses and mouse clicks are blocked from other software
  • The program does not terminate

If you actually run this program, it will count for 1 seconds (where the variable 1 is the first passed parameter), all the while counting how many key presses you made and blocking each one. When that time expires, it pops up a message box with the total. However, seeing as how all keyboard and mouse inputs are still blocked, it's rather difficult to dismiss that message. That sounds like a job for the next gatekeeper.

\$\endgroup\$
3
\$\begingroup\$

C++ 11, MSVC, 255 254 246 244 bytes, MSVC without /Za flag : 204 202 bytes

-1 byte thanks to Zacharý
-8 bytes thanks to Tas
-42 bytes for the second version thanks to Tas

Can be compiled with /Za flag ( disabled extensions ) :

#include<thread>
#include<conio.h>
#define S(t)std::this_thread::sleep_for(std::chrono::milliseconds(t))
int r=1;void k(int*a){while(r){if(_kbhit()&&_getch())++*a;S(1);}}int c(int n){int a=0;std::thread t(k,&a);S(n*1000);r=0;t.join();return a;}

Can't be compiled with /Za flag ( require enabled extensions ). For more details, see this answer

#include<thread>
#include<conio.h>
#include<Windows.h>
int r=1;void k(int*a){while(r){if(_kbhit()&&_getch())++*a;Sleep(1);}}int c(int n){int a=0;std::thread t(k,&a);Sleep(n*1000);r=0;t.join();return a;}

Ungolfed and explanations :

#include<thread> // For the thread standard library
// Console IO, C header used mostly by MS-DOS compilers. Not ISO C nor POSIX standard
#include<conio.h> // Used for _getch and _kbhit

//Macro that takes the number of milliseconds to make the current thread go to bed and sleep
#define S(t) std::this_thread::sleep_for(std::chrono::milliseconds(t))

//Global bool that will indicate the input thread if it continues to run or not
bool r=true;

/**
 * @brief: Function that increment a variable every time a key is pressed
 * @param a : a pointer to the memory location where to increment the counter
 * References are unfortunately forbidden
 */
void k(int* a) {
    while(r) {
        if(_kbhit() && _getch())
            ++*a;
        S(1);
    }
}

/** Function to call
 * @brief : Counts the number of time a key is pressed
 * @param : The number of seconds it have to capture the key presses
 * @return : the number of times a key was pressed
 */
int c(int n) {
    int a=0;
    std::thread t(k,&a);
    S(n*1000);
    r=false;
    t.join();
    return a;
}

Conio.h Wikipedia page

\$\endgroup\$
  • \$\begingroup\$ You don't need the space after S(t). 1000 => 1e3. \$\endgroup\$ – Zacharý Jul 31 '17 at 22:58
  • \$\begingroup\$ @Zacharý i can't replace 1000 by 1e3, i will get an error if i do \$\endgroup\$ – HatsuPointerKun Aug 1 '17 at 23:20
  • 1
    \$\begingroup\$ @Tas Updated. It works \$\endgroup\$ – HatsuPointerKun Aug 1 '17 at 23:47
  • \$\begingroup\$ Sweet. I removed my other comments. You might also be able to save bytes by using Windows Sleep function: you'd have to #include<Windows.h> but std::this_thread::sleep_for(std::chrono::millseconds would simply be Sleep(t); \$\endgroup\$ – Tas Aug 2 '17 at 0:00
  • 1
    \$\begingroup\$ @Tas I added a version with your solution, but as separate, since you can't compile Windows header files with /Za flag \$\endgroup\$ – HatsuPointerKun Aug 2 '17 at 1:07
2
\$\begingroup\$

JavaScript (ES6), 50 bytes

t=>setTimeout("alert(i)",1e3*t,i=0,onclick=_=>i++)

Test Snippet

f=
t=>setTimeout("alert(i)",1e3*t,i=0,onclick=_=>i++)

;f(10)
document.write("click to count...")
*{user-select:none}

\$\endgroup\$
2
\$\begingroup\$

Bash + coreutils, 39 bytes

This is an ugly way that creates a file t in the current directory because I couldn't get process substitution to work.. You count by pressing the return key and it continues counting if it's held down.

Use it like this: $ f DURATION


f(){ timeout -s3 $1 cat>t;cat t|wc -l;}

Try it online!

\$\endgroup\$
2
\$\begingroup\$

C#, 132 122 bytes

namespace System.Threading.Tasks{n=>{int c=0;Task.Run(()=>{for(;;++c)Console.ReadKey();});Thread.Sleep(n*1000);return c;}}

Saved 10 bytes thanks to @DaveParsons.

Full/Formatted version:

namespace System.Threading.Tasks
{
    class P
    {
        static void Main()
        {
            Func<int, int> f = n =>
            {
                int c = 0;

                Task.Run(() =>
                {
                    for (; ; ++c)
                        Console.ReadKey();
                });

                Thread.Sleep(n * 1000);

                return c;
            };

            Console.WriteLine(f(10));

            Console.ReadLine();
        }
    }
}
\$\endgroup\$
  • \$\begingroup\$ @Bob I don't have it to check but it would be good if you can. Either way that's not part of the code for the submission anyway. \$\endgroup\$ – TheLethalCoder Aug 1 '17 at 8:18
  • \$\begingroup\$ Yea, sorry - I just realised your golfed version is significantly different from the full one. \$\endgroup\$ – Bob Aug 1 '17 at 8:18
  • \$\begingroup\$ @Bob Well it's not the golfed code is all the code from async to return c;} and including the namespace. \$\endgroup\$ – TheLethalCoder Aug 1 '17 at 8:19
  • \$\begingroup\$ I thought it was almost-runnable code at first... "since when did C# let you define functions outside of classes?" :P \$\endgroup\$ – Bob Aug 1 '17 at 8:24
  • \$\begingroup\$ @Bob Haha! Just the way I show the code, instead of adding a "The byte count also includes namespace System.Threading.Tasks{}. I prefer it this way. \$\endgroup\$ – TheLethalCoder Aug 1 '17 at 8:29
1
\$\begingroup\$

Python 3, 116 110 Bytes

import time
def f(t):
 s,l=time.time(),[]
 while True:
  l.append(input())
  if time.time()-s>t:return len(l)

This is my first post, so not sure if this follows the format correctly. Thanks for another few bytes Step

\$\endgroup\$
  • \$\begingroup\$ Welcome to PPCG! You can use while 1: instead of while True:. You can also move the import outside of the function to save a space, and do from time import* to get rid of time. twice. \$\endgroup\$ – Stephen Jul 31 '17 at 23:28
  • \$\begingroup\$ I wasn't sure if it was legal to have global state if I was going to turn in a function rather than a program. Thanks. I'll make those improvements. \$\endgroup\$ – Thoth19 Jul 31 '17 at 23:30
  • \$\begingroup\$ No problem! I believe the rule on functions is that they have to be reusable, but you can use global state as long as it works if the function is called multiple times. \$\endgroup\$ – Stephen Jul 31 '17 at 23:31
  • \$\begingroup\$ And I have once again demonstrated that I have no idea how to format things on SE. \$\endgroup\$ – Thoth19 Jul 31 '17 at 23:35
  • 1
    \$\begingroup\$ <s> instead of [s] and four spaces in front of each line of code \$\endgroup\$ – Stephen Jul 31 '17 at 23:37
1
\$\begingroup\$

C + gcc + Linux x86_64, 89 bytes

d[999];f(n){for(*d=0,d[1]=n;d[5]=1;*d+=read(0,d+5,4))if(!select(1,d+5,0,0,d+1))return*d;}

Pass the number of seconds in as the argument n. Press Enter to count a student (and don't press other keys before or during the function). Returns the number of students counted when time is up.

Extremely unportable, and easily the most evil code I've ever written. It makes assumptions about the size and layout of fd_set and struct timeval, and about the behavior of select.

Anyway, d[0] is the student counter, d[1] through d[4] is the struct timeval, and d[5] through d[260] is the fd_set. d[5] is also the unused scratch space passed to read, and then gets immediately reset to 1 for the next select call.

\$\endgroup\$
0
\$\begingroup\$

GameMaker Language, 49 45 bytes

Make sure you have default that uninitialized variables are treated as 0. Also, default fps is 30. We're looking for any key to be pressed and this does repeat if held down.

In step:

while s<argument0*30{a+=keyboard_check(1)++s}

Alternatively,

while(get_timer()<argument0*1000000)a+=keyboard_check(1)
\$\endgroup\$
  • \$\begingroup\$ What version of GameMaker are you using? In my 8.0 version it reports a syntax error for your first script, but changing s++ to ++s works properly. Also, you can save 3 bytes by replacing vk_up with literal number 38 because it is just a constant. \$\endgroup\$ – user72349 Jul 31 '17 at 19:30
  • \$\begingroup\$ @ThePirateBay Strange, I usually use studio but I have 8.0 somewhere. Probably ++s would work with both and it's the same bytecount. Also, thanks for pointing that out, I didn't realize you could substitute the number. Looks like vk_anykey is 1. Thanks for the tips! \$\endgroup\$ – Timtech Jul 31 '17 at 20:52
  • \$\begingroup\$ I tested it in studio and it doesn't report a syntax error. It is either GameMaker issue or maybe I don't know to use it properly. This is how it looks in 8.0 and this is how it looks in studio. \$\endgroup\$ – user72349 Jul 31 '17 at 22:19
  • \$\begingroup\$ @ThePirateBay Thanks for checking it out, I suppose it's some kind of bug in 8.0. Either way, changing it to ++s should make it compatible with both. \$\endgroup\$ – Timtech Jul 31 '17 at 23:40
0
\$\begingroup\$

JavaScript (Node.js), 112 111 bytes

t=>require('readline').createInterface(process.stdin).on('line',_=>k++,k=0,setTimeout(_=>console.log(k),t*1e3))

I don't think it can be golfed more because Node.js function names are pretty verbose.

\$\endgroup\$
0
\$\begingroup\$

Python 3, 88 bytes

Takes Enter as input and doesn't terminate.

from threading import*
l=[0]
Timer(int(input()),print,l).start()
while 1:input();l[0]+=1
\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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