40
\$\begingroup\$

Your task today is to implement a time limit for getting input, a task I've found rather annoying to achieve in most languages.

You will create a program function which prompts the user for input. Immediatly after the user supplies input, print the message input received and end execution/return. However, if the user waits for more than 10 seconds to provide input, output the message no input received and end execution/return.

Input must be from stdin (the console) or equivalent, not function or program arguments, however output can be either to stdout, your function's return value, or any other accepted output method.

You may ask for any amount of input, it can be a single character, a line, a word, or whatever method is shortest in your language as long as it waits for at least one character.

You must output as soon as the input is received, not after the 10 seconds have passed.

After 10 seconds have passed, you must end, you cannot continue waiting for input after no input received has been printed.

You may assume that input is not passed in the time between 10 seconds elapsing and text being printed to the screen, as this is an extremely small window. You may also assume that your language's builtin equivalent of sleep is consistently, absolutely perfect.

This is , fewest bytes wins!

\$\endgroup\$
  • 6
    \$\begingroup\$ +1 just for the nice touch to prevent golfing languages from using their dictionary. Oh, and great challenge too. \$\endgroup\$ – Adám Jun 8 '17 at 15:50
  • 1
    \$\begingroup\$ @Adám unless your language has a builtin read with timeout, I think the only good way to do this is OS/Thread magic, which most golfing languages can't do anyway. \$\endgroup\$ – Pavel Jun 8 '17 at 15:53
  • \$\begingroup\$ Now I have to rewrite my program. Was almost ready to post... ;-) \$\endgroup\$ – Adám Jun 8 '17 at 15:55
  • 1
    \$\begingroup\$ @TheLethalCoder You can assume your language's equivalent of sleep functions perfectly 100% of the time. \$\endgroup\$ – Pavel Jun 8 '17 at 16:16
  • 1
    \$\begingroup\$ @Lembik There you go, a Python answer. \$\endgroup\$ – Pavel Jun 9 '17 at 0:34

24 Answers 24

24
\$\begingroup\$

bash, 38 bytes

read -t10||a=no;echo $a input received

This uses the -t (timeout) option to bash's read, which causes it to fail and return a nonzero exit code if no input is given in the specified number of seconds.

\$\endgroup\$
  • 6
    \$\begingroup\$ It is supposed to say "(no )input recieved" which importantly obstructs golfing languages with dictionaries. \$\endgroup\$ – Adám Jun 8 '17 at 15:49
  • 8
    \$\begingroup\$ @Adám Actually that's a typo \$\endgroup\$ – Pavel Jun 8 '17 at 15:53
  • 7
    \$\begingroup\$ @Phoenix Noooo! \$\endgroup\$ – Adám Jun 8 '17 at 15:54
  • 1
    \$\begingroup\$ Why do a=no then $a? is there a purpose? EDIT I got it I didn't read the question properly \$\endgroup\$ – Felix Guo Jun 8 '17 at 17:50
12
\$\begingroup\$

Haskell, 97 89 bytes

import System.Timeout
timeout(10^7)getChar>>=putStr.(++"input received").maybe"no "mempty

If timeout times out it returns Nothing and Just Char (Char, because we're using getChar) otherwise. This return value is converted to "no " or "" by function maybe "no " mempty. Append "input received" and print.

Edit: @BMO suggested maybe and saved some bytes.

\$\endgroup\$
  • \$\begingroup\$ Doesnt seem to run correctly in ghci. \$\endgroup\$ – maple_shaft Jun 9 '17 at 16:59
  • \$\begingroup\$ @maple_shaft: Within ghci you have to bind g with let: let g Nothing="no ";g _="", then the function call timeout.... works fine for me. \$\endgroup\$ – nimi Jun 9 '17 at 18:47
  • 1
    \$\begingroup\$ You can replace g by maybe"no "(pure"") which is shorter and you can even inline it - saving you 6 bytes. \$\endgroup\$ – ბიმო Feb 21 '18 at 19:59
  • \$\begingroup\$ @BMO: Nice! mempty instead of (pure"") is even shorter. \$\endgroup\$ – nimi Feb 21 '18 at 21:23
  • \$\begingroup\$ Very nice, that's really clever! \$\endgroup\$ – ბიმო Feb 21 '18 at 21:30
11
\$\begingroup\$

POSIX C99, 71 63 bytes

main(){puts("no input received"+3*poll((int[]){0,1},1,10000));}

Ungolfed:

#include <unistd.h>
#include <poll.h>
#include <stdio.h>
int main()
{
  struct pollfd pfd; 
  pfd.fd = STDIN_FILENO; 
  pfd.events = POLLIN;  
  puts("no input received"+3*poll(&pfd,1,10000));
}

Since poll will return 1 in case of success, we multiply the result by 3 and shift the string accordingly. Then, we use the fact that struct pollfd has the following layout:

     struct pollfd {
     int    fd;       /* file descriptor */
     short  events;   /* events to look for */
     short  revents;  /* events returned */
 };

and that STDIN_FILENO is 0, POLLIN is 1 to replace pfd with int pfd[] = {0,1}, which we finally make a compound litteral (as allowed by C99).

\$\endgroup\$
  • 3
    \$\begingroup\$ You need to specify that this targets POSIX, as the poll.h header is not part of the C99 language standard. \$\endgroup\$ – Cody Gray Jun 9 '17 at 7:24
8
\$\begingroup\$

Applescript, 113

Applescript doesn't really do reading from STDIN. Hopefully a display dialog is acceptable here:

({"","no "}'s item((display dialog""default answer""giving up after 10)'s gave up as integer+1))&"input received"
\$\endgroup\$
6
\$\begingroup\$

APL (Dyalog), 41 40 bytes

'no input received'↓⍨{3*⍨⎕RTL←10::0⋄3⊣⍞}

This is an anonymous tacit function which needs a dummy argument to run.

'no input received' the full string

↓⍨ drop as many characters from the front of that as the number returned by the

{ anonymous explicit function ( denotes the argument)

⎕RTL←10 set Response Time Limit to ten seconds

3*⍨ raise that number (ten) to the power of three (a thousand means "all")

:: upon those exceptions (all),

  0 return 0

 try:

   get input

  3⊣ discard that and instead return 3

} end of function (note that the argument was never mentioned)

\$\endgroup\$
6
\$\begingroup\$

Perl, 74 67 bytes

$m="input received";$SIG{ALRM}=sub{die"no $m\n"};alarm 10;<>;say$m

Old Version

$m="input received";$SIG{ALRM}=sub{die "no $m\n"};alarm 10;<stdin>;say $m;

(Run via perl -M5.10.1 ...)

\$\endgroup\$
  • \$\begingroup\$ No trailing newline is necessary in output, so you can cut \n. \$\endgroup\$ – Pavel Jun 8 '17 at 16:25
  • 3
    \$\begingroup\$ Welcome to PPCG! \$\endgroup\$ – Pavel Jun 8 '17 at 16:27
  • \$\begingroup\$ Actually you don't need -M5.10.1. You can just substitute -e with -E. (if you needed -M5.10.1, you would have to add a penalty to your score) \$\endgroup\$ – Brad Gilbert b2gills Jun 8 '17 at 22:05
  • \$\begingroup\$ @Phoenix, the \n is there because of die's behavior: “If the last element of LIST does not end in a newline, the current script line number and input line number (if any) are also printed, and a newline is supplied.” So without it would display “no input received at -e line 1.”. But of course, it could be a literal line break in the string. Beside that, the spaces between die and say and their parameters are not needed. Same for the final ;. And <> is enough to read from standard input. \$\endgroup\$ – manatwork Jun 9 '17 at 9:28
  • 1
    \$\begingroup\$ If you eval the read from STDIN, you can avoid needing a die message. In fact, a runtime error works just as well: $SIG{ALRM}=sub{&0};alarm 10;say'no 'x!eval'<>','input received'. \$\endgroup\$ – primo Jun 10 '17 at 13:29
6
\$\begingroup\$

Perl 6,  72  66 bytes

my $s='input received';Promise.in(10).then:{say "no $s";exit};get;say $s

Try it with no input
Try it with input

my$s='input received';start {sleep 10;say "no $s";exit};get;say $s

Try it with no input
Try it with input

my $s = 'input received'; # base message

start {         # create a Promise with a code block
                # that is run in parallel
  sleep 10;     # delay for 10 seconds
  say "no $s";  # say 「no input received」
  exit          # exit from the process
}

get;            # get a line from the input
say $s          # say 「input received」
\$\endgroup\$
  • 1
    \$\begingroup\$ "my ess is input recieved -- promise in 10 then say 'no ess' and exit or get say 'ess'" \$\endgroup\$ – cat Jun 9 '17 at 11:33
  • \$\begingroup\$ Can you remove the space between start and {? \$\endgroup\$ – Pavel Jun 12 '17 at 20:38
  • \$\begingroup\$ @Phoenix That would be parsed as associative indexing on a sigilless variable named start, so no. \$\endgroup\$ – Brad Gilbert b2gills Jun 12 '17 at 23:01
  • \$\begingroup\$ Your TIO links appear not to work anymore. \$\endgroup\$ – Pavel Feb 20 '18 at 18:18
  • \$\begingroup\$ @Pavel, Fixed, just had to make the dummy test class a subtype of IO::Handle and call .new on it \$\endgroup\$ – Brad Gilbert b2gills Feb 20 '18 at 20:02
5
\$\begingroup\$

C#, 180 171 148 131 bytes

()=>{var t=new System.Threading.Thread(()=>{System.Console.ReadKey();});t.Start();return(t.Join(10000)?"":"no ")+"input recieved";}

Saved 17 bytes thanks to @VisualMelon.

Full/Formatted version:

class P
{
    static void Main()
    {
        System.Func<string> f = () =>
        {
            var t = new System.Threading.Thread(() =>
            {
                System.Console.ReadKey();
            });
            t.Start();

            return (t.Join(10000) ? "" : "no ") + "input recieved";
        };

        System.Console.WriteLine(f());
        System.Console.ReadLine();
    }
}
\$\endgroup\$
  • \$\begingroup\$ Why namespace and not a using directive? \$\endgroup\$ – Pavel Jun 8 '17 at 16:37
  • \$\begingroup\$ @Phoenix they would need a namespace anyway so they save all the bytes of the using \$\endgroup\$ – LiefdeWen Jun 8 '17 at 21:27
  • \$\begingroup\$ Why did you save the crucial part as an Action and execute it afterwards? I can't really see the question specifying this. \$\endgroup\$ – Snowfire Jun 9 '17 at 5:50
  • 1
    \$\begingroup\$ Can save quite a bit by using the return value from Thread.Join(int), (rid of c, lose braces, etc. etc.): var t=new System.Threading.Thread(()=>System.Console.ReadKey());t.Start();return(t.Join(10000)?"":"no ")+"input recieved"; (VB.NET already seems to do this) \$\endgroup\$ – VisualMelon Jun 9 '17 at 9:21
  • 1
    \$\begingroup\$ @TaylorScott I can do 1e4 but that is a double and I'd need an int so I'd have to do (int)1e4 :( Nice idea though \$\endgroup\$ – TheLethalCoder Jun 13 '17 at 8:15
5
\$\begingroup\$

TI-BASIC, 84 77 bytes

-7 thanks to @kamoroso94

:startTmr→T         //Start Timer, 5 bytes
:Repeat checkTmr(T)=10 or abs(int(.1K)-8)≤1 and 1≥abs(3-10fPart(.1K  //Loop until the timer is 10 seconds or a number key is pressed, 32 bytes
:getKey→K           //get key code, 4 bytes
:End                //end loop, 2 bytes
:"NO INPUT RECEIVED //Push string "NO INPUT RECEIVED" to Ans, 18 bytes
:If K               //If input was received, 3 bytes
:Disp sub(Ans,3,15  //Diplay "INPUT RECEIVED", 9 bytes
:If not(K           //If no input, 3 bytes
:Ans                //Display "NO INPUT RECEIVED", 1 byte

Waits until a number is pressed.

I am trying to figure out how to golf the sequence {72,73,74,82,83,84,92,93,94}. It is taking up a lot of space.

\$\endgroup\$
  • \$\begingroup\$ If you want to wait for just any key, then Repeat K or 10=checkTmr(T would do. \$\endgroup\$ – bb94 Jun 11 '17 at 5:26
  • \$\begingroup\$ Also, the last 4 lines could be shortened to :4-3not(K:sub("NO INPUT RECEIVED",Ans,18-Ans \$\endgroup\$ – bb94 Jun 11 '17 at 5:29
  • 1
    \$\begingroup\$ @bb94 I don't really want to wait for just any key, since not all of those would actually input a character. It would be like waiting for the Shift key on a computer. Also, shortening the last 4 lines with your method actually gives the same byte count as mine. I like your method, though. \$\endgroup\$ – Scott Milner Jun 12 '17 at 15:06
  • \$\begingroup\$ You could check for any key that isn't 21 or 31. \$\endgroup\$ – bb94 Jun 12 '17 at 21:05
  • \$\begingroup\$ After or in your repeat statement, use this instead for -7 bytes: abs(int(.1K)-8)≤1 and 1≥abs(3-10fPart(.1K \$\endgroup\$ – kamoroso94 Feb 21 '18 at 22:56
4
\$\begingroup\$

NodeJS, 105 103 101 bytes

-2 bytes thanks to @apsillers
-2 bytes by moving console.log() into exit()

with(process)stdin.on('data',r=x=>exit(console.log((x?'':'no ')+'input received'))),setTimeout(r,1e4)

Run by saving to a file and running it with node or run it straight from the command line by doing node -e "<code>"

\$\endgroup\$
  • \$\begingroup\$ @apsillers Yup, good catch. \$\endgroup\$ – Justin Mariner Jun 8 '17 at 17:19
  • \$\begingroup\$ @apsillers I was about to edit again to actually move the console.log() call into the parameter of exit(). That's two less, now. \$\endgroup\$ – Justin Mariner Jun 8 '17 at 17:24
4
\$\begingroup\$

JavaScript (ES6) + HTML, 86 84 82 79+11 = 97 95 93 90 bytes

setTimeout(oninput=_=>i.remove(alert(`${i.value?"":"no "}input received`)),1e4)
<input id=i
  • 2 bytes saved thanks to apsillers pointing out that I'm dumb!

Try it

Requires a closing > on the input in order to work in a Snippet.

setTimeout(oninput=_=>i.remove(alert(`${i.value?"":"no "}input received`)),1e4)
<input id=i>

\$\endgroup\$
  • \$\begingroup\$ 1e5 is 100,000 or 100 seconds, 1e4 is 10 seconds \$\endgroup\$ – PunPun1000 Jun 9 '17 at 13:41
  • \$\begingroup\$ Oops! Well spotted, thanks, @PunPun1000 \$\endgroup\$ – Shaggy Jun 9 '17 at 13:42
  • \$\begingroup\$ Wouldn't it be shorter to write 10 instead of 1e4? \$\endgroup\$ – musicman523 Jun 10 '17 at 23:20
  • \$\begingroup\$ @musicman523, 10 would be 10 milliseconds, the challenge challenge specifically says 10 seconds, which is 10000 milliseconds, hence 1e4. \$\endgroup\$ – Shaggy Jun 10 '17 at 23:27
  • \$\begingroup\$ My bad, forgot that 10 != 1e4 because I'm a fool \$\endgroup\$ – musicman523 Jun 10 '17 at 23:52
3
\$\begingroup\$

VB.Net - 174 bytes

Module M
Sub Main()
Dim t=New Threading.Thread(Sub()Console.Read()):t.Start():Console.WriteLine(If(t.Join(10000),"","no ") & "input received"):End
End Sub
End Module

COBOL version coming tomorrow ;-)

\$\endgroup\$
  • 3
    \$\begingroup\$ I'm not sure what the advantage is of combining lines with :. That takes the same number of bytes as a line break, so it just decreases readability without improving the golf score. \$\endgroup\$ – Cody Gray Jun 9 '17 at 7:25
  • \$\begingroup\$ @CodyGray I believe that the : line break substitution may be so that the treading call may be declared inline without repeating - but that said I am not positive, my main language is VBA which does not support threading or reading from the <strike>console</strike> immediate window asside from at the time of function definition or calling :P \$\endgroup\$ – Taylor Scott Jun 13 '17 at 4:24
3
\$\begingroup\$

Go, 149 bytes

package main
import(
."fmt"
."time"
."os"
)
func main(){
o:="input received"
go func(){Sleep(1e10)
Print("no "+o)
Exit(0)}()
i:=""
Scan(&i)
Print(o)}
\$\endgroup\$
3
\$\begingroup\$

AHK, 67 65 bytes

2 bytes saved by Blauhirn

InputBox,o,,,,,,,,,10
s:=ErrorLevel?"no ":
Send %s%input received

AHK has a built-in timeout for input boxes.
I tried to get clever and use !o instead of ErrorLevel but that fails if the user inputs a falsey value.
Almost half of the answer is just the command names and fixed text.

\$\endgroup\$
  • 1
    \$\begingroup\$ What are all the commas for? \$\endgroup\$ – Pavel Jun 8 '17 at 15:55
  • \$\begingroup\$ @Phoenix Probably eliding arguments to InputBox \$\endgroup\$ – Adám Jun 8 '17 at 15:55
  • \$\begingroup\$ @Phoenix Timeout is almost the last parameter: InputBox, OutputVar [, Title, Prompt, HIDE, Width, Height, X, Y, Font, Timeout, Default] \$\endgroup\$ – Engineer Toast Jun 8 '17 at 15:57
  • \$\begingroup\$ two chars shorter: s:=errorLevel?"no ": \$\endgroup\$ – Blauhirn Jun 9 '17 at 11:58
  • \$\begingroup\$ @Blauhirn Gah! I'm an idiot. Thanks. \$\endgroup\$ – Engineer Toast Jun 9 '17 at 15:37
3
\$\begingroup\$

Python3, 100 89 83 71 bytes

import pty
print("no input received"[3*any(pty.select([0],[],[],10)):])

First try at golfing.

-4 for any(), -7 for slicing, thanks @user2357112!

-6, get select() from pty instead of select.

\$\endgroup\$
  • \$\begingroup\$ You can cut some bytes out by slicing a "no input received" string: "no input received"[3*bool(...):]. \$\endgroup\$ – user2357112 Jun 9 '17 at 16:37
  • \$\begingroup\$ You can also use any(...) instead of bool(...[0]). \$\endgroup\$ – user2357112 Jun 9 '17 at 16:43
  • \$\begingroup\$ -New User: "on Windows it throws ModuleNotFoundError: No module named 'termios'" \$\endgroup\$ – FantaC Jan 10 '18 at 4:29
  • \$\begingroup\$ The pty module is only available on linux platforms, but I'm only using it because its name is short and it makes select available. Version 2 probably works better on Windows. \$\endgroup\$ – Seth Jan 10 '18 at 23:20
3
\$\begingroup\$

PowerShell, 110 bytes

$s1=date;while(![console]::KeyAvailable-and($i=((date)-$s1).seconds-lt10)){}
"{0}input received"-f(,'no ')[$i]
\$\endgroup\$
3
\$\begingroup\$

Python 3, 158 bytes

import os,threading as t,time
def k(t=10):time.sleep(t);print("No input received"[(10-t)//3:]);os.kill(os.getpid(),t)
t.Thread(None,k).start()
if input():k(0)

I tried running Seth's Python 3 answer but on Windows it throws ModuleNotFoundError: No module named 'termios', and since I can't comment on his answer about it, I decided to instead come up with a solution that should be platform independent.

It's my first time golfing so I'm sure it could be improved.

\$\endgroup\$
  • 2
    \$\begingroup\$ Welcome to PPCG! \$\endgroup\$ – Steadybox Jan 10 '18 at 2:09
2
\$\begingroup\$

Tcl, 99 bytes

after 10000 {set () no}
vwait [fileevent stdin r {gets stdin (x)}]
puts [lappend () input received]
\$\endgroup\$
2
\$\begingroup\$

SmileBASIC 3, 74 bytes

"Accepts input" by waiting for any button press (that should count as input.)

M=MAINCNT@L
N=MAINCNT-M>599CLS?"NO "*N;"INPUT RECEIVED
ON N+BUTTON()GOTO@L
\$\endgroup\$
  • \$\begingroup\$ Output should be "(no) input received", not "INPUT (NOT) RECEIVED" \$\endgroup\$ – Pavel Jul 28 '18 at 7:07
2
\$\begingroup\$

Scratch 2/3.x, 41 points (Explanation)

Impatient timer

1: When GF clicked

1: ask [] and wait

1 + 14 chars: say [input received]

1: stop [all v] (note: since "all" was its default setting I counted the block as 1)

1 + 2 digits: wait (10) seconds

1 + 17 chars: say [no input received]

1: stop [all v]

\$\endgroup\$
  • \$\begingroup\$ Welcome to PCG! \$\endgroup\$ – Rahul Bharadwaj Feb 5 at 6:29
1
\$\begingroup\$

><>, 43 + 6 = 49 bytes

a/!/i0(?\~"input recieved"r>o<
o "\?:-1/r"n

Try it online!

+5 for the -t.08 flag, which sets the tick to 0.08 seconds, and +1 for the a flag, which counts whitespace and skipped instructions as ticks.

The program checks for input about once every second, and exits the loop if input is detected. If input is not received, it exits the loop from the bottom, appending no to the beginning of the string. The initial / is to ensure that the last check for input is exactly on the 10 second mark.

It then takes about 5-6 seconds to print the string itself.

\$\endgroup\$
  • \$\begingroup\$ You can use a single flag, -at.08 to save a byte. \$\endgroup\$ – Pavel Jan 10 '18 at 4:22
  • \$\begingroup\$ @Pavel, Thanks! \$\endgroup\$ – Jo King Jan 10 '18 at 4:25
1
\$\begingroup\$

Java 1.4+, 284 bytes

import static java.lang.System.*;public class X{public static void main(String[]x){new Thread(){public void run(){try{Thread.sleep(10000L);}catch(Exception e){}out.print("no input recieved");exit(0);}}.start();new java.util.Scanner(System.in).nextLine();out.print("input recieved");}}

Ungolfed:

import static java.lang.System.*;

public class InputAndWait {
    public static void main(String[] x) {
        new Thread() {
            public void run() {
                try {
                    Thread.sleep(10000L);
                } catch (Exception e) {
                }
                out.print("no input recieved");
                exit(0);
            }
        }.start();
        new java.util.Scanner(System.in).nextLine();
        out.print("input recieved");
    }
}

Please don't suggest Version-specific Java improvements, this is a generic Java answer that works in all currently stable Java Environments (1.4 and above).


Very freaking wordy... The catch is required, can't throw it. System import shaves off like 5 bytes... Overloading is also wordy, so it ends up a wordy poorly-golfed-looking mess.

\$\endgroup\$
  • \$\begingroup\$ Does it have to be 10000L and not 10000? I thought ints cast to longs automatically. \$\endgroup\$ – Pavel Feb 21 '18 at 19:02
1
\$\begingroup\$

Julia 0.6, 78 bytes

Longer than I expected. See comments for "no input recieved" TIO link.

s="input recieved"
Timer(x->(show("no "*s);exit()),10)
readline(STDIN)
show(s)

Try it online!

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

SmileBASIC, 74 73 bytes

M=MAINCNT
WHILE!I*M>MAINCNT-600I=INKEY$()>"
WEND?"no "*!I;"input received

Takes 1 character of input.

And a 39 byte solution which probably isn't valid (doesn't actually accept text input, just has an OK button that you can press)

?"no "*!DIALOG("",,,10);"input received
\$\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.