Сколько экземпляров запущено?


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/5 → 1/4
  • 2/5 → 2/4
  • 3/5 → (прекращено)
  • 4/5 → 3/4
  • 5/5 → 4/4

правила

  • Вы можете вывести два числа (номер экземпляра, общее количество экземпляров) в любом приемлемом формате.
  • Каждый раз, когда экземпляр запускается или завершается, все остальные экземпляры должны обновить свои соответствующие выходные данные в течение 100 миллисекунд.
  • Если вы решите обновить вывод, печатая на новую строку (или другой «добавляющий» формат вывода; в отличие от замены), вы должны печатать только при изменении количества экземпляров, а не в любое другое время.
  • Это код гольф. Самая короткая программа в байтах побеждает.
  • В своем ответе вам предлагается указать, что пользователь должен сделать, чтобы открыть более одного экземпляра, и / или записать скринкаст для демонстрации.

У кого-нибудь есть предложения по добавлению тегов?
— Darrylyeo

Такая программа будет зависеть от ОС.
— user202729

«Каждый раз, когда экземпляр запускается или завершается, все остальные экземпляры должны обновлять свои соответствующие выходные данные в течение 100 миллисекунд», даже в пределах нашего контроля, учитывая, что мы должны полагаться на ОС для связи (и тот факт, что мы могли бы породить много, многие процессы могут ') не поможет)?
— Джонатан Аллан

Процесс взаимодействия @Ouros не может быть независимым от операционной системы
— edc65

Ответы:


3

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

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

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

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

{… } Анонимная лямбда где ⍵аргумент (изначально ⍬пустой числовой вектор)

 n[… ] Индекс n(подлежит определению) с:

  ⎕TNUMS~0 все Т hread Num Берс кроме номера 0(The РЕПЛ)

   n← хранить как n

   ⍋ перестановка, которая будет сортировать по возрастанию

  теперь у нас есть активные темы в порядке

  ⍵≡ если аргумент идентичен этому ...

  : тогда:

   ∇⍵ Хвост рекурс на аргумент

  ⋄ еще:

   ⊢/n самый правый номер резьбы

   ⎕TID, в этом T hread в ID (номер нити) предваряется , что

   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 мс, у меня есть решение, но дольше
— Науэль Фуийе

0

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

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

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.