Wie viele Instanzen werden ausgeführt?


13

Schreiben Sie ein Programm, das auf unbestimmte Zeit ausgeführt wird und angibt, wie viele Instanzen von ihm gerade ausgeführt werden. Jede Instanz des Programms sollte auch die Reihenfolge angeben, in der es von allen anderen derzeit ausgeführten Instanzen geöffnet wurde.

Beispiel

Der Benutzer startet das Programm zum ersten Mal - wir nennen dies Instanz 1. Instanz 1 wird angezeigt 1/1, da es die erste Instanz von insgesamt 1 derzeit ausgeführten Instanzen ist.

Während Instanz 1 ausgeführt wird, startet der Benutzer das Programm ein zweites Mal, um Instanz 2 zu werden. Instanz 1 wird nun angezeigt 1/2und ist die erste von insgesamt 2 derzeit ausgeführten Instanzen. Instanz 2 wird angezeigt 2/2, da es sich um die zweite Instanz von insgesamt 2 derzeit ausgeführten Instanzen handelt.

Nehmen wir an, der Benutzer spawnt so lange mehr Instanzen, bis es 5 davon gibt. Um die Markteinführung, ihre Ausgänge sind: 1/5 2/5 3/5 4/5 5/5.

Angenommen, der Benutzer entscheidet sich, Instanz 3 zu beenden. Instanz 4 wird dann zur neuen Instanz 3 und Instanz 5 zur neuen Instanz 4, da dies die dritte bzw. vierte Instanz ist, die von insgesamt 4 gestartet wurde Instanzen. Die Ausgabe jeder Instanz würde sich also wie folgt ändern:

  • 1/51/4
  • 2/52/4
  • 3/5 → (Abgebrochen)
  • 4/53/4
  • 5/54/4

Regeln

  • Sie können die beiden Zahlen (Instanznummer, Gesamtzahl der Instanzen) in jedem vernünftigen Format ausgeben.
  • Jedes Mal, wenn eine Instanz gestartet oder beendet wird, müssen alle anderen Instanzen ihre jeweiligen Ausgaben innerhalb von 100 Millisekunden aktualisieren.
  • Wenn Sie die Ausgabe aktualisieren möchten, indem Sie in eine neue Zeile drucken (oder ein anderes Ausgabeformat "Anhängen"; im Gegensatz zum Ersetzen), müssen Sie nur drucken, wenn sich die Anzahl der Instanzen ändert, und nicht zu einem anderen Zeitpunkt.
  • Das ist Code Golf. Kürzestes Programm in Bytes gewinnt.
  • In Ihrer Antwort werden Sie aufgefordert, anzugeben, was der Benutzer tun muss, um mehr als eine Instanz zu öffnen, und / oder einen Screencast aufzuzeichnen, um dies zu demonstrieren.

Hat jemand Vorschläge für Tags?
Darrylyeo

Ein solches Programm wäre betriebssystemspezifisch.
user202729

Ist "Jedes Mal, wenn eine Instanz gestartet oder beendet wird, müssen alle anderen Instanzen ihre jeweiligen Ausgaben innerhalb von 100 Millisekunden aktualisieren", auch wenn wir uns auf die Kommunikation des Betriebssystems verlassen müssen (und auf die Tatsache, dass wir viele, viele Prozesse erzeugen können). " nicht helfen)?
Jonathan Allan

@Ouros Prozessinteroperation kann nicht unabhängig vom Betriebssystem sein
edc65

Antworten:


3

APL (Dyalog Unicode) , 39 Byte SBCS

Anonyme Präfixfunktion. Rufen Sie auf, indem Sie das Dummy-Argument (leerer numerischer Vektor) aufrufen, dh f&⍬. Fragen Sie derzeit laufende Threads mit ab ⎕TNUMSund beenden Sie einen oder mehrere Threads mit ⎕TKILL n. Threads geben Änderungen in [eigene Nummer, Gesamtzahl] aus, sobald sie Prozessorzeit erhalten, dh ziemlich sofort.

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

Probieren Sie es online!

{} Anonymes Lambda wo ist das Argument (anfangs der leere numerische Vektor)

n[] Index n(zu definieren) mit:

  ⎕TNUMS~0 alle T hread Num mern außer Nummer 0(die REPL)

   n← speichern als n

    Permutation, die aufsteigend sortieren würde

  Jetzt haben wir die aktiven Threads in Ordnung

  ⍵≡ wenn das Argument damit identisch ist ...

  : dann:

   ∇⍵ Schwanz rekursieren auf das Argument

   sonst:

   ⊢/n die am weitesten rechts stehende Thread-Nummer

   ⎕TID, Diese T der hread ID (Garnnummer) vorangestellt , dass

   n⍳ Finde die Geheimnisse dieser beiden

   ⎕← Drucken Sie das zu STDOUT

   n⊣ verwerfe das zugunsten von n

    darauf zurückgreifen


2

Python 3, 694 691 Bytes

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 (kurz für 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")

Warum ist es so lang?

Leider scheint diese Funktionalität nicht in Python integriert zu sein. Ich war versucht, Multiprocessing zu verwenden, aber das schien nicht ganz das Richtige für das zu sein, was wir tun (einen Benutzer von überall aus ein Programm öffnen zu lassen).

Also nahm ich den Rat eines StackOverflow-Posts an, den ich gesehen hatte (ich habe den Link verlegt) und implementierte ihn mit bottle. (Ich bin offen für neue Vorschläge).

Ich habe die Flaschenbibliothek verwendet, um meinen eigenen Mini-HTTP-Server zu betreiben, damit alle verschiedenen Instanzen miteinander kommunizieren können. Ich nehme an, ich hätte einen Socket verwenden können, obwohl ich nicht überzeugt bin, dass dies die Byteanzahl verringert hätte.

Ich habe zwei separate Dateien sund main.py. sDer Server ist knapp und da er im Code enthalten ist, habe ich mir vorgenommen, den Namen so kurz wie möglich zu halten.

API des Kommunikationswebservers

Der Webserver akzeptiert nur POST-Anfragen und antwortet nur auf Eingaben innerhalb des POST-Körpers.

Alle Anfragen gehen durch /(oder localhost/).

Gültige Eingabe:

  • * Im Post-Body wird der Server aufgefordert, eine neue ID zurückzugeben, um den Client zuzuweisen.
  • -<id> im Beitragskörper wird die ID aus der aktiven Liste der IDs entfernt, wobei alle relevanten IDs und die Gesamtanzahl verringert werden.
  • Bei einer leeren Anforderung im Post-Body wird einfach eine leere Zeichenfolge zurückgegeben. Dies wird verwendet, um zu testen, ob der Server online ist.

Programm schließen

Ich habe Multithreading implementiert, sodass das Schließen des Programms so einfach wie das Drücken der Eingabetaste ist.

Programm öffnen

Wenn Sie das Python-Setup in Ihren Umgebungsvariablen nicht korrekt eingerichtet haben, erstellen Sie einfach eine .batDatei und legen Sie sie in demselben Ordner wie main.pyund smit dem folgenden Code ab (wenn Sie Python für alle Benutzer installiert haben, befindet es sich möglicherweise an einem anderen Speicherort):

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

Credits

Von 694 bis 691 Bytes Adám .


Kannst du nicht entfernen :8080/?
Adám

Wenn ich den Port Port 80 zuweisen würde, dann ja; sonst nein. Der Standardport für Webbrowser (und Anfragen) ist Port 80, aber ich kann den entfernen /.
Neil

@Adám Ich habe es mit der Portänderung aktualisiert, 1 Byte auf diese Weise gespeichert.
Neil

1

sh + Linux / Unix-Tools, 128 Bytes

wenn sleep Gleitkommazahlen unterstützt

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

ansonsten 159 Bytes

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

oder Schlaf kann durch :(no-op) ersetzt werden, aber es wird das Warten aktiv.


Dies ist sehr ähnlich: "Sie müssen nur drucken, wenn sich die Anzahl der Instanzen ändert, und nicht zu einem anderen Zeitpunkt."
darrylyeo

@Darrylyeo nur zu beheben, aber auf der Suche nach kürzeren Lösung, aber nicht die Zeit, auch zu schlafen 100ms, ich habe eine Lösung, aber länger
Nahuel Fouilleul

0

Java 8, (199 + 301 =) 500 Bytes

M.jar: (das Hauptprogramm)

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: (der Server zur Steuerung des Programmflusses)

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);}}}}

Erklärung des Codes:

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

Allgemeine Erklärung:

Alle Programme zeichnen ihre eigene ID auf. die Gesamtzahl der verbleibenden Instanzen; ob eine Entfernung stattgefunden hat; und welche Programme haben geschlossen.

Der Server ist nur eine Wrapper-Klasse zum Starten und Beenden von Programmen. Wenn ein Benutzer eingibt 0, wird ein neues Programm gestartet. Wenn der verwendete eine positive Ganzzahl eingibt (dh 2), wird das Programm mit dieser ID geschlossen. (Hinweis: S.jar hat M.jar als Bibliothek, um darauf zuzugreifen.)

Gif um es in Aktion zu sehen:

Bildbeschreibung hier eingeben

Gedanken, es weiter zu golfen:

Beim Schreiben der Erklärung ist mir gerade aufgefallen, dass ich das nur ObservableListfür das Hinzufügen / Entfernen verwende ListChangeListenerund den Inhalt überhaupt nicht verwende. Wenn Sie dies entfernen und einen anderen statischen Listener verwenden, ist dies möglicherweise kürzer.

Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.