Нетерпляче чекайте введення


39

Сьогодні ваше завдання - реалізувати обмеження часу для отримання інформації, яку я вважаю досить прикрою для більшості мов.

Ви створите функцію програми, яка запитує користувача на введення. Одразу після того, як користувач подасть введення, надрукуйте повідомлення input receivedта закінчіть виконання / повернення. Однак якщо користувач чекає більше 10 секунд, щоб надати вхід, виведіть повідомлення no input receivedта закінчіть виконання / повернення.

Вхід повинен бути з stdin(консолі) або еквівалентного, а не аргументу функції або програми, однак вихід може бути або stdoutповерненим значенням вашої функції, або будь-яким іншим прийнятим способом виведення.

Ви можете запитати будь-яку кількість введення, це може бути один символ, рядок, слово або будь-який метод, який є найкоротшим у вашій мові, доки він чекає хоча б одного символу.

Ви повинні вивести, як тільки отриманий вхід, а не через 10 секунд.

Після того, як пройшло 10 секунд, ви повинні закінчитись, ви не можете продовжувати чекати введення даних після того, no input receivedяк буде надруковано.

Ви можете припустити, що введення не проходить у проміжок часу між 10 секундами та надрукуванням тексту на екрані, оскільки це надзвичайно маленьке вікно. Ви також можете припустити, що ваш еквівалент мови sleepє постійно, абсолютно ідеальним.

Це , найменше виграш байтів!


6
+1 лише для приємного дотику, щоб уникнути використання словниками мов для гольфу. О, і великий виклик теж.
Адам

1
@ Adám, якщо ваша мова не має вбудованого читання з таймаутом, я думаю, що єдиний хороший спосіб зробити це магія OS / Thread, яку більшість мов для гри в гольф все одно не можуть зробити.
Павло

Тепер мені доведеться переписати свою програму. Майже готовий до публікації ... ;-)
Адама

1
@TheLethalCoder Ви можете вважати, що еквівалент sleepфункцій вашої мови ідеально 100% часу.
Павло

1
@Lembik Ось ти, відповідь Python.
Павло

Відповіді:


24

баш, 38 байт

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

При цьому використовується параметр -t(timeout) для того, щоб башти read, що призводить до виходу з ладу і повернення ненульового коду виходу, якщо не вказано вхід у вказану кількість секунд.


6
Потрібно сказати "(не) введення rec ie ved", що важливо перешкоджає мовам гольфу словниками.
Adám

8
@ Adám Насправді це помилка
Павло

7
@Phoenix Noooo!
Адам

1
Чому a = no тоді $ a? чи є мета? EDIT Я зрозумів, що питання не прочитав належним чином
Фелікс Го

12

Haskell, 97 89 байт

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

Якщо timeoutраз з нього повертається Nothingі Just Char( Char, тому що ми використовуємо getChar) в іншому випадку. Це повернене значення перетворюється на "no "або ""за функцією maybe "no " mempty. Додайте "input received"та роздрукуйте.

Редагувати: @BMO запропонував maybeі зберегло кілька байтів.


Здається, не працює правильно в ghci.
maple_shaft

@maple_shaft: В GHCI ви повинні пов'язувати gз let: let g Nothing="no ";g _="", то виклик функції timeout....відмінно працює для мене.
німі

1
Ви можете замінити gна maybe"no "(pure"")який коротший і навіть можете вбудовувати його - заощаджуючи 6 байт.
ბიმო

@BMO: Приємно! memptyзамість того (pure"")ще коротше.
німі

Дуже приємно, це справді розумно!
ბიმო

11

POSIX C99, 71 63 байт

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

Безголовки:

#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));
}

Оскільки pollу випадку успіху повернеться 1, результат помножимо на 3 і відповідно змістимо рядок. Потім ми використовуємо той факт, що struct pollfdмає такий макет:

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

і що STDIN_FILENOє 0, POLLINце 1замінити pfdз int pfd[] = {0,1}, що ми , нарешті , зробити з'єднання litteral (як дозволено C99).


3
Вам потрібно вказати, що це націлено на POSIX, оскільки poll.hзаголовок не є частиною мовного стандарту C99.
Коді Грей

8

Яблукопис, 113

Applescript насправді не читає з STDIN. Сподіваємось, а display dialogтут прийнятний:

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

6

APL (Dyalog) , 41 40 байт

'no input received'↓⍨{3*⍨⎕RTL10::03⊣⍞}

Це анонімна негласна функція, для якої потрібен фіктивний аргумент .

'no input received' повний рядок

↓⍨ викиньте стільки символів з передньої частини, скільки число, повернене знаком

{ анонімна явна функція ( позначає аргумент)

⎕RTL←10 встановіть R esponse T ime L imit на десять секунд

3*⍨ підняти це число (десять) до сили три (тисяча означає "все")

:: за тими винятками (усі),

  0 повернути 0

 спробуйте:

   отримати вхід

  3⊣ відкиньте це і замість цього поверніть 3

}кінець функції (зауважте, що аргумент ніколи не згадувався)


6

Perl , 74 67 байт

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

Стара версія

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

(Запустити через perl -M5.10.1 ...)


Немає потрібного нового рядка у виході, тому ви можете вирізати \n.
Павло

3
Ласкаво просимо до PPCG!
Павло

Насправді вам це не потрібно -M5.10.1. Ви можете просто замінити -eз -E. (якщо вам потрібно -M5.10.1, вам доведеться додати штраф до свого рахунку)
Бред Гілберт b2gills

@Phoenix, \nце є через dieповедінку: "Якщо останній елемент СПИСОКУ не закінчується новим рядком, також надрукується поточний номер рядка сценарію та номер вхідного рядка (якщо такий є) і надається новий рядок". Тож без нього не відображатиметься "жоден вхід, отриманий у рядку -e 1". Але звичайно, це може бути буквальний розрив рядка в рядку. Крім того, простір між dieта sayі їх параметри не потрібні. Те саме для фіналу ;. І <>цього достатньо для читання зі стандартного вводу.
манатура

1
Якщо ви evalчитаєте з STDIN, ви можете уникнути необхідності dieповідомлення. Насправді, помилка у час виконання робіт точно так же: $SIG{ALRM}=sub{&0};alarm 10;say'no 'x!eval'<>','input received'.
прима

6

Perl 6 ,  72  66 байт

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

Спробуйте без введення
Спробуйте з введенням

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

Спробуйте без введення
Спробуйте з введенням

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」

1
"мій ess отриманий вхід - обіцяйте через 10, тоді скажіть" no ess "та вийдіть або скажіть" ess ""
cat

Чи можете ви видалити пробіл між startі {?
Павло

@Phoenix Це було б розібрано як асоціативне індексування без змінної без змінної назви start, так що ні.
Бред Гілберт b2gills

Ваші посилання TIO більше не працюють.
Павло

@Pavel, виправлено, просто довелося зробити манекенний тестовий клас підтипом IO :: Handle та зателефонувати .newна нього
Бред Гілберт b2gills

5

C #, 180 171 148 131 байт

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

Збережено 17 байт завдяки @VisualMelon.

Повна / відформатована версія:

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();
    }
}

Чому namespaceі не usingдиректива?
Павло

@Phoenix їм все одно знадобиться простір імен, тому вони using
збережуть

Чому ви зберегли найважливішу частину як дії та виконали її після цього? Я не можу реально побачити питання, яке це визначає.
Сніжної пожежі

1
Можна трохи заощадити, використовуючи значення, що повертається Thread.Join(int), (позбутися c, втратити дужки тощо): var t=new System.Threading.Thread(()=>System.Console.ReadKey());t.Start();return(t.Join(10000)?"":"no ")+"input recieved";(VB.NET, здається, це робить)
VisualMelon

1
@TaylorScott Я можу зробити, 1e4але це є, doubleі мені це потрібно, intтому я повинен був би зробити (int)1e4:( Хороша ідея, хоча
TheLethalCoder

5

TI-BASIC, 84 77 байт

-7 завдяки @ 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

Зачекає, поки число буде натиснене.

Я намагаюся розібратися, як грати в послідовність {72,73,74,82,83,84,92,93,94}. Це займає багато місця.


Якщо ви хочете чекати будь-якого ключа, то Repeat K or 10=checkTmr(Tзробите це.
bb94

Також останні 4 рядки можна було б скоротити до:4-3not(K:sub("NO INPUT RECEIVED",Ans,18-Ans
bb94

1
@ bb94 Мені дуже не хочеться чекати будь-якої клавіші, оскільки не всі з них насправді вводять символ. Це було б як чекати Shiftключа на комп’ютері. Крім того, скорочення останніх 4 рядків з вашим методом фактично дає такий самий підрахунок байтів, що і мій. Мені подобається твій метод.
Скотт Мілнер

Ви можете перевірити наявність будь-якого ключа, якому немає 21 або 31.
bb94

Після того, як orу своєму повторному висловлюванні використовуйте це замість -7 байтів:abs(int(.1K)-8)≤1 and 1≥abs(3-10fPart(.1K
kamoroso94

4

NodeJS, 105 103 101 байт

-2 байти завдяки @apsillers
-2 байтам, переїхавши console.log()вexit()

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

Запустити, збереживши у файл і запустивши його з вузлом, або запустити його прямо з командного рядка, виконавши node -e "<code>"


@apsillers Так, хороший улов.
Джастін Марінер

@apsillers Я збирався знову відредагувати, щоб фактично перемістити console.log()виклик у параметр exit(). Це на два менше.
Джастін Марінер

4

JavaScript (ES6) + HTML, 86 84 82 79 + 11 = 97 95 93 90 байт

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

Спробуй це

Потрібно закриття >на inputдля роботи в сниппет.

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


1e5 - 100 000 або 100 секунд, 1e4 - 10 секунд
PunPun1000

На жаль! Добре помічений, спасибі, @ PunPun1000
Shaggy

Чи не було б коротше писати 10замість 1e4?
музикант523

@ musicman523 10буде 10 мілісекунд, виклик виклику конкретно говорить про 10 секунд , а це 10000 мілісекунд, отже 1e4.
Кудлатий

Мій поганий, забув це, 10 != 1e4тому що я дурень
musicman523

3

VB.Net - 174 байти

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 приходить завтра ;-)


3
Я не впевнений, у чому перевага поєднання ліній :. Це займає таку ж кількість байтів, як і перерва рядка, тому це просто зменшує читабельність без поліпшення оцінки гольфу.
Коді Грей

@CodyGray Я вважаю, що :заміна розриву рядка може бути такою, що тренд-дзвінок може бути оголошений вбудованим, не повторюючись - але це сказав, що я не позитивний, моя основна мова - VBA, яка не підтримує нарізку чи читання з консолі <strike> < / страйк> негайне вікно надати на момент визначення функції або виклику: P
Тейлор Скотт

3

Ідіть, 149 байт

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)}

3

AHK , 67 65 байт

2 байти, збережені Blauhirn

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

AHK має вбудований тайм-аут для вхідних полів.
Я намагався бути розумним і використовувати !oзамість цього, ErrorLevelале це не вдається, якщо користувач вводить значення фальси.
Майже половина відповіді - це лише назви команд та закріплений текст.


1
Для чого всі коми?
Павло

@Phoenix Можливо, схильні аргументи до InputBox
Adám

@Phoenix Timeout- це майже останній параметр:InputBox, OutputVar [, Title, Prompt, HIDE, Width, Height, X, Y, Font, Timeout, Default]
Інженер Тост

два символи коротше:s:=errorLevel?"no ":
phil294

@Blauhirn Gah! Я ідіот. Спасибі.
Інженер Тост

3

Python3, 100 89 83 71 байт

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

Спочатку спробуйте в гольфі.

-4 за any(), -7 за нарізку, дякую @ user2357112!

-6, отримати select()від ptyзамість select.


Ви можете вирізати деякі байти шляху нарізки "no input received"рядки: "no input received"[3*bool(...):].
user2357112 підтримує Моніку

Ви також можете використовувати any(...)замість bool(...[0]).
user2357112 підтримує Моніку

-Новий користувач: "у Windows він кидає ModuleNotFoundError: Немає модуля з назвою" termios ""
FantaC

ptyМодуль доступний тільки на платформах Лінукса, але я тільки використовувати його , тому що його ім'я коротко , і це робить selectдоступно. Версія 2, ймовірно, працює краще в Windows.
Сет

3

PowerShell, 110 байт

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

3

Python 3, 158 байт

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)

Я спробував запустити відповідь Seth's Python 3, але в Windows це кидає ModuleNotFoundError: No module named 'termios', і оскільки я не можу коментувати його відповідь про це, я вирішив замість цього придумати рішення, яке повинно бути незалежним від платформи.

Це мій перший гольф, тому я впевнений, що його можна було б покращити.


2
Ласкаво просимо до PPCG!
Steadybox


2

SmileBASIC 3, 74 байти

"Приймає введення", чекаючи будь-якого натискання кнопки (що має враховуватися як вхід.)

M=MAINCNT@L
N=MAINCNT-M>599CLS?"NO "*N;"INPUT RECEIVED
ON N+BUTTON()GOTO@L

Вихід повинен бути "(не) вхід отриманий", а не "Вхід (НЕ) ВИХОВАНО"
Павло

2

Scratch 2 / 3.x, 41 бал ( Пояснення )

Нетерплячий таймер

1: Коли GF клацнув

1: запитати [] і чекати

1 + 14 символів: сказати [вхід отримано]

1: стоп [all v] (зауважте: оскільки значення "за замовчуванням" було за замовчуванням, я вважав блок 1)

1 + 2 цифри: зачекайте (10) секунд

1 + 17 символів: сказати [вхід не отримано]

1: зупинка [всі v]


Ласкаво просимо до PCG!
Рахул Бхарадвай

1

> <> , 43 + 6 = 49 байт

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

Спробуйте в Інтернеті!

+5 для -t.08прапора, який встановлює галочку на 0,08 секунди, і +1 для aпрапора, який рахує пробіл та пропущені інструкції як кліщі.

Програма перевіряє введення приблизно раз на секунду та виходить з циклу, якщо вхід виявлений. Якщо вхід не отримано, він виходить з циклу знизу, додаючи noдо початку рядка. Початкова /полягає в тому, щоб остання перевірка вводу була точно на позначці 10 секунд.

Потім потрібно приблизно 5-6 секунд для друку самого рядка.


Ви можете використовувати один прапор, -at.08щоб зберегти байт.
Павло

@Pavel, спасибі!
Jo King

1

Java 1.4+, 284 байти

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");}}

Безголовки:

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");
    }
}

Будь ласка, не пропонуйте конкретні для Версії покращення Java, це загальна відповідь на Java, яка працює у всіх стабільних на даний момент середовищах Java (1.4 і вище).


Дуже вигадливий багатослівний ... Улов потрібен, його не можна кидати. Системний імпорт голиться, як 5 байт ... Перевантаження також є багатозначною, так що це закінчується багатословним поганим походом в гольф.


Чи має бути, 10000Lа ні 10000? Я подумав, що інтерни передаються автоматично.
Павло

1

Джулія 0,6 , 78 байт

Довше, ніж я очікував. Дивіться коментарі до посилання TIO "не отримано вхідних даних".

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

Спробуйте в Інтернеті!


1
Він не блокується в TIO, оскільки він читає з файлу. Він потрапляє на EOF і закінчується миттєво. Якщо ви передасте
Павло

0

SmileBASIC, 74 73 байт

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

Бере 1 символ введення.

І рішення на 39 байт, яке, ймовірно, недійсне (насправді не приймає текст, просто є OKкнопка, яку можна натиснути)

?"no "*!DIALOG("",,,10);"input received
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.