Зачекайте хвилину - менше ніж за десять секунд


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
Цікаво, чи це призведе до того, що всі автори мови для гольфу
втягнуться

3
@NoOneIsHere Ну, добре, правильно реалізований метод сну не повинен зайняти ядро, тому кількість потоків може перевищувати кількість (віртуальних) процесорів.
Адам

Відповіді:


15

Діялог 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 байт. Це цілком очевидно, я не знаю, чому я не думав про це вперше.
marinus

Ось так. Тільки ще 6 байт, поки не отримаєте галочку. Три речі, які ви повинні зробити, теж досить очевидні, заощаджуючи відповідно 1, 2 та 3 байти.
Адам

Дуже добре, ви знайшли номер 1 і номер 3. Число 2 насправді не є гольф, як альтернатива реалізації ...
Adám

Номер 2: Оскільки аргументи вам не потрібні, просто перетворіть їх у тіло tfn.
Адам

18

Пітон 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], замінити Append шляхом 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виконуваного файлу замість вбудованої оболонки шляхом префіксації a \.

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


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

1
@DewiMorgan Так, вимога виведення робить це дещо складніше. Що ви пропонуєте, можна пограти в щось подібне(($1<9))&&$0 $[$1+1]&sleep 7
Digital Trauma

9

Перехід - 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

Bash 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)і загалом дивіться Поради щодо гольфу на Баші про те, як звести його до цього: pastebin.com/DDqUaDug
манатура

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

Оскільки пізніше була визначена мінімальна точність, забудьте пропозицію b=`date +%s`b=$SECONDS.
манатура

1
Як bashі лише ціла арифметика, все рішення потрібно переписати, щоб використовувати зовнішній інструмент для обчислення. Зазвичай bc: pastebin.com/eYFEVUuz
манатура

1
@JuliePelletier Добре, я опублікую це як свою власну відповідь. І все-таки, я думаю, ви можете все-таки застосувати деякі методи гри в гольф до своєї відповіді, не змінюючи підходу: pastebin.com/ssYzVs1n (93 байт)
Digital Trauma

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 байт (оберти процесора)

Це рішення обертає процесор замість сну, і відраховує час, використовуючи функцію timesPOSIX (яка вимірює час процесора, який витрачається на батьківський процес та у всіх очікуваних дітей).

Він розщеплює 7 процесів, які крутяться протягом 9 секунд за штуку, і друкує остаточний час у годиннику С (для більшості систем 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

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 м на 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

Scratch - 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 для здібностей з гольфу.

Спасибі скеле, я зовсім забув про наукові позначення і не можу повірити, що не бачив apply. Я думаю, що я використовував це в тому, що я займався гольфом вчора, але ніколи не публікував. Ти врятував мені 2 байти.


Ласкаво просимо до PPCG! Гарний перший пост! Ви можете запитати ОП про вихідний формат.
Rɪᴋᴇʀ

Не потрібно реверсувати. ОП: будь-якими способами та в будь-якому форматі .
Adám

Здається, ви можете використовувати 7e3замість цього 7000і використовувати applyзамістьreduce
cliffroot

3

Іржа, 257 , 247 байт

Я використовую ті ж часи, що і відповідь Mego's 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 }

Безголівки:

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

Математика, 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

Java, 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 секунд, дискваліфікуючи її?
Boschman

@ABoschman дякує за пропозицію, і її вже виправлено, вона більше не працює більше 10 сек
user902383

1
Крім того, не забувайте, у нас є чудова база користувачів порад щодо гольфу в java :)
Katenkyo

1
Це здається сприйнятливим до умов перегонів читання-запису. У вас немає жодного замикання або нічого навколо static long t. Я згадую це лише тому, що специфікація говорить: "Обидва часові значення повинні мати точність принаймні 0,1 секунди".
Поки

1
Ви можете видалити long до sі додати ,sдо, static long t,i,s;щоб зберегти кілька байт.
Kevin Cruijssen

2

C (з pthreads), 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

Загальний 166 байт Lisp (SBCL):

(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 може змінювати. Це може не вистачити місця перед тим, як перейти на більш швидкі машини.

Безголівки:

(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для вимірювання часу.


Ласкаво просимо до громади !!
Ерік Атголфер

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

Ruby (з 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

Матлаб, 75 байт

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

Швидке пояснення: parforстворюється паралельний цикл, розподілений по пулу працівників. ticі tocвимірювати час, що минув (і, на мою думку, є однією з найкращих іменованих функцій в MATLAB). Останній рядок (масив із загальним проспаним часом та минулим реальним часом) виводиться, оскільки він не закінчується крапкою з комою.

Однак зауважте, що це створює колосальні 9 повноцінних процесів MATLAB. Тоді ймовірність того, що саме ця програма ця програма не закінчиться протягом відведених 10 секунд на вашій машині. Однак я думаю, що встановлення MATLAB, у якого немає наборів інструментів, за винятком встановленого набору інструментів Parallel Computing - встановленого в системі високого класу з SSD - може просто змогти закінчити протягом 10 секунд. Якщо потрібно, ви можете налаштувати параметри, щоб менше процесів спали більше.


Помилка щодо b, ймовірно, лише тому, що ви вже мали щось у своєму робочому просторі. У 2015b у мене немає проблемparfor q=b
Suever,

@Suever О, ей, у мене в папці MATLAB був сценарій з ім'ям bm.
Санчіз
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.