Подождите минуту - менее чем за десять секунд


69

задача

Используя любой тип распараллеливания, подождите несколько периодов, чтобы общее время сна составляло не менее минуты (но не более полутора минут).

Программа / функция должна завершиться в течение 10 секунд и вернуть (любым способом и в любом формате) два значения: общее истекшее время и общее выполненное время ожидания. Оба значения времени должны иметь точность не менее 0,1 секунды.

Это похоже на концепцию человеко-часов : работа, которая занимает 60 часов, может быть выполнена всего за 6 часов, если 10 работников разделят работу. Здесь у нас может быть 60 секунд времени ожидания, например, в 10 параллельных потоках, поэтому для завершения всей работы потребуется всего 6 секунд.

пример

Программа MyProgram создает 14 потоков, каждый поток спит 5 секунд:

MyProgram[5.016,70.105]

Время выполнения превышает 5 секунд, а общее время ожидания превышает 70 секунд из-за служебной нагрузки.


2
Я прочитал вопрос несколько раз, и я не понимаю. Можешь немного уточнить? Почему «10 секунд» и задержка «70 секунд»? Как все эти времена связаны?
Луис Мендо

3
Сколько потоков мы можем предположить, будет выполняться параллельно?
миль

3
Какая точность требуется для времени на выходе?
edc65

20
Интересно, не приведёт ли это к тому, что все авторы языка игры в гольф сумасшедшим образом добавят многопоточность к своим творениям ...
Adám

3
@NoOneIsHere А, ну, правильно реализованный метод сна не должен занимать ядро, поэтому число потоков может превышать количество (виртуальных) процессоров.
Адам

Ответы:


15

Dyalog APL, 65 27 23 21 байт

(⌈/,+/)⎕TSYNC⎕DL&¨9/7

То есть:

      (⌈/,+/)⎕TSYNC⎕DL&¨9/7
7.022 63.162

Объяснение:

  • ⎕DL&¨9/7: раскрутить 9 потоков, каждый из которых ждет 7 секунд. ⎕DLвозвращает фактическое количество времени, потраченное на ожидание, в секундах, которое будет таким же, как его аргумент дает или принимает несколько миллисекунд.
  • ⎕TSYNC: дождитесь завершения всех потоков и получите результат для каждого потока.
  • (⌈/,+/): возвращает самое длинное время выполнения одного отдельного потока (во время выполнения которого все другие потоки закончили, так что это фактическое время выполнения), за которым следует сумма времени выполнения всех потоков.

Попробуйте онлайн!


Это не будет работать, если выполнено в 23:59:57. Тем не менее, вы на правильном пути ... Хотя вы уже самый короткий, можете ли вы уйти в гольф еще 40 байтов?
Адам

1
@ Adám: нет, но я могу играть в гольф 38 байтов. Это совершенно очевидно, я не знаю, почему я не думал об этом в первый раз.
Маринус

Вот и ты. Только еще 6 байтов, пока вы не получите галочку. Три вещи, которые вы должны сделать, также довольно очевидны, сохраняя 1, 2 и 3 байта соответственно.
Адам

Очень хорошо, вы нашли номер 1 и номер 3. Номер 2 на самом деле не игра в гольф, а скорее альтернатива реализации ...
Adám

Номер 2: Поскольку вам не нужны аргументы, просто сделайте это в теле tfn.
Адам

18

Python 2, 172 байта

import threading as H,time as T
m=T.time
z=H.Thread
s=m()
r=[]
def f():n=m();T.sleep(9);f.t+=m()-n
f.t=0
exec"r+=[z(None,f)];r[-1].start();"*8
map(z.join,r)
print m()-s,f.t

Это требует операционной системы с точностью времени более 1 секунды для правильной работы (другими словами, любой современной ОС). Создается 8 потоков, каждый из которых спит по 9 секунд, в результате чего время выполнения в реальном времени составляет ~ 9 секунд, а время параллельной работы ~ 72 секунды.

Хотя в официальной документации сказано, что Threadконструктор должен вызываться с помощью аргументов с ключевыми словами, я все же осторожен и в любом случае использую позиционные аргументы. Первый аргумент ( group) должен быть None, а второй аргумент является целевой функцией.

nneonneo указал в комментариях, что доступ к атрибуту (например, f.t) короче, чем доступ по индексу списка (например t[0]). К сожалению, в большинстве случаев несколько байтов, полученных в результате этого, будут потеряны из-за необходимости создания объекта, который позволяет создавать пользовательские атрибуты во время выполнения. К счастью, функции поддерживают пользовательские атрибуты во время выполнения, поэтому я использую это, сохраняя общее время в tатрибуте f.

Попробуйте онлайн

Спасибо DenkerAffe за трюк -5 байтов exec.

Спасибо kundor за -7 байт, указав, что аргумент потока не нужен.

Спасибо nneonneo за -7 байтов от разных улучшений.


Вы можете сохранить два байта, удалив аргумент в f()и два последних аргумента Thread(таким образом удаляя 7 символов) и используя, t.append(m()-n)чтобы избежать присвоения локальной переменной t(используя на 5 символов больше, чем +=.)
Ник Маттео

И вы можете сохранить еще пять, сохранив сумму вместо списка раз: инициализировать tс t=[0], заменить добавление на t[0]+=m()-nи заменить sum(t)на t[0].
Ник Маттео

Имена потоков могут быть опущены.
pppery

@ppperry: нет, если вам нужно использовать последующие позиционные аргументы (но, как я уже упоминал в предыдущих комментариях, вы можете их исключить)
Ник Маттео

Сохранить три байта с помощью import threading as H,time as t; сохранить еще два байта с помощью z=H.Threadи map(z.join,r); сохраните еще два байта, сохранив общее время как атрибут (например T.z+=m()-n)
nneonneo

11

Утилиты Bash + GNU, 85

\time -f%e bash -c 'for i in {1..8};{ \time -aoj -f%e sleep 8&};wait'
paste -sd+ j|bc

Принудительное использование timeисполняемого файла вместо встроенной оболочки путем добавления префикса к \.

Добавляется в файл j, который должен быть пустым или отсутствовать в начале.


А как насчет сценария разветвления? if [ $1 -lt 9 ];then { ./a $(( $1 + 1 )) &};sleep 7;fiили что-то такое? Это противоречит правилам или что-то, чего я не понимаю в спецификации? [редактировать; Я пропустил требование для вывода. Ох, это делает это интересным!]
Деви Морган

1
@DewiMorgan Да, требование к выходу делает его немного сложнее. То, что вы предлагаете, может быть связано с чем-то вроде(($1<9))&&$0 $[$1+1]&sleep 7
Digital Trauma

9

Go - 189 байт

Спасибо @cat!

package main
import(."fmt";."time");var m,t=60001,make(chan int,m);func main(){s:=Now();for i:=0;i<m;i++{go func(){Sleep(Millisecond);t<-0}()};c:=0;for i:=0;i<m;i++{c++};Print(Since(s),c)}

Выходы (мс): 160,9939 мс , 60001 (160 мс для ожидания 60,001 с)


1
Здравствуйте и добро пожаловать в PPCG! Этот комментарий @Rob In some languages the obvious solution is already (close to) the shortest. Besides, one way to view code-golf challenges is finding the shortest solution in EACH language. Otherwise Jelly will win most of the time... So: go ahead.не означает, что вы не должны пытаться сыграть в гольф свой ответ, но это нормально, если он не победит. Можете ли вы добавить решение для игры в гольф?
NoOneIsHere

Извините, я только что прочитал ваше редактирование. Для игры в гольф вы можете удалить новые строки и пробелы или изменить totчто-то подобное q.
NoOneIsHere

@ NoOneIsHere, спасибо за это, я полностью пропустил эту переменную! Также ударил вместе м и т.
Роб

1
codebeautify.org/javaviewer - нажмите преуменьшать
кот


8

Баш 196 117 114 93 байта

Обновлен для поддержки большей точности времени благодаря интеграции предложений от @manatwork и @Digital Trauma, а также нескольких других оптимизаций пространства:

d()(date +$1%s.%N;)
b=`d`
for i in {1..8};{ (d -;sleep 8;d +)>>j&}
wait
bc<<<`d`-$b
bc<<<`<j`

Обратите внимание, что это предполагает, что jфайл отсутствует в начале.


2
function ss(), b=`date +%s`b=$SECONDS, expr $t + $i$[t+i], `cat j`$(<j)и вообще см. Советы по игре в гольф в Bash о том, как уменьшить это до значения: pastebin.com/DDqUaDug
manatwork

Чтобы еще больше его уменьшить, лучше напишите непосредственно формулу в файл j. Я имею в виду вместо 5↵5↵5↵…записи +5+5+5…- затем загрузите все это непосредственно в арифметическую оценку и
сэкономьте

Поскольку минимальная точность была указана позже, забудьте предложение b=`date +%s`b=$SECONDS.
Манатворк

1
Как bashи в случае целочисленной арифметики, все решение необходимо переписать, чтобы использовать внешний инструмент для расчета. Обычно bc: pastebin.com/eYFEVUuz
manatwork

1
@JuliePelletier Хорошо, я отправлю это как мой собственный ответ. Тем не менее, я думаю, что вы все еще можете применить некоторые из техник игры в гольф к своему ответу без существенного изменения подхода: pastebin.com/ssYzVs1n (93 байта)
цифровая травма

8

JavaScript (ES6), 148 байт

with(performance)Promise.all([...Array(9)].map(_=>new Promise(r=>setTimeout(_=>r(t+=now()),7e3,t-=now())),t=0,n=now())).then(_=>alert([now()-n,t]));

Обещает ждать 9 раз в течение 7 секунд в общей сложности 63 секунды (на самом деле 63,43, когда я пытаюсь), но на самом деле, когда я пытаюсь, только 7,05 секунды реального времени.


8

C, 127 байт (вращается процессор)

Это решение вращает процессор вместо сна и подсчитывает время с помощью timesфункции POSIX (которая измеряет время процессора, потребляемое родительским процессом и всеми ожидаемыми дочерними процессами).

Он запускает 7 процессов, которые вращаются по 9 секунд каждый, и выводит окончательное время в C часах (в большинстве систем 100 тактов = 1 секунда).

t;v[4];main(){fork(fork(fork(t=time(0))));while(time(0)<=t+9);wait(0);wait(0);wait(0)>0&&(times(v),printf("%d,%d",v[0],v[2]));}

Образец вывода:

906,6347

что означает 9,06 секунд реального времени и 63,47 секунд общего времени процессора.

Для -std=c90 -m32достижения наилучших результатов скомпилируйте с помощью (принудительное использование 32-битного кода на 64-битной машине).


5

PowerShell v4, 144 байта

$d=date;gjb|rjb
1..20|%{sajb{$x=date;sleep 3;((date)-$x).Ticks/1e7}>$null}
while(gjb -s "Running"){}(gjb|rcjb)-join'+'|iex
((date)-$d).Ticks/1e7

Устанавливает $dравным Get-Dateи очищает любые существующие истории заданий с Get-Job | Remove-Job. Затем мы 1..20|%{...}выполняем цикл и выполняем каждую итерацию, Start-Jobпередавая ему блок сценария {$x=date;sleep 3;((date)-$x).ticks/1e7}для задания (то есть каждое задание будет выполнять этот блок сценария). Мы направляем этот вывод для >$nullподавления обратной связи (т. Е. Имени задания, статуса и т. Д.), Которая возвращается.

Блок сценария устанавливается $xна Get-Date, затем Start-Sleepна 3несколько секунд, затем принимает новое Get-Dateчтение, вычитает $x, получает .Ticksи делит на, 1e7чтобы получить секунды (с точностью).

Вернемся к основной теме, пока любая работа по-прежнему -Sтатус "Running", мы вращаемся внутри пустой whileпетли. Как только это будет сделано, мы будем Get-Jobизвлекать объекты для всех существующих заданий, направлять те, в Receive-Jobкоторые будет извлекать эквивалент STDOUT (то есть то, что они выводят), -joinрезультаты вместе с ними +и направлять iex( Invoke-Expressionи аналогично eval). Это выведет итоговое время ожидания плюс накладные расходы.

Последняя строка похожа в том, что она получает новую дату, вычитает исходную отметку даты $d, получает .Ticksи делит 1e7для вывода общего времени выполнения.


NB

Хорошо, так что это немного изгиба правил. По-видимому, при первом выполнении PowerShell необходимо загрузить несколько сборок .NET с диска для различных операций с потоками, поскольку они не загружены с профилем оболочки по умолчанию. Последующие исполнения, поскольку сборки уже находятся в памяти, работают нормально. Если вы оставите окно оболочки в бездействии достаточно долго, вы получите встроенную сборку мусора PowerShell и разгрузите все эти сборки, в результате чего следующее выполнение займет много времени, так как он перезагружает их. Я не уверен, что можно обойти это.

Вы можете увидеть это во время выполнения в следующих запусках. Я запустил новую оболочку, перешел к своему каталогу по гольфу и выполнил сценарий. Первый запуск был ужасным, но второй (выполненный немедленно) работал нормально. Затем я оставил оболочку на несколько минут бездействующей, чтобы позволить сборке мусора, и затем этот цикл снова стал длительным, но последующие циклы снова работают нормально.

Пример работает

Windows PowerShell
Copyright (C) 2014 Microsoft Corporation. All rights reserved.

PS H:\> c:

PS C:\> cd C:\Tools\Scripts\golfing

PS C:\Tools\Scripts\golfing> .\wait-a-minute.ps1
63.232359
67.8403415

PS C:\Tools\Scripts\golfing> .\wait-a-minute.ps1
61.0809705
8.8991164

PS C:\Tools\Scripts\golfing> .\wait-a-minute.ps1
62.5791712
67.3228933

PS C:\Tools\Scripts\golfing> .\wait-a-minute.ps1
61.1303589
8.5939405

PS C:\Tools\Scripts\golfing> .\wait-a-minute.ps1
61.3210352
8.6386886

PS C:\Tools\Scripts\golfing>

1
Я скажу, что все в порядке. :-)
Адам

5

Javascript (ES6), 212 203 145 байт

Этот код создает 10 изображений с интервалом времени ровно 6 секунд каждое при загрузке.

Время выполнения чуть выше (из-за накладных расходов).

Этот код перезаписывает все в документе!

P=performance,M=P.now(T=Y=0),document.body.innerHTML='<img src=# onerror=setTimeout(`T+=P.now()-M,--i||alert([P.now()-M,T])`,6e3) >'.repeat(i=10)

Это предполагает, что вы используете однобайтовую кодировку для обратных ссылок, которая необходима для того, чтобы механизм Javascript не отключался.


В качестве альтернативы, если вы не хотите тратить 6 секунд на ожидание, вот решение длиной в 1 байт, которое заканчивается менее чем за секунду:

P=performance,M=P.now(T=Y=0),document.body.innerHTML='<img src=# onerror=setTimeout(`T+=P.now()-M,--i||alert([P.now()-M,T])`,600) >'.repeat(i=100)

Разница в том, что этот код ожидает 600 мс на 100 изображениях. Это даст огромное количество накладных расходов.


Старая версия (203 байта):

Этот код создает 10 фреймов с интервалом времени ровно 6 секунд каждый вместо создания 10 изображений.

for(P=performance,M=P.now(T=Y=i=0),D=document,X=_=>{T+=_,--i||alert([P.now()-M,T])};i<10;i++)I=D.createElement`iframe`,I.src='javascript:setTimeout(_=>top.X(performance.now()),6e3)',D.body.appendChild(I)


Оригинальная версия (212 байт):

P=performance,M=P.now(T=Y=0),D=document,X=_=>{T+=_,Y++>8&&alert([P.now()-M,T])},[...''+1e9].map(_=>{I=D.createElement`iframe`,I.src='javascript:setTimeout(_=>top.X(performance.now()),6e3)',D.body.appendChild(I)})


2
+1 Очень хороший и другой подход. Что произойдет в однопоточном браузере?
Адам

2
@ Adám Никаких изменений в поведении. Там все равно будет задержка около 6 секунд. Firefox (однопоточный браузер) иногда выводит забавные вещи, такие как время выполнения 59999. <что-то>.
Исмаэль Мигель

4

Руби, 92

n=->{Time.now}
t=n[]
a=0
(0..9).map{Thread.new{b=n[];sleep 6;a+=n[]-b}}.map &:join
p n[]-t,a

4

Javascript (ES6), 108 92 байта

Я делаю новый ответ, так как он использует немного другой подход.

Он генерирует огромное количество setTimeouts, которые почти все выполняются с 4 мс между ними.

Каждый интервал составляет 610 миллисекунд, в общей сложности 99 интервалов.

M=(N=Date.now)(T=Y=0),eval('setTimeout("T+=N()-M,--i||alert([N()-M,T])",610);'.repeat(i=99))

Обычно он выполняется в течение 610 мс, общее время выполнения составляет около 60,5 секунд.

Это было проверено на Google Chrome версии 51.0.2704.84 m, на Windows 8.1 x64.


Старая версия (108 байт):

P=performance,M=P.now(T=Y=0),eval('setTimeout("T+=P.now()-M,--i||alert([P.now()-M,T])",610);'.repeat(i=99))


4

Царапина - 164 байта (16 блоков)

when gf clicked
set[t v]to[
repeat(9
  create clone of[s v
end
wait until<(t)>[60
say(join(join(t)[ ])(timer
when I start as a clone
wait(8)secs
change[t v]by(timer

Визуальный скрипт

Смотрите это в действии здесь .

Использует переменную с именем 't' и спрайт с именем 's'. Спрайт создает своих клонов, каждый из которых ожидает 8 секунд, и увеличивает переменную, синхронизирующую все время ожидания. В конце указывается общее время выполнения и общее время ожидания (например, 65.488 8.302).


4

Clojure, 135 120 111 109 байт

(let[t #(System/nanoTime)s(t)f #(-(t)%)][(apply +(pmap #(let[s(t)](Thread/sleep 7e3)%(f s))(range 9)))(f s)])

Отформатированная версия с именованными переменными:

(let [time #(System/currentTimeMillis)
      start (time)
      fmt #(- (time) %)]
  [(apply +
           (pmap #(let [thread-start (time)]
                   (Thread/sleep 7e3)
                   %
                   (fmt thread-start)) (range 9)))
   (fmt start)])

выход (в наносекундах):

[62999772966 7001137032]

Изменен формат. Спасибо Адам, я мог пропустить эту спецификацию формата в вопросе, когда я читал ее.

Изменено на nanoTime для игры в гольф.

Спасибо Cliffroot, я полностью забыл о научных обозначениях и не могу поверить, что я не видел apply. Я думаю, что использовал это в чем-то, что я вчера играл в гольф, но никогда не писал. Вы спасли мне 2 байта.


Добро пожаловать в PPCG! Хороший первый пост! Вы можете спросить у ОП о формате вывода.
Rɪᴋᴇʀ

Нет необходимости переворачивать. ОП: любым способом и в любом формате .
Адам

кажется, что вы можете использовать 7e3вместо 7000и использовать applyвместоreduce
Cliffroot

3

Ржавчина, 257 , 247 байт

Я использую то же время, что и в ответе Mego на Python.

На самом деле единственный немного умный бит использует ii, чтобы получить длительность 0 секунд.

fn main(){let n=std::time::Instant::now;let i=n();let h:Vec<_>=(0..8).map(|_|std::thread::spawn(move||{let i=n();std::thread::sleep_ms(9000);i.elapsed()})).collect();let mut t=i-i;for x in h{t+=x.join().unwrap();}print!("{:?}{:?}",t,i.elapsed());}

Печать:

Duration { secs: 71, nanos: 995877193 }Duration { secs: 9, nanos: 774491 }

Ungolfed:

fn main(){
    let n = std::time::Instant::now;
    let i = n();
    let h :Vec<_> =
        (0..8).map(|_|
            std::thread::spawn(
                move||{
                    let i = n();
                    std::thread::sleep_ms(9000);
                    i.elapsed()
                }
            )
        ).collect();
    let mut t=i-i;
    for x in h{
        t+=x.join().unwrap();
    }
    print!("{:?}{:?}",t,i.elapsed());
}

Редактировать: старый добрый цикл немного короче


3

JavaScript (ES6, используя WebWorkers), 233 215 байтов

c=s=0;d=new Date();for(i=14;i-->0;)(new Worker(URL.createObjectURL(new Blob(['a=new Date();setTimeout(()=>postMessage(new Date()-a),5e3)'])))).onmessage=m=>{s+=m.data;if(++c>13)console.log((new Date()-d)/1e3,s/1e3)}

UPD: заменил способ выполнения работника из строки на более компактный и кросс-браузерный в аспекте политик кросс-происхождения. Не будет работать в Safari, если в нем все еще есть webkitURLобъект URL, и в IE.


1
Я получаю сообщение об ошибке при запуске этого:{ "message": "Uncaught SecurityError: Failed to construct 'Worker': Script at 'data:application/javascript,a%3Dnew%20Date()%3BsetTimeout(()%3D%3EpostMessage(new%20Date()-a)%2C5e3)' cannot be accessed from origin 'null'.", "filename": "http://stacksnippets.net/js", "lineno": 13, "colno": 45 }
DJMcMayhem

3

Python 2, 130 байт

import thread as H,time as T
m=T.clock;T.z=m()
def f(k):T.sleep(k);T.z+=m()
exec"H.start_new_thread(f,(7,));"*9
f(8);print m(),T.z

Это вывод ответа Мего, но он достаточно отличается, так что я подумал, что это должен быть отдельный ответ. Протестировано для работы на Windows.

По сути, он разветвляет 9 потоков, которые спят в течение 7 секунд, в то время как родитель спит в течение 8. Затем он распечатывает время. Образец вывода:

8.00059192923 71.0259046024

В Windows time.clockизмеряет время ожидания после первого звонка.


Важно отметить, что это работает только на Windows - time.clock()ведет себя по-разному на платформах Windows и UNIX / Linux .
Mego

3

Perl 6, 72 71 байт

Там может быть более короткий способ сделать это

say sum await map {start {sleep 7;now -ENTER now}},^9;say now -INIT now

это выводы

63.00660729694
7.0064013

2

Mathematica, 109 байт

a=AbsoluteTiming;LaunchKernels@7;Plus@@@a@ParallelTable[#&@@a@Pause@9,{7},Method->"EvaluationsPerKernel"->1]&

Анонимная функция. Требуется лицензия с 7+ ядрами для запуска. Занимает 9 секунд в реальном времени и 63 секунды в режиме ядра, без учета накладных расходов. Убедитесь, что предыдущие операторы выполняются только один раз (чтобы они не пытались перезапустить ядра). Тестирование:

In[1]:= a=AbsoluteTiming;LaunchKernels@7;func=Plus@@@a@ParallelTable[#&@@a@Pause
@9,{7},Method->"EvaluationsPerKernel"->1]&;

In[2]:= func[]

Out[2]= {9.01498, 63.0068}

In[3]:= func[]

Out[3]= {9.01167, 63.0047}

In[4]:= func[]

Out[4]= {9.00587, 63.0051}

2
Оставьте это Вольфраму, чтобы установить лицензионные ограничения для разветвления дочернего процесса.
Марио Карнейро

2

Javascript (ES6), 105 байт

((t,c,d)=>{i=t();while(c--)setTimeout((c,s)=>{d+=t()-s;if(!c)alert([t()-i,d])},8e3,c,t())})(Date.now,8,0)

Обновленная версия: 106 байт Заимствовано у @Ismael Miguel, поскольку у него была прекрасная идея уменьшить время сна и увеличить интервалы.

((t,c,d)=>{i=t();while(c--)setTimeout((c,s)=>{d+=t()-s;if(!c)alert([t()-i,d])},610,c,t())})(Date.now,99,0)

Javascript Ungolfed, 167 байтов

(function(t, c, d){
	i = t();
	while(c--){
		setTimeout(function(c, s){
			d += t() - s;
			if (!c) alert([t() - i, d])
		}, 8e3, c, t())
	}
})(Date.now, 8, 0)


2
Вместо этого d+=t()-s;if(!c)alert([t()-i,d])вы можете написать d+=t()-s;c||alert([t()-i,d]), что сэкономит несколько байтов. Кроме того , если вы удалите функцию и переписать все это, вы можете конкурировать с моим 92-байтовым длительным решением: for(c=8,i=(t=Date.now)(d=0);c--;)setTimeout((c,s)=>{d+=t()-s;c||alert([t()-i,d])},8e3,c,t()). И да, этот также длиной 92 байта.
Исмаэль Мигель

2

Ява, 358 343 337 316 313 байт

import static java.lang.System.*;class t extends Thread{public void run(){long s=nanoTime();try{sleep(999);}catch(Exception e){}t+=nanoTime()-s;}static long t,i,x;public static void main(String[]a)throws Exception{x=nanoTime();for(;++i<99;)new t().start();sleep(9000);out.println((nanoTime()-x)/1e9+" "+t/1e9);}}

и без золота

import static java.lang.System.*;

class t extends Thread {
    public void run() {
        long s = nanoTime();
        try {
            sleep(999);
        } catch (Exception e) {
        }
        t += nanoTime() - s;
    }

    static long t,i,x;

    public static void main(String[] a) throws Exception {
        x = nanoTime();
        for (; ++i < 99;)
            new t().start();
        sleep(9000);
        out.println((nanoTime() - x) / 1e9 + " " + t / 1e9);
    }
}

пожалуйста, не пытайтесь сделать это дома, так как это решение не безопасно.

Редактировать:

Я принял предложения @A Boschman и @ Adám, и теперь моей программе требуется менее 10 секунд для запуска, и она короче на 15 байтов.


2
Вы находитесь внутри потомка класса Thread, не можете ли вы опустить Thread.статические вызовы метода sleep ()? Кроме того, не прекратит ли эта программа чуть более 10 секунд, дисквалифицируя ее?
Восстановить Монику

@ABoschman спасибо за предложение, и оно уже исправлено, оно больше не работает более 10 секунд
user902383

1
Кроме того, не забывайте, у нас есть отличная база советов для игры в гольф на Java :)
Katenkyo

1
Это кажется восприимчивым к условиям чтения-изменения-записи. У вас нет какой-либо блокировки или чего-то другого вокруг вас static long t. Я упоминаю об этом только потому, что спецификация гласит: «Оба значения времени должны иметь точность не менее 0,1 секунды».
Тыкать

1
Вы можете удалить long перед sи добавить ,sв, static long t,i,s;чтобы сохранить несколько байтов.
Кевин Круйссен

2

С (с нитями), 339 336 335 байт

#include<stdio.h>
#include<sys/time.h>
#include<pthread.h>
#define d double
d s=0;int i;pthread_t p[14];d t(){struct timeval a;gettimeofday(&a,NULL);return a.tv_sec+a.tv_usec/1e6;}
h(){d b=t();sleep(5);s+=t()-b;}
main(){d g=t();for(i=14;i-->0;)pthread_create(&p[i],0,&h,0);for(i=14;i-->0;)pthread_join(p[i],0);printf("%f %f",t()-g,s);}

2

C90 (OpenMP), 131 байт (+ 17 для переменной env) = 148 байт

#include <omp.h>
#define o omp_get_wtime()
n[4];main(t){t=o;
#pragma omp parallel
while(o-9<t);times(n);printf("%d,%f",n[0],o-t);}

Пример вывода:

7091,9.000014

Примечания:

7091 находится в циклах (100 / сек), поэтому программа работала в течение 70 секунд

Может быть намного короче, если бы я нашел способ заставить работать таймер, отличный от omp_get_wtime (), потому что тогда я мог бы также удалить оператор include.

Запустить с OMP_NUM_THREADS = 9


Вы можете настроить env var, но для этого вам нужно будет подсчитать байты, за исключением случаев, когда выбранный вами параметр является стандартным по умолчанию.
Адам

@ Adám Спасибо, это то, что я думал, это экономит 6 или 7 байт
dj0wns

2

Common Lisp (SBCL) 166 байт:

(do((m #1=(get-internal-real-time))(o(list 0)))((>(car o)60000)`(,(car o),(- #1#m)))(sb-thread:make-thread(lambda(&aux(s #1#))(sleep 1)(atomic-incf(car o)(- #1#s)))))

Это просто порождает потоки, которые спят, а затем атомарно увеличивают время, которое требуется, с внешним циклом, который вращается, ожидая, что общее время будет больше 60000 тиков (то есть 60 секунд на sbcl). Счетчик хранится в списке из-за ограничений типов мест, которые может изменить atomic-incf. Это может закончиться, прежде чем завершится на более быстрых машинах.

Ungolfed:

(do ((outer-start (get-internal-real-time))
       (total-inner (list 0)))
      ((> (car total-inner) 60000)
       `(,(car total-inner)
      ,(- (get-internal-real-time) outer-start)))
    (sb-thread:make-thread
     (lambda (&aux(start (get-internal-real-time)))
       (sleep 1)
       (atomic-incf (car total-inner) (- (get-internal-real-time) start)))))

2

Perl, 101 байт

use Time::HiRes<time sleep>;pipe*1=\time,0;
print time-$1,eval<1>if open-print{fork&fork&fork}-sleep 9

Форкс 7 дочерних процессов, каждый из которых ждет 9 секунд.

Пример вывода:

perl wait-one-minute.pl
9.00925707817078-63.001741

1

Groovy, 158 143 персонажа

d={new Date().getTime()}
s=d(j=0)
8.times{Thread.start{b=d(m=1000)
sleep 8*m
synchronized(j){j+=d()-b}}}addShutdownHook{print([(d()-s)/m,j/m])}

Образец прогона:

bash-4.3$ groovy wait1minute.groovy
[8.031, 64.055]

1

Эликсир, 168 байт

import Task;import Enum;IO.puts elem(:timer.tc(fn->IO.puts(map(map(1..16,fn _->async(fn->:timer.tc(fn->:timer.sleep(4000)end)end)end),&(elem(await(&1),0)))|>sum)end),0)

Образец прогона:

$ elixir thing.exs
64012846
4007547

Выходными данными является общее время ожидания, за которым следует время, в течение которого программа работала, в микросекундах.

Программа порождает 14 Taskс, и ждет каждого из них, сопоставляя их, а затем находит сумму их прошедшего времени. Он использует Эрланга timerдля измерения времени.


Добро пожаловать в сообщество!
Эрик Outgolfer

1

Haskell, 278 271 262 246 байт

import Control.Concurrent.Chan
import Data.Time
import GHC.Conc
t=getCurrentTime
b!a=b=<<flip diffUTCTime<$>t<*>(a>>t)
w=threadDelay$5^10
0#_=t
i#a=a>>(i-1)#a
main=print!do r<-newChan;9#(forkIO$writeChan r!w);getChanContents r>>=print.sum.take 9

!измеряет время, затраченное действием a(второй аргумент) и применяет b(первый аргумент) к результату.

w это функция сна.

mainизмеряется сам, и результат печатается ( print!...).

#есть replicateMповторение данного действия N раз (и возвращение tиз-за игры в гольф).

Внутри измеряемой части 9 потоков ( replicate 9 $ forkIO ...) спят в течение 5^10миллисекунд (9,765625 секунд) и отправляют результат ( writeChan) в канал, созданный основным потоком ( newChan), который суммирует 9 результатов и печатает итог ( getChanContents >>= print . sum . take 9).

Выход:

87.938546708s
9.772032144s

1
@ Adám 6 ^ 9> 10 ^ 7 (10 секунд).
Котерпиллар

1

Python 2, 132 байта

Использует пул процессов, чтобы порождать 9 процессов и дать каждому спать в течение 7 секунд.

import time as t,multiprocessing as m
def f(x):d=s();t.sleep(x);return s()-d
s=t.time
a=s()
print sum(m.Pool(9).map(f,[7]*9)),s()-a

Сначала выводится общее накопленное время сна, а затем фактическое время выполнения:

$ python test.py
63.0631158352 7.04391384125

1

Рубин (с parallelжемчужиной), 123 116 байт

require'parallel'
n=->{Time.now}
t=n[]
q=0
Parallel.each(1..10,:in_threads=>10){z=n[];sleep 6;q+=n[]-z}
puts n[]-t,q

Изменить: Добавлена ​​ссылка "Time.now" из ответа Руби гистократ.


1

Matlab, 75 байт

tic;parpool(9);b=1:9;parfor q=b
a=tic;pause(7);b(q)=toc(a);end
[sum(b);toc]

Краткое объяснение: parforсоздает параллельный цикл for, распределенный по пулу рабочих. ticи tocизмерять прошедшее время (и, по моему мнению, это одна из лучших функций MATLAB). Последняя строка (массив с общим временем ожидания и прошедшим в реальном времени) выводится, поскольку она не заканчивается точкой с запятой.

Обратите внимание, что это создает колоссальные 9 полноценных процессов MATLAB. Тогда есть вероятность, что эта конкретная программа не будет завершена в течение выделенных 10 секунд на вашем компьютере. Тем не менее, я думаю, что с установкой MATLAB, в которой нет наборов инструментов, за исключением установленного набора инструментов для параллельных вычислений, установленного в высокопроизводительной системе с SSD, можно завершить работу в течение 10 секунд. При необходимости вы можете настроить параметры, чтобы меньше процессов спало больше.


Ошибка о b, вероятно, только потому, что у вас уже было что-то в вашей рабочей области. У меня нет проблем на 2015b с использованиемparfor q=b
Suever

@Suever О, эй, у меня в папке MATLAB был скрипт с именем bm.
Sanchises
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.