時間依存エコー


38

バックグラウンド

echoプログラムはとてもきれいです。あなたはそれに何でも言うことができ、それはあなたの言葉を毎回完璧に繰り返します!なんてかっこいい!残念なことに、入力速度に関係なく、入力を一度に繰り返しますが、これはあまり現実的ではありません。これを修正する必要があります。

タスク

プログラムは、STDINまたは最も近い同等物から入力を受け取るものとします。ユーザーから空の行が入力されるまで、行を1つずつ読み取り、場合によってはプロンプトを表示します。その後、指定されたのと同じ順序で、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

プログラムが文字を出力するのにかかる時間を無視できますか?つまり、私の言語がcharを出力するのに0.1秒かかることを測定できる場合、それを考慮に入れるべきですか?完全な開示、私は> <>通訳者のティックタイムを使用して遅延を実装することを計画しています。この場合、入力時間を経過するループがあり、表示ループの経過時間を無視できますか?
アーロン

1
@AaronGOUZITあなたが一貫している限り、それを許可します:プログラムが行を印刷し始める瞬間の時間間隔はすべてユーザーから取られるか、行を印刷し終えてから印刷を開始するまでの待ち時間次はすべてユーザーから取得されます。
ズガーブ

1
@TessellatingHeckler後者。セッション例を参照してください。
-Zgarb

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...whileJS にループがあることを学んだ日をマークしてください
コナーオブライエン

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

Pythには機能がないため、の呼び出しで多くのバイトを無駄にしました。sleepsleep


3
たぶん、あなたはPythへの追加としてそれを提案するべきです。
mbomb007

待機中に1つずれたエラーがあると思います。プログラムを起動して、しばらく待ってから、何かを入力してEnterキーをすばやく2回押してみてください。すぐに最初の行を出力し、しばらく待ってから終了します。
FryAmTheEggman

6

ルビー、74

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

トリック:*a最初の行で空の配列を初期化します。$*代わりに使用できますが、いくつかの呼び出しが行われ、1バイトしか節約されないため、やや大ざっぱです。$/は改行であり$_、によって取得される最後の行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

Python 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バイトのコストがかかります。おそらく最善のアプローチではありません。

Megoにクレジットされた129バイトのUnixフレンドリーバージョン:

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+!$_)]}

TessellatngHecklertomkandyのゴルフ支援とインスピレーションの小道具

これは、以下の121バイトバージョンと概念が非常に似ており、whileループを介して明示的な配列に格納するのではなく、オブジェクトのリストを動的に作成および構築するだけです$a。どちらの場合も、そのオブジェクトのリストは同じforeachループにパイプライン化されます|%{...}。今回は、result-array-selectorへのインデックス付けが($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
}

Previous-er-er、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ありがとう!改善されて更新されました。
AdmBorkBork

@TessellatingHecklerすばらしい!私は交互を効果的に制御する方法に苦労していました。そして、そのような配列へのインデックス付けは、私がそれを見たので明白な選択です。ちなみに、私は削除することで、別のバイトをgolfed @それはそう下に、このコンテキストでは必要に応じていないとして、その配列から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)ループし、95$l=1;を取得するドロップ)
TessellatingHeckler

3

Perl 6、70文字

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

Perl 6インタープリターは、3つのシンボリック変数のみを定義します(Perl 5の狂気とは異なります)。正確に$/は、、、$!および$_。このプログラムは、すべてを使用して、を使用して変数を宣言するコストを回避しますmy

getSTDINから行を読み取ります。Perl 5とは異なり、改行は含まれていません。

nowbuiltinは現在の時刻を返します。減算すると、文字列に渡すことができる間隔が得られます。

それを左(のように何も方法.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

MATLAB、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%正確ではありませんが、タイミングが非常に速いため、タイミング的にはかなり近いはずです。


簡単に再検討した後、2層の深いセル配列を削除して、数バイトを節約しました。必要なのは、;梱包時に正しく分割することだけでした。


1
たぶん、あなたはMATLでゴルフされたバージョンを作ることができます。
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標準では時間固有の第2レベルの解像度しか必要とされないため、この問題はANSI MUMPSでは解決できません$H[OROLOG]。幸いなことに、現在MUMPSの業界をリードするプラットフォームであるIntersystemsCachéは$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);}}  

どうにかこれを減らすことができるかどうか見てみましょう。


のスペース#includeとの型宣言を削除できますmain。これは7バイトです。多くはありませんが、開始点です。また、使用することができるかもしれないautoのではなく、stringためs
アレックスA.

フィードバックをお寄せいただきありがとうございます。メインの戻り値の型を保持します。正しく覚えていれば、それだけcを指定する必要はありません。私は最初に使用しようとしましたauto s...しかし、それは変換されconst char *ていないように見えstd::stringます。のエイリアスを作成できるかどうか疑問に思いますwhile
wendelbsilva

戻り値の型を削除することは、標準では「すべきではない」にもかかわらず、C ++では機能します。多分をwhile使用するためのエイリアスを作成してみてください#define
アレックスA.

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 228バイト

私はこれがたくさんゴルフできると確信しています。彼らは入力数を指定しなかったので、配列の長さはそれよりも短いのでハードコーディングしましたRedim preserve

入力はポップアップ経由で、出力はMODALを生成してコードを停止するdebug.printためmsgboxです。

これが0.01の精度であるかどうかをテストする方法がわかりません。誰かがテストできるかもしれませんが、私は待機コマンドにミリ秒を使用する必要がある方法で番号を与えていますが、VBAはそれをすべきことをしていません。

If gotoウェルgolfedによって置換することができてもよいです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

Microsoftは一貫性を嫌っているため、アクセスには待機コマンドがないため、Access VBAでは動作しません


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;
}
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.