Скільки запущених екземплярів?


13

Напишіть нескінченно запущену програму, яка повідомляє про кількість запущених екземплярів. Кожен екземпляр програми повинен також повідомляти про порядок їх відкриття з усіх інших запущених екземплярів.

Приклад

Користувач запускає програму вперше - ми називаємо цей Екземпляр 1. Відображається екземпляр 1 1/1, оскільки це перший екземпляр, який запускається із загальної кількості 1, що працює в даний час.

Поки Імпульс 1 працює, користувач запускає програму вдруге, щоб стати інстанцією 2. Тепер відображається екземпляр 1 1/2, який є першим екземпляром із загальної кількості 2 запущених екземплярів. Екземпляр 2 відображається 2/2, оскільки це другий екземпляр із загальної кількості 2 запущених екземплярів.

Скажімо, користувач продовжує нерестувати більше примірників, поки їх не буде 5 . Для запуску, їх виходи: 1/5 2/5 3/5 4/5 5/5.

Скажімо, користувач вирішує скасувати інстанцію 3. Екземпляр 4 потім стає новим екземпляром 3, а екземпляр 5 - новим екземпляром 4, оскільки вони відповідно третій та четвертий екземпляри були запущені з того, що зараз усього 4 екземпляри. Отже, зміна випуску кожного примірника буде такою:

  • 1/51/4
  • 2/52/4
  • 3/5 → (Припинено)
  • 4/53/4
  • 5/54/4

Правила

  • Ви можете вивести два числа (номер примірника, загальна кількість примірників) у будь-якому розумному форматі.
  • Щоразу, коли екземпляр запускається або припиняється, всі інші екземпляри повинні оновлювати свої відповідні результати протягом 100 мілісекунд.
  • Якщо ви вирішили оновити вихід, надрукувавши новий рядок (або інший "додаючий" формат виводу; на відміну від заміни), ви повинні друкувати лише тоді, коли кількість екземплярів змінюється, а не в інший час.
  • Це код гольфу. Виграє найкоротша програма в байтах.
  • У своїй відповіді вам пропонується вказати, що повинен зробити користувач, щоб відкрити більше одного екземпляра та / або записати екранну трансляцію для демонстрації.

Хтось має запропонувати теги для включення?
darrylyeo

Така програма була б специфічною для ОС.
користувач202729

"Якщо щойно запускається або припиняється екземпляр, всі інші екземпляри повинні оновлювати свої відповідні виходи протягом 100 мілісекунд", навіть в межах нашого контролю, враховуючи, що ми повинні покладатися на операційну систему для зв'язку (і те, що ми могли породити багато, багато процесів може " t допомогти)?
Джонатан Аллан

Взаємодія операції @Ouros не може бути незалежною від ОС
edc65

Відповіді:


3

APL (Dyalog Unicode) , 39 байт SBCS

Функція анонімного префікса. Виклик шляхом нерестування аргументу манекена (порожній числовий вектор), тобто f&⍬. Запитуйте поточні потоки з ⎕TNUMSі вбийте одну або кілька потоків за допомогою ⎕TKILL n. Виведення ниток змінюється [власне число, загальна кількість], як тільки вони отримують час процесора, тобто майже миттєво.

{⍵≡nn[⍋n←⎕TNUMS~0]:∇n⋄∇n⊣⎕←n⍳⎕TID,⊢/n}

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

{} Анонімний лямбда, де аргумент (спочатку порожній числовий вектор)

n[] Індекс n(повинен бути визначений) з:

  ⎕TNUMS~0 всі Т hread Num Берс крім номера 0(The реплєї)

   n← зберігати як n

    перестановка, яка б сортувала висхідну

  тепер у нас є активні нитки в порядку

  ⍵≡ якщо аргумент ідентичний тому ...

  : потім:

   ∇⍵ хвіст повторюється на аргументі

   ще:

   ⊢/n крайній правий номер потоку

   ⎕TID, цей ідентифікатор T- рядка (номер потоку) передчував це

   n⍳ знайти ɩ ndices тих , два

   ⎕← роздрукуйте це до STDOUT

   n⊣ відмовтеся від цього на користь n

    повторювати це


2

Python 3, 694 691 байт

main.py

from requests import post as u
from _thread import*
import os
os.system("start cmd /C python s")
def l():
 def p(q):
  while 1:print(u(*q).text,end="\r")
 q=['http://localhost']
 q+=[u(q[0],'*').text]
 start_new_thread(p,(q,))
 input()
 u(q[0],'-'+q[1])
while 1:
 try:l();break
 except:0

s (короткий для server.py)

from bottle import*
from requests import post as q
try:
 q("http://localhost")
except:
 ids=["0"]
 @post('/')
 def _():
  content = request.body.read().decode('utf-8')
  if len(content)==0:return""
  if content[0]=="*":ids.append(str(int(ids[-1])+1));return str(ids[-1])
  elif content[0]=="-":del ids[ids.index(content[1:])]
  else:return str(ids.index(content)) + "/" + str(len(ids)-1)
 run(port="80")

Чому це так довго?

На жаль, ця функціональність, здається, не вбудована в Python. Мене спокусило використовувати багатопроцесорний процес, але це не зовсім підходить для того, що ми робимо (дозволяючи користувачеві відкривати програму з будь-якого місця).

Отже, я взяв поради щодо публікації в StackOverflow, яку я побачив (я неправильно помістив посилання) і реалізував його за допомогою bottle. (Я відкритий для нових пропозицій).

Я використовував бібліотеку Bottle, щоб запустити свій власний міні-http сервер, щоб усі різні екземпляри могли спілкуватися між собою. Я думаю, я міг би використовувати сокет, хоча я не впевнений, що це зменшило б байт.

У мене є два окремі файли, sі main.py. sне вистачає сервера, і оскільки він з'являється в коді, я подумав, що я повинен зробити ім'я якомога коротшим.

API веб-сервера зв'язку

Веб-сервер приймає лише запити POST і відповідає лише на вхід всередину тіла POST.

Усі запити проходять /(або localhost/).

Дійсний вхід:

  • * в органі публікації буде запитуватися, щоб сервер повернув новий ідентифікатор для призначення клієнту.
  • -<id> в тілі публікації видалить ідентифікатор з активного списку ідентифікаторів, зменшивши всі відповідні ідентифікатори та загальну кількість.
  • Порожній запит у тілі повідомлення просто поверне порожню рядок. Це те, що використовується для тестування, щоб перевірити, чи є сервер в Інтернеті.

Закриття програми

Я реалізував багатопотоковість, тому закриття програми настільки ж просто, як натискання клавіші Enter.

Відкриття програми

Якщо у вас не встановлено належну настройку Python всередині ваших змінних навколишнього середовища, просто створіть .batфайл і помістіть його в ту саму папку, що main.pyі sз наступним кодом (якщо ви встановили Python для всіх користувачів, він може бути в іншому місці):

set PATH=%userprofile%\AppData\Local\Programs\Python\Python36
python main.py

Кредити

Від 694 до 691 байт Adám .


Ви не можете видалити :8080/?
Адам

Якби я призначив порт порту 80, то так; інакше ні. Портом за замовчуванням для веб-браузерів (і запитів) є порт 80, але я можу видалити /.
Ніл

@ Adám Я оновив його зі зміною порту, таким чином зберег 1 байт.
Ніл

1

sh + linux / unix інструменти, 128 байт

якщо сон підтримує числа з плаваючою комою

trap '(flock 9;grep -vw $$ p>t;mv t p)9>l' exit;(flock 9;echo $$>>p)9>l;f(){ echo $(sed -n /^$$\$/= p)/$(wc -l<p);sleep .1;f;};f

в іншому випадку 159 байт

trap '(flock 9;grep -vw $$ p>t;mv t p)9>l' exit;(flock 9;echo $$>>p)9>l;perl -MTime::HiRes=usleep -nE/^$$'$/&&say("$./",$.+(@a=<>)),usleep 1e5,$.=-(@ARGV=p)' p

або сон можна замінити на :(не-оп), але це змусить активно чекати.


Це дійсно близько - "Ви повинні друкувати лише тоді, коли кількість екземплярів змінюється, а не в інший час".
darrylyeo

@darrylyeo просто виправте, але шукав більш короткого рішення, але не встиг, також спати 100 мс, у мене є рішення, але довше
Nahuel Fouilleul

0

Java 8, (199 + 301 =) 500 байт

М.Яр: (основна програма)

import javafx.collections.*;class M{static ObservableList o=FXCollections.observableArrayList();static int j,F;int i,f;{F=0;ListChangeListener e=(ListChangeListener.Change c)->{if(f<1)System.out.println((F>0&i>F?--i:i)+"/"+j);};o.addListener(e);o.add(i=++j);}public void f(){F=f=i;j--;o.remove(--i);}}

S.jar: (сервер для управління потоком програми)

import java.util.*;interface S{static void main(String[]a){List<M>l=new Stack();for(Scanner s=new Scanner(System.in);;){Float n=s.nextFloat();if(n%1==0)l.add(new M());else{int t=(int)(n*10-1);l.get(t).f();l.remove(t);}}}}

Пояснення коду:

import javafx.collections.*;
                  // Required import for ObservableList, FXCollections, and ListChangeListener
class M{          // Program-class
  static ObservableList o=FXCollections.observableArrayList(); 
                  //  Static list to keep record of all instances
  static int j,   //  Static integer (total number of instances)
             F;   //  Static flag (remove occurred?)
  int i,          //  Non-static integer (id of this instance)
      f;          //  Non-static flag (has been removed)
  {               //  Non-static initializer-block (shorter than constructor)
    F=0;          //   Reset the static flag remove_occurred, because we add a new instance
    o.addListener((ListChangeListener.Change c)->{
                  //   Add a change listener for the ObservableList
                  //   This will monitor any additions or removes on the List
       if(f<1)    //    If this instance is not removed yet:
         System.out.println(
                  //     Print:
           (F>0&i>F?
                  //      If a removed occurred and this id is larger than the removed instance
             --i  //       Decrease its id by 1 before printing it
            :     //      Else:
             i)   //       Just print its id
           +"/"+j);
                  //      Plus the total number of instances left
    });
    o.add(        //   Add anything to the Observable list to trigger the listener
     i=++j);      //    Increase the total amount of instances, and set the id of this instance to the last one
  }               //  End of non-static initializer-block
  public void f(){//  Finalize-method
    F=f=i;        //   Set both flags to the current id
    j--;          //   Decrease the total amount of instances
    o.remove(--i);//   Remove the current instance from the list to trigger the listener
  }               //  End of Finalize-method
}                 // End of Program-class

import java.util.*;
                  // Required import for List, Stack and Scanner
interface S{      // Server-class
  static void main(String[]a){
                  //  Mandatory main-method
    List<M>l=new Stack();
                  //   List of programs
    for(Scanner s=new Scanner(System.in);
                  //   Create a STDIN-listener for user input
        ;){       //   Loop indefinitely
      int t=s.nextInt();
                  //    Get the next integer inputted
      if(t<1)     //    If it's 0:
        l.add(new M());
                  //     Startup a new program, and add its instance to the list
      else{       //    Else:
        l.get(t).f();
                  //     Close the program with this integer as id
        l.remove(t);}
                  //     And remove it from the list of programs
    }             //   End of loop
  }               //  End of main-method
}                 // End of Server-class

Загальне пояснення:

Усі програми зберігатимуть власний ідентифікатор; загальна кількість залишених примірників; чи відбулося видалення; і які програми закрили.

Сервер - просто клас обгортки для запуску та зупинки програм. Коли користувач введе 0, він запустить нову програму. Коли використане вводить додатне ціле число (тобто 2), воно закриє програму цим ідентифікатором. (Примітка. S.jar має M.jar як бібліотеку для доступу до неї.)

Gif, щоб побачити це в дії:

введіть тут опис зображення

Думки про гольф далі:

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

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