Часовий відлуння


38

Фон

echoПрограма настільки акуратно. Ви можете сказати що завгодно, і це повторює ваші слова щоразу! Як класно це! Розчаровуючи, він повторює введення все відразу, незалежно від швидкості набору тексту, що не дуже реально. Треба буде це виправити.

Завдання

Ваша програма бере свій внесок від STDIN або найближчого еквівалента. Він повинен читати рядки від користувача один за одним, можливо, відображаючи деякий запит, поки вони не вводять порожній рядок. Після цього він надрукує рядки до STDOUT або найближчого еквівалента в тому ж порядку, як вони були задані. Останній (порожній) рядок не друкується, і в останньому надрукованому рядку не потрібно мати зворотного нового рядка.

Крім того, програма повинна зберігати інтервали часу між кожним рядком: якщо xдля введення рядка потрібні користувачеві секунди, xдля друку програми потрібні секунди. Це стосується і першого, і останнього рядків; порожній рядок не друкується, але програма все одно чекає перед завершенням.

Приклад

Ось приклад сесії з програмою. Усі дії, які не створюють текст, описані в дужках, а підказка (необов'язково) відображається як >.

[begin program]
> fhtagn[enter; 1.48s passed since starting program]
> yum yum[enter; 3.33s passed since previous enter]
> so cool![enter; 2.24s passed since previous enter]
> [enter; 0.23s passed since previous enter]
[wait 1.48s]fhtagn
[wait 3.33s]yum yum
[wait 2.24s]so cool!
[wait 0.23s, then end program]

Без дій сеанс виглядає так:

> fhtagn
> yum yum
> so cool!
> 
fhtagn
yum yum
so cool!

Правила та підрахунок балів

Час очікування повинен бути точним до 0,01 секунди (на практиці, якщо середній чоловік не може визначити різницю, у вас все добре). Виграє найменший кількість байтів, а стандартні лазівки заборонені. Якщо ваша мова має вбудовану функцію саме для цього завдання, ви можете не використовувати її.


9
Наступний крок: Гольф - програма, яка грає в основну ритм-гру: P
Sp3000

Чи можемо ми нехтувати тим часом, який програма займає для виведення символів? Я маю на увазі, якщо я можу виміряти, що моїй мові потрібно 0,1 секунди для виведення знака, чи варто це враховувати? Повне розкриття інформації я планую використовувати для перекладу термін "<> перекладачів; в цьому випадку, чи можу я мати цикл, що минає вхідний час, а потім ігнорувати час, який минув мій цикл відображення?
Аарон

1
@AaronGOUZIT Я дозволю це, якщо ви будете послідовні: або часові інтервали між моментами, коли ваша програма починає друкувати рядок, приймаються у користувача, АБО час очікування між закінченням друку рядка та початком друку наступні - всі взяті у користувача.
Згарб

1
@TessellatingHeckler Останнє; див. приклад сеансу.
Згарб

1
@KritixiLithos Я використовував лише праву руку yum yum, яка була досить громіздкою.
Zgarb

Відповіді:


15

CJam, 45 41 39 36 34 байт

{eslN1$}g;es](es-fm3/{){_es>}g;o}/

Це, звичайно, не має сенсу в онлайн-перекладачі, але це працює в інтерпретаторі Java.

Він не відображає підказку.

Пояснення

{        e# Do while... (popping the condition from the stack)
  es     e#   Get the current timestamp.
  l      e#   Wait for a line to be entered and read it.
  N      e#   Push a linefeed.
  1$     e#   Copy the line we read - this terminates if the line is empty, because
         e#   empty strings/arrays are falsy.
}g
;        e# Discard the last linefeed (the one after the empty input).
es       e# Push the current timestamp (corresponding to the last, empty, input).
]        e# Wrap everything in an array. This is now a flat array containing:
         e#   - The initial timestamp.
         e#   - Three elements for each line: the line, a linefeed, the timestamp.
         e#   - Two elements for the last line: the empty string and the timestamp.
(        e# Pull off the initial time.
es-      e# Subtract the current time, which gives (minus) the difference between
         e# when a line was entered and when it should be printed back.
fm       e# This maps "minus that value" onto each element in the array. Now the lines
         e# and linefeeds are strings (arrays) - so minus is set difference, but they
         e# only contain characters, not any integers (like the difference value), so
         e# none of the strings will be affected.
         e# The timestamps on the other hand will be incremented by the time difference
         e# between reading and printing, giving the time at which each line should be
         e# printed back.
3/       e# Split the array into chunks of 3 (where the remaining two elements are
         e# just grouped as a pair).
{        e# For each of those chunks...
  )      e#   Pull off the timestamp.
  {      e#   Do while... (popping the condition from the stack)
    _    e#     Duplicate the target time.
    es>  e#     Check if it's still greater than the current time.
  }g
  ;o     e# Discard the target time and print the rest of the current chunk, which will
         e# automatically be flattened/concatenated into a single string.
}/

9

JavaScript, 119 112 байт

k=(d=Date.now)(i=j=[]);do{i[++j]=[prompt(),d()-k]}while(i[j][0]);i.map(a=>setTimeout(b=>console.log(a[0]),a[1]))

Сподіваючись знайти ще кілька байтів, щоб вирізати.


1
Ви можете зберегти пару байтів за допомогою j=i=[]( ++все одно буде працювати!) Також, вам whileне потрібно, !=''оскільки це хибність! Так розчарований я пропустив map! +1
Дом Гастінгс

1
Гарна примітка !=''. Був стурбований, якщо вхід був 0, але, здається, справляється з цим чудово. Я раніше помічав []можливість збільшення, але я був нерозумний і намагався це зробити j++. Робить ++jроботи, оскільки []++, мабуть, 0 XD Спасибі!
Mwr247

1
Позначте цей день, коли я дізнався, що do...whileв JS були петлі
Conor O'Brien

6

JavaScript, 120 байт

Ніякого шансу наблизитися до CJam при такому підході, але прямолінійний сценарій.

a=[];t=+new Date;while(s=prompt()){a.push({s:s,t:+new Date})}while(v=a.pop()){setTimeout(`console.log('${v.s}')`,v.t-t)}

1
Здається, ми обидва пішли на JS одночасно ха-ха, хоча ви отримали своє трохи раніше мого. Все-таки різні підходи.
Mwr247

@ Mwr247 Дійсно, твій більш елегантний!
Дом Гастінгс

6

Pyth, 68 байт

M&p+Gb$__import__('time').sleep(H)$J].dZWeaYwaJ.dZ)aJ.dZp&gVPY-VtJJk

Ви витратили багато байт під час виклику sleep, оскільки Pyth не має sleepфункції.


3
Можливо, вам слід запропонувати це як додаток до Pyth.
mbomb007

Я вважаю, що у вас чекають помилки очікування. Спробуйте запустити програму, зачекавши, а потім наберіть щось та натисніть клавішу Enter двічі. Він одразу надрукує перший рядок, потім зачекайте деякий час, перш ніж закінчити.
FryAmTheEggman

6

Рубі, 74

t,*a=Time.now
a<<[$_,t-t=Time.now]while$/<gets
a.map{|l,i|sleep -i;puts l}

Прийоми: *aна першому рядку ініціалізує порожній масив. Я міг би використати $*натомість, але це м'яко схематично, оскільки він заповнений деякими викликами і лише економить мені байт. $/- це новий рядок, і $_це останній рядок, отриманий користувачем gets.

Редагувати: спати в кінці коштує ще 20 байтів, ймовірно, спосіб покататися на ньому

t,*a=Time.now
a<<[$_,t-t=Time.now]while$/<gets
t-=Time.now
a.map{|l,i|sleep -i;puts l}
sleep -t

Я думаю, вам потрібно спати на останньому рядку, залежно від того, скільки часу користувачеві потрібно було ввести порожній рядок.
Конрад Боровський

Якщо ви спите в кінці (рішення 2), ви зателефонуєте Time.nowдостатньо разів, використовуючи def n;Time.now;end, заощадивши цілі 2 байти
значення чорнила

6

Пітон 3, 124

Працює лише на платформах Windows

from time import*
s=[(1,clock())]
while s[-1][0]:s+=[(input(),clock()-s[-1][1])]
[sleep(y)or x and print(x)for x,y in s[1:]]

Утримання введення та часу в окремих списках коштувало мені ще 3 байти . Напевно, не найкращий підхід.

129-байтова версія Unix, кредитна Mego :

from time import*
t=time
s=[(1,t())]
while s[-1][0]:s+=[(input(),t(),t()-s[-1][1])]
[sleep(y)or x and print(x)for x,z,y in s[1:]]

Ви не можете використовувати time()замість цього, clock()щоб зберегти 2 байти?
kirbyfan64sos

4

SWI-Prolog, 185 байт

a:-b([],S),reverse(S,T),c(T),!.
b(R,S):-get_time(X),read_string(user_input,"\n","",_,A),get_time(Y),Z is Y-X,(A="",S=[A:Z|R];b([A:Z|R],S)).
c([A:Z|T]):-sleep(Z),T=[];(write(A),nl,c(T)).

Тут, мабуть, багато для гольфу, але це буде робити зараз ...


4

PowerShell, 261 190 121 95 байт

$(do{Measure-Command{$l=read-host};$l}while($l))|%{($_,(sleep -m($_.Ticks/1e4)))[($b=!$b+!$_)]}

Реквізити TessellatngHeckler і tomkandy для допомоги в гольфі та натхнення

Це за принципом дуже схоже на 121-байтну версію, представлену нижче, ми просто динамічно створюємо та створюємо список об’єктів, замість того, щоб пройти цикл, щоб зберігати їх у явному масиві $a. В обох випадках цей список об'єктів потрапляє в ту саму петлю передбачення |%{...}. Індексація в селекторі масивів результатів ($b=!$b+!$_)цей час формулюється для усунення if($_){$_}нижченаведених ітерацій, що економить ще кілька байт.


Попередній, 121 байт

$l,$a=1,@();while($l){$t=Measure-Command{$l=read-host};$a+=$t,$l}$a|%{($(if($_){$_}),(sleep -m($_.Ticks/1e4)))[($b=!$b)]}

Розширено та пояснено:

$l,$a=1,@()                        # Set variable $l and create array $a
while($l){                         # So long as we don't have a blank line
  $t=Measure-Command{$l=read-host} # Read the input and measure time to input
  $a+=$t,$l                        # Add those values into the array
}
$a|%{                              # For each item in $a, do
  ($(if($_){$_}),(sleep -m($_.Ticks/1e4)))[($b=!$b)]
  # Magic happens here ... first, we set $b to the NOT of it's uninitialized
  # value, so $b is initially set to truthy
  # This value in [...] selects which of the two elements ( , ) get selected
  # Truthy to start means the second command, sleep, gets chosen first, and
  # then it alternates every next item, so it sleeps, then prints, then
  # sleeps, then prints, etc., until we run out of $a
}

Попередня, 190 байт

function f {param($m)sleep -m $a[$m].totalmilliseconds}$a=1,1;while($a[-1]-ne""){$a+=Measure-Command{$b=read-host};$a+=$b}if(!($a[3])){f 2;exit}$i=2;while($i-lt$a.length){f($i++);$a[($i++)]}

function f {                        # Define a new function
  param($m)                         # with $m as input
  sleep -m $a[$m].totalmilliseconds # sleep for $a[$m] milliseconds
}
$a=1,1                              # Create new array with two elements
while($a[-1]-ne""){                 # While the last element isn't empty
  $a+=Measure-Command{$b=read-host} # Read into $b and measure how long that took,
                                    # and add the time into $a
  $a+=$b                            # Then add the input into $a
}
if(!($a[3])){                       # If the third element is empty, the user entered
                                    # a blank as the only input, so...
  f 2                               # sleep for $a[2] ms (how long it took them to hit enter)...
  exit                              # and exit the script
}                                   # Else ...
$i=2                                # Set a counter variable
while($i-lt$a.length){              # While we haven't reached the end of $a
  f($i++)                           # Sleep
  $a[($i++)]                        # Write the output
}

Попередній ер-ер, 261 байт

$a=$d=@();$d+=,@(date);$x=Read-Host
while($x){$a+=,@($x);$d+=,@(date);$x=Read-Host}
if($x){0..($a.Length-1)|%{sleep -m((($d[$_+1]).ticks-($d[$_]).ticks)/1e4);$a[$_]};sleep -m((($d[-1]).ticks-($d[-2]).ticks)/1e4)}
else{sleep -m(((date).Ticks-($d[0]).Ticks)/1e4)}

Святе багатослів’я, Бетмен! Давайте розбимо його:

$a=$d=@()                  # Create two empty arrays
$d+=,@(date)               # Add the current time into $d
$x=Read-Host               # Read the first line
while($x){                 # So long as it's not empty
  $a+=,@($x)               # Add it into our output array
  $d+=,@(date)             # Add the current time into $d
  $x=Read-Host             # Get the next line
}
if($a){                    # So long as $a exists (i.e., the first input wasn't blank)
  0..($a.Length-1)|%{      # For-loop over the length
                           # Sleep for how long it took to do input
    sleep -m((($d[$_+1]).ticks-($d[$_]).ticks)/1e4)
    $a[$_]                 # Print out the input
  }
                           # Sleep the length it took for the final blank
  sleep -m((($d[-1]).ticks-($d[-2]).ticks)/1e4)
}
else{
                           # If we're here, the initial input was blank, so just sleep
  sleep -m(((date).Ticks-($d[0]).Ticks)/1e4)
}

144$a=1,1;while($a[-1]-ne""){$a+=Measure-Command{$b=read-host};$a+=$b};$i=2;while($i-lt$a.length){sleep -m $a[($i++)].totalmilliseconds;$a[($i++)]}
tomkandy

@tomkandy Дякую! Оновлено з удосконаленнями.
AdmBorkBork

@TessellatingHeckler Відмінно! Я боровся зі способом ефективно керувати чергуванням та індексувати такий масив, як очевидний вибір зараз, коли я його бачу. Між іншим, я переграв ще один байт, видаливши @з цього масиву, як це не потрібно в цьому контексті, так що до 121 .
AdmBorkBork

@TimmyD, що я намагався вчора, було вкласти пари ($ t, $ l) у $ a, створивши вкладений масив. Я не міг змусити його працювати, але сьогодні я міг, і це трохи допомагає, тому що не потрібно перемикатися, просто читайте кожну пару і використовуйте їх. Тоді я зрозумів - у нас ідеально хороший трубопровід, який може ставити в чергу чергу, навіщо взагалі зберігати масив? $($l=1;while($l){Measure-Command{$l=read-host};$l})|%{($_,(sleep -m($_.Ticks/1e4)))[($b=!$b+!$_)]}- і зі зміною перемикача, так що коли рядок порожній, вона не перемикається, а замість неї спить - 98
TessellatingHeckler

(Зробіть це do{...}while($l)цикл і опустіть, $l=1;щоб отримати 95 )
TessellatingHeckler

3

Perl 6, 70 символів

repeat {$/=now;.push($!=get,now -$/)}while $!;.map:{sleep $^b;say $^a}

Інтерпретатор Perl 6 визначає лише три символьні змінні (на відміну від божевілля Perl 5). Щоб бути точним, то $/, $!і $_. Ця програма використовує їх усі, щоб уникнути витрат на декларування змінних my.

getчитає рядок зі STDIN. Він не містить нового рядка, на відміну від Perl 5.

nowвбудований повертає поточний час. Якщо відняти, він дає інтервал, який може бути переданий рядку.

Працює метод без нічого зліва (як .pushі .mapв цьому коді) $_.

Використовуючи repeat whileцикл (відомий як do whileв інших мовах програмування), Perl 6 записує поточну часову мітку в $/та виштовхує отриманий рядок (до якого він також зберігається $!) та різницю між поточним часом та часовою міткою в $/. Через порядок параметрів nowне обчислюється до отримання рядка.

У whileперевіряє стан , якщо рядок не порожній (в Perl 6, "0"це справжнє значення, в відміну від Perl 5).

Після того, як я отримую всі часові позначки та лінії, я просто надаю їм mapзворотний дзвінок, який трохи спить, і каже те, що було сказано.


2

Groovy, 202 байти

def b={System.currentTimeMillis()};def h=[];for(;;){def t=b();def s=System.console().readLine();h.add(s+" "+(b()-t));if(s=="")break};for(def s:h){Thread.sleep((s=s.split(" "))[1].toLong());println s[0]}

Радикальний.

Негольована версія:

def b = {System.currentTimeMillis()}; // Creates a closure (short function) b that returns the current time since the epoch in milliseconds.
def h = []; // Makes an empty list
for(;;) { // Infinite loop
  def t = b(); // Get the time
  def s = System.console().readLine(); // Read a line
  h.add(s + " " + b()-t); // Add the string plus the amount of time elapsed to the list
  if(s=="") // If the string is blank
    break; // Exit loop
}
for(def s : h) { // Iterate through array
  Thread.sleep((s=s.split(" "))[1].toLong()); // Splits s into an array and puts the value in s, then takes the second element (the time), converts into a long and sleeps for that time.
  println s[0] // Print the first element (text)
}

2

JavaScript (ES6) 102

Об'єднавши зусилля Mwr247 та Dom Hastings (CW)

/* for TEST */ console.log=x=>O.innerHTML+=x+'\n'

for(k=new Date,i=[];p=prompt();i.push([p,new Date]));i.map(a=>setTimeout(b=>console.log(a[0]),a[1]-k))
<pre id=O></pre>


2

МАТЛАБ, 107 99

tic;a={};i=1;while nnz(i);i=input('','s');a=[a;{i,toc}];tic;end;for b=a';pause(b{2});disp(b{1});end

І неозорені:

tic; %Start timer
a={};
i=1; %Make us enter the while loop
while nnz(i); %While i has some non-zero elements (this is used to detect a zero length input where we end)
    i=input('','s'); %Get an input string
    a=[a;{i,toc}]; %Append the string and current time as a new cell in a
    tic; %Restart timer
end
for b=a' %For each input
    pause(b{2}); %Wait for the required time
    disp(b{1}); %Then print the string
end

Це не буде на 100% точним у часі, оскільки він не враховує час, необхідний для відображення кожної рядки, але це повинно бути досить швидким, так що терміни повинні бути досить близькими.


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


1
Можливо, ви могли б зробити версію, яка в МАТЛ гольфу.
ckjbgames

1

Java, використовуючи версію 1,04 цієї бібліотеки , 385 байт

import sj224.lib.util.*;import java.util.*;class E{static long t(){return System.currentTimeMillis();}public static void main(String[]a) throws Exception{List<Pair<?,Long>>l=new ArrayList();Scanner i=new Scanner(System.in);while(true){long t=t();String s=i.nextLine();if(s.isEmpty())break;l.add(new Pair(s,t()-t));}for(Pair<?,Long>p:l){Thread.sleep(p.two);System.out.println(p.one);}}}

1

Caché ObjectScript, 123 байти

w() q $P($ZTS,",",2)
r f  s i=i+1,t=$$w() r x,! q:x=""  s g(i,x)=$$w()-t
    f i=1:1 s s=$O(g(i,"")) q:s=""  w s,! h g(i,s)
    q

Як завжди, це передбачає чисту таблицю символів перед запуском d r.

Цю проблему неможливо вирішити в ANSI MUMPS, оскільки для стандарту ANSI потрібне лише дозвіл другого рівня для внутрішнього часу $H[OROLOG] . На щастя, Intersystems Caché, яка в даний час в галузі платформу для свинка, забезпечує в реалізації певних $ZT[IME]S[TAMP]сутнісних , яка забезпечує дозвіл мікросекунд-рівня.

(Раніше оцінка склала 105 байт, але помилка.)


1

C ++ 11, 343 338 байт

Хотів подивитися, скільки байтів знадобиться код для цього в c ++. Набагато більше, ніж я очікував. Можливо, я над складним рішенням.

#include<iostream>
#include<vector>
#include<chrono>
int i;using namespace std;int main(){auto n=chrono::system_clock::now;auto t=n();string s{1};vector<string>r;vector<decltype(t-t)>w;while(s.size())getline(cin,s),r.push_back(s),w.push_back(n()-t),t=n();while(i<r.size()){while((n()-t)<w[i]);t=n();cout<<r[i++]<<(i<r.size()-1?"\n":0);}}  

Давайте подивимось, чи можу я якось зменшити це.


Ви можете видалити пробіли в #includes та декларацію типу для main. Це 7 байт - не багато, але початок. Ви також можете використовувати, autoа не stringдля s.
Олексій А.

Дякуємо за відгук. Я збережу тип повернення для основного. Якщо я пам’ятаю правильно, лише для cцього нам не потрібно його вказувати. Я спробував спочатку використовувати auto s... але схоже на те, що він перетворений const char *і ні std::string. Цікаво, чи можу я створити псевдонім для while.
wendelbsilva

Видалення типу повернення працює для C ++, хоча він "не повинен" відповідно до стандарту. Ви можете спробувати створити псевдонім для whileвикористання #defineможливо.
Олексій А.

1

Bash, 91 90 байт

while r=`\time -fsleep\ %e head -1`
[[ $r ]]
do printf{,\ %%b\ %q\;} "$r
"
done>t 2>&1
. t

Це створює тимчасовий файл t . Він замінить наявний файл з тим самим іменем.

Сама ідея досить коротка, але розмова зі спеціальними символами у вводі додає близько 15 байт ...


1

VBA, 233 байт

Я впевнений, що це можна багато в гольф. вони не вказали, скільки входів, тому я важко кодував довжину мого масиву, оскільки його тоді коротшеRedim preserve .

Введення здійснюється через спливаюче вікно, вихід - debug.printтому що msgboxстворюється МОДАЛЬНИЙ і зупиняє код.

Я не знаю, як перевірити, чи це точно до 0,01. Можливо, хтось може перевірити, але я даю команду очікування номер таким чином, щоб він ДОЛЖЕН використовувати мілісекунди, але VBA не відомий для того, щоб робити те, що повинен.

Вони If gotoможуть бути замінені на криниці для гольфу Do Loop While.

Sub a()
Dim k(99) As String
Dim h(99) As Date
b:
t=Now()
i=i+1
k(i)=InputBox("")
h(i)=Now()-t
If k(i)<>"" Then GoTo b
For u=1 To i
Application.Wait (Now()+(Format(h(u),"s")&Format(h(u),"ms"))/10^8)
Debug.Print k(u)
Next
End Sub

Не працюватиме в Access VBA, оскільки в доступі немає команди очікування, оскільки Microsoft ненавидить послідовність


0

SmileBASIC, 122 байти

DIM A$[0],T[0]@L
C=MAINCNT
LINPUT S$PUSH A$,S$PUSH T,MAINCNT-C
IF""<S$GOTO@L@P
WAIT SHIFT(T)IF""<A$[0]THEN?SHIFT(A$)GOTO@P

Я думаю, що це можна зробити трохи коротше.


0

C UNIX, 272 байти

#include <stdio.h>
#include <unistd.h>
#define P printf
i;r;c;main(){char*L[99]={0};size_t s;long T[99]={0};while(1){P(">  ");T[c]=time(0);r=getline(&L[c],&s,stdin);T[c]=time(0)-T[c];if(r==-1|!(*L[c]-10))break;c++;}while(i<c){P("> ");usleep(T[i]*1000);P("%s", L[i]);i++;}}

Детально

#include <stdio.h>
#include <unistd.h>

int main(void)
{
    int i = 0, c = 0, r;
    char * L[99] = {0};
    size_t size;
    long T[99] = {0L};

    while(1)
    {
        printf("> ");
        T[c] = time(0);
        r = getline(&L[c], &size, stdin);
        T[c] = time(0) - T[c];
        if(r == (-1)) break;
        if(*L[c]=='\0' || *L[c]=='\n') break;
        c = c + 1;
    }

    while(i < c)
    {
        printf(" %ld > ",T[i]);
        usleep(T[i]*1000);
        printf("%s", L[i]);
        i = i + 1;
    }

    return 0;
}
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.